Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: simplify toAssignable routine #11032

Merged
merged 5 commits into from Jan 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 7 additions & 10 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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(
Expand Down
163 changes: 68 additions & 95 deletions packages/babel-parser/src/parser/lval.js
Expand Up @@ -50,114 +50,89 @@ 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) {
toAssignable(node: Node): Node {
let parenthesized = undefined;
if (node.type === "ParenthesizedExpression" || node.extra?.parenthesized) {
parenthesized = unwrapParenthesizedExpression(node);
if (
(this.options.createParenthesizedExpressions &&
node.type === "ParenthesizedExpression") ||
node.extra?.parenthesized
parenthesized.type !== "Identifier" &&
parenthesized.type !== "MemberExpression"
) {
const parenthesized = unwrapParenthesizedExpression(node);
if (
parenthesized.type !== "Identifier" &&
parenthesized.type !== "MemberExpression"
) {
this.raise(node.start, "Invalid parenthesized assignment pattern");
}
this.raise(node.start, "Invalid parenthesized assignment pattern");
}
}

switch (node.type) {
case "Identifier":
case "ObjectPattern":
case "ArrayPattern":
case "AssignmentPattern":
break;

switch (node.type) {
case "Identifier":
case "ObjectPattern":
case "ArrayPattern":
case "AssignmentPattern":
break;

case "ObjectExpression":
node.type = "ObjectPattern";
for (
let i = 0, length = node.properties.length, last = length - 1;
i < length;
i++
case "ObjectExpression":
node.type = "ObjectPattern";
for (
let i = 0, length = node.properties.length, last = length - 1;
i < length;
i++
) {
const prop = node.properties[i];
const isLast = i === last;
this.toAssignableObjectExpressionProp(prop, isLast);

if (
isLast &&
prop.type === "RestElement" &&
node.extra?.trailingComma
) {
const prop = node.properties[i];
const isLast = i === last;
this.toAssignableObjectExpressionProp(prop, isBinding, isLast);

if (
isLast &&
prop.type === "RestElement" &&
node.extra?.trailingComma
) {
this.raiseRestNotLast(node.extra.trailingComma);
}
this.raiseRestNotLast(node.extra.trailingComma);
}
break;

case "ObjectProperty":
this.toAssignable(node.value, isBinding, contextDescription);
break;

case "SpreadElement": {
this.checkToRestConversion(node);

node.type = "RestElement";
const arg = node.argument;
this.toAssignable(arg, isBinding, contextDescription);
break;
}
break;

case "ArrayExpression":
node.type = "ArrayPattern";
this.toAssignableList(
node.elements,
isBinding,
contextDescription,
node.extra?.trailingComma,
);
break;
case "ObjectProperty":
this.toAssignable(node.value);
break;

case "AssignmentExpression":
if (node.operator !== "=") {
this.raise(
node.left.end,
"Only '=' operator can be used for specifying default value.",
);
}
case "SpreadElement": {
this.checkToRestConversion(node);

node.type = "AssignmentPattern";
delete node.operator;
this.toAssignable(node.left, isBinding, contextDescription);
break;
node.type = "RestElement";
const arg = node.argument;
this.toAssignable(arg);
break;
}

case "ArrayExpression":
node.type = "ArrayPattern";
this.toAssignableList(node.elements, node.extra?.trailingComma);
break;

case "ParenthesizedExpression":
node.expression = this.toAssignable(
node.expression,
isBinding,
contextDescription,
case "AssignmentExpression":
if (node.operator !== "=") {
this.raise(
node.left.end,
"Only '=' operator can be used for specifying default value.",
);
break;
}

case "MemberExpression":
if (!isBinding) break;
node.type = "AssignmentPattern";
delete node.operator;
this.toAssignable(node.left);
break;

default:
// We don't know how to deal with this node. It will
// be reported by a later call to checkLVal
}
case "ParenthesizedExpression":
this.toAssignable(((parenthesized: any): Expression));
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"
Expand All @@ -168,16 +143,14 @@ 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);
}
}

// Convert list of expression atoms to binding list.

toAssignableList(
exprList: Expression[],
isBinding: ?boolean,
contextDescription: string,
trailingCommaPos?: ?number,
): $ReadOnlyArray<Pattern> {
let end = exprList.length;
Expand All @@ -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" &&
Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/parser/statement.js
Expand Up @@ -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 {
Expand Down
18 changes: 5 additions & 13 deletions packages/babel-parser/src/plugins/estree.js
Expand Up @@ -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,
Expand All @@ -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);
}
}

Expand Down
25 changes: 4 additions & 21 deletions packages/babel-parser/src/plugins/flow.js
Expand Up @@ -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
Expand Down Expand Up @@ -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++) {
Expand All @@ -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
Expand Down