Skip to content

Commit 885db7d

Browse files
committed
Try caching the flow cache key for better perf
1 parent 69ddc92 commit 885db7d

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15326,31 +15326,40 @@ namespace ts {
1532615326
n => n.kind === SyntaxKind.TypeQuery ? true : n.kind === SyntaxKind.Identifier || n.kind === SyntaxKind.QualifiedName ? false : "quit");
1532715327
}
1532815328

15329+
15330+
function getFlowCacheKey(node: Node): string | undefined {
15331+
const links = getNodeLinks(node);
15332+
if (links.flowCacheKey === undefined) {
15333+
links.flowCacheKey = getFlowCacheKeyWorker(node);
15334+
}
15335+
return links.flowCacheKey === false ? undefined : links.flowCacheKey;
15336+
}
15337+
1532915338
// Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
1533015339
// separated by dots). The key consists of the id of the symbol referenced by the
1533115340
// leftmost identifier followed by zero or more property names separated by dots.
1533215341
// The result is undefined if the reference isn't a dotted name. We prefix nodes
1533315342
// occurring in an apparent type position with '@' because the control flow type
1533415343
// of such nodes may be based on the apparent type instead of the declared type.
15335-
function getFlowCacheKey(node: Node): string | undefined {
15344+
function getFlowCacheKeyWorker(node: Node): string | false {
1533615345
switch (node.kind) {
1533715346
case SyntaxKind.Identifier:
1533815347
const symbol = getResolvedSymbol(<Identifier>node);
15339-
return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
15348+
return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : false;
1534015349
case SyntaxKind.ThisKeyword:
1534115350
return "0";
1534215351
case SyntaxKind.NonNullExpression:
1534315352
case SyntaxKind.ParenthesizedExpression:
15344-
return getFlowCacheKey((<NonNullExpression | ParenthesizedExpression>node).expression);
15353+
return getFlowCacheKeyWorker((<NonNullExpression | ParenthesizedExpression>node).expression);
1534515354
case SyntaxKind.PropertyAccessExpression:
1534615355
case SyntaxKind.ElementAccessExpression:
1534715356
const propName = getAccessedPropertyName(<AccessExpression>node);
1534815357
if (propName !== undefined) {
1534915358
const key = getFlowCacheKey((<AccessExpression>node).expression);
15350-
return key && key + "." + propName;
15359+
return !key ? false : key + "." + propName;
1535115360
}
1535215361
}
15353-
return undefined;
15362+
return false;
1535415363
}
1535515364

1535615365
function isMatchingReference(source: Node, target: Node): boolean {

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3882,6 +3882,7 @@ namespace ts {
38823882
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
38833883
deferredNodes?: Map<Node>; // Set of nodes whose checking has been deferred
38843884
capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement
3885+
flowCacheKey?: string | false; // Flow-control loop cache key for the reference indicated by this node
38853886
}
38863887

38873888
export const enum TypeFlags {

0 commit comments

Comments
 (0)