Skip to content

Commit 3d8668c

Browse files
authored
Merge pull request #28742 from Microsoft/fixIncrementalParsingBailout
Fix incremental parsing bailout logic
2 parents 1dbe063 + 92a8cc9 commit 3d8668c

File tree

1 file changed

+31
-27
lines changed

1 file changed

+31
-27
lines changed

src/compiler/parser.ts

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,37 +1717,26 @@ namespace ts {
17171717
}
17181718

17191719
function currentNode(parsingContext: ParsingContext): Node | undefined {
1720+
// If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
1721+
//
17201722
// If there is an outstanding parse error that we've encountered, but not attached to
17211723
// some node, then we cannot get a node from the old source tree. This is because we
17221724
// want to mark the next node we encounter as being unusable.
17231725
//
17241726
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
17251727
// on it (or its leftmost child) as having the error. For now though, being conservative
17261728
// is nice and likely won't ever affect perf.
1727-
if (parseErrorBeforeNextFinishedNode) {
1728-
return undefined;
1729-
}
1730-
1731-
if (!syntaxCursor) {
1732-
// if we don't have a cursor, we could never return a node from the old tree.
1729+
if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
17331730
return undefined;
17341731
}
17351732

17361733
const node = syntaxCursor.currentNode(scanner.getStartPos());
17371734

17381735
// Can't reuse a missing node.
1739-
if (nodeIsMissing(node)) {
1740-
return undefined;
1741-
}
1742-
17431736
// Can't reuse a node that intersected the change range.
1744-
if (node.intersectsChange) {
1745-
return undefined;
1746-
}
1747-
17481737
// Can't reuse a node that contains a parse error. This is necessary so that we
17491738
// produce the same set of errors again.
1750-
if (containsParseError(node)) {
1739+
if (nodeIsMissing(node) || node.intersectsChange || containsParseError(node)) {
17511740
return undefined;
17521741
}
17531742

@@ -1788,6 +1777,23 @@ namespace ts {
17881777
return node;
17891778
}
17901779

1780+
function isReusableParsingContext(parsingContext: ParsingContext): boolean {
1781+
switch (parsingContext) {
1782+
case ParsingContext.ClassMembers:
1783+
case ParsingContext.SwitchClauses:
1784+
case ParsingContext.SourceElements:
1785+
case ParsingContext.BlockStatements:
1786+
case ParsingContext.SwitchClauseStatements:
1787+
case ParsingContext.EnumMembers:
1788+
case ParsingContext.TypeMembers:
1789+
case ParsingContext.VariableDeclarations:
1790+
case ParsingContext.JSDocParameters:
1791+
case ParsingContext.Parameters:
1792+
return true;
1793+
}
1794+
return false;
1795+
}
1796+
17911797
function canReuseNode(node: Node, parsingContext: ParsingContext): boolean {
17921798
switch (parsingContext) {
17931799
case ParsingContext.ClassMembers:
@@ -1814,25 +1820,23 @@ namespace ts {
18141820
case ParsingContext.Parameters:
18151821
return isReusableParameter(node);
18161822

1817-
case ParsingContext.RestProperties:
1818-
return false;
1819-
18201823
// Any other lists we do not care about reusing nodes in. But feel free to add if
18211824
// you can do so safely. Danger areas involve nodes that may involve speculative
18221825
// parsing. If speculative parsing is involved with the node, then the range the
18231826
// parser reached while looking ahead might be in the edited range (see the example
18241827
// in canReuseVariableDeclaratorNode for a good case of this).
1825-
case ParsingContext.HeritageClauses:
1828+
1829+
// case ParsingContext.HeritageClauses:
18261830
// This would probably be safe to reuse. There is no speculative parsing with
18271831
// heritage clauses.
18281832

1829-
case ParsingContext.TypeParameters:
1833+
// case ParsingContext.TypeParameters:
18301834
// This would probably be safe to reuse. There is no speculative parsing with
18311835
// type parameters. Note that that's because type *parameters* only occur in
18321836
// unambiguous *type* contexts. While type *arguments* occur in very ambiguous
18331837
// *expression* contexts.
18341838

1835-
case ParsingContext.TupleElementTypes:
1839+
// case ParsingContext.TupleElementTypes:
18361840
// This would probably be safe to reuse. There is no speculative parsing with
18371841
// tuple types.
18381842

@@ -1841,28 +1845,28 @@ namespace ts {
18411845
// produced from speculative parsing a < as a type argument list), we only have
18421846
// the types because speculative parsing succeeded. Thus, the lookahead never
18431847
// went past the end of the list and rewound.
1844-
case ParsingContext.TypeArguments:
1848+
// case ParsingContext.TypeArguments:
18451849

18461850
// Note: these are almost certainly not safe to ever reuse. Expressions commonly
18471851
// need a large amount of lookahead, and we should not reuse them as they may
18481852
// have actually intersected the edit.
1849-
case ParsingContext.ArgumentExpressions:
1853+
// case ParsingContext.ArgumentExpressions:
18501854

18511855
// This is not safe to reuse for the same reason as the 'AssignmentExpression'
18521856
// cases. i.e. a property assignment may end with an expression, and thus might
18531857
// have lookahead far beyond it's old node.
1854-
case ParsingContext.ObjectLiteralMembers:
1858+
// case ParsingContext.ObjectLiteralMembers:
18551859

18561860
// This is probably not safe to reuse. There can be speculative parsing with
18571861
// type names in a heritage clause. There can be generic names in the type
18581862
// name list, and there can be left hand side expressions (which can have type
18591863
// arguments.)
1860-
case ParsingContext.HeritageClauseElement:
1864+
// case ParsingContext.HeritageClauseElement:
18611865

18621866
// Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
18631867
// on any given element. Same for children.
1864-
case ParsingContext.JsxAttributes:
1865-
case ParsingContext.JsxChildren:
1868+
// case ParsingContext.JsxAttributes:
1869+
// case ParsingContext.JsxChildren:
18661870

18671871
}
18681872

0 commit comments

Comments
 (0)