Skip to content

Commit be5e5fb

Browse files
authored
Merge pull request #11150 from Microsoft/object-spread
Object spread/rest
2 parents 6398e0d + 25462c9 commit be5e5fb

File tree

96 files changed

+6519
-1514
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+6519
-1514
lines changed

Diff for: Jakefile.js

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var compilerSources = [
7171
"transformers/destructuring.ts",
7272
"transformers/ts.ts",
7373
"transformers/jsx.ts",
74+
"transformers/esnext.ts",
7475
"transformers/es2017.ts",
7576
"transformers/es2016.ts",
7677
"transformers/es2015.ts",
@@ -107,6 +108,7 @@ var servicesSources = [
107108
"transformers/destructuring.ts",
108109
"transformers/ts.ts",
109110
"transformers/jsx.ts",
111+
"transformers/esnext.ts",
110112
"transformers/es2017.ts",
111113
"transformers/es2016.ts",
112114
"transformers/es2015.ts",

Diff for: src/compiler/binder.ts

+89-20
Original file line numberDiff line numberDiff line change
@@ -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
}
@@ -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

Comments
 (0)