@@ -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