Throw if rest element is not in last position for object expressions

This commit is contained in:
Brian Ng 2017-08-25 22:29:17 -05:00
parent 083a44658c
commit 2fa1f9929f
No known key found for this signature in database
GPG Key ID: 3F2380E1E1508CA9
5 changed files with 49 additions and 42 deletions

View File

@ -750,8 +750,6 @@ language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-w
language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-generator-declaration.js(strict mode)
language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js(default)
language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js(strict mode)
language/expressions/assignment/dstr-obj-rest-not-last-element-invalid.js(default)
language/expressions/assignment/dstr-obj-rest-not-last-element-invalid.js(strict mode)
language/expressions/async-generator/dflt-params-duplicates.js(default)
language/expressions/async-generator/early-errors-expression-await-as-function-binding-identifier.js(default)
language/expressions/async-generator/early-errors-expression-await-as-function-binding-identifier.js(strict mode)
@ -784,12 +782,8 @@ language/statements/for-await-of/escaped-of.js(default)
language/statements/for-await-of/escaped-of.js(strict mode)
language/statements/for-in/decl-async-gen.js(default)
language/statements/for-in/decl-async-gen.js(strict mode)
language/statements/for-in/dstr-obj-rest-not-last-element-invalid.js(default)
language/statements/for-in/dstr-obj-rest-not-last-element-invalid.js(strict mode)
language/statements/for-of/decl-async-gen.js(default)
language/statements/for-of/decl-async-gen.js(strict mode)
language/statements/for-of/dstr-obj-rest-not-last-element-invalid.js(default)
language/statements/for-of/dstr-obj-rest-not-last-element-invalid.js(strict mode)
language/statements/if/if-async-gen-else-async-gen.js(default)
language/statements/if/if-async-gen-else-async-gen.js(strict mode)
language/statements/if/if-async-gen-else-stmt.js(default)

View File

@ -56,26 +56,12 @@ export default class LValParser extends NodeUtils {
case "ObjectExpression":
node.type = "ObjectPattern";
for (const prop of node.properties) {
if (prop.type === "ObjectMethod") {
if (prop.kind === "get" || prop.kind === "set") {
this.raise(
prop.key.start,
"Object pattern can't contain getter or setter",
);
} else {
this.raise(
prop.key.start,
"Object pattern can't contain methods",
);
}
} else {
this.toAssignable(
prop,
isBinding,
"object destructuring pattern",
);
}
for (const [index, prop] of node.properties.entries()) {
this.toAssignableObjectExpressionProp(
prop,
isBinding,
index === node.properties.length - 1,
);
}
break;
@ -124,6 +110,28 @@ export default class LValParser extends NodeUtils {
return node;
}
toAssignableObjectExpressionProp(
prop: Node,
isBinding: ?boolean,
isLast: boolean,
) {
if (prop.type === "ObjectMethod") {
const error =
prop.kind === "get" || prop.kind === "set"
? "Object pattern can't contain getter or setter"
: "Object pattern can't contain methods";
this.raise(prop.key.start, error);
} else if (prop.type === "SpreadElement" && !isLast) {
this.raise(
prop.start,
"The rest element has to be the last element when destructuring",
);
} else {
this.toAssignable(prop, isBinding, "object destructuring pattern");
}
}
// Convert list of expression atoms to binding list.
toAssignableList(

View File

@ -317,25 +317,26 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (isSimpleProperty(node)) {
this.toAssignable(node.value, isBinding, contextDescription);
return node;
} else if (node.type === "ObjectExpression") {
node.type = "ObjectPattern";
for (const prop of node.properties) {
if (prop.kind === "get" || prop.kind === "set") {
this.raise(
prop.key.start,
"Object pattern can't contain getter or setter",
);
} else if (prop.method) {
this.raise(prop.key.start, "Object pattern can't contain methods");
} else {
this.toAssignable(prop, isBinding, "object destructuring pattern");
}
}
return node;
}
return super.toAssignable(node, isBinding, contextDescription);
}
toAssignableObjectExpressionProp(
prop: N.Node,
isBinding: ?boolean,
isLast: boolean,
) {
if (prop.kind === "get" || prop.kind === "set") {
this.raise(
prop.key.start,
"Object pattern can't contain getter or setter",
);
} else if (prop.method) {
this.raise(prop.key.start, "Object pattern can't contain methods");
} else {
super.toAssignableObjectExpressionProp(prop, isBinding, isLast);
}
}
};

View File

@ -0,0 +1 @@
({...rest, b} = {})

View File

@ -0,0 +1,3 @@
{
"throws": "The rest element has to be the last element when destructuring (1:2)"
}