From 86e19d7b1665e3a56e9a00d4e9576268c3c74022 Mon Sep 17 00:00:00 2001 From: tony-go Date: Wed, 2 Jun 2021 09:01:26 +0200 Subject: [PATCH 1/6] fix(babel-parser): throw when ObjectProperty value is an AssignmentPattern in async call --- packages/babel-parser/src/parser/expression.js | 6 +++++- .../parenthesized-argument-object-with-assignment/input.js | 1 + .../options.json | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/input.js create mode 100644 packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/options.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index eb2ddaa9e14e..866e21e3c21b 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -766,6 +766,7 @@ export default class ExpressionParser extends LValParser { optional: boolean, ): N.Expression { const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const refExpressionErrors = new ExpressionErrors(); this.state.maybeInArrowParameters = true; this.next(); // eat `(` @@ -788,6 +789,7 @@ export default class ExpressionParser extends LValParser { base.type === "Import", base.type !== "Super", node, + refExpressionErrors, ); } this.finishCallExpression(node, state.optionalChainMember); @@ -801,6 +803,7 @@ export default class ExpressionParser extends LValParser { node, ); } else { + this.checkExpressionErrors(refExpressionErrors, true); if (state.maybeAsyncArrow) { this.expressionScope.exit(); } @@ -894,6 +897,7 @@ export default class ExpressionParser extends LValParser { dynamicImport?: boolean, allowPlaceholder?: boolean, nodeForExtra?: ?N.Node, + refExpressionErrors?: ?ExpressionErrors, ): $ReadOnlyArray { const elts = []; let first = true; @@ -931,7 +935,7 @@ export default class ExpressionParser extends LValParser { elts.push( this.parseExprListItem( false, - possibleAsyncArrow ? new ExpressionErrors() : undefined, + refExpressionErrors || new ExpressionErrors(), possibleAsyncArrow ? { start: 0 } : undefined, allowPlaceholder, ), diff --git a/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/input.js b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/input.js new file mode 100644 index 000000000000..c048527f250e --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/input.js @@ -0,0 +1 @@ +async({ foo33 = 1 }); \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/options.json b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/options.json new file mode 100644 index 000000000000..51c483f3d3d8 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-with-assignment/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:14)" +} \ No newline at end of file From 092b0a064ea703948487fd1424399079ec3b365e Mon Sep 17 00:00:00 2001 From: tony-go Date: Wed, 2 Jun 2021 20:25:00 +0200 Subject: [PATCH 2/6] feat(parser): simplify parseCallExpressionArguments --- packages/babel-parser/src/parser/expression.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 866e21e3c21b..fc1e9983669b 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -781,11 +781,10 @@ export default class ExpressionParser extends LValParser { node.optional = optional; } if (optional) { - node.arguments = this.parseCallExpressionArguments(tt.parenR, false); + node.arguments = this.parseCallExpressionArguments(tt.parenR); } else { node.arguments = this.parseCallExpressionArguments( tt.parenR, - state.maybeAsyncArrow, base.type === "Import", base.type !== "Super", node, @@ -893,7 +892,6 @@ export default class ExpressionParser extends LValParser { parseCallExpressionArguments( close: TokenType, - possibleAsyncArrow: boolean, dynamicImport?: boolean, allowPlaceholder?: boolean, nodeForExtra?: ?N.Node, @@ -936,7 +934,7 @@ export default class ExpressionParser extends LValParser { this.parseExprListItem( false, refExpressionErrors || new ExpressionErrors(), - possibleAsyncArrow ? { start: 0 } : undefined, + { start: 0 }, allowPlaceholder, ), ); From 1183a3cfa429fc37f27e88db92949bc0bb428e23 Mon Sep 17 00:00:00 2001 From: tony-go Date: Wed, 2 Jun 2021 22:01:23 +0200 Subject: [PATCH 3/6] chore(babel-parser): add test for double proto in async call --- .../input.js | 1 + .../output.json | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/input.js create mode 100644 packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/output.json diff --git a/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/input.js b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/input.js new file mode 100644 index 000000000000..eeb01ee23578 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/input.js @@ -0,0 +1 @@ +async({ __proto__: x, __proto__: y }) \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/output.json b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/output.json new file mode 100644 index 000000000000..35abfd88cdf5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-call/parenthesized-argument-object-double-proto/output.json @@ -0,0 +1,71 @@ +{ + "type": "File", + "start":0,"end":37,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}}, + "errors": [ + "SyntaxError: Redefinition of __proto__ property. (1:22)" + ], + "program": { + "type": "Program", + "start":0,"end":37,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":37,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}}, + "expression": { + "type": "CallExpression", + "start":0,"end":37,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}}, + "callee": { + "type": "Identifier", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5},"identifierName":"async"}, + "name": "async" + }, + "arguments": [ + { + "type": "ObjectExpression", + "start":6,"end":36,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":36}}, + "properties": [ + { + "type": "ObjectProperty", + "start":8,"end":20,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":20}}, + "method": false, + "key": { + "type": "Identifier", + "start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20},"identifierName":"x"}, + "name": "x" + } + }, + { + "type": "ObjectProperty", + "start":22,"end":34,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":34}}, + "method": false, + "key": { + "type": "Identifier", + "start":22,"end":31,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":31},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":33,"end":34,"loc":{"start":{"line":1,"column":33},"end":{"line":1,"column":34},"identifierName":"y"}, + "name": "y" + } + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 85e6386d3e19e94475b8ad6634cad95353709bee Mon Sep 17 00:00:00 2001 From: tony-go Date: Thu, 3 Jun 2021 09:04:54 +0200 Subject: [PATCH 4/6] chore(parser): add new tests cases and avoir useless refExpressionErrors's creation --- .../babel-parser/src/parser/expression.js | 2 +- .../parenthesized-assign-object/input.js | 1 + .../parenthesized-assign-object/output.json | 72 +++++++++++++++++++ .../input.js | 1 + .../output.json | 72 +++++++++++++++++++ 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/input.js create mode 100644 packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/output.json create mode 100644 packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index fc1e9983669b..f900b74f1925 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -933,7 +933,7 @@ export default class ExpressionParser extends LValParser { elts.push( this.parseExprListItem( false, - refExpressionErrors || new ExpressionErrors(), + refExpressionErrors, { start: 0 }, allowPlaceholder, ), diff --git a/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/input.js b/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/input.js new file mode 100644 index 000000000000..fbeb7c26b39e --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/input.js @@ -0,0 +1 @@ +async ({ __proto__: x, __proto__: y }) => {} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/output.json b/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/output.json new file mode 100644 index 000000000000..c12e4a550316 --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-arrow/parenthesized-assign-object/output.json @@ -0,0 +1,72 @@ +{ + "type": "File", + "start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":44}}, + "program": { + "type": "Program", + "start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":44}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":44}}, + "expression": { + "type": "ArrowFunctionExpression", + "start":0,"end":44,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":44}}, + "id": null, + "generator": false, + "async": true, + "params": [ + { + "type": "ObjectPattern", + "start":7,"end":37,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":37}}, + "properties": [ + { + "type": "ObjectProperty", + "start":9,"end":21,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":21}}, + "method": false, + "key": { + "type": "Identifier", + "start":9,"end":18,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":18},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":20,"end":21,"loc":{"start":{"line":1,"column":20},"end":{"line":1,"column":21},"identifierName":"x"}, + "name": "x" + } + }, + { + "type": "ObjectProperty", + "start":23,"end":35,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":35}}, + "method": false, + "key": { + "type": "Identifier", + "start":23,"end":32,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":32},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":34,"end":35,"loc":{"start":{"line":1,"column":34},"end":{"line":1,"column":35},"identifierName":"y"}, + "name": "y" + } + } + ] + } + ], + "body": { + "type": "BlockStatement", + "start":42,"end":44,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":44}}, + "body": [], + "directives": [] + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/input.js b/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/input.js new file mode 100644 index 000000000000..e5e4e0318078 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/input.js @@ -0,0 +1 @@ +async?.({ __proto__: x, __proto__: y }) \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/output.json b/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/output.json new file mode 100644 index 000000000000..332361411823 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/async-call/parenthesized-argument-object-double-proto/output.json @@ -0,0 +1,72 @@ +{ + "type": "File", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}}, + "errors": [ + "SyntaxError: Redefinition of __proto__ property. (1:24)" + ], + "program": { + "type": "Program", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}}, + "expression": { + "type": "OptionalCallExpression", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}}, + "callee": { + "type": "Identifier", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5},"identifierName":"async"}, + "name": "async" + }, + "optional": true, + "arguments": [ + { + "type": "ObjectExpression", + "start":8,"end":38,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":38}}, + "properties": [ + { + "type": "ObjectProperty", + "start":10,"end":22,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":22}}, + "method": false, + "key": { + "type": "Identifier", + "start":10,"end":19,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":19},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":21,"end":22,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":22},"identifierName":"x"}, + "name": "x" + } + }, + { + "type": "ObjectProperty", + "start":24,"end":36,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":36}}, + "method": false, + "key": { + "type": "Identifier", + "start":24,"end":33,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":33},"identifierName":"__proto__"}, + "name": "__proto__" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start":35,"end":36,"loc":{"start":{"line":1,"column":35},"end":{"line":1,"column":36},"identifierName":"y"}, + "name": "y" + } + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 7ab3018b044808d8acb4f69d56b15fae0f037b7a Mon Sep 17 00:00:00 2001 From: tony-go Date: Thu, 3 Jun 2021 09:08:15 +0200 Subject: [PATCH 5/6] fix(parser): create ExpressionErrors condtionaly --- packages/babel-parser/src/parser/expression.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index f900b74f1925..a08f128c3afd 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -766,7 +766,9 @@ export default class ExpressionParser extends LValParser { optional: boolean, ): N.Expression { const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; - const refExpressionErrors = new ExpressionErrors(); + const refExpressionErrors = state.maybeAsyncArrow + ? new ExpressionErrors() + : null; this.state.maybeInArrowParameters = true; this.next(); // eat `(` @@ -802,7 +804,10 @@ export default class ExpressionParser extends LValParser { node, ); } else { - this.checkExpressionErrors(refExpressionErrors, true); + if (refExpressionErrors !== null) { + this.checkExpressionErrors(refExpressionErrors, true); + } + if (state.maybeAsyncArrow) { this.expressionScope.exit(); } From 1716f881bb91caa8330e8153e4f8367feb0f55b1 Mon Sep 17 00:00:00 2001 From: tony-go Date: Thu, 3 Jun 2021 15:48:59 +0200 Subject: [PATCH 6/6] fix(parser): avoid useless branching in parseCoverCallAndAsyncArrowHead --- packages/babel-parser/src/parser/expression.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index a08f128c3afd..6370448b2de1 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -766,22 +766,23 @@ export default class ExpressionParser extends LValParser { optional: boolean, ): N.Expression { const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; - const refExpressionErrors = state.maybeAsyncArrow - ? new ExpressionErrors() - : null; - this.state.maybeInArrowParameters = true; + let refExpressionErrors = null; + this.state.maybeInArrowParameters = true; this.next(); // eat `(` let node = this.startNodeAt(startPos, startLoc); node.callee = base; + if (state.maybeAsyncArrow) { this.expressionScope.enter(newAsyncArrowScope()); + refExpressionErrors = new ExpressionErrors(); } if (state.optionalChainMember) { node.optional = optional; } + if (optional) { node.arguments = this.parseCallExpressionArguments(tt.parenR); } else { @@ -804,11 +805,8 @@ export default class ExpressionParser extends LValParser { node, ); } else { - if (refExpressionErrors !== null) { - this.checkExpressionErrors(refExpressionErrors, true); - } - if (state.maybeAsyncArrow) { + this.checkExpressionErrors(refExpressionErrors, true); this.expressionScope.exit(); } this.toReferencedArguments(node);