From ab686d83e991eecd922d6848709f5417f61f77c6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 4 Feb 2023 02:27:29 +0000 Subject: [PATCH] Try tracking deferred nodes using 2 arrays: one to maintain order, the other as a simple sparse array. --- src/compiler/checker.ts | 17 ++++++++++++++--- src/compiler/types.ts | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a01c44bf6aaff..016b946b4111c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44345,15 +44345,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const enclosingFile = getSourceFileOfNode(node); const links = getNodeLinks(enclosingFile); if (!(links.flags & NodeCheckFlags.TypeChecked)) { - links.deferredNodes ||= new Set(); - links.deferredNodes.add(node); + links.deferredNodes ??= { + order: [], + set: [], + }; + const { order, set } = links.deferredNodes; + const nodeId = getNodeId(node); + if (set[nodeId] === undefined) { + order.push(nodeId); + set[nodeId] = node; + } } } function checkDeferredNodes(context: SourceFile) { const links = getNodeLinks(context); if (links.deferredNodes) { - links.deferredNodes.forEach(checkDeferredNode); + const { order, set } = links.deferredNodes; + for (const nodeId of order) { + checkDeferredNode(set[nodeId]); + } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0a43afe978ea4..62c0ead7955fc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5975,7 +5975,7 @@ export interface NodeLinks { jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive - deferredNodes?: Set; // Set of nodes whose checking has been deferred + deferredNodes?: { order: number[]; set: Record }; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type isExhaustive?: boolean | 0; // Is node an exhaustive switch statement (0 indicates in-process resolution)