refactor: simplify toAssignable routine (#11032)
* refactor: remove isBinding parameter * remove unused contextDescription * refactor: remove unnecessary nullish check * refactor: simplify toAssignable on ParenthesizedExpression * tests: categorize createParenthesizedExpression tests
This commit is contained in:
parent
9bc04baeb5
commit
43b23e0869
@ -212,7 +212,7 @@ export default class ExpressionParser extends LValParser {
|
||||
this.expectPlugin("logicalAssignment");
|
||||
}
|
||||
if (this.match(tt.eq)) {
|
||||
node.left = this.toAssignable(left, undefined, "assignment expression");
|
||||
node.left = this.toAssignable(left);
|
||||
refExpressionErrors.doubleProto = -1; // reset because double __proto__ is valid in assignment expression
|
||||
} else {
|
||||
node.left = left;
|
||||
@ -1857,15 +1857,17 @@ export default class ExpressionParser extends LValParser {
|
||||
): N.ArrowFunctionExpression {
|
||||
this.scope.enter(functionFlags(isAsync, false) | SCOPE_ARROW);
|
||||
this.initFunction(node, isAsync);
|
||||
|
||||
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
||||
const oldYieldPos = this.state.yieldPos;
|
||||
const oldAwaitPos = this.state.awaitPos;
|
||||
|
||||
if (params) {
|
||||
this.state.maybeInArrowParameters = true;
|
||||
this.setArrowFunctionParameters(node, params, trailingCommaPos);
|
||||
}
|
||||
this.state.maybeInArrowParameters = false;
|
||||
this.state.yieldPos = -1;
|
||||
this.state.awaitPos = -1;
|
||||
|
||||
if (params) this.setArrowFunctionParameters(node, params, trailingCommaPos);
|
||||
this.parseFunctionBody(node, true);
|
||||
|
||||
this.scope.exit();
|
||||
@ -1881,12 +1883,7 @@ export default class ExpressionParser extends LValParser {
|
||||
params: N.Expression[],
|
||||
trailingCommaPos: ?number,
|
||||
): void {
|
||||
node.params = this.toAssignableList(
|
||||
params,
|
||||
true,
|
||||
"arrow function parameters",
|
||||
trailingCommaPos,
|
||||
);
|
||||
node.params = this.toAssignableList(params, trailingCommaPos);
|
||||
}
|
||||
|
||||
parseFunctionBodyAndFinish(
|
||||
|
||||
@ -50,18 +50,10 @@ export default class LValParser extends NodeUtils {
|
||||
// NOTE: There is a corresponding "isAssignable" method in flow.js.
|
||||
// When this one is updated, please check if also that one needs to be updated.
|
||||
|
||||
toAssignable(
|
||||
node: Node,
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
): Node {
|
||||
if (node) {
|
||||
if (
|
||||
(this.options.createParenthesizedExpressions &&
|
||||
node.type === "ParenthesizedExpression") ||
|
||||
node.extra?.parenthesized
|
||||
) {
|
||||
const parenthesized = unwrapParenthesizedExpression(node);
|
||||
toAssignable(node: Node): Node {
|
||||
let parenthesized = undefined;
|
||||
if (node.type === "ParenthesizedExpression" || node.extra?.parenthesized) {
|
||||
parenthesized = unwrapParenthesizedExpression(node);
|
||||
if (
|
||||
parenthesized.type !== "Identifier" &&
|
||||
parenthesized.type !== "MemberExpression"
|
||||
@ -86,7 +78,7 @@ export default class LValParser extends NodeUtils {
|
||||
) {
|
||||
const prop = node.properties[i];
|
||||
const isLast = i === last;
|
||||
this.toAssignableObjectExpressionProp(prop, isBinding, isLast);
|
||||
this.toAssignableObjectExpressionProp(prop, isLast);
|
||||
|
||||
if (
|
||||
isLast &&
|
||||
@ -99,7 +91,7 @@ export default class LValParser extends NodeUtils {
|
||||
break;
|
||||
|
||||
case "ObjectProperty":
|
||||
this.toAssignable(node.value, isBinding, contextDescription);
|
||||
this.toAssignable(node.value);
|
||||
break;
|
||||
|
||||
case "SpreadElement": {
|
||||
@ -107,18 +99,13 @@ export default class LValParser extends NodeUtils {
|
||||
|
||||
node.type = "RestElement";
|
||||
const arg = node.argument;
|
||||
this.toAssignable(arg, isBinding, contextDescription);
|
||||
this.toAssignable(arg);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ArrayExpression":
|
||||
node.type = "ArrayPattern";
|
||||
this.toAssignableList(
|
||||
node.elements,
|
||||
isBinding,
|
||||
contextDescription,
|
||||
node.extra?.trailingComma,
|
||||
);
|
||||
this.toAssignableList(node.elements, node.extra?.trailingComma);
|
||||
break;
|
||||
|
||||
case "AssignmentExpression":
|
||||
@ -131,33 +118,21 @@ export default class LValParser extends NodeUtils {
|
||||
|
||||
node.type = "AssignmentPattern";
|
||||
delete node.operator;
|
||||
this.toAssignable(node.left, isBinding, contextDescription);
|
||||
this.toAssignable(node.left);
|
||||
break;
|
||||
|
||||
case "ParenthesizedExpression":
|
||||
node.expression = this.toAssignable(
|
||||
node.expression,
|
||||
isBinding,
|
||||
contextDescription,
|
||||
);
|
||||
this.toAssignable(((parenthesized: any): Expression));
|
||||
break;
|
||||
|
||||
case "MemberExpression":
|
||||
if (!isBinding) break;
|
||||
|
||||
default:
|
||||
// We don't know how to deal with this node. It will
|
||||
// be reported by a later call to checkLVal
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
toAssignableObjectExpressionProp(
|
||||
prop: Node,
|
||||
isBinding: ?boolean,
|
||||
isLast: boolean,
|
||||
) {
|
||||
toAssignableObjectExpressionProp(prop: Node, isLast: boolean) {
|
||||
if (prop.type === "ObjectMethod") {
|
||||
const error =
|
||||
prop.kind === "get" || prop.kind === "set"
|
||||
@ -168,7 +143,7 @@ export default class LValParser extends NodeUtils {
|
||||
} else if (prop.type === "SpreadElement" && !isLast) {
|
||||
this.raiseRestNotLast(prop.start);
|
||||
} else {
|
||||
this.toAssignable(prop, isBinding, "object destructuring pattern");
|
||||
this.toAssignable(prop);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,8 +151,6 @@ export default class LValParser extends NodeUtils {
|
||||
|
||||
toAssignableList(
|
||||
exprList: Expression[],
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
trailingCommaPos?: ?number,
|
||||
): $ReadOnlyArray<Pattern> {
|
||||
let end = exprList.length;
|
||||
@ -188,7 +161,7 @@ export default class LValParser extends NodeUtils {
|
||||
} else if (last && last.type === "SpreadElement") {
|
||||
last.type = "RestElement";
|
||||
const arg = last.argument;
|
||||
this.toAssignable(arg, isBinding, contextDescription);
|
||||
this.toAssignable(arg);
|
||||
if (
|
||||
arg.type !== "Identifier" &&
|
||||
arg.type !== "MemberExpression" &&
|
||||
@ -208,7 +181,7 @@ export default class LValParser extends NodeUtils {
|
||||
for (let i = 0; i < end; i++) {
|
||||
const elt = exprList[i];
|
||||
if (elt) {
|
||||
this.toAssignable(elt, isBinding, contextDescription);
|
||||
this.toAssignable(elt);
|
||||
if (elt.type === "RestElement") {
|
||||
this.raiseRestNotLast(elt.start);
|
||||
}
|
||||
|
||||
@ -537,10 +537,10 @@ export default class StatementParser extends ExpressionParser {
|
||||
const refExpressionErrors = new ExpressionErrors();
|
||||
const init = this.parseExpression(true, refExpressionErrors);
|
||||
if (this.match(tt._in) || this.isContextual("of")) {
|
||||
this.toAssignable(init);
|
||||
const description = this.isContextual("of")
|
||||
? "for-of statement"
|
||||
: "for-in statement";
|
||||
this.toAssignable(init, undefined, description);
|
||||
this.checkLVal(init, undefined, undefined, description);
|
||||
return this.parseForIn(node, init, awaitAt);
|
||||
} else {
|
||||
|
||||
@ -362,25 +362,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
return (node: any);
|
||||
}
|
||||
|
||||
toAssignable(
|
||||
node: N.Node,
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
): N.Node {
|
||||
toAssignable(node: N.Node): N.Node {
|
||||
if (isSimpleProperty(node)) {
|
||||
this.toAssignable(node.value, isBinding, contextDescription);
|
||||
this.toAssignable(node.value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
return super.toAssignable(node, isBinding, contextDescription);
|
||||
return super.toAssignable(node);
|
||||
}
|
||||
|
||||
toAssignableObjectExpressionProp(
|
||||
prop: N.Node,
|
||||
isBinding: ?boolean,
|
||||
isLast: boolean,
|
||||
) {
|
||||
toAssignableObjectExpressionProp(prop: N.Node, isLast: boolean) {
|
||||
if (prop.kind === "get" || prop.kind === "set") {
|
||||
throw this.raise(
|
||||
prop.key.start,
|
||||
@ -392,7 +384,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
"Object pattern can't contain methods",
|
||||
);
|
||||
} else {
|
||||
super.toAssignableObjectExpressionProp(prop, isBinding, isLast);
|
||||
super.toAssignableObjectExpressionProp(prop, isLast);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1886,8 +1886,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
// node.params is Expression[] instead of $ReadOnlyArray<Pattern> because it
|
||||
// has not been converted yet.
|
||||
((node.params: any): N.Expression[]),
|
||||
true,
|
||||
"arrow function parameters",
|
||||
node.extra?.trailingComma,
|
||||
);
|
||||
// Enter scope, as checkParams defines bindings
|
||||
@ -2091,27 +2089,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
}
|
||||
}
|
||||
|
||||
toAssignable(
|
||||
node: N.Node,
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
): N.Node {
|
||||
toAssignable(node: N.Node): N.Node {
|
||||
if (node.type === "TypeCastExpression") {
|
||||
return super.toAssignable(
|
||||
this.typeCastToParameter(node),
|
||||
isBinding,
|
||||
contextDescription,
|
||||
);
|
||||
return super.toAssignable(this.typeCastToParameter(node));
|
||||
} else {
|
||||
return super.toAssignable(node, isBinding, contextDescription);
|
||||
return super.toAssignable(node);
|
||||
}
|
||||
}
|
||||
|
||||
// turn type casts that we found in function parameter head into type annotated params
|
||||
toAssignableList(
|
||||
exprList: N.Expression[],
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
trailingCommaPos?: ?number,
|
||||
): $ReadOnlyArray<N.Pattern> {
|
||||
for (let i = 0; i < exprList.length; i++) {
|
||||
@ -2120,12 +2108,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
exprList[i] = this.typeCastToParameter(expr);
|
||||
}
|
||||
}
|
||||
return super.toAssignableList(
|
||||
exprList,
|
||||
isBinding,
|
||||
contextDescription,
|
||||
trailingCommaPos,
|
||||
);
|
||||
return super.toAssignableList(exprList, trailingCommaPos);
|
||||
}
|
||||
|
||||
// this is a list of nodes, from something like a call expression, we need to filter the
|
||||
|
||||
@ -2392,31 +2392,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
return param;
|
||||
}
|
||||
|
||||
toAssignable(
|
||||
node: N.Node,
|
||||
isBinding: ?boolean,
|
||||
contextDescription: string,
|
||||
): N.Node {
|
||||
toAssignable(node: N.Node): N.Node {
|
||||
switch (node.type) {
|
||||
case "TSTypeCastExpression":
|
||||
return super.toAssignable(
|
||||
this.typeCastToParameter(node),
|
||||
isBinding,
|
||||
contextDescription,
|
||||
);
|
||||
return super.toAssignable(this.typeCastToParameter(node));
|
||||
case "TSParameterProperty":
|
||||
return super.toAssignable(node, isBinding, contextDescription);
|
||||
return super.toAssignable(node);
|
||||
case "TSAsExpression":
|
||||
case "TSNonNullExpression":
|
||||
case "TSTypeAssertion":
|
||||
node.expression = this.toAssignable(
|
||||
node.expression,
|
||||
isBinding,
|
||||
contextDescription,
|
||||
);
|
||||
node.expression = this.toAssignable(node.expression);
|
||||
return node;
|
||||
default:
|
||||
return super.toAssignable(node, isBinding, contextDescription);
|
||||
return super.toAssignable(node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2524,10 +2512,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
}
|
||||
}
|
||||
|
||||
toAssignableList(
|
||||
exprList: N.Expression[],
|
||||
isBinding: ?boolean,
|
||||
): $ReadOnlyArray<N.Pattern> {
|
||||
toAssignableList(exprList: N.Expression[]): $ReadOnlyArray<N.Pattern> {
|
||||
for (let i = 0; i < exprList.length; i++) {
|
||||
const expr = exprList[i];
|
||||
if (!expr) continue;
|
||||
@ -2537,7 +2522,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
break;
|
||||
case "TSAsExpression":
|
||||
case "TSTypeAssertion":
|
||||
if (!isBinding) {
|
||||
if (!this.state.maybeInArrowParameters) {
|
||||
exprList[i] = this.typeCastToParameter(expr);
|
||||
} else {
|
||||
this.raise(
|
||||
|
||||
@ -0,0 +1 @@
|
||||
(!a) += 1
|
||||
@ -0,0 +1,138 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start": 0,
|
||||
"end": 9,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 9
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
"SyntaxError: Invalid left-hand side in parenthesized expression (1:1)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start": 0,
|
||||
"end": 9,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 9
|
||||
}
|
||||
},
|
||||
"sourceType": "script",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"start": 0,
|
||||
"end": 9,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 9
|
||||
}
|
||||
},
|
||||
"expression": {
|
||||
"type": "AssignmentExpression",
|
||||
"start": 0,
|
||||
"end": 9,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 9
|
||||
}
|
||||
},
|
||||
"operator": "+=",
|
||||
"left": {
|
||||
"type": "ParenthesizedExpression",
|
||||
"start": 0,
|
||||
"end": 4,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 4
|
||||
}
|
||||
},
|
||||
"expression": {
|
||||
"type": "UnaryExpression",
|
||||
"start": 1,
|
||||
"end": 3,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 1
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 3
|
||||
}
|
||||
},
|
||||
"operator": "!",
|
||||
"prefix": true,
|
||||
"argument": {
|
||||
"type": "Identifier",
|
||||
"start": 2,
|
||||
"end": 3,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 2
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 3
|
||||
},
|
||||
"identifierName": "a"
|
||||
},
|
||||
"name": "a"
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "NumericLiteral",
|
||||
"start": 8,
|
||||
"end": 9,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 8
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 9
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"rawValue": 1,
|
||||
"raw": "1"
|
||||
},
|
||||
"value": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"createParenthesizedExpressions": true
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user