Skip to content

Commit 3d8650c

Browse files
Merge pull request #3601 from Microsoft/emptyBindingPatternParam
Emit valid code when a parameter's binding pattern has no elements
2 parents 559c9b0 + 740fd9c commit 3d8650c

File tree

35 files changed

+366
-25
lines changed

35 files changed

+366
-25
lines changed

src/compiler/emitter.ts

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,33 +3140,49 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
31403140
function emitDefaultValueAssignments(node: FunctionLikeDeclaration) {
31413141
if (languageVersion < ScriptTarget.ES6) {
31423142
let tempIndex = 0;
3143-
forEach(node.parameters, p => {
3143+
forEach(node.parameters, parameter => {
31443144
// A rest parameter cannot have a binding pattern or an initializer,
31453145
// so let's just ignore it.
3146-
if (p.dotDotDotToken) {
3146+
if (parameter.dotDotDotToken) {
31473147
return;
31483148
}
31493149

3150-
if (isBindingPattern(p.name)) {
3151-
writeLine();
3152-
write("var ");
3153-
emitDestructuring(p, /*isAssignmentExpressionStatement*/ false, tempParameters[tempIndex]);
3154-
write(";");
3155-
tempIndex++;
3150+
let { name: paramName, initializer } = parameter;
3151+
if (isBindingPattern(paramName)) {
3152+
// In cases where a binding pattern is simply '[]' or '{}',
3153+
// we usually don't want to emit a var declaration; however, in the presence
3154+
// of an initializer, we must emit that expression to preserve side effects.
3155+
let hasBindingElements = paramName.elements.length > 0;
3156+
if (hasBindingElements || initializer) {
3157+
writeLine();
3158+
write("var ");
3159+
3160+
if (hasBindingElements) {
3161+
emitDestructuring(parameter, /*isAssignmentExpressionStatement*/ false, tempParameters[tempIndex]);
3162+
}
3163+
else {
3164+
emit(tempParameters[tempIndex]);
3165+
write(" = ");
3166+
emit(initializer);
3167+
}
3168+
3169+
write(";");
3170+
tempIndex++;
3171+
}
31563172
}
3157-
else if (p.initializer) {
3173+
else if (initializer) {
31583174
writeLine();
3159-
emitStart(p);
3175+
emitStart(parameter);
31603176
write("if (");
3161-
emitNodeWithoutSourceMap(p.name);
3177+
emitNodeWithoutSourceMap(paramName);
31623178
write(" === void 0)");
3163-
emitEnd(p);
3179+
emitEnd(parameter);
31643180
write(" { ");
3165-
emitStart(p);
3166-
emitNodeWithoutSourceMap(p.name);
3181+
emitStart(parameter);
3182+
emitNodeWithoutSourceMap(paramName);
31673183
write(" = ");
3168-
emitNodeWithoutSourceMap(p.initializer);
3169-
emitEnd(p);
3184+
emitNodeWithoutSourceMap(initializer);
3185+
emitEnd(parameter);
31703186
write("; }");
31713187
}
31723188
});

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ namespace ts {
10651065
return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken;
10661066
}
10671067

1068-
export function isBindingPattern(node: Node) {
1068+
export function isBindingPattern(node: Node): node is BindingPattern {
10691069
return !!node && (node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern);
10701070
}
10711071

tests/baselines/reference/declarationEmitDestructuring4.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,16 @@ function baz4({} = { x: 10 }) { }
1515
// For an array binding pattern with empty elements,
1616
// we will not make any modification and will emit
1717
// the similar binding pattern users' have written
18-
function baz(_a) {
19-
var ;
20-
}
18+
function baz(_a) { }
2119
function baz1(_a) {
22-
var _b = _a === void 0 ? [1, 2, 3] : _a;
20+
var _a = [1, 2, 3];
2321
}
2422
function baz2(_a) {
2523
var _b = (_a === void 0 ? [[1, 2, 3]] : _a)[0];
2624
}
27-
function baz3(_a) {
28-
var ;
29-
}
25+
function baz3(_a) { }
3026
function baz4(_a) {
31-
var _b = _a === void 0 ? { x: 10 } : _a;
27+
var _a = { x: 10 };
3228
}
3329

3430

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [emptyArrayBindingPatternParameter01.ts]
2+
3+
4+
function f([]) {
5+
var x, y, z;
6+
}
7+
8+
//// [emptyArrayBindingPatternParameter01.js]
9+
function f(_a) {
10+
var x, y, z;
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/conformance/es6/destructuring/emptyArrayBindingPatternParameter01.ts ===
2+
3+
4+
function f([]) {
5+
>f : Symbol(f, Decl(emptyArrayBindingPatternParameter01.ts, 0, 0))
6+
7+
var x, y, z;
8+
>x : Symbol(x, Decl(emptyArrayBindingPatternParameter01.ts, 3, 4))
9+
>y : Symbol(y, Decl(emptyArrayBindingPatternParameter01.ts, 3, 7))
10+
>z : Symbol(z, Decl(emptyArrayBindingPatternParameter01.ts, 3, 10))
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/conformance/es6/destructuring/emptyArrayBindingPatternParameter01.ts ===
2+
3+
4+
function f([]) {
5+
>f : ([]: any[]) => void
6+
7+
var x, y, z;
8+
>x : any
9+
>y : any
10+
>z : any
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [emptyArrayBindingPatternParameter02.ts]
2+
3+
4+
function f(a, []) {
5+
var x, y, z;
6+
}
7+
8+
//// [emptyArrayBindingPatternParameter02.js]
9+
function f(a, _a) {
10+
var x, y, z;
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/conformance/es6/destructuring/emptyArrayBindingPatternParameter02.ts ===
2+
3+
4+
function f(a, []) {
5+
>f : Symbol(f, Decl(emptyArrayBindingPatternParameter02.ts, 0, 0))
6+
>a : Symbol(a, Decl(emptyArrayBindingPatternParameter02.ts, 2, 11))
7+
8+
var x, y, z;
9+
>x : Symbol(x, Decl(emptyArrayBindingPatternParameter02.ts, 3, 7))
10+
>y : Symbol(y, Decl(emptyArrayBindingPatternParameter02.ts, 3, 10))
11+
>z : Symbol(z, Decl(emptyArrayBindingPatternParameter02.ts, 3, 13))
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/conformance/es6/destructuring/emptyArrayBindingPatternParameter02.ts ===
2+
3+
4+
function f(a, []) {
5+
>f : (a: any, []: any[]) => void
6+
>a : any
7+
8+
var x, y, z;
9+
>x : any
10+
>y : any
11+
>z : any
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [emptyArrayBindingPatternParameter03.ts]
2+
3+
4+
function f(a, []) {
5+
var x, y, z;
6+
}
7+
8+
//// [emptyArrayBindingPatternParameter03.js]
9+
function f(a, _a) {
10+
var x, y, z;
11+
}

0 commit comments

Comments
 (0)