@@ -345,13 +345,6 @@ namespace ts {
345
345
}
346
346
}
347
347
348
- function functionBodyVisitor ( node : Block ) : Block {
349
- if ( shouldVisitNode ( node ) ) {
350
- return visitBlock ( node , /*isFunctionBody*/ true ) ;
351
- }
352
- return node ;
353
- }
354
-
355
348
function callExpressionVisitor ( node : Node ) : VisitResult < Node > {
356
349
if ( node . kind === SyntaxKind . SuperKeyword ) {
357
350
return visitSuperKeyword ( /*isExpressionOfCall*/ true ) ;
@@ -507,15 +500,15 @@ namespace ts {
507
500
const statements : Statement [ ] = [ ] ;
508
501
startLexicalEnvironment ( ) ;
509
502
let statementOffset = addStandardPrologue ( prologue , node . statements , /*ensureUseStrict*/ false ) ;
510
- insertCaptureThisForNodeIfNeeded ( prologue , node ) ;
511
503
statementOffset = addCustomPrologue ( prologue , node . statements , statementOffset , visitor ) ;
512
504
addRange ( statements , visitNodes ( node . statements , visitor , isStatement , statementOffset ) ) ;
513
505
if ( taggedTemplateStringDeclarations ) {
514
506
statements . push (
515
507
createVariableStatement ( /*modifiers*/ undefined ,
516
508
createVariableDeclarationList ( taggedTemplateStringDeclarations ) ) ) ;
517
509
}
518
- insertStatementsAfterStandardPrologue ( prologue , endLexicalEnvironment ( ) ) ;
510
+ mergeLexicalEnvironment ( prologue , endLexicalEnvironment ( ) ) ;
511
+ insertCaptureThisForNodeIfNeeded ( prologue , node ) ;
519
512
exitSubtree ( ancestorFacts , HierarchyFacts . None , HierarchyFacts . None ) ;
520
513
return updateSourceFileNode (
521
514
node ,
@@ -1194,11 +1187,6 @@ namespace ts {
1194
1187
|| isBindingPattern ( node . name ) ;
1195
1188
}
1196
1189
1197
- function hasDefaultValueOrBindingPatternOrRest ( node : ParameterDeclaration ) {
1198
- return hasDefaultValueOrBindingPattern ( node )
1199
- || node . dotDotDotToken !== undefined ;
1200
- }
1201
-
1202
1190
/**
1203
1191
* Adds statements to the body of a function-like node if it contains parameters with
1204
1192
* binding patterns or initializers.
@@ -1446,12 +1434,13 @@ namespace ts {
1446
1434
1447
1435
/**
1448
1436
* Adds a statement to capture the `this` of a function declaration if it is needed.
1437
+ * NOTE: This must be executed *after* the subtree has been visited.
1449
1438
*
1450
1439
* @param statements The statements for the new function body.
1451
1440
* @param node A node.
1452
1441
*/
1453
1442
function insertCaptureThisForNodeIfNeeded ( statements : Statement [ ] , node : Node ) : boolean {
1454
- if ( node . transformFlags & TransformFlags . ContainsCapturedLexicalThis && node . kind !== SyntaxKind . ArrowFunction ) {
1443
+ if ( hierarchyFacts & HierarchyFacts . CapturedLexicalThis && node . kind !== SyntaxKind . ArrowFunction ) {
1455
1444
insertCaptureThisForNode ( statements , node , createThis ( ) ) ;
1456
1445
return true ;
1457
1446
}
@@ -1731,10 +1720,6 @@ namespace ts {
1731
1720
return func ;
1732
1721
}
1733
1722
1734
- function containsCapturedLexicalThis ( node : Node ) {
1735
- return ( node . transformFlags & TransformFlags . ContainsCapturedLexicalThis ) !== 0 ;
1736
- }
1737
-
1738
1723
/**
1739
1724
* Visits a FunctionExpression node.
1740
1725
*
@@ -1748,11 +1733,7 @@ namespace ts {
1748
1733
convertedLoopState = undefined ;
1749
1734
1750
1735
const parameters = visitParameterList ( node . parameters , visitor , context ) ;
1751
- const shouldTransform = forEachChild ( node , containsCapturedLexicalThis )
1752
- || some ( node . parameters , hasDefaultValueOrBindingPatternOrRest ) ;
1753
- const body = shouldTransform
1754
- ? transformFunctionBody ( node )
1755
- : visitFunctionBodyDownLevel ( node ) ;
1736
+ const body = transformFunctionBody ( node ) ;
1756
1737
const name = hierarchyFacts & HierarchyFacts . NewTarget
1757
1738
? getLocalName ( node )
1758
1739
: node . name ;
@@ -1781,11 +1762,7 @@ namespace ts {
1781
1762
convertedLoopState = undefined ;
1782
1763
const ancestorFacts = enterSubtree ( HierarchyFacts . FunctionExcludes , HierarchyFacts . FunctionIncludes ) ;
1783
1764
const parameters = visitParameterList ( node . parameters , visitor , context ) ;
1784
- const shouldTransform = forEachChild ( node , containsCapturedLexicalThis )
1785
- || some ( node . parameters , hasDefaultValueOrBindingPatternOrRest ) ;
1786
- const body = shouldTransform
1787
- ? transformFunctionBody ( node )
1788
- : visitFunctionBodyDownLevel ( node ) ;
1765
+ const body = transformFunctionBody ( node ) ;
1789
1766
const name = hierarchyFacts & HierarchyFacts . NewTarget
1790
1767
? getLocalName ( node )
1791
1768
: node . name ;
@@ -1921,7 +1898,13 @@ namespace ts {
1921
1898
multiLine = true ;
1922
1899
}
1923
1900
1924
- const block = createBlock ( setTextRange ( createNodeArray ( concatenate ( prologue , statements ) ) , statementsLocation ) , multiLine ) ;
1901
+ statements . unshift ( ...prologue ) ;
1902
+ if ( isBlock ( body ) && arrayIsEqualTo ( statements , body . statements ) ) {
1903
+ // no changes were made, preserve the tree
1904
+ return body ;
1905
+ }
1906
+
1907
+ const block = createBlock ( setTextRange ( createNodeArray ( statements ) , statementsLocation ) , multiLine ) ;
1925
1908
setTextRange ( block , node . body ) ;
1926
1909
if ( ! multiLine && singleLine ) {
1927
1910
setEmitFlags ( block , EmitFlags . SingleLine ) ;
@@ -1935,19 +1918,6 @@ namespace ts {
1935
1918
return block ;
1936
1919
}
1937
1920
1938
- function visitFunctionBodyDownLevel ( node : FunctionDeclaration | FunctionExpression | AccessorDeclaration ) {
1939
- const updated = visitFunctionBody ( node . body , functionBodyVisitor , context ) ! ;
1940
- return updateBlock (
1941
- updated ,
1942
- setTextRange (
1943
- createNodeArray (
1944
- insertCaptureNewTargetIfNeeded ( updated . statements as MutableNodeArray < Statement > , node , /*copyOnWrite*/ true )
1945
- ) ,
1946
- /*location*/ updated . statements
1947
- )
1948
- ) ;
1949
- }
1950
-
1951
1921
function visitBlock ( node : Block , isFunctionBody : boolean ) : Block {
1952
1922
if ( isFunctionBody ) {
1953
1923
// A function body is not a block scope.
@@ -3501,9 +3471,7 @@ namespace ts {
3501
3471
const ancestorFacts = enterSubtree ( HierarchyFacts . FunctionExcludes , HierarchyFacts . FunctionIncludes ) ;
3502
3472
let updated : AccessorDeclaration ;
3503
3473
const parameters = visitParameterList ( node . parameters , visitor , context ) ;
3504
- const body = node . transformFlags & ( TransformFlags . ContainsCapturedLexicalThis | TransformFlags . ContainsES2015 )
3505
- ? transformFunctionBody ( node )
3506
- : visitFunctionBodyDownLevel ( node ) ;
3474
+ const body = transformFunctionBody ( node ) ;
3507
3475
if ( node . kind === SyntaxKind . GetAccessor ) {
3508
3476
updated = updateGetAccessor ( node , node . decorators , node . modifiers , node . name , parameters , node . type , body ) ;
3509
3477
}
0 commit comments