@@ -395,6 +395,9 @@ namespace ts {
395395 // extra cost of calling `getParseTreeNode` when calling these functions from inside the
396396 // checker.
397397 const checker: TypeChecker = {
398+ setSymbolChainCache: (cache: SymbolChainCache | undefined): void => {
399+ nodeBuilder.setSymbolChainCache(cache);
400+ },
398401 getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
399402 getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
400403 getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount,
@@ -4901,7 +4904,9 @@ namespace ts {
49014904 }
49024905
49034906 function createNodeBuilder() {
4907+ let symbolChainCache: SymbolChainCache | undefined;
49044908 return {
4909+ setSymbolChainCache: (cache: SymbolChainCache | undefined): void => { symbolChainCache = cache },
49054910 typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) =>
49064911 withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)),
49074912 indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) =>
@@ -4942,6 +4947,7 @@ namespace ts {
49424947 readFile: host.readFile ? (fileName => host.readFile!(fileName)) : undefined,
49434948 } : undefined },
49444949 encounteredError: false,
4950+ cache: symbolChainCache,
49454951 reportedDiagnostic: false,
49464952 visitedTypes: undefined,
49474953 symbolDepth: undefined,
@@ -6146,6 +6152,30 @@ namespace ts {
61466152
61476153 /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
61486154 function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined {
6155+ let key: SymbolChainCacheKey | undefined;
6156+ let result: Symbol[] | undefined;
6157+ if (context.cache) {
6158+ key = {
6159+ symbol,
6160+ enclosingDeclaration: context.enclosingDeclaration,
6161+ flags: context.flags,
6162+ meaning: meaning,
6163+ yieldModuleSymbol: yieldModuleSymbol,
6164+ endOfChain: endOfChain
6165+ }
6166+ result = context.cache.lookup(key);
6167+ if (result) {
6168+ return result;
6169+ }
6170+ }
6171+ result = doGetSymbolChain(symbol, meaning, endOfChain);
6172+ if (result && key && context.cache) {
6173+ context.cache.cache(key, result);
6174+ }
6175+ return result;
6176+ }
6177+
6178+ function doGetSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined {
61496179 let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing));
61506180 let parentSpecifiers: (string | undefined)[];
61516181 if (!accessibleSymbolChain ||
@@ -8423,6 +8453,7 @@ namespace ts {
84238453 enclosingDeclaration: Node | undefined;
84248454 flags: NodeBuilderFlags;
84258455 tracker: SymbolTracker;
8456+ cache: SymbolChainCache | undefined;
84268457
84278458 // State
84288459 encounteredError: boolean;
0 commit comments