mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into addUndefinedCheckToCollectLinkedAliases
This commit is contained in:
+44
-5
@@ -741,7 +741,9 @@ namespace ts {
|
||||
|
||||
if (!result) {
|
||||
if (nameNotFoundMessage) {
|
||||
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
|
||||
if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg)) {
|
||||
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -778,6 +780,43 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: string, nameArg: string | Identifier): boolean {
|
||||
if (!errorLocation || (errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(<Identifier>errorLocation)) || isInTypeQuery(errorLocation))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const container = getThisContainer(errorLocation, /* includeArrowFunctions */ true);
|
||||
let location = container;
|
||||
while (location) {
|
||||
if (isClassLike(location.parent)) {
|
||||
const classSymbol = getSymbolOfNode(location.parent);
|
||||
if (!classSymbol) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check to see if a static member exists.
|
||||
const constructorType = getTypeOfSymbol(classSymbol);
|
||||
if (getPropertyOfType(constructorType, name)) {
|
||||
error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg), symbolToString(classSymbol));
|
||||
return true;
|
||||
}
|
||||
|
||||
// No static member is present.
|
||||
// Check if we're in an instance method and look for a relevant instance member.
|
||||
if (location === container && !(location.flags & NodeFlags.Static)) {
|
||||
const instanceType = (<InterfaceType>getDeclaredTypeOfSymbol(classSymbol)).thisType;
|
||||
if (getPropertyOfType(instanceType, name)) {
|
||||
error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
location = location.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
|
||||
Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0);
|
||||
// Block-scoped variables cannot be used before their definition
|
||||
@@ -6688,10 +6727,6 @@ namespace ts {
|
||||
if (typeInfo && typeInfo.type === undefinedType) {
|
||||
return type;
|
||||
}
|
||||
// If the type to be narrowed is any and we're checking a primitive with assumeTrue=true, return the primitive
|
||||
if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
|
||||
return typeInfo.type;
|
||||
}
|
||||
let flags: TypeFlags;
|
||||
if (typeInfo) {
|
||||
flags = typeInfo.flags;
|
||||
@@ -6702,6 +6737,10 @@ namespace ts {
|
||||
}
|
||||
// At this point we can bail if it's not a union
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
// If we're on the true branch and the type is a subtype, we should return the primitive type
|
||||
if (assumeTrue && typeInfo && isTypeSubtypeOf(typeInfo.type, type)) {
|
||||
return typeInfo.type;
|
||||
}
|
||||
// If the active non-union type would be removed from a union by this type guard, return an empty union
|
||||
return filterUnion(type) ? type : emptyUnionType;
|
||||
}
|
||||
|
||||
+10
-1
@@ -616,7 +616,9 @@ namespace ts {
|
||||
return path.substr(0, rootLength) + normalized.join(directorySeparator);
|
||||
}
|
||||
|
||||
export function getDirectoryPath(path: string) {
|
||||
export function getDirectoryPath(path: Path): Path;
|
||||
export function getDirectoryPath(path: string): string;
|
||||
export function getDirectoryPath(path: string): any {
|
||||
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
|
||||
}
|
||||
|
||||
@@ -874,4 +876,11 @@ namespace ts {
|
||||
}
|
||||
return copiedList;
|
||||
}
|
||||
|
||||
export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitivefileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1767,6 +1767,14 @@
|
||||
"category": "Error",
|
||||
"code": 2661
|
||||
},
|
||||
"Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?": {
|
||||
"category": "Error",
|
||||
"code": 2662
|
||||
},
|
||||
"Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?": {
|
||||
"category": "Error",
|
||||
"code": 2663
|
||||
},
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
|
||||
@@ -2886,7 +2886,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
if ((<ForStatement | ForInStatement | ForOfStatement>node).initializer.kind === SyntaxKind.VariableDeclarationList) {
|
||||
const initializer = (<ForStatement | ForInStatement | ForOfStatement>node).initializer;
|
||||
if (initializer && initializer.kind === SyntaxKind.VariableDeclarationList) {
|
||||
loopInitializer = <VariableDeclarationList>(<ForStatement | ForInStatement | ForOfStatement>node).initializer;
|
||||
}
|
||||
break;
|
||||
|
||||
+124
-22
@@ -1,6 +1,9 @@
|
||||
/// <reference path="core.ts"/>
|
||||
|
||||
namespace ts {
|
||||
export type FileWatcherCallback = (path: string, removed?: boolean) => void;
|
||||
export type DirectoryWatcherCallback = (path: string) => void;
|
||||
|
||||
export interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
@@ -8,8 +11,8 @@ namespace ts {
|
||||
write(s: string): void;
|
||||
readFile(path: string, encoding?: string): string;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
watchFile?(path: string, callback: (path: string, removed?: boolean) => void): FileWatcher;
|
||||
watchDirectory?(path: string, callback: (path: string) => void, recursive?: boolean): FileWatcher;
|
||||
watchFile?(path: Path, callback: FileWatcherCallback): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
resolvePath(path: string): string;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
@@ -22,15 +25,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface WatchedFile {
|
||||
fileName: string;
|
||||
callback: (fileName: string, removed?: boolean) => void;
|
||||
mtime: Date;
|
||||
filePath: Path;
|
||||
callback: FileWatcherCallback;
|
||||
mtime?: Date;
|
||||
}
|
||||
|
||||
export interface FileWatcher {
|
||||
close(): void;
|
||||
}
|
||||
|
||||
export interface DirectoryWatcher extends FileWatcher {
|
||||
directoryPath: Path;
|
||||
referenceCount: number;
|
||||
}
|
||||
|
||||
declare var require: any;
|
||||
declare var module: any;
|
||||
declare var process: any;
|
||||
@@ -62,8 +70,8 @@ namespace ts {
|
||||
readFile(path: string): string;
|
||||
writeFile(path: string, contents: string): void;
|
||||
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
|
||||
watchFile?(path: string, callback: (path: string, removed?: boolean) => void): FileWatcher;
|
||||
watchDirectory?(path: string, callback: (path: string) => void, recursive?: boolean): FileWatcher;
|
||||
watchFile?(path: string, callback: FileWatcherCallback): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
};
|
||||
|
||||
export var sys: System = (function () {
|
||||
@@ -221,7 +229,7 @@ namespace ts {
|
||||
|
||||
// average async stat takes about 30 microseconds
|
||||
// set chunk size to do 30 files in < 1 millisecond
|
||||
function createWatchedFileSet(interval = 2500, chunkSize = 30) {
|
||||
function createPollingWatchedFileSet(interval = 2500, chunkSize = 30) {
|
||||
let watchedFiles: WatchedFile[] = [];
|
||||
let nextFileToCheck = 0;
|
||||
let watchTimer: any;
|
||||
@@ -236,13 +244,13 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
_fs.stat(watchedFile.fileName, (err: any, stats: any) => {
|
||||
_fs.stat(watchedFile.filePath, (err: any, stats: any) => {
|
||||
if (err) {
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
watchedFile.callback(watchedFile.filePath);
|
||||
}
|
||||
else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
|
||||
watchedFile.mtime = getModifiedTime(watchedFile.fileName);
|
||||
watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0);
|
||||
watchedFile.mtime = getModifiedTime(watchedFile.filePath);
|
||||
watchedFile.callback(watchedFile.filePath, watchedFile.mtime.getTime() === 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -270,11 +278,11 @@ namespace ts {
|
||||
}, interval);
|
||||
}
|
||||
|
||||
function addFile(fileName: string, callback: (fileName: string, removed?: boolean) => void): WatchedFile {
|
||||
function addFile(filePath: Path, callback: FileWatcherCallback): WatchedFile {
|
||||
const file: WatchedFile = {
|
||||
fileName,
|
||||
filePath,
|
||||
callback,
|
||||
mtime: getModifiedTime(fileName)
|
||||
mtime: getModifiedTime(filePath)
|
||||
};
|
||||
|
||||
watchedFiles.push(file);
|
||||
@@ -297,6 +305,88 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function createWatchedFileSet() {
|
||||
const dirWatchers = createFileMap<DirectoryWatcher>();
|
||||
// One file can have multiple watchers
|
||||
const fileWatcherCallbacks = createFileMap<FileWatcherCallback[]>();
|
||||
return { addFile, removeFile };
|
||||
|
||||
function reduceDirWatcherRefCountForFile(filePath: Path) {
|
||||
const dirPath = getDirectoryPath(filePath);
|
||||
if (dirWatchers.contains(dirPath)) {
|
||||
const watcher = dirWatchers.get(dirPath);
|
||||
watcher.referenceCount -= 1;
|
||||
if (watcher.referenceCount <= 0) {
|
||||
watcher.close();
|
||||
dirWatchers.remove(dirPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addDirWatcher(dirPath: Path): void {
|
||||
if (dirWatchers.contains(dirPath)) {
|
||||
const watcher = dirWatchers.get(dirPath);
|
||||
watcher.referenceCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const watcher: DirectoryWatcher = _fs.watch(
|
||||
dirPath,
|
||||
{ persistent: true },
|
||||
(eventName: string, relativeFileName: string) => fileEventHandler(eventName, relativeFileName, dirPath)
|
||||
);
|
||||
watcher.referenceCount = 1;
|
||||
dirWatchers.set(dirPath, watcher);
|
||||
return;
|
||||
}
|
||||
|
||||
function addFileWatcherCallback(filePath: Path, callback: FileWatcherCallback): void {
|
||||
if (fileWatcherCallbacks.contains(filePath)) {
|
||||
fileWatcherCallbacks.get(filePath).push(callback);
|
||||
}
|
||||
else {
|
||||
fileWatcherCallbacks.set(filePath, [callback]);
|
||||
}
|
||||
}
|
||||
|
||||
function addFile(filePath: Path, callback: FileWatcherCallback): WatchedFile {
|
||||
addFileWatcherCallback(filePath, callback);
|
||||
addDirWatcher(getDirectoryPath(filePath));
|
||||
|
||||
return { filePath, callback };
|
||||
}
|
||||
|
||||
function removeFile(watchedFile: WatchedFile) {
|
||||
removeFileWatcherCallback(watchedFile.filePath, watchedFile.callback);
|
||||
reduceDirWatcherRefCountForFile(watchedFile.filePath);
|
||||
}
|
||||
|
||||
function removeFileWatcherCallback(filePath: Path, callback: FileWatcherCallback) {
|
||||
if (fileWatcherCallbacks.contains(filePath)) {
|
||||
const newCallbacks = copyListRemovingItem(callback, fileWatcherCallbacks.get(filePath));
|
||||
if (newCallbacks.length === 0) {
|
||||
fileWatcherCallbacks.remove(filePath);
|
||||
}
|
||||
else {
|
||||
fileWatcherCallbacks.set(filePath, newCallbacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param watcherPath is the path from which the watcher is triggered.
|
||||
*/
|
||||
function fileEventHandler(eventName: string, relativefileName: string, baseDirPath: Path) {
|
||||
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
|
||||
const filePath = relativefileName === undefined ? undefined : toPath(relativefileName, baseDirPath, getCanonicalPath);
|
||||
if (eventName === "change" && fileWatcherCallbacks.contains(filePath)) {
|
||||
for (const fileCallback of fileWatcherCallbacks.get(filePath)) {
|
||||
fileCallback(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REVIEW: for now this implementation uses polling.
|
||||
// The advantage of polling is that it works reliably
|
||||
// on all os and with network mounted files.
|
||||
@@ -310,8 +400,13 @@ namespace ts {
|
||||
// changes for large reference sets? If so, do we want
|
||||
// to increase the chunk size or decrease the interval
|
||||
// time dynamically to match the large reference set?
|
||||
const pollingWatchedFileSet = createPollingWatchedFileSet();
|
||||
const watchedFileSet = createWatchedFileSet();
|
||||
|
||||
function isNode4OrLater(): boolean {
|
||||
return parseInt(process.version.charAt(1)) >= 4;
|
||||
}
|
||||
|
||||
const platform: string = _os.platform();
|
||||
// win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive
|
||||
const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
|
||||
@@ -405,29 +500,38 @@ namespace ts {
|
||||
},
|
||||
readFile,
|
||||
writeFile,
|
||||
watchFile: (fileName, callback) => {
|
||||
watchFile: (filePath, callback) => {
|
||||
// Node 4.0 stablized the `fs.watch` function on Windows which avoids polling
|
||||
// and is more efficient than `fs.watchFile` (ref: https://github.com/nodejs/node/pull/2649
|
||||
// and https://github.com/Microsoft/TypeScript/issues/4643), therefore
|
||||
// if the current node.js version is newer than 4, use `fs.watch` instead.
|
||||
const watchedFile = watchedFileSet.addFile(fileName, callback);
|
||||
const watchSet = isNode4OrLater() ? watchedFileSet : pollingWatchedFileSet;
|
||||
const watchedFile = watchSet.addFile(filePath, callback);
|
||||
return {
|
||||
close: () => watchedFileSet.removeFile(watchedFile)
|
||||
close: () => watchSet.removeFile(watchedFile)
|
||||
};
|
||||
},
|
||||
watchDirectory: (path, callback, recursive) => {
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
let options: any;
|
||||
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
options = { persistent: true, recursive: !!recursive };
|
||||
}
|
||||
else {
|
||||
options = { persistent: true };
|
||||
}
|
||||
|
||||
return _fs.watch(
|
||||
path,
|
||||
{ persistent: true, recursive: !!recursive },
|
||||
options,
|
||||
(eventName: string, relativeFileName: string) => {
|
||||
// In watchDirectory we only care about adding and removing files (when event name is
|
||||
// "rename"); changes made within files are handled by corresponding fileWatchers (when
|
||||
// event name is "change")
|
||||
if (eventName === "rename") {
|
||||
// When deleting a file, the passed baseFileName is null
|
||||
callback(!relativeFileName ? relativeFileName : normalizePath(ts.combinePaths(path, relativeFileName)));
|
||||
callback(!relativeFileName ? relativeFileName : normalizePath(combinePaths(path, relativeFileName)));
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -511,5 +615,3 @@ namespace ts {
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-2
@@ -334,7 +334,8 @@ namespace ts {
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
if (configFileName) {
|
||||
configFileWatcher = sys.watchFile(configFileName, configFileChanged);
|
||||
const configFilePath = toPath(configFileName, sys.getCurrentDirectory(), createGetCanonicalFileName(sys.useCaseSensitiveFileNames));
|
||||
configFileWatcher = sys.watchFile(configFilePath, configFileChanged);
|
||||
}
|
||||
if (sys.watchDirectory && configFileName) {
|
||||
const directory = ts.getDirectoryPath(configFileName);
|
||||
@@ -442,7 +443,8 @@ namespace ts {
|
||||
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
||||
if (sourceFile && compilerOptions.watch) {
|
||||
// Attach a file watcher
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
const filePath = toPath(sourceFile.fileName, sys.getCurrentDirectory(), createGetCanonicalFileName(sys.useCaseSensitiveFileNames));
|
||||
sourceFile.fileWatcher = sys.watchFile(filePath, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
}
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
@@ -1002,7 +1002,7 @@ namespace ts.server {
|
||||
info.setFormatOptions(this.getFormatCodeOptions());
|
||||
this.filenameToScriptInfo[fileName] = info;
|
||||
if (!info.isOpen) {
|
||||
info.fileWatcher = this.host.watchFile(fileName, _ => { this.watchedFileChanged(fileName); });
|
||||
info.fileWatcher = this.host.watchFile(<Path>fileName, _ => { this.watchedFileChanged(fileName); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1215,7 +1215,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
project.finishGraph();
|
||||
project.projectFileWatcher = this.host.watchFile(configFilename, _ => this.watchedProjectConfigFileChanged(project));
|
||||
project.projectFileWatcher = this.host.watchFile(<Path>configFilename, _ => this.watchedProjectConfigFileChanged(project));
|
||||
this.log("Add recursive watcher for: " + ts.getDirectoryPath(configFilename));
|
||||
project.directoryWatcher = this.host.watchDirectory(
|
||||
ts.getDirectoryPath(configFilename),
|
||||
|
||||
+29
-11
@@ -2018,13 +2018,6 @@ namespace ts {
|
||||
return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true);
|
||||
}
|
||||
|
||||
export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitivefileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry {
|
||||
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
|
||||
// for those settings.
|
||||
@@ -6018,14 +6011,38 @@ namespace ts {
|
||||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {});
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[]): void {
|
||||
/**
|
||||
* Find symbol of the given property-name and add the symbol to the given result array
|
||||
* @param symbol a symbol to start searching for the given propertyName
|
||||
* @param propertyName a name of property to serach for
|
||||
* @param result an array of symbol of found property symbols
|
||||
* @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisitng of the same symbol.
|
||||
* The value of previousIterationSymbol is undefined when the function is first called.
|
||||
*/
|
||||
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[],
|
||||
previousIterationSymbolsCache: SymbolTable): void {
|
||||
// If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited
|
||||
// This is particularly important for the following cases, so that we do not infinitely visit the same symbol.
|
||||
// For example:
|
||||
// interface C extends C {
|
||||
// /*findRef*/propName: string;
|
||||
// }
|
||||
// The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName,
|
||||
// the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined,
|
||||
// the function will add any found symbol of the property-name, then its sub-routine will call
|
||||
// getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
|
||||
// visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
|
||||
if (hasProperty(previousIterationSymbolsCache, symbol.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (symbol && symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
forEach(symbol.getDeclarations(), declaration => {
|
||||
if (declaration.kind === SyntaxKind.ClassDeclaration) {
|
||||
@@ -6049,7 +6066,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Visit the typeReference as well to see if it directly or indirectly use that property
|
||||
getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result);
|
||||
previousIterationSymbolsCache[symbol.name] = symbol;
|
||||
getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6101,7 +6119,7 @@ namespace ts {
|
||||
// see if any is in the list
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {});
|
||||
return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user