diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index e16f5b50f3f1..99771eed9d8f 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -3016,9 +3016,13 @@ export default class ExpressionParser extends LValParser { parseWhenMatchClause(): N.MatchClause { const node = this.startNode(); this.next(); // skip "when" - this.expect(tt.parenL); - node.test = this.parseMaybeBinaryMatchPattern(); - this.expect(tt.parenR); + if (this.match(tt.bitwiseXOR)) { + node.test = this.parseExpressionMatchPattern(); + } else { + this.expect(tt.parenL); + node.test = this.parseMaybeBinaryMatchPattern(); + this.expect(tt.parenR); + } if (this.isLineTerminator()) { this.unexpected( @@ -3056,11 +3060,27 @@ export default class ExpressionParser extends LValParser { return this.parseArrayMatchPattern(); case tt.plusMin: return this.parseSimpleUnaryExpression(); + case tt.bitwiseXOR: + return this.parseExpressionMatchPattern(); default: throw this.unexpected(); } } + parseExpressionMatchPattern(): N.ExpressionMatchPattern { + const node = this.startNode(); + this.next(); // skip ^ + let expression: N.Expression; + if (this.match(tt.parenL)) { + expression = this.parseParenAndDistinguishExpression(false); + } else { + expression = this.parseExprSubscripts(); + } + + node.expression = expression; + return this.finishNode(node, "ExpressionMatchPattern"); + } + parseSimpleUnaryExpression(): N.UnaryExpression { const node = this.startNode(); node.operator = this.state.value; diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/input.js deleted file mode 100644 index 8e4907211ad0..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/input.js +++ /dev/null @@ -1,3 +0,0 @@ -match (token) { - when (^LF | ^CR) {} -} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/input.js new file mode 100644 index 000000000000..7e71d3021a67 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/input.js @@ -0,0 +1,3 @@ +match (foo) { + when ^foo + 1 {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/options.json similarity index 59% rename from packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/options.json rename to packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/options.json index 8a871e54811c..5820a09c2e16 100644 --- a/packages/babel-parser/test/fixtures/experimental/pattern-matching/expression-match-pattern/options.json +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/options.json @@ -4,5 +4,5 @@ "patternMatching" ] ], - "throws": "Unexpected token (2:8)" + "throws": "Unexpected token (2:16)" } \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/input.js new file mode 100644 index 000000000000..ad2e1777d2ec --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/input.js @@ -0,0 +1,4 @@ +match (foo) { + when ^(foo + 1) {} + when (^(LF) | ^(CR)) {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/output.json new file mode 100644 index 000000000000..a1ec15d42fb4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/parenthesized-expression-match-pattern/output.json @@ -0,0 +1,106 @@ +{ + "type": "File", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10},"identifierName":"foo"}, + "name": "foo" + }, + "clauses": [ + { + "type": "MatchClause", + "start":16,"end":34,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}}, + "test": { + "type": "ExpressionMatchPattern", + "start":21,"end":31,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}}, + "expression": { + "type": "BinaryExpression", + "start":23,"end":30,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":16}}, + "extra": { + "parenthesized": true, + "parenStart": 22 + }, + "left": { + "type": "Identifier", + "start":23,"end":26,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "start":29,"end":30,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":16}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + }, + "consequent": { + "type": "BlockStatement", + "start":32,"end":34,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":20}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":37,"end":60,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":25}}, + "test": { + "type": "BinaryMatchPattern", + "start":43,"end":56,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":21}}, + "left": { + "type": "ExpressionMatchPattern", + "start":43,"end":48,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":13}}, + "expression": { + "type": "Identifier", + "start":45,"end":47,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":12},"identifierName":"LF"}, + "extra": { + "parenthesized": true, + "parenStart": 44 + }, + "name": "LF" + } + }, + "operator": "or", + "right": { + "type": "ExpressionMatchPattern", + "start":51,"end":56,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":21}}, + "expression": { + "type": "Identifier", + "start":53,"end":55,"loc":{"start":{"line":3,"column":18},"end":{"line":3,"column":20},"identifierName":"CR"}, + "extra": { + "parenthesized": true, + "parenStart": 52 + }, + "name": "CR" + } + } + }, + "consequent": { + "type": "BlockStatement", + "start":58,"end":60,"loc":{"start":{"line":3,"column":23},"end":{"line":3,"column":25}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/input.js new file mode 100644 index 000000000000..3d3c81893743 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/input.js @@ -0,0 +1,8 @@ +match (token) { + when ^foo {} + when ^foo.bar.zoo {} + when ^baz.bar() {} + when ^baz?.bar() {} + when ^baz["foo"].bar {} + when (^LF | ^CR) {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/output.json new file mode 100644 index 000000000000..1824d7c3b15e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unparenthesized-expression-match-pattern/output.json @@ -0,0 +1,232 @@ +{ + "type": "File", + "start":0,"end":146,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":146,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":146,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":146,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":12,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":12},"identifierName":"token"}, + "name": "token" + }, + "clauses": [ + { + "type": "MatchClause", + "start":18,"end":30,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":14}}, + "test": { + "type": "ExpressionMatchPattern", + "start":23,"end":27,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":11}}, + "expression": { + "type": "Identifier", + "start":24,"end":27,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":11},"identifierName":"foo"}, + "name": "foo" + } + }, + "consequent": { + "type": "BlockStatement", + "start":28,"end":30,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":14}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":33,"end":53,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":22}}, + "test": { + "type": "ExpressionMatchPattern", + "start":38,"end":50,"loc":{"start":{"line":3,"column":7},"end":{"line":3,"column":19}}, + "expression": { + "type": "MemberExpression", + "start":39,"end":50,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":19}}, + "object": { + "type": "MemberExpression", + "start":39,"end":46,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":15}}, + "object": { + "type": "Identifier", + "start":39,"end":42,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":11},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":43,"end":46,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":15},"identifierName":"bar"}, + "name": "bar" + } + }, + "computed": false, + "property": { + "type": "Identifier", + "start":47,"end":50,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19},"identifierName":"zoo"}, + "name": "zoo" + } + } + }, + "consequent": { + "type": "BlockStatement", + "start":51,"end":53,"loc":{"start":{"line":3,"column":20},"end":{"line":3,"column":22}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":56,"end":74,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":20}}, + "test": { + "type": "ExpressionMatchPattern", + "start":61,"end":71,"loc":{"start":{"line":4,"column":7},"end":{"line":4,"column":17}}, + "expression": { + "type": "CallExpression", + "start":62,"end":71,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":17}}, + "callee": { + "type": "MemberExpression", + "start":62,"end":69,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":15}}, + "object": { + "type": "Identifier", + "start":62,"end":65,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":11},"identifierName":"baz"}, + "name": "baz" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":66,"end":69,"loc":{"start":{"line":4,"column":12},"end":{"line":4,"column":15},"identifierName":"bar"}, + "name": "bar" + } + }, + "arguments": [] + } + }, + "consequent": { + "type": "BlockStatement", + "start":72,"end":74,"loc":{"start":{"line":4,"column":18},"end":{"line":4,"column":20}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":77,"end":96,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":21}}, + "test": { + "type": "ExpressionMatchPattern", + "start":82,"end":93,"loc":{"start":{"line":5,"column":7},"end":{"line":5,"column":18}}, + "expression": { + "type": "OptionalCallExpression", + "start":83,"end":93,"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":18}}, + "callee": { + "type": "OptionalMemberExpression", + "start":83,"end":91,"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":16}}, + "object": { + "type": "Identifier", + "start":83,"end":86,"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":11},"identifierName":"baz"}, + "name": "baz" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":88,"end":91,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":16},"identifierName":"bar"}, + "name": "bar" + }, + "optional": true + }, + "optional": false, + "arguments": [] + } + }, + "consequent": { + "type": "BlockStatement", + "start":94,"end":96,"loc":{"start":{"line":5,"column":19},"end":{"line":5,"column":21}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":99,"end":122,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":25}}, + "test": { + "type": "ExpressionMatchPattern", + "start":104,"end":119,"loc":{"start":{"line":6,"column":7},"end":{"line":6,"column":22}}, + "expression": { + "type": "MemberExpression", + "start":105,"end":119,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":22}}, + "object": { + "type": "MemberExpression", + "start":105,"end":115,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":18}}, + "object": { + "type": "Identifier", + "start":105,"end":108,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":11},"identifierName":"baz"}, + "name": "baz" + }, + "computed": true, + "property": { + "type": "StringLiteral", + "start":109,"end":114,"loc":{"start":{"line":6,"column":12},"end":{"line":6,"column":17}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + }, + "computed": false, + "property": { + "type": "Identifier", + "start":116,"end":119,"loc":{"start":{"line":6,"column":19},"end":{"line":6,"column":22},"identifierName":"bar"}, + "name": "bar" + } + } + }, + "consequent": { + "type": "BlockStatement", + "start":120,"end":122,"loc":{"start":{"line":6,"column":23},"end":{"line":6,"column":25}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":125,"end":144,"loc":{"start":{"line":7,"column":2},"end":{"line":7,"column":21}}, + "test": { + "type": "BinaryMatchPattern", + "start":131,"end":140,"loc":{"start":{"line":7,"column":8},"end":{"line":7,"column":17}}, + "left": { + "type": "ExpressionMatchPattern", + "start":131,"end":134,"loc":{"start":{"line":7,"column":8},"end":{"line":7,"column":11}}, + "expression": { + "type": "Identifier", + "start":132,"end":134,"loc":{"start":{"line":7,"column":9},"end":{"line":7,"column":11},"identifierName":"LF"}, + "name": "LF" + } + }, + "operator": "or", + "right": { + "type": "ExpressionMatchPattern", + "start":137,"end":140,"loc":{"start":{"line":7,"column":14},"end":{"line":7,"column":17}}, + "expression": { + "type": "Identifier", + "start":138,"end":140,"loc":{"start":{"line":7,"column":15},"end":{"line":7,"column":17},"identifierName":"CR"}, + "name": "CR" + } + } + }, + "consequent": { + "type": "BlockStatement", + "start":142,"end":144,"loc":{"start":{"line":7,"column":19},"end":{"line":7,"column":21}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file