fix: disallow all parenthesized pattern except parsing LHS (#12327)

* fix: disallow all parenthesized pattern except parsing LHS

* fix: forStatement requires LHS

* simplify toAssignable

* add more test cases

* fix: pass through isLHS on object property and assignment expression

* fix: record parenthesized identifier error for LHS

* remove duplicated skipped tests

* fix: do not record errors on ancestry arrow head

* Update packages/babel-parser/src/util/expression-scope.js

Co-authored-by: Brian Ng <bng412@gmail.com>

Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
Huáng Jùnliàng
2020-11-10 14:42:37 -05:00
committed by GitHub
parent 08c7280167
commit 5bbad8936b
93 changed files with 2273 additions and 115 deletions

View File

@@ -341,23 +341,23 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return (node: any);
}
toAssignable(node: N.Node): N.Node {
toAssignable(node: N.Node, isLHS: boolean = false): N.Node {
if (isSimpleProperty(node)) {
this.toAssignable(node.value);
return node;
}
return super.toAssignable(node);
return super.toAssignable(node, isLHS);
}
toAssignableObjectExpressionProp(prop: N.Node, isLast: boolean) {
toAssignableObjectExpressionProp(prop: N.Node, ...args) {
if (prop.kind === "get" || prop.kind === "set") {
throw this.raise(prop.key.start, Errors.PatternHasAccessor);
} else if (prop.method) {
throw this.raise(prop.key.start, Errors.PatternHasMethod);
} else {
super.toAssignableObjectExpressionProp(prop, isLast);
super.toAssignableObjectExpressionProp(prop, ...args);
}
}

View File

@@ -1955,6 +1955,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// has not been converted yet.
((node.params: any): N.Expression[]),
node.extra?.trailingComma,
/* isLHS */ false,
);
// Enter scope, as checkParams defines bindings
this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW);
@@ -2192,11 +2193,11 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
toAssignable(node: N.Node): N.Node {
toAssignable(node: N.Node, isLHS: boolean = false): N.Node {
if (node.type === "TypeCastExpression") {
return super.toAssignable(this.typeCastToParameter(node));
return super.toAssignable(this.typeCastToParameter(node), isLHS);
} else {
return super.toAssignable(node);
return super.toAssignable(node, isLHS);
}
}
@@ -2204,6 +2205,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
toAssignableList(
exprList: N.Expression[],
trailingCommaPos?: ?number,
isLHS: boolean,
): $ReadOnlyArray<N.Pattern> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];
@@ -2211,7 +2213,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
exprList[i] = this.typeCastToParameter(expr);
}
}
return super.toAssignableList(exprList, trailingCommaPos);
return super.toAssignableList(exprList, trailingCommaPos, isLHS);
}
// this is a list of nodes, from something like a call expression, we need to filter the

View File

@@ -2596,19 +2596,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return param;
}
toAssignable(node: N.Node): N.Node {
toAssignable(node: N.Node, isLHS: boolean = false): N.Node {
switch (node.type) {
case "TSTypeCastExpression":
return super.toAssignable(this.typeCastToParameter(node));
return super.toAssignable(this.typeCastToParameter(node), isLHS);
case "TSParameterProperty":
return super.toAssignable(node);
return super.toAssignable(node, isLHS);
case "TSAsExpression":
case "TSNonNullExpression":
case "TSTypeAssertion":
node.expression = this.toAssignable(node.expression);
node.expression = this.toAssignable(node.expression, isLHS);
return node;
default:
return super.toAssignable(node);
return super.toAssignable(node, isLHS);
}
}