@@ -381,6 +381,9 @@ namespace ts {
381381 // extra cost of calling `getParseTreeNode` when calling these functions from inside the
382382 // checker.
383383 const checker: TypeChecker = {
384+ setSymbolChainCache: (cache: SymbolChainCache | undefined): void => {
385+ nodeBuilder.setSymbolChainCache(cache);
386+ },
384387 getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
385388 getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
386389 getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount,
@@ -4323,7 +4326,9 @@ namespace ts {
43234326 }
43244327
43254328 function createNodeBuilder() {
4329+ let symbolChainCache: SymbolChainCache | undefined;
43264330 return {
4331+ setSymbolChainCache: (cache: SymbolChainCache | undefined): void => { symbolChainCache = cache },
43274332 typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) =>
43284333 withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)),
43294334 indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) =>
@@ -4341,7 +4346,7 @@ namespace ts {
43414346 typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) =>
43424347 withContext(enclosingDeclaration, flags, tracker, context => typeParameterToDeclaration(parameter, context)),
43434348 symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker, bundled?: boolean) =>
4344- withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context, bundled)),
4349+ withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context, bundled))
43454350 };
43464351
43474352 function withContext<T>(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined {
@@ -4361,6 +4366,7 @@ namespace ts {
43614366 isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName),
43624367 fileExists: fileName => host.fileExists(fileName),
43634368 } : undefined },
4369+ cache: symbolChainCache,
43644370 encounteredError: false,
43654371 visitedTypes: undefined,
43664372 symbolDepth: undefined,
@@ -5333,6 +5339,30 @@ namespace ts {
53335339
53345340 /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
53355341 function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined {
5342+ let key: SymbolChainCacheKey | undefined;
5343+ let result: Symbol[] | undefined;
5344+ if (context.cache) {
5345+ key = {
5346+ symbol,
5347+ enclosingDeclaration: context.enclosingDeclaration,
5348+ flags: context.flags,
5349+ meaning: meaning,
5350+ yieldModuleSymbol: yieldModuleSymbol,
5351+ endOfChain: endOfChain
5352+ }
5353+ result = context.cache.lookup(key);
5354+ if (result) {
5355+ return result;
5356+ }
5357+ }
5358+ result = doGetSymbolChain(symbol, meaning, endOfChain);
5359+ if (result && key && context.cache) {
5360+ context.cache.cache(key, result);
5361+ }
5362+ return result;
5363+ }
5364+
5365+ function doGetSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined {
53365366 let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing));
53375367 let parentSpecifiers: (string | undefined)[];
53385368 if (!accessibleSymbolChain ||
@@ -7446,6 +7476,7 @@ namespace ts {
74467476 enclosingDeclaration: Node | undefined;
74477477 flags: NodeBuilderFlags;
74487478 tracker: SymbolTracker;
7479+ cache: SymbolChainCache | undefined;
74497480
74507481 // State
74517482 encounteredError: boolean;
0 commit comments