From 484a6d65e170edc25d2f504603cb76475646d49b Mon Sep 17 00:00:00 2001 From: bowei Date: Sat, 2 Nov 2019 23:51:17 -0400 Subject: [PATCH] validate against nested ParenthesizedExpressions --- packages/babel-parser/src/parser/lval.js | 41 +++-- .../valid-assignment-pattern-3/input.js | 1 + .../valid-assignment-pattern-3/output.json | 121 +++++++++++++ .../fixtures/core/uncategorised/566/input.js | 1 + .../core/uncategorised/566/options.json | 3 + .../core/uncategorised/566/output.json | 162 ++++++++++++++++++ 6 files changed, 308 insertions(+), 21 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/input.js create mode 100644 packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/output.json create mode 100644 packages/babel-parser/test/fixtures/core/uncategorised/566/input.js create mode 100644 packages/babel-parser/test/fixtures/core/uncategorised/566/options.json create mode 100644 packages/babel-parser/test/fixtures/core/uncategorised/566/output.json diff --git a/packages/babel-parser/src/parser/lval.js b/packages/babel-parser/src/parser/lval.js index 9a6f35ab5c21..c2a56d2e8cfe 100644 --- a/packages/babel-parser/src/parser/lval.js +++ b/packages/babel-parser/src/parser/lval.js @@ -19,6 +19,12 @@ import { isStrictBindReservedWord } from "../util/identifier"; import { NodeUtils } from "./node"; import { type BindingTypes, BIND_NONE } from "../util/scopeflags"; +const unwrapParenthesizedExpression = (node: Node) => { + return node.type === "ParenthesizedExpression" + ? unwrapParenthesizedExpression(node.expression) + : node; +}; + export default class LValParser extends NodeUtils { // Forward-declaration: defined in expression.js +parseIdentifier: (liberal?: boolean) => Identifier; @@ -38,33 +44,26 @@ export default class LValParser extends NodeUtils { // Convert existing expression atom to assignable pattern // if possible. - validateParenthesizedExpression(node: Node): void { - let parenthesized; - if ( - this.options.createParenthesizedExpressions && - node.type === "ParenthesizedExpression" - ) { - parenthesized = node.expression; - } else if (node.extra?.parenthesized) { - parenthesized = node; - } - - if ( - parenthesized && - parenthesized.type !== "Identifier" && - parenthesized.type !== "MemberExpression" - ) { - this.raise(node.start, "Invalid parenthesized assignment pattern"); - } - } - toAssignable( node: Node, isBinding: ?boolean, contextDescription: string, ): Node { if (node) { - this.validateParenthesizedExpression(node); + if ( + (this.options.createParenthesizedExpressions && + node.type === "ParenthesizedExpression") || + node.extra?.parenthesized + ) { + const parenthesized = unwrapParenthesizedExpression(node); + if ( + parenthesized.type !== "Identifier" && + parenthesized.type !== "MemberExpression" + ) { + this.raise(node.start, "Invalid parenthesized assignment pattern"); + } + } + switch (node.type) { case "Identifier": case "ObjectPattern": diff --git a/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/input.js b/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/input.js new file mode 100644 index 000000000000..320748c0282f --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/input.js @@ -0,0 +1 @@ +[(((x)))] = t; \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/output.json b/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/output.json new file mode 100644 index 000000000000..ec252128aaf2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/categorized/valid-assignment-pattern-3/output.json @@ -0,0 +1,121 @@ +{ + "type": "File", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "operator": "=", + "left": { + "type": "ArrayPattern", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "elements": [ + { + "type": "Identifier", + "start": 4, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 5 + }, + "identifierName": "x" + }, + "name": "x", + "extra": { + "parenthesized": true, + "parenStart": 1 + } + } + ] + }, + "right": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + }, + "identifierName": "t" + }, + "name": "t" + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/core/uncategorised/566/input.js b/packages/babel-parser/test/fixtures/core/uncategorised/566/input.js new file mode 100644 index 000000000000..320748c0282f --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/uncategorised/566/input.js @@ -0,0 +1 @@ +[(((x)))] = t; \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/core/uncategorised/566/options.json b/packages/babel-parser/test/fixtures/core/uncategorised/566/options.json new file mode 100644 index 000000000000..0861962d889d --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/uncategorised/566/options.json @@ -0,0 +1,3 @@ +{ + "createParenthesizedExpressions": true +} diff --git a/packages/babel-parser/test/fixtures/core/uncategorised/566/output.json b/packages/babel-parser/test/fixtures/core/uncategorised/566/output.json new file mode 100644 index 000000000000..2e4db8c547f6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/uncategorised/566/output.json @@ -0,0 +1,162 @@ +{ + "type": "File", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "operator": "=", + "left": { + "type": "ArrayPattern", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "elements": [ + { + "type": "ParenthesizedExpression", + "start": 1, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "expression": { + "type": "ParenthesizedExpression", + "start": 2, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 2 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "expression": { + "type": "ParenthesizedExpression", + "start": 3, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "expression": { + "type": "Identifier", + "start": 4, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 5 + }, + "identifierName": "x" + }, + "name": "x" + } + } + } + } + ] + }, + "right": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + }, + "identifierName": "t" + }, + "name": "t" + } + } + } + ], + "directives": [] + } +} \ No newline at end of file