@@ -1717,37 +1717,26 @@ namespace ts {
1717
1717
}
1718
1718
1719
1719
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
+ //
1720
1722
// If there is an outstanding parse error that we've encountered, but not attached to
1721
1723
// some node, then we cannot get a node from the old source tree. This is because we
1722
1724
// want to mark the next node we encounter as being unusable.
1723
1725
//
1724
1726
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
1725
1727
// on it (or its leftmost child) as having the error. For now though, being conservative
1726
1728
// 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 ) {
1733
1730
return undefined ;
1734
1731
}
1735
1732
1736
1733
const node = syntaxCursor . currentNode ( scanner . getStartPos ( ) ) ;
1737
1734
1738
1735
// Can't reuse a missing node.
1739
- if ( nodeIsMissing ( node ) ) {
1740
- return undefined ;
1741
- }
1742
-
1743
1736
// Can't reuse a node that intersected the change range.
1744
- if ( node . intersectsChange ) {
1745
- return undefined ;
1746
- }
1747
-
1748
1737
// Can't reuse a node that contains a parse error. This is necessary so that we
1749
1738
// produce the same set of errors again.
1750
- if ( containsParseError ( node ) ) {
1739
+ if ( nodeIsMissing ( node ) || node . intersectsChange || containsParseError ( node ) ) {
1751
1740
return undefined ;
1752
1741
}
1753
1742
@@ -1788,6 +1777,23 @@ namespace ts {
1788
1777
return node ;
1789
1778
}
1790
1779
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
+
1791
1797
function canReuseNode ( node : Node , parsingContext : ParsingContext ) : boolean {
1792
1798
switch ( parsingContext ) {
1793
1799
case ParsingContext . ClassMembers :
@@ -1814,25 +1820,23 @@ namespace ts {
1814
1820
case ParsingContext . Parameters :
1815
1821
return isReusableParameter ( node ) ;
1816
1822
1817
- case ParsingContext . RestProperties :
1818
- return false ;
1819
-
1820
1823
// Any other lists we do not care about reusing nodes in. But feel free to add if
1821
1824
// you can do so safely. Danger areas involve nodes that may involve speculative
1822
1825
// parsing. If speculative parsing is involved with the node, then the range the
1823
1826
// parser reached while looking ahead might be in the edited range (see the example
1824
1827
// in canReuseVariableDeclaratorNode for a good case of this).
1825
- case ParsingContext . HeritageClauses :
1828
+
1829
+ // case ParsingContext.HeritageClauses:
1826
1830
// This would probably be safe to reuse. There is no speculative parsing with
1827
1831
// heritage clauses.
1828
1832
1829
- case ParsingContext . TypeParameters :
1833
+ // case ParsingContext.TypeParameters:
1830
1834
// This would probably be safe to reuse. There is no speculative parsing with
1831
1835
// type parameters. Note that that's because type *parameters* only occur in
1832
1836
// unambiguous *type* contexts. While type *arguments* occur in very ambiguous
1833
1837
// *expression* contexts.
1834
1838
1835
- case ParsingContext . TupleElementTypes :
1839
+ // case ParsingContext.TupleElementTypes:
1836
1840
// This would probably be safe to reuse. There is no speculative parsing with
1837
1841
// tuple types.
1838
1842
@@ -1841,28 +1845,28 @@ namespace ts {
1841
1845
// produced from speculative parsing a < as a type argument list), we only have
1842
1846
// the types because speculative parsing succeeded. Thus, the lookahead never
1843
1847
// went past the end of the list and rewound.
1844
- case ParsingContext . TypeArguments :
1848
+ // case ParsingContext.TypeArguments:
1845
1849
1846
1850
// Note: these are almost certainly not safe to ever reuse. Expressions commonly
1847
1851
// need a large amount of lookahead, and we should not reuse them as they may
1848
1852
// have actually intersected the edit.
1849
- case ParsingContext . ArgumentExpressions :
1853
+ // case ParsingContext.ArgumentExpressions:
1850
1854
1851
1855
// This is not safe to reuse for the same reason as the 'AssignmentExpression'
1852
1856
// cases. i.e. a property assignment may end with an expression, and thus might
1853
1857
// have lookahead far beyond it's old node.
1854
- case ParsingContext . ObjectLiteralMembers :
1858
+ // case ParsingContext.ObjectLiteralMembers:
1855
1859
1856
1860
// This is probably not safe to reuse. There can be speculative parsing with
1857
1861
// type names in a heritage clause. There can be generic names in the type
1858
1862
// name list, and there can be left hand side expressions (which can have type
1859
1863
// arguments.)
1860
- case ParsingContext . HeritageClauseElement :
1864
+ // case ParsingContext.HeritageClauseElement:
1861
1865
1862
1866
// Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
1863
1867
// on any given element. Same for children.
1864
- case ParsingContext . JsxAttributes :
1865
- case ParsingContext . JsxChildren :
1868
+ // case ParsingContext.JsxAttributes:
1869
+ // case ParsingContext.JsxChildren:
1866
1870
1867
1871
}
1868
1872
0 commit comments