diff --git a/lib/tsc.js b/lib/tsc.js index bacfdc2d70464..1c2188f24aff5 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -36367,6 +36367,9 @@ var ts; var requireSymbol = createSymbol(4, "require"); var apparentArgumentCount; var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -39625,7 +39628,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -39672,6 +39677,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -40544,6 +40550,29 @@ var ts; } return chain; function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128)); var parentSpecifiers; if (!accessibleSymbolChain || diff --git a/lib/tsserver.js b/lib/tsserver.js index 2ebe0565b4ee9..56d986fadbaae 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -44650,6 +44650,9 @@ var ts; // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -48372,7 +48375,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32 /* Class */) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824 /* IsClassInstanceClone */)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -48420,6 +48425,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -49340,6 +49346,29 @@ var ts; return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */)); var parentSpecifiers; if (!accessibleSymbolChain || @@ -152926,10 +152955,11 @@ var ts; synchronizeHostData(); return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, preferences); } - function getQuickInfoAtPosition(fileName, position) { + function getQuickInfoAtPosition(arg0, arg1) { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); - var node = ts.getTouchingPropertyName(sourceFile, position); + var sourceFile = typeof arg0 === 'string' ? getValidSourceFile(arg0) : (arg1 !== undefined) ? arg1 : arg0.getSourceFile(); + var node = typeof arg0 === 'string' ? ts.getTouchingPropertyName(sourceFile, arg1) : arg0; + var position = typeof arg1 === 'number' ? arg1 : node.getStart(sourceFile, false); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -153178,9 +153208,9 @@ var ts; // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName) { + function getOutliningSpans(arg0) { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + var sourceFile = typeof arg0 === 'string' ? syntaxTreeCache.getCurrentSourceFile(arg0) : arg0; return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } var braceMatching = new ts.Map(ts.getEntries((_a = {}, @@ -154925,14 +154955,11 @@ var ts; return _this.realizeDiagnostics(diagnostics); }); }; - /// QUICKINFO - /** - * Computes a string representation of the type at the requested position - * in the active file. - */ - LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) { + LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (arg0, arg1) { var _this = this; - return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); }); + var fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? arg1.fileName : arg0.getSourceFile().fileName; + var position = typeof arg0 === "string" ? arg1 : arg0.getStart(arg1); + return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(arg0, arg1); }); }; /// NAMEORDOTTEDNAMESPAN /** @@ -155107,9 +155134,10 @@ var ts; var _this = this; return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); }); }; - LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) { + LanguageServiceShimObject.prototype.getOutliningSpans = function (arg0) { var _this = this; - return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); }); + var fileName = typeof arg0 === "string" ? arg0 : arg0.fileName; + return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(arg0); }); }; LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) { var _this = this; diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index a2ff8fc1ea29a..0b59737e9e7af 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2163,7 +2163,20 @@ declare namespace ts { diagnostics: readonly Diagnostic[]; emittedFiles?: string[]; } + export interface SymbolChainCacheKey { + symbol: Symbol; + enclosingDeclaration?: Node; + flags: NodeBuilderFlags; + meaning: SymbolFlags; + yieldModuleSymbol?: boolean; + endOfChain: boolean; + } + export interface SymbolChainCache { + lookup(key: SymbolChainCacheKey): Symbol[] | undefined; + cache(key: SymbolChainCacheKey, value: Symbol[]): void; + } export interface TypeChecker { + setSymbolChainCache(cache: SymbolChainCache | undefined): void; getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; @@ -5599,6 +5612,7 @@ declare namespace ts { * @param position A zero-based index of the character where you want the quick info */ getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; + getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo | undefined; getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined; getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined; getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined; @@ -5622,6 +5636,7 @@ declare namespace ts { provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; + getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 086d3b2f2a99b..2adf0ee1be91e 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -44844,6 +44844,9 @@ var ts; // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -48566,7 +48569,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32 /* Class */) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824 /* IsClassInstanceClone */)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -48614,6 +48619,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -49534,6 +49540,29 @@ var ts; return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */)); var parentSpecifiers; if (!accessibleSymbolChain || @@ -153495,10 +153524,11 @@ var ts; synchronizeHostData(); return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, preferences); } - function getQuickInfoAtPosition(fileName, position) { + function getQuickInfoAtPosition(arg0, arg1) { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); - var node = ts.getTouchingPropertyName(sourceFile, position); + var sourceFile = typeof arg0 === 'string' ? getValidSourceFile(arg0) : (arg1 !== undefined) ? arg1 : arg0.getSourceFile(); + var node = typeof arg0 === 'string' ? ts.getTouchingPropertyName(sourceFile, arg1) : arg0; + var position = typeof arg1 === 'number' ? arg1 : node.getStart(sourceFile, false); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -153747,9 +153777,9 @@ var ts; // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName) { + function getOutliningSpans(arg0) { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + var sourceFile = typeof arg0 === 'string' ? syntaxTreeCache.getCurrentSourceFile(arg0) : arg0; return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } var braceMatching = new ts.Map(ts.getEntries((_a = {}, @@ -155494,14 +155524,11 @@ var ts; return _this.realizeDiagnostics(diagnostics); }); }; - /// QUICKINFO - /** - * Computes a string representation of the type at the requested position - * in the active file. - */ - LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) { + LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (arg0, arg1) { var _this = this; - return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); }); + var fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? arg1.fileName : arg0.getSourceFile().fileName; + var position = typeof arg0 === "string" ? arg1 : arg0.getStart(arg1); + return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(arg0, arg1); }); }; /// NAMEORDOTTEDNAMESPAN /** @@ -155676,9 +155703,10 @@ var ts; var _this = this; return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); }); }; - LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) { + LanguageServiceShimObject.prototype.getOutliningSpans = function (arg0) { var _this = this; - return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); }); + var fileName = typeof arg0 === "string" ? arg0 : arg0.fileName; + return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(arg0); }); }; LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) { var _this = this; diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 0b2d291eeddb5..b1b071aa237b4 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -2163,7 +2163,20 @@ declare namespace ts { diagnostics: readonly Diagnostic[]; emittedFiles?: string[]; } + export interface SymbolChainCacheKey { + symbol: Symbol; + enclosingDeclaration?: Node; + flags: NodeBuilderFlags; + meaning: SymbolFlags; + yieldModuleSymbol?: boolean; + endOfChain: boolean; + } + export interface SymbolChainCache { + lookup(key: SymbolChainCacheKey): Symbol[] | undefined; + cache(key: SymbolChainCacheKey, value: Symbol[]): void; + } export interface TypeChecker { + setSymbolChainCache(cache: SymbolChainCache | undefined): void; getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; @@ -5599,6 +5612,7 @@ declare namespace ts { * @param position A zero-based index of the character where you want the quick info */ getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; + getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo | undefined; getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined; getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined; getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined; @@ -5622,6 +5636,7 @@ declare namespace ts { provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; + getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number; diff --git a/lib/typescript.js b/lib/typescript.js index 9c998682479cc..166db90487a25 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -44844,6 +44844,9 @@ var ts; // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -48566,7 +48569,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32 /* Class */) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824 /* IsClassInstanceClone */)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -48614,6 +48619,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -49534,6 +49540,29 @@ var ts; return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */)); var parentSpecifiers; if (!accessibleSymbolChain || @@ -153495,10 +153524,11 @@ var ts; synchronizeHostData(); return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, preferences); } - function getQuickInfoAtPosition(fileName, position) { + function getQuickInfoAtPosition(arg0, arg1) { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); - var node = ts.getTouchingPropertyName(sourceFile, position); + var sourceFile = typeof arg0 === 'string' ? getValidSourceFile(arg0) : (arg1 !== undefined) ? arg1 : arg0.getSourceFile(); + var node = typeof arg0 === 'string' ? ts.getTouchingPropertyName(sourceFile, arg1) : arg0; + var position = typeof arg1 === 'number' ? arg1 : node.getStart(sourceFile, false); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -153747,9 +153777,9 @@ var ts; // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName) { + function getOutliningSpans(arg0) { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + var sourceFile = typeof arg0 === 'string' ? syntaxTreeCache.getCurrentSourceFile(arg0) : arg0; return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } var braceMatching = new ts.Map(ts.getEntries((_a = {}, @@ -155494,14 +155524,11 @@ var ts; return _this.realizeDiagnostics(diagnostics); }); }; - /// QUICKINFO - /** - * Computes a string representation of the type at the requested position - * in the active file. - */ - LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) { + LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (arg0, arg1) { var _this = this; - return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); }); + var fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? arg1.fileName : arg0.getSourceFile().fileName; + var position = typeof arg0 === "string" ? arg1 : arg0.getStart(arg1); + return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(arg0, arg1); }); }; /// NAMEORDOTTEDNAMESPAN /** @@ -155676,9 +155703,10 @@ var ts; var _this = this; return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); }); }; - LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) { + LanguageServiceShimObject.prototype.getOutliningSpans = function (arg0) { var _this = this; - return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); }); + var fileName = typeof arg0 === "string" ? arg0 : arg0.fileName; + return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(arg0); }); }; LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) { var _this = this; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 56e1d342d9697..0c84821ac1da2 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2163,7 +2163,20 @@ declare namespace ts { diagnostics: readonly Diagnostic[]; emittedFiles?: string[]; } + export interface SymbolChainCacheKey { + symbol: Symbol; + enclosingDeclaration?: Node; + flags: NodeBuilderFlags; + meaning: SymbolFlags; + yieldModuleSymbol?: boolean; + endOfChain: boolean; + } + export interface SymbolChainCache { + lookup(key: SymbolChainCacheKey): Symbol[] | undefined; + cache(key: SymbolChainCacheKey, value: Symbol[]): void; + } export interface TypeChecker { + setSymbolChainCache(cache: SymbolChainCache | undefined): void; getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; @@ -5599,6 +5612,7 @@ declare namespace ts { * @param position A zero-based index of the character where you want the quick info */ getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; + getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo | undefined; getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined; getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined; getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined; @@ -5622,6 +5636,7 @@ declare namespace ts { provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; + getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index b192a23a409d0..262ec0f7cceda 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -44844,6 +44844,9 @@ var ts; // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -48566,7 +48569,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32 /* Class */) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824 /* IsClassInstanceClone */)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -48614,6 +48619,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -49534,6 +49540,29 @@ var ts; return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */)); var parentSpecifiers; if (!accessibleSymbolChain || @@ -153495,10 +153524,11 @@ var ts; synchronizeHostData(); return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name: name, source: source }, host, preferences); } - function getQuickInfoAtPosition(fileName, position) { + function getQuickInfoAtPosition(arg0, arg1) { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); - var node = ts.getTouchingPropertyName(sourceFile, position); + var sourceFile = typeof arg0 === 'string' ? getValidSourceFile(arg0) : (arg1 !== undefined) ? arg1 : arg0.getSourceFile(); + var node = typeof arg0 === 'string' ? ts.getTouchingPropertyName(sourceFile, arg1) : arg0; + var position = typeof arg1 === 'number' ? arg1 : node.getStart(sourceFile, false); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -153747,9 +153777,9 @@ var ts; // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName) { + function getOutliningSpans(arg0) { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + var sourceFile = typeof arg0 === 'string' ? syntaxTreeCache.getCurrentSourceFile(arg0) : arg0; return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } var braceMatching = new ts.Map(ts.getEntries((_a = {}, @@ -155494,14 +155524,11 @@ var ts; return _this.realizeDiagnostics(diagnostics); }); }; - /// QUICKINFO - /** - * Computes a string representation of the type at the requested position - * in the active file. - */ - LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) { + LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (arg0, arg1) { var _this = this; - return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); }); + var fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? arg1.fileName : arg0.getSourceFile().fileName; + var position = typeof arg0 === "string" ? arg1 : arg0.getStart(arg1); + return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(arg0, arg1); }); }; /// NAMEORDOTTEDNAMESPAN /** @@ -155676,9 +155703,10 @@ var ts; var _this = this; return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); }); }; - LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) { + LanguageServiceShimObject.prototype.getOutliningSpans = function (arg0) { var _this = this; - return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); }); + var fileName = typeof arg0 === "string" ? arg0 : arg0.fileName; + return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(arg0); }); }; LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) { var _this = this; diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 1210fe11bb963..6b2e17fafba2b 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -44639,6 +44639,9 @@ var ts; // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { + setSymbolChainCache: function (cache) { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, @@ -48361,7 +48364,9 @@ var ts; return !!type.symbol && !!(type.symbol.flags & 32 /* Class */) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(ts.getObjectFlags(type) & 1073741824 /* IsClassInstanceClone */)); } function createNodeBuilder() { + var symbolChainCache; return { + setSymbolChainCache: function (cache) { symbolChainCache = cache; }, typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) { return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); }); }, @@ -48409,6 +48414,7 @@ var ts; fileExists: function (fileName) { return host.fileExists(fileName); }, getFileIncludeReasons: function () { return host.getFileIncludeReasons(); }, } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -49329,6 +49335,29 @@ var ts; return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { + var key; + var result; + if (context.cache) { + key = { + symbol: symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + }; + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + function doGetSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */)); var parentSpecifiers; if (!accessibleSymbolChain || diff --git a/package.json b/package.json index 92a33852d31ae..90ee4ead24536 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "https://www.typescriptlang.org/", - "version": "4.3.0-beta", + "version": "4.3.0-lsif.1", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 726690dd48fae..9732e92994b86 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -381,6 +381,9 @@ namespace ts { // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. const checker: TypeChecker = { + setSymbolChainCache: (cache: SymbolChainCache | undefined): void => { + nodeBuilder.setSymbolChainCache(cache); + }, getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"), getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"), getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount, @@ -4447,7 +4450,9 @@ namespace ts { } function createNodeBuilder() { + let symbolChainCache: SymbolChainCache | undefined; return { + setSymbolChainCache: (cache: SymbolChainCache | undefined): void => { symbolChainCache = cache }, typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => @@ -4486,6 +4491,7 @@ namespace ts { fileExists: fileName => host.fileExists(fileName), getFileIncludeReasons: () => host.getFileIncludeReasons(), } : undefined }, + cache: symbolChainCache, encounteredError: false, visitedTypes: undefined, symbolDepth: undefined, @@ -5494,6 +5500,30 @@ namespace ts { /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { + let key: SymbolChainCacheKey | undefined; + let result: Symbol[] | undefined; + if (context.cache) { + key = { + symbol, + enclosingDeclaration: context.enclosingDeclaration, + flags: context.flags, + meaning: meaning, + yieldModuleSymbol: yieldModuleSymbol, + endOfChain: endOfChain + } + result = context.cache.lookup(key); + if (result) { + return result; + } + } + result = doGetSymbolChain(symbol, meaning, endOfChain); + if (result && key && context.cache) { + context.cache.cache(key, result); + } + return result; + } + + function doGetSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing)); let parentSpecifiers: (string | undefined)[]; if (!accessibleSymbolChain || @@ -7698,6 +7728,7 @@ namespace ts { enclosingDeclaration: Node | undefined; flags: NodeBuilderFlags; tracker: SymbolTracker; + cache: SymbolChainCache | undefined; // State encounteredError: boolean; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0deacbe8e8a6a..56fd58bcab082 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4032,7 +4032,22 @@ namespace ts { readonly redirectTargetsMap: RedirectTargetsMap; } + export interface SymbolChainCacheKey { + symbol: Symbol; + enclosingDeclaration?: Node; + flags: NodeBuilderFlags; + meaning: SymbolFlags; + yieldModuleSymbol?: boolean; + endOfChain: boolean; + } + + export interface SymbolChainCache { + lookup(key: SymbolChainCacheKey): Symbol[] | undefined; + cache(key: SymbolChainCacheKey, value: Symbol[]): void; + } + export interface TypeChecker { + setSymbolChainCache(cache: SymbolChainCache | undefined): void; getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; diff --git a/src/harness/client.ts b/src/harness/client.ts index f85e0e111317d..2f54344d611e3 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -163,7 +163,11 @@ namespace ts.server { return { line, character: offset }; } - getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { + getQuickInfoAtPosition(fileName: string, position: number): QuickInfo; + getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo; + getQuickInfoAtPosition(arg0: string | ts.Node, arg1: number | ts.SourceFile | undefined): QuickInfo { + const fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? (arg1 as ts.SourceFile).fileName : arg0.getSourceFile().fileName; + const position = typeof arg0 === "string" ? arg1 as number : arg0.getStart(arg1 as ts.SourceFile); const args = this.createFileLocationRequestArgs(fileName, position); const request = this.processRequest(CommandNames.Quickinfo, args); @@ -598,7 +602,10 @@ namespace ts.server { })); } - getOutliningSpans(file: string): OutliningSpan[] { + getOutliningSpans(file: string): OutliningSpan[]; + getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; + getOutliningSpans(arg0: string | ts.SourceFile): OutliningSpan[] { + const file = typeof arg0 === "string" ? arg0 : arg0.fileName; const request = this.processRequest(CommandNames.GetOutliningSpans, { file }); const response = this.processResponse(request); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 17026bd5001b0..49aed3cb77326 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -480,8 +480,10 @@ namespace Harness.LanguageService { getCompletionEntrySymbol(): ts.Symbol { throw new Error("getCompletionEntrySymbol not implemented across the shim layer."); } - getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo { - return unwrapJSONCallResult(this.shim.getQuickInfoAtPosition(fileName, position)); + getQuickInfoAtPosition(filename: string, position: number): ts.QuickInfo | undefined; + getQuickInfoAtPosition(node: ts.Node, sourceFile: ts.SourceFile | undefined): ts.QuickInfo | undefined; + getQuickInfoAtPosition(arg0: string | ts.Node, arg1: number | ts.SourceFile | undefined): ts.QuickInfo | undefined { + return unwrapJSONCallResult(this.shim.getQuickInfoAtPosition(arg0 as any, arg1 as any)); } getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): ts.TextSpan { return unwrapJSONCallResult(this.shim.getNameOrDottedNameSpan(fileName, startPos, endPos)); @@ -537,8 +539,8 @@ namespace Harness.LanguageService { getNavigationTree(fileName: string): ts.NavigationTree { return unwrapJSONCallResult(this.shim.getNavigationTree(fileName)); } - getOutliningSpans(fileName: string): ts.OutliningSpan[] { - return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName)); + getOutliningSpans(arg0: string | ts.SourceFile): ts.OutliningSpan[] { + return unwrapJSONCallResult(this.shim.getOutliningSpans(arg0 as any)); } getTodoComments(fileName: string, descriptors: ts.TodoCommentDescriptor[]): ts.TodoComment[] { return unwrapJSONCallResult(this.shim.getTodoComments(fileName, JSON.stringify(descriptors))); diff --git a/src/services/services.ts b/src/services/services.ts index 5c5ce10cfbbc1..b5b384868f6d5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1614,11 +1614,15 @@ namespace ts { return Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences); } - function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined { - synchronizeHostData(); + function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; + function getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo | undefined; + function getQuickInfoAtPosition(arg0: string | ts.Node, arg1: number | ts.SourceFile | undefined): QuickInfo | undefined { + synchronizeHostData(); + + const sourceFile: ts.SourceFile = typeof arg0 === 'string' ? getValidSourceFile(arg0) : (arg1 !== undefined) ? arg1 as ts.SourceFile : arg0.getSourceFile(); + const node: ts.Node = typeof arg0 === 'string' ? getTouchingPropertyName(sourceFile, arg1 as number) : arg0; + const position: number = typeof arg1 === 'number' ? arg1 : node.getStart(sourceFile, false); - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -1926,11 +1930,13 @@ namespace ts { return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName: string): OutliningSpan[] { - // doesn't use compiler - no need to synchronize with host - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + function getOutliningSpans(fileName: string): OutliningSpan[]; + function getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; + function getOutliningSpans(arg0: string | ts.SourceFile): OutliningSpan[] { + // doesn't use compiler - no need to synchronize with host + const sourceFile = typeof arg0 === 'string' ? syntaxTreeCache.getCurrentSourceFile(arg0) : arg0; return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); - } + } const braceMatching = new Map(getEntries({ [SyntaxKind.OpenBraceToken]: SyntaxKind.CloseBraceToken, diff --git a/src/services/shims.ts b/src/services/shims.ts index fa0bdf459b972..5823c9e1976b0 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -762,12 +762,16 @@ namespace ts { * Computes a string representation of the type at the requested position * in the active file. */ - public getQuickInfoAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getQuickInfoAtPosition('${fileName}', ${position})`, - () => this.languageService.getQuickInfoAtPosition(fileName, position) - ); - } + public getQuickInfoAtPosition(fileName: string, position: number): string; + public getQuickInfoAtPosition(node: ts.Node, sourceFile: ts.SourceFile | undefined): string; + public getQuickInfoAtPosition(arg0: string | ts.Node, arg1: number | ts.SourceFile | undefined): string { + const fileName = typeof arg0 === "string" ? arg0 : arg1 !== undefined ? (arg1 as ts.SourceFile).fileName : arg0.getSourceFile().fileName; + const position = typeof arg0 === "string" ? arg1 as number : arg0.getStart(arg1 as ts.SourceFile); + return this.forwardJSONCall( + `getQuickInfoAtPosition('${fileName}', ${position})`, + () => this.languageService.getQuickInfoAtPosition(arg0 as any, arg1 as any) + ); + } /// NAMEORDOTTEDNAMESPAN @@ -1030,12 +1034,15 @@ namespace ts { ); } - public getOutliningSpans(fileName: string): string { - return this.forwardJSONCall( - `getOutliningSpans('${fileName}')`, - () => this.languageService.getOutliningSpans(fileName) - ); - } + public getOutliningSpans(fileName: string): string; + public getOutliningSpans(sourceFile: ts.SourceFile): string; + public getOutliningSpans(arg0: string | ts.SourceFile): string { + let fileName = typeof arg0 === "string" ? arg0 : arg0.fileName; + return this.forwardJSONCall( + `getOutliningSpans('${fileName}')`, + () => this.languageService.getOutliningSpans(arg0 as any) + ); + } public getTodoComments(fileName: string, descriptors: string): string { return this.forwardJSONCall( diff --git a/src/services/types.ts b/src/services/types.ts index 0d50cab5e624c..d140364ed503b 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -454,6 +454,7 @@ namespace ts { * @param position A zero-based index of the character where you want the quick info */ getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; + getQuickInfoAtPosition(node: ts.Node, sourceFile?: ts.SourceFile): QuickInfo | undefined; getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined; @@ -488,6 +489,7 @@ namespace ts { provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; getOutliningSpans(fileName: string): OutliningSpan[]; + getOutliningSpans(sourceFile: ts.SourceFile): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number;