@@ -1139,8 +1139,8 @@ namespace ts {
11391139 }
11401140 else if ( node . kind === SyntaxKind . ArrayLiteralExpression ) {
11411141 for ( const e of ( < ArrayLiteralExpression > node ) . elements ) {
1142- if ( e . kind === SyntaxKind . SpreadElementExpression ) {
1143- bindAssignmentTargetFlow ( ( < SpreadElementExpression > e ) . expression ) ;
1142+ if ( e . kind === SyntaxKind . SpreadElement ) {
1143+ bindAssignmentTargetFlow ( ( < SpreadElement > e ) . expression ) ;
11441144 }
11451145 else {
11461146 bindDestructuringTargetFlow ( e ) ;
@@ -1155,6 +1155,9 @@ namespace ts {
11551155 else if ( p . kind === SyntaxKind . ShorthandPropertyAssignment ) {
11561156 bindAssignmentTargetFlow ( ( < ShorthandPropertyAssignment > p ) . name ) ;
11571157 }
1158+ else if ( p . kind === SyntaxKind . SpreadAssignment ) {
1159+ bindAssignmentTargetFlow ( ( < SpreadAssignment > p ) . expression ) ;
1160+ }
11581161 }
11591162 }
11601163 }
@@ -1550,7 +1553,7 @@ namespace ts {
15501553 const seen = createMap < ElementKind > ( ) ;
15511554
15521555 for ( const prop of node . properties ) {
1553- if ( prop . name . kind !== SyntaxKind . Identifier ) {
1556+ if ( prop . kind === SyntaxKind . SpreadAssignment || prop . name . kind !== SyntaxKind . Identifier ) {
15541557 continue ;
15551558 }
15561559
@@ -1916,6 +1919,9 @@ namespace ts {
19161919 return bindParameter ( < ParameterDeclaration > node ) ;
19171920 case SyntaxKind . VariableDeclaration :
19181921 case SyntaxKind . BindingElement :
1922+ if ( ( node as BindingElement ) . dotDotDotToken && node . parent . kind === SyntaxKind . ObjectBindingPattern ) {
1923+ emitFlags |= NodeFlags . HasRestAttribute ;
1924+ }
19191925 return bindVariableDeclarationOrBindingElement ( < VariableDeclaration | BindingElement > node ) ;
19201926 case SyntaxKind . PropertyDeclaration :
19211927 case SyntaxKind . PropertySignature :
@@ -1929,8 +1935,21 @@ namespace ts {
19291935 case SyntaxKind . EnumMember :
19301936 return bindPropertyOrMethodOrAccessor ( < Declaration > node , SymbolFlags . EnumMember , SymbolFlags . EnumMemberExcludes ) ;
19311937
1938+ case SyntaxKind . SpreadAssignment :
19321939 case SyntaxKind . JsxSpreadAttribute :
1933- emitFlags |= NodeFlags . HasJsxSpreadAttributes ;
1940+ let root = container ;
1941+ let hasRest = false ;
1942+ while ( root . parent ) {
1943+ if ( root . kind === SyntaxKind . ObjectLiteralExpression &&
1944+ root . parent . kind === SyntaxKind . BinaryExpression &&
1945+ ( root . parent as BinaryExpression ) . operatorToken . kind === SyntaxKind . EqualsToken &&
1946+ ( root . parent as BinaryExpression ) . left === root ) {
1947+ hasRest = true ;
1948+ break ;
1949+ }
1950+ root = root . parent ;
1951+ }
1952+ emitFlags |= hasRest ? NodeFlags . HasRestAttribute : NodeFlags . HasSpreadAttribute ;
19341953 return ;
19351954
19361955 case SyntaxKind . CallSignature :
@@ -2495,9 +2514,9 @@ namespace ts {
24952514 transformFlags |= TransformFlags . AssertTypeScript ;
24962515 }
24972516
2498- if ( subtreeFlags & TransformFlags . ContainsSpreadElementExpression
2517+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression
24992518 || isSuperOrSuperProperty ( expression , expressionKind ) ) {
2500- // If the this node contains a SpreadElementExpression , or is a super call, then it is an ES6
2519+ // If the this node contains a SpreadExpression , or is a super call, then it is an ES6
25012520 // node.
25022521 transformFlags |= TransformFlags . AssertES2015 ;
25032522 }
@@ -2526,7 +2545,7 @@ namespace ts {
25262545 if ( node . typeArguments ) {
25272546 transformFlags |= TransformFlags . AssertTypeScript ;
25282547 }
2529- if ( subtreeFlags & TransformFlags . ContainsSpreadElementExpression ) {
2548+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
25302549 // If the this node contains a SpreadElementExpression then it is an ES6
25312550 // node.
25322551 transformFlags |= TransformFlags . AssertES2015 ;
@@ -2541,10 +2560,13 @@ namespace ts {
25412560 const operatorTokenKind = node . operatorToken . kind ;
25422561 const leftKind = node . left . kind ;
25432562
2544- if ( operatorTokenKind === SyntaxKind . EqualsToken
2545- && ( leftKind === SyntaxKind . ObjectLiteralExpression
2546- || leftKind === SyntaxKind . ArrayLiteralExpression ) ) {
2547- // Destructuring assignments are ES6 syntax.
2563+ if ( operatorTokenKind === SyntaxKind . EqualsToken && leftKind === SyntaxKind . ObjectLiteralExpression ) {
2564+ // Destructuring object assignments with are ES2015 syntax
2565+ // and possibly ESNext if they contain rest
2566+ transformFlags |= TransformFlags . AssertESNext | TransformFlags . AssertES2015 | TransformFlags . AssertDestructuringAssignment ;
2567+ }
2568+ else if ( operatorTokenKind === SyntaxKind . EqualsToken && leftKind === SyntaxKind . ArrayLiteralExpression ) {
2569+ // Destructuring assignments are ES2015 syntax.
25482570 transformFlags |= TransformFlags . AssertES2015 | TransformFlags . AssertDestructuringAssignment ;
25492571 }
25502572 else if ( operatorTokenKind === SyntaxKind . AsteriskAsteriskToken
@@ -2578,6 +2600,11 @@ namespace ts {
25782600 transformFlags |= TransformFlags . AssertTypeScript | TransformFlags . ContainsParameterPropertyAssignments ;
25792601 }
25802602
2603+ // parameters with object rest destructuring are ES Next syntax
2604+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2605+ transformFlags |= TransformFlags . AssertESNext ;
2606+ }
2607+
25812608 // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
25822609 // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
25832610 if ( subtreeFlags & TransformFlags . ContainsBindingPattern || initializer || dotDotDotToken ) {
@@ -2811,6 +2838,11 @@ namespace ts {
28112838 transformFlags |= TransformFlags . AssertES2017 ;
28122839 }
28132840
2841+ // function declarations with object rest destructuring are ES Next syntax
2842+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2843+ transformFlags |= TransformFlags . AssertESNext ;
2844+ }
2845+
28142846 // If a FunctionDeclaration's subtree has marked the container as needing to capture the
28152847 // lexical this, or the function contains parameters with initializers, then this node is
28162848 // ES6 syntax.
@@ -2848,6 +2880,12 @@ namespace ts {
28482880 transformFlags |= TransformFlags . AssertES2017 ;
28492881 }
28502882
2883+ // function expressions with object rest destructuring are ES Next syntax
2884+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2885+ transformFlags |= TransformFlags . AssertESNext ;
2886+ }
2887+
2888+
28512889 // If a FunctionExpression's subtree has marked the container as needing to capture the
28522890 // lexical this, or the function contains parameters with initializers, then this node is
28532891 // ES6 syntax.
@@ -2885,6 +2923,11 @@ namespace ts {
28852923 transformFlags |= TransformFlags . AssertES2017 ;
28862924 }
28872925
2926+ // arrow functions with object rest destructuring are ES Next syntax
2927+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
2928+ transformFlags |= TransformFlags . AssertESNext ;
2929+ }
2930+
28882931 // If an ArrowFunction contains a lexical this, its container must capture the lexical this.
28892932 if ( subtreeFlags & TransformFlags . ContainsLexicalThis ) {
28902933 transformFlags |= TransformFlags . ContainsCapturedLexicalThis ;
@@ -2913,8 +2956,13 @@ namespace ts {
29132956 let transformFlags = subtreeFlags ;
29142957 const nameKind = node . name . kind ;
29152958
2916- // A VariableDeclaration with a binding pattern is ES6 syntax.
2917- if ( nameKind === SyntaxKind . ObjectBindingPattern || nameKind === SyntaxKind . ArrayBindingPattern ) {
2959+ // A VariableDeclaration with an object binding pattern is ES2015 syntax
2960+ // and possibly ESNext syntax if it contains an object binding pattern
2961+ if ( nameKind === SyntaxKind . ObjectBindingPattern ) {
2962+ transformFlags |= TransformFlags . AssertESNext | TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
2963+ }
2964+ // A VariableDeclaration with an object binding pattern is ES2015 syntax.
2965+ else if ( nameKind === SyntaxKind . ArrayBindingPattern ) {
29182966 transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
29192967 }
29202968
@@ -3055,14 +3103,17 @@ namespace ts {
30553103 transformFlags |= TransformFlags . AssertJsx ;
30563104 break ;
30573105
3106+ case SyntaxKind . ForOfStatement :
3107+ // for-of might be ESNext if it has a rest destructuring
3108+ transformFlags |= TransformFlags . AssertESNext ;
3109+ // FALLTHROUGH
30583110 case SyntaxKind . NoSubstitutionTemplateLiteral :
30593111 case SyntaxKind . TemplateHead :
30603112 case SyntaxKind . TemplateMiddle :
30613113 case SyntaxKind . TemplateTail :
30623114 case SyntaxKind . TemplateExpression :
30633115 case SyntaxKind . TaggedTemplateExpression :
30643116 case SyntaxKind . ShorthandPropertyAssignment :
3065- case SyntaxKind . ForOfStatement :
30663117 case SyntaxKind . StaticKeyword :
30673118 // These nodes are ES6 syntax.
30683119 transformFlags |= TransformFlags . AssertES2015 ;
@@ -3126,11 +3177,18 @@ namespace ts {
31263177 }
31273178 break ;
31283179
3129- case SyntaxKind . SpreadElementExpression :
3130- // This node is ES6 syntax, but is handled by a containing node.
3131- transformFlags |= TransformFlags . ContainsSpreadElementExpression ;
3180+ case SyntaxKind . SpreadElement :
3181+ case SyntaxKind . SpreadAssignment :
3182+ // This node is ES6 or ES next syntax, but is handled by a containing node.
3183+ transformFlags |= TransformFlags . ContainsSpreadExpression ;
31323184 break ;
31333185
3186+ 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 ;
3190+ }
3191+
31343192 case SyntaxKind . SuperKeyword :
31353193 // This node is ES6 syntax.
31363194 transformFlags |= TransformFlags . AssertES2015 ;
@@ -3143,8 +3201,13 @@ namespace ts {
31433201
31443202 case SyntaxKind . ObjectBindingPattern :
31453203 case SyntaxKind . ArrayBindingPattern :
3146- // These nodes are ES6 syntax.
3147- transformFlags |= TransformFlags . AssertES2015 | TransformFlags . ContainsBindingPattern ;
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 ;
3210+ }
31483211 break ;
31493212
31503213 case SyntaxKind . Decorator :
@@ -3166,13 +3229,19 @@ namespace ts {
31663229 transformFlags |= TransformFlags . ContainsLexicalThis ;
31673230 }
31683231
3232+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
3233+ // If an ObjectLiteralExpression contains a spread element, then it
3234+ // is an ES next node.
3235+ transformFlags |= TransformFlags . AssertESNext ;
3236+ }
3237+
31693238 break ;
31703239
31713240 case SyntaxKind . ArrayLiteralExpression :
31723241 case SyntaxKind . NewExpression :
31733242 excludeFlags = TransformFlags . ArrayLiteralOrCallOrNewExcludes ;
3174- if ( subtreeFlags & TransformFlags . ContainsSpreadElementExpression ) {
3175- // If the this node contains a SpreadElementExpression , then it is an ES6
3243+ if ( subtreeFlags & TransformFlags . ContainsSpreadExpression ) {
3244+ // If the this node contains a SpreadExpression , then it is an ES6
31763245 // node.
31773246 transformFlags |= TransformFlags . AssertES2015 ;
31783247 }
0 commit comments