Skip to content

Commit d4f6b9b

Browse files
committed
allow BindingPattern in FunctionRestParameter
also add downlevel emit for the destructured rest param Part of microsoft#6275
1 parent 3bfe91c commit d4f6b9b

16 files changed

+42
-125
lines changed

src/compiler/checker.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28570,10 +28570,6 @@ namespace ts {
2857028570
checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
2857128571
}
2857228572

28573-
if (isBindingPattern(parameter.name)) {
28574-
return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
28575-
}
28576-
2857728573
if (parameter.questionToken) {
2857828574
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional);
2857928575
}

src/compiler/transformers/es2015.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,8 +1340,8 @@ namespace ts {
13401340
* part of a constructor declaration with a
13411341
* synthesized call to `super`
13421342
*/
1343-
function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean) {
1344-
return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper;
1343+
function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean): node is ParameterDeclaration {
1344+
return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
13451345
}
13461346

13471347
/**
@@ -1360,11 +1360,11 @@ namespace ts {
13601360
}
13611361

13621362
// `declarationName` is the name of the local declaration for the parameter.
1363-
const declarationName = getMutableClone(<Identifier>parameter!.name);
1363+
const declarationName = parameter.name.kind === SyntaxKind.Identifier ? getMutableClone(parameter.name) : createTempVariable(/*recordTempVariable*/ undefined);
13641364
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
13651365

13661366
// `expressionName` is the name of the parameter used in expressions.
1367-
const expressionName = getSynthesizedClone(<Identifier>parameter!.name);
1367+
const expressionName = parameter.name.kind === SyntaxKind.Identifier ? getSynthesizedClone(parameter.name) : declarationName;
13681368
const restIndex = node.parameters.length - 1;
13691369
const temp = createLoopVariable();
13701370

@@ -1429,6 +1429,24 @@ namespace ts {
14291429
setEmitFlags(forStatement, EmitFlags.CustomPrologue);
14301430
startOnNewLine(forStatement);
14311431
statements.push(forStatement);
1432+
1433+
if (parameter.name.kind !== SyntaxKind.Identifier) {
1434+
// do the actual destructuring of the rest parameter if necessary
1435+
statements.push(
1436+
setEmitFlags(
1437+
setTextRange(
1438+
createVariableStatement(
1439+
/*modifiers*/ undefined,
1440+
createVariableDeclarationList(
1441+
flattenDestructuringBinding(parameter, visitor, context, FlattenLevel.All, expressionName),
1442+
)
1443+
),
1444+
parameter
1445+
),
1446+
EmitFlags.CustomPrologue
1447+
)
1448+
);
1449+
}
14321450
}
14331451

14341452
/**

tests/baselines/reference/iterableArrayPattern14.errors.txt

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/baselines/reference/iterableArrayPattern15.errors.txt

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/baselines/reference/iterableArrayPattern16.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'.
32
Property '0' is missing in type 'FooIterator'.
43
tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,12): error TS2449: Class 'FooIteratorIterator' used before its declaration.
54

65

7-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (3 errors) ====
6+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (2 errors) ====
87
function fun(...[a, b]: [Bar, Bar][]) { }
9-
~~~~~~
10-
!!! error TS2501: A rest element cannot contain a binding pattern.
118
fun(...new FooIteratorIterator);
129
~~~~~~~~~~~~~~~~~~~~~~~~~~
1310
!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'.

tests/baselines/reference/iterableArrayPattern17.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(16,17): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'.
32
Property 'x' is missing in type 'FooIterator'.
43

54

6-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (2 errors) ====
5+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (1 errors) ====
76
class Bar { x }
87
class Foo extends Bar { y }
98
class FooIterator {
@@ -20,8 +19,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error
2019
}
2120

2221
function fun(...[a, b]: Bar[]) { }
23-
~~~~~~
24-
!!! error TS2501: A rest element cannot contain a binding pattern.
2522
fun(new FooIterator);
2623
~~~~~~~~~~~~~~~
2724
!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'.

tests/baselines/reference/iterableArrayPattern20.errors.txt

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(2,1): error TS2554: Expected 2 arguments, but got 1.
32

43

5-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (2 errors) ====
4+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (1 errors) ====
65
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]) { }
7-
~~~~~~~~~~~~~~~~~~~~
8-
!!! error TS2501: A rest element cannot contain a binding pattern.
96
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
107
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
!!! error TS2554: Expected 2 arguments, but got 1.

tests/baselines/reference/iterableArrayPattern26.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(2,21): error TS2345: Argument of type 'Map<string, number>' is not assignable to parameter of type '[string, number]'.
32
Property '0' is missing in type 'Map<string, number>'.
43

54

6-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (2 errors) ====
5+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (1 errors) ====
76
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
8-
~~~~~~~~~~~~~~~~~~~~
9-
!!! error TS2501: A rest element cannot contain a binding pattern.
107
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
118
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129
!!! error TS2345: Argument of type 'Map<string, number>' is not assignable to parameter of type '[string, number]'.

tests/baselines/reference/iterableArrayPattern27.errors.txt

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/baselines/reference/iterableArrayPattern28.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'.
32
Types of property 'concat' are incompatible.
43
Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'.
@@ -8,10 +7,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error
87
Type 'boolean' is not assignable to type 'number'.
98

109

11-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ====
10+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (1 errors) ====
1211
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
13-
~~~~~~~~~~~~~~~~~~~~
14-
!!! error TS2501: A rest element cannot contain a binding pattern.
1512
takeFirstTwoEntries(...new Map([["", 0], ["hello", true]]));
1613
~~~~~~~~~~~~~~~~~~~~~~~~~~
1714
!!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'.

tests/baselines/reference/iterableArrayPattern29.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
21
tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(2,21): error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'.
32
Type 'boolean' is not assignable to type 'number'.
43

54

6-
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (2 errors) ====
5+
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (1 errors) ====
76
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
8-
~~~~~~~~~~~~~~~~~~~~
9-
!!! error TS2501: A rest element cannot contain a binding pattern.
107
takeFirstTwoEntries(...new Map([["", true], ["hello", true]]));
118
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129
!!! error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'.

tests/baselines/reference/restParameterWithBindingPattern1.errors.txt

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/baselines/reference/restParameterWithBindingPattern1.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22
function a(...{a, b}) { }
33

44
//// [restParameterWithBindingPattern1.js]
5-
function a() { }
5+
function a() {
6+
var _a = [];
7+
for (var _i = 0; _i < arguments.length; _i++) {
8+
_a[_i] = arguments[_i];
9+
}
10+
var a = _a.a, b = _a.b;
11+
}

tests/baselines/reference/restParameterWithBindingPattern2.errors.txt

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/baselines/reference/restParameterWithBindingPattern2.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22
function a(...[a, b]) { }
33

44
//// [restParameterWithBindingPattern2.js]
5-
function a() { }
5+
function a() {
6+
var _a = [];
7+
for (var _i = 0; _i < arguments.length; _i++) {
8+
_a[_i] = arguments[_i];
9+
}
10+
var a = _a[0], b = _a[1];
11+
}

0 commit comments

Comments
 (0)