@@ -570,6 +570,31 @@ namespace ts {
570570 }
571571 }
572572
573+ function bindEach ( nodes : NodeArray < Node > ) {
574+ if ( nodes === undefined ) {
575+ return ;
576+ }
577+
578+ if ( skipTransformFlagAggregation ) {
579+ forEach ( nodes , bind ) ;
580+ }
581+ else {
582+ const savedSubtreeTransformFlags = subtreeTransformFlags ;
583+ subtreeTransformFlags = TransformFlags . None ;
584+ let nodeArrayFlags = TransformFlags . None ;
585+ for ( const node of nodes ) {
586+ bind ( node ) ;
587+ nodeArrayFlags |= node . transformFlags & ~ TransformFlags . HasComputedFlags ;
588+ }
589+ nodes . transformFlags = nodeArrayFlags | TransformFlags . HasComputedFlags ;
590+ subtreeTransformFlags |= savedSubtreeTransformFlags ;
591+ }
592+ }
593+
594+ function bindEachChild ( node : Node ) {
595+ forEachChild ( node , bind , bindEach ) ;
596+ }
597+
573598 function bindChildrenWorker ( node : Node ) : void {
574599 // Binding of JsDocComment should be done before the current block scope container changes.
575600 // because the scope of JsDocComment should not be affected by whether the current node is a
@@ -578,7 +603,7 @@ namespace ts {
578603 forEach ( node . jsDocComments , bind ) ;
579604 }
580605 if ( checkUnreachable ( node ) ) {
581- forEachChild ( node , bind ) ;
606+ bindEachChild ( node ) ;
582607 return ;
583608 }
584609 switch ( node . kind ) {
@@ -643,7 +668,7 @@ namespace ts {
643668 bindCallExpressionFlow ( < CallExpression > node ) ;
644669 break ;
645670 default :
646- forEachChild ( node , bind ) ;
671+ bindEachChild ( node ) ;
647672 break ;
648673 }
649674 }
@@ -976,7 +1001,7 @@ namespace ts {
9761001 return undefined ;
9771002 }
9781003
979- function bindbreakOrContinueFlow ( node : BreakOrContinueStatement , breakTarget : FlowLabel , continueTarget : FlowLabel ) {
1004+ function bindBreakOrContinueFlow ( node : BreakOrContinueStatement , breakTarget : FlowLabel , continueTarget : FlowLabel ) {
9801005 const flowLabel = node . kind === SyntaxKind . BreakStatement ? breakTarget : continueTarget ;
9811006 if ( flowLabel ) {
9821007 addAntecedent ( flowLabel , currentFlow ) ;
@@ -990,11 +1015,11 @@ namespace ts {
9901015 const activeLabel = findActiveLabel ( node . label . text ) ;
9911016 if ( activeLabel ) {
9921017 activeLabel . referenced = true ;
993- bindbreakOrContinueFlow ( node , activeLabel . breakTarget , activeLabel . continueTarget ) ;
1018+ bindBreakOrContinueFlow ( node , activeLabel . breakTarget , activeLabel . continueTarget ) ;
9941019 }
9951020 }
9961021 else {
997- bindbreakOrContinueFlow ( node , currentBreakTarget , currentContinueTarget ) ;
1022+ bindBreakOrContinueFlow ( node , currentBreakTarget , currentContinueTarget ) ;
9981023 }
9991024 }
10001025
@@ -1062,6 +1087,8 @@ namespace ts {
10621087 }
10631088
10641089 function bindCaseBlock ( node : CaseBlock ) : void {
1090+ const savedSubtreeTransformFlags = subtreeTransformFlags ;
1091+ subtreeTransformFlags = 0 ;
10651092 const clauses = node . clauses ;
10661093 let fallthroughFlow = unreachableFlow ;
10671094 for ( let i = 0 ; i < clauses . length ; i ++ ) {
@@ -1081,14 +1108,16 @@ namespace ts {
10811108 errorOnFirstToken ( clause , Diagnostics . Fallthrough_case_in_switch ) ;
10821109 }
10831110 }
1111+ clauses . transformFlags = subtreeTransformFlags | TransformFlags . HasComputedFlags ;
1112+ subtreeTransformFlags |= savedSubtreeTransformFlags ;
10841113 }
10851114
10861115 function bindCaseClause ( node : CaseClause ) : void {
10871116 const saveCurrentFlow = currentFlow ;
10881117 currentFlow = preSwitchCaseFlow ;
10891118 bind ( node . expression ) ;
10901119 currentFlow = saveCurrentFlow ;
1091- forEach ( node . statements , bind ) ;
1120+ bindEach ( node . statements ) ;
10921121 }
10931122
10941123 function pushActiveLabel ( name : string , breakTarget : FlowLabel , continueTarget : FlowLabel ) : ActiveLabel {
@@ -1180,20 +1209,20 @@ namespace ts {
11801209 const saveTrueTarget = currentTrueTarget ;
11811210 currentTrueTarget = currentFalseTarget ;
11821211 currentFalseTarget = saveTrueTarget ;
1183- forEachChild ( node , bind ) ;
1212+ bindEachChild ( node ) ;
11841213 currentFalseTarget = currentTrueTarget ;
11851214 currentTrueTarget = saveTrueTarget ;
11861215 }
11871216 else {
1188- forEachChild ( node , bind ) ;
1217+ bindEachChild ( node ) ;
11891218 if ( node . operator === SyntaxKind . PlusPlusToken || node . operator === SyntaxKind . MinusMinusToken ) {
11901219 bindAssignmentTargetFlow ( node . operand ) ;
11911220 }
11921221 }
11931222 }
11941223
11951224 function bindPostfixUnaryExpressionFlow ( node : PostfixUnaryExpression ) {
1196- forEachChild ( node , bind ) ;
1225+ bindEachChild ( node ) ;
11971226 if ( node . operator === SyntaxKind . PlusPlusToken || node . operator === SyntaxKind . MinusMinusToken ) {
11981227 bindAssignmentTargetFlow ( node . operand ) ;
11991228 }
@@ -1212,7 +1241,7 @@ namespace ts {
12121241 }
12131242 }
12141243 else {
1215- forEachChild ( node , bind ) ;
1244+ bindEachChild ( node ) ;
12161245 if ( isAssignmentOperator ( operator ) && ! isAssignmentTarget ( node ) ) {
12171246 bindAssignmentTargetFlow ( node . left ) ;
12181247 if ( operator === SyntaxKind . EqualsToken && node . left . kind === SyntaxKind . ElementAccessExpression ) {
@@ -1226,7 +1255,7 @@ namespace ts {
12261255 }
12271256
12281257 function bindDeleteExpressionFlow ( node : DeleteExpression ) {
1229- forEachChild ( node , bind ) ;
1258+ bindEachChild ( node ) ;
12301259 if ( node . expression . kind === SyntaxKind . PropertyAccessExpression ) {
12311260 bindAssignmentTargetFlow ( node . expression ) ;
12321261 }
@@ -1261,7 +1290,7 @@ namespace ts {
12611290 }
12621291
12631292 function bindVariableDeclarationFlow ( node : VariableDeclaration ) {
1264- forEachChild ( node , bind ) ;
1293+ bindEachChild ( node ) ;
12651294 if ( node . initializer || node . parent . parent . kind === SyntaxKind . ForInStatement || node . parent . parent . kind === SyntaxKind . ForOfStatement ) {
12661295 bindInitializedVariableFlow ( node ) ;
12671296 }
@@ -1276,12 +1305,12 @@ namespace ts {
12761305 expr = ( < ParenthesizedExpression > expr ) . expression ;
12771306 }
12781307 if ( expr . kind === SyntaxKind . FunctionExpression || expr . kind === SyntaxKind . ArrowFunction ) {
1279- forEach ( node . typeArguments , bind ) ;
1280- forEach ( node . arguments , bind ) ;
1308+ bindEach ( node . typeArguments ) ;
1309+ bindEach ( node . arguments ) ;
12811310 bind ( node . expression ) ;
12821311 }
12831312 else {
1284- forEachChild ( node , bind ) ;
1313+ bindEachChild ( node ) ;
12851314 }
12861315 if ( node . expression . kind === SyntaxKind . PropertyAccessExpression ) {
12871316 const propertyAccess = < PropertyAccessExpression > node . expression ;
@@ -2514,7 +2543,7 @@ namespace ts {
25142543 transformFlags |= TransformFlags . AssertTypeScript ;
25152544 }
25162545
2517- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression
2546+ if ( subtreeFlags & TransformFlags . ContainsSpread
25182547 || isSuperOrSuperProperty ( expression , expressionKind ) ) {
25192548 // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
25202549 // node.
@@ -2545,7 +2574,7 @@ namespace ts {
25452574 if ( node . typeArguments ) {
25462575 transformFlags |= TransformFlags . AssertTypeScript ;
25472576 }
2548- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2577+ if ( subtreeFlags & TransformFlags . ContainsSpread ) {
25492578 // If the this node contains a SpreadElementExpression then it is an ES6
25502579 // node.
25512580 transformFlags |= TransformFlags . AssertES2015 ;
@@ -2554,7 +2583,6 @@ namespace ts {
25542583 return transformFlags & ~ TransformFlags . ArrayLiteralOrCallOrNewExcludes ;
25552584 }
25562585
2557-
25582586 function computeBinaryExpression ( node : BinaryExpression , subtreeFlags : TransformFlags ) {
25592587 let transformFlags = subtreeFlags ;
25602588 const operatorTokenKind = node . operatorToken . kind ;
@@ -2601,7 +2629,7 @@ namespace ts {
26012629 }
26022630
26032631 // parameters with object rest destructuring are ES Next syntax
2604- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2632+ if ( subtreeFlags & ( TransformFlags . ContainsRest | TransformFlags . ContainsObjectRest ) ) {
26052633 transformFlags |= TransformFlags . AssertESNext ;
26062634 }
26072635
@@ -2723,7 +2751,7 @@ namespace ts {
27232751 }
27242752
27252753 node . transformFlags = transformFlags | TransformFlags . HasComputedFlags ;
2726- return transformFlags & ~ TransformFlags . NodeExcludes ;
2754+ return transformFlags & ~ TransformFlags . CatchClauseExcludes ;
27272755 }
27282756
27292757 function computeExpressionWithTypeArguments ( node : ExpressionWithTypeArguments , subtreeFlags : TransformFlags ) {
@@ -2839,7 +2867,7 @@ namespace ts {
28392867 }
28402868
28412869 // function declarations with object rest destructuring are ES Next syntax
2842- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2870+ if ( subtreeFlags & ( TransformFlags . ContainsRest | TransformFlags . ContainsObjectRest ) ) {
28432871 transformFlags |= TransformFlags . AssertESNext ;
28442872 }
28452873
@@ -2881,7 +2909,7 @@ namespace ts {
28812909 }
28822910
28832911 // function expressions with object rest destructuring are ES Next syntax
2884- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2912+ if ( subtreeFlags & ( TransformFlags . ContainsRest | TransformFlags . ContainsObjectRest ) ) {
28852913 transformFlags |= TransformFlags . AssertESNext ;
28862914 }
28872915
@@ -2924,7 +2952,7 @@ namespace ts {
29242952 }
29252953
29262954 // arrow functions with object rest destructuring are ES Next syntax
2927- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2955+ if ( subtreeFlags & ( TransformFlags . ContainsRest | TransformFlags . ContainsObjectRest ) ) {
29282956 transformFlags |= TransformFlags . AssertESNext ;
29292957 }
29302958
@@ -3178,16 +3206,19 @@ namespace ts {
31783206 break ;
31793207
31803208 case SyntaxKind . SpreadElement :
3209+ transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsSpread ;
3210+ break ;
3211+
31813212 case SyntaxKind . SpreadAssignment :
3182- // This node is ES6 or ES next syntax, but is handled by a containing node.
3183- transformFlags |= TransformFlags . ContainsSpreadExpression ;
3213+ transformFlags |= TransformFlags . AssertESNext | TransformFlags . ContainsSpread | TransformFlags . ContainsObjectSpread ;
31843214 break ;
31853215
31863216 case SyntaxKind . BindingElement :
3187- if ( ( node as BindingElement ) . dotDotDotToken ) {
3188- // this node is ES2015 or ES next syntax, but is handled by a containing node.
3189- transformFlags |= TransformFlags . ContainsSpreadExpression ;
3217+ transformFlags |= TransformFlags . AssertES2015 ;
3218+ if ( ( < BindingElement > node ) . dotDotDotToken ) {
3219+ transformFlags |= TransformFlags . ContainsRest ;
31903220 }
3221+ break ;
31913222
31923223 case SyntaxKind . SuperKeyword :
31933224 // This node is ES6 syntax.
@@ -3200,14 +3231,16 @@ namespace ts {
32003231 break ;
32013232
32023233 case SyntaxKind . ObjectBindingPattern :
3203- case SyntaxKind . ArrayBindingPattern :
3204- // These nodes are ES2015 or ES Next syntax.
3205- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
3206- transformFlags |= TransformFlags . AssertESNext | TransformFlags . ContainsBindingPattern ;
3207- }
3208- else {
3209- transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
3234+ transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
3235+ if ( subtreeFlags & TransformFlags . ContainsSpread ) {
3236+ transformFlags |= TransformFlags . AssertESNext | TransformFlags . ContainsObjectRest ;
32103237 }
3238+ excludeFlags = TransformFlags . BindingPatternExcludes ;
3239+ break ;
3240+
3241+ case SyntaxKind . ArrayBindingPattern :
3242+ transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
3243+ excludeFlags = TransformFlags . BindingPatternExcludes ;
32113244 break ;
32123245
32133246 case SyntaxKind . Decorator :
@@ -3229,18 +3262,18 @@ namespace ts {
32293262 transformFlags |= TransformFlags . ContainsLexicalThis ;
32303263 }
32313264
3232- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
3265+ if ( subtreeFlags & TransformFlags . ContainsSpread ) {
32333266 // If an ObjectLiteralExpression contains a spread element, then it
32343267 // is an ES next node.
3235- transformFlags |= TransformFlags . AssertESNext ;
3268+ transformFlags |= TransformFlags . AssertESNext | TransformFlags . ContainsObjectSpread ;
32363269 }
32373270
32383271 break ;
32393272
32403273 case SyntaxKind . ArrayLiteralExpression :
32413274 case SyntaxKind . NewExpression :
32423275 excludeFlags = TransformFlags . ArrayLiteralOrCallOrNewExcludes ;
3243- if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
3276+ if ( subtreeFlags & TransformFlags . ContainsSpread ) {
32443277 // If the this node contains a SpreadExpression, then it is an ES6
32453278 // node.
32463279 transformFlags |= TransformFlags . AssertES2015 ;
@@ -3333,6 +3366,11 @@ namespace ts {
33333366 return TransformFlags . TypeExcludes ;
33343367 case SyntaxKind . ObjectLiteralExpression :
33353368 return TransformFlags . ObjectLiteralExcludes ;
3369+ case SyntaxKind . CatchClause :
3370+ return TransformFlags . CatchClauseExcludes ;
3371+ case SyntaxKind . ObjectBindingPattern :
3372+ case SyntaxKind . ArrayBindingPattern :
3373+ return TransformFlags . BindingPatternExcludes ;
33363374 default :
33373375 return TransformFlags . NodeExcludes ;
33383376 }
0 commit comments