diff --git a/packages/babel-parser/src/parser/error-message.js b/packages/babel-parser/src/parser/error-message.js index 8b7f1c6182c6..12130c1a6b3b 100644 --- a/packages/babel-parser/src/parser/error-message.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -77,6 +77,8 @@ export const ErrorMessages = makeErrorTemplates( ImportCallNotNewExpression: "Cannot use new with import(...).", ImportCallSpreadArgument: "`...` is not allowed in `import()`.", InvalidBigIntLiteral: "Invalid BigIntLiteral.", + InvalidBinaryMatchPattern: + "Different binary match pattern operators cannot be at the same level.", InvalidCodePoint: "Code point out of bounds.", InvalidDecimal: "Invalid decimal.", InvalidDigit: "Expected number in radix %0.", @@ -99,6 +101,8 @@ export const ErrorMessages = makeErrorTemplates( LabelRedeclaration: "Label '%0' is already declared.", LetInLexicalBinding: "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", + LineTerminatorAfterMatchPattern: + "No line terminator allowed after match pattern.", LineTerminatorBeforeArrow: "No line break is allowed before '=>'.", MalformedRegExpFlags: "Invalid regular expression flag.", MissingClassName: "A class name is required.", @@ -175,6 +179,8 @@ export const ErrorMessages = makeErrorTemplates( RestTrailingComma: "Unexpected trailing comma after rest element.", SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement.", + SpreadElementInMatchExpression: + "Spread elements are not allowed in match expressions.", StaticPrototype: "Classes may not have static property named prototype.", StrictDelete: "Deleting local variable in strict mode.", StrictEvalArguments: "Assigning to '%0' in strict mode.", diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index a7daba941ff1..99771eed9d8f 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -93,6 +93,8 @@ export default class ExpressionParser extends LValParser { +parseProgram: ( program: N.Program, end: TokenType, sourceType?: SourceType ) => N.Program + +parseStatement: (context: ?string, topLevel?: boolean) => N.Statement + +parseHeaderExpression: () => N.Expression */ // For object literal, check if property __proto__ has been used more than once. @@ -813,6 +815,7 @@ export default class ExpressionParser extends LValParser { optional: boolean, ): N.Expression { const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const lineTerminatorAfterId = this.isLineTerminator(); let refExpressionErrors = null; this.state.maybeInArrowParameters = true; @@ -851,6 +854,18 @@ export default class ExpressionParser extends LValParser { this.startNodeAt(startPos, startLoc), node, ); + } else if ( + base.name === "match" && + this.hasPlugin("patternMatching") && + !lineTerminatorAfterId && + !this.isLineTerminator() && + !optional && + node.arguments.length > 0 + ) { + node = this.parseMatchExpressionFromCallExpression( + this.startNodeAt(startPos, startLoc), + node, + ); } else { if (state.maybeAsyncArrow) { this.checkExpressionErrors(refExpressionErrors, true); @@ -2934,4 +2949,237 @@ export default class ExpressionParser extends LValParser { this.eat(tt.braceR); return this.finishNode(node, "ModuleExpression"); } + + // https://github.com/tc39/proposal-pattern-matching + parseMatchExpressionFromCallExpression( + node: N.MatchExpression, + callExpression: N.CallExpression, + ): N.MatchExpression { + const expressions = callExpression.arguments; + this.checkMatchExpressionDiscriminant(expressions); + if (expressions.length > 1) { + const sequence = this.startNodeAtNode(expressions[0]); + sequence.expressions = expressions; + const lastExpression = expressions[expressions.length - 1]; + node.discriminant = this.finishNodeAt( + sequence, + "SequenceExpression", + lastExpression.end, + lastExpression.loc.end, + ); + } else { + node.discriminant = expressions[0]; + } + node.clauses = this.parseMatchClauses(); + return this.finishNode(node, "MatchExpression"); + } + + checkMatchExpressionDiscriminant( + expressions: Array, + ) { + for (const expression of expressions) { + if (expression.type === "SpreadElement") { + this.unexpected( + expression.start, + Errors.SpreadElementInMatchExpression, + ); + } + } + } + + parseMatchClauses(): N.MatchClause[] { + this.eat(tt.braceL); + const clauses = []; + while (!this.eat(tt.braceR)) { + if (this.match(tt._if) || this.match(tt._else)) { + clauses.push(this.parseConditionalMatchClause()); + } else if (this.isContextual("when")) { + clauses.push(this.parseWhenMatchClause()); + } else { + this.unexpected(); + } + } + return clauses; + } + + parseConditionalMatchClause(): N.MatchClause { + const node = this.startNode(); + const type = this.state.type; + this.next(); // skip "if" / "else" + if (type === tt._if) { + node.guard = this.parseHeaderExpression(); + } + node.consequent = this.parseStatement("if"); + return this.finishNode(node, "MatchClause"); + } + + parseWhenMatchClause(): N.MatchClause { + const node = this.startNode(); + this.next(); // skip "when" + 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( + this.state.lastTokEnd, + Errors.LineTerminatorAfterMatchPattern, + ); + } + node.consequent = this.parseStatement("do"); + return this.finishNode(node, "MatchClause"); + } + + parseMatchPattern(): N.MatchPattern { + switch (this.state.type) { + case tt.slash: + case tt.slashAssign: + this.readRegexp(); + return this.parseRegExpLiteral(this.state.value); + case tt.num: + return this.parseNumericLiteral(this.state.value); + case tt.bigint: + return this.parseBigIntLiteral(this.state.value); + case tt.string: + return this.parseStringLiteral(this.state.value); + case tt._null: + return this.parseNullLiteral(); + case tt._true: + return this.parseBooleanLiteral(true); + case tt._false: + return this.parseBooleanLiteral(false); + case tt.name: + return this.parseIdentifier(); + case tt.braceL: + return this.parseObjectMatchPattern(); + case tt.bracketL: + 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; + this.next(); // skip operator (+/-) + node.prefix = true; + switch (this.state.type) { + case tt.num: + node.argument = this.parseNumericLiteral(this.state.value); + break; + case tt.bigint: + node.argument = this.parseBigIntLiteral(this.state.value); + break; + default: + if (this.isContextual("Infinity")) { + node.argument = this.parseIdentifier(); + break; + } + throw this.unexpected(); + } + return this.finishNode(node, "UnaryExpression"); + } + + parseMaybeBinaryMatchPattern( + previousOp?: "and" | "or", + ): N.BinaryMatchPattern | N.MatchPattern { + const node = this.startNode(); + const lhs = this.parseMatchPattern(); + if (this.match(tt.bitwiseOR) || this.match(tt.bitwiseAND)) { + const operator = this.match(tt.bitwiseOR) ? "or" : "and"; + if (previousOp && previousOp !== operator) { + this.unexpected(this.state.start, Errors.InvalidBinaryMatchPattern); + } + this.next(); // skip "or" or "and" + node.left = lhs; + node.operator = operator; + node.right = this.parseMaybeBinaryMatchPattern(operator); + return this.finishNode(node, "BinaryMatchPattern"); + } else { + return lhs; + } + } + + parseObjectMatchPattern(): N.ObjectMatchPattern { + const node = this.startNode(); + this.expect(tt.braceL); + const properties: (N.AssignmentMatchProperty | N.RestMatchElement)[] = []; + while (!this.eat(tt.braceR)) { + if (this.match(tt.ellipsis)) { + properties.push(this.parseRestMatchElement()); + this.checkCommaAfterRest(charCodes.rightCurlyBrace); + this.expect(tt.braceR); + break; + } + const node = this.startNode(); + node.method = false; + this.parsePropertyName(node, /* isPrivateNameAllowed */ false); + if (this.eat(tt.colon)) { + node.value = this.parseMaybeBinaryMatchPattern(); + } + this.finishNode(node, "ObjectProperty"); + properties.push(node); + this.eat(tt.comma); + } + + node.properties = properties; + return this.finishNode(node, "ObjectMatchPattern"); + } + + parseArrayMatchPattern(): N.ArrayMatchPattern { + const node = this.startNode(); + this.expect(tt.bracketL); + + const elements: N.MatchPattern[] = []; + + while (!this.eat(tt.bracketR)) { + if (this.match(tt.ellipsis)) { + elements.push(this.parseRestMatchElement()); + } else if (this.isContextual("_")) { + elements.push(this.parseNullMatchPattern()); + } else { + elements.push(this.parseMaybeBinaryMatchPattern()); + } + this.eat(tt.comma); + } + + node.elements = elements; + return this.finishNode(node, "ArrayMatchPattern"); + } + + parseNullMatchPattern(): N.NullMatchPattern { + const node = this.startNode(); + this.next(); // skip "_" + return this.finishNode(node, "NullMatchPattern"); + } + + parseRestMatchElement(): N.RestMatchElement { + const node = this.startNode(); + this.expect(tt.ellipsis); + node.argument = this.parseMaybeBinaryMatchPattern(); + return this.finishNode(node, "RestMatchElement"); + } } diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.js index e747abc6b5f5..8d565267ddd6 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.js @@ -283,6 +283,76 @@ export type SwitchCase = NodeBase & { consequent: $ReadOnlyArray, }; +// Pattern Matching +export type MatchExpression = Expression & { + type: "MatchExpression", + discriminant: Expression, + id: Pattern | null, + clauses: $ReadOnlyArray, +}; + +export type MatchClause = NodeBase & { + type: "MatchClause", + test: MatchPattern | null, + guard: Expression | null, + id: Pattern | null, + consequent: BlockStatement, +}; + +export type MatchPattern = + | ArrayMatchPattern + | ObjectMatchPattern + | RestMatchElement + | BinaryMatchPattern + | AsMatchPattern + | ExpressionMatchPattern + | NullMatchPattern + | Literal + | Identifier + | UnaryExpression; + +export type ArrayMatchPattern = NodeBase & { + type: "ArrayMatchPattern", + elements: $ReadOnlyArray, +}; + +export type AssignmentMatchProperty = ObjectProperty & { + value: MatchPattern, + kind: "init", + method: false, +}; + +export type ObjectMatchPattern = NodeBase & { + type: "ObjectMatchPattern", + properties: $ReadOnlyArray, +}; + +export type RestMatchElement = NodeBase & { + type: "RestMatchElement", + argument: MatchPattern, +}; + +export type BinaryMatchPattern = NodeBase & { + type: "BinaryMatchPattern", + operator: "and" | "or" | "with", + left: MatchPattern, + right: MatchPattern, +}; + +export type AsMatchPattern = NodeBase & { + type: "AsMatchPattern", + test: MatchPattern, + id: Pattern, +}; + +export type ExpressionMatchPattern = NodeBase & { + type: "ExpressionMatchPattern", + expression: Expression, +}; + +export type NullMatchPattern = NodeBase & { + type: "NullMatchPattern", +}; // Exceptions export type ThrowStatement = NodeBase & { diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/input.js new file mode 100644 index 000000000000..8206763c9415 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/input.js @@ -0,0 +1,7 @@ +match(x) { + when([ + _, + _, + { foo: 200 }, + ]) { "foo" } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/output.json new file mode 100644 index 000000000000..027c8f51dfdd --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern-trailing-comma/output.json @@ -0,0 +1,92 @@ +{ + "type": "File", + "start":0,"end":68,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":68,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":68,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":68,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":6,"end":7,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":7},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":13,"end":66,"loc":{"start":{"line":2,"column":2},"end":{"line":6,"column":14}}, + "test": { + "type": "ArrayMatchPattern", + "start":18,"end":55,"loc":{"start":{"line":2,"column":7},"end":{"line":6,"column":3}}, + "elements": [ + { + "type": "NullMatchPattern", + "start":24,"end":25,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":5}} + }, + { + "type": "NullMatchPattern", + "start":31,"end":32,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":5}} + }, + { + "type": "ObjectMatchPattern", + "start":38,"end":50,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":16}}, + "properties": [ + { + "type": "ObjectProperty", + "start":40,"end":48,"loc":{"start":{"line":5,"column":6},"end":{"line":5,"column":14}}, + "method": false, + "key": { + "type": "Identifier", + "start":40,"end":43,"loc":{"start":{"line":5,"column":6},"end":{"line":5,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":45,"end":48,"loc":{"start":{"line":5,"column":11},"end":{"line":5,"column":14}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":57,"end":66,"loc":{"start":{"line":6,"column":5},"end":{"line":6,"column":14}}, + "body": [ + { + "type": "ExpressionStatement", + "start":59,"end":64,"loc":{"start":{"line":6,"column":7},"end":{"line":6,"column":12}}, + "expression": { + "type": "StringLiteral", + "start":59,"end":64,"loc":{"start":{"line":6,"column":7},"end":{"line":6,"column":12}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/input.js new file mode 100644 index 000000000000..50b6a8b16da7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/input.js @@ -0,0 +1,6 @@ +match(x) { + when([_, _, 200]) { "foo" } + else { + "name" + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/output.json new file mode 100644 index 000000000000..3ec009263655 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/array-match-pattern/output.json @@ -0,0 +1,99 @@ +{ + "type": "File", + "start":0,"end":66,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":66,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":66,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":66,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":6,"end":7,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":7},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":13,"end":40,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":29}}, + "test": { + "type": "ArrayMatchPattern", + "start":18,"end":29,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":18}}, + "elements": [ + { + "type": "NullMatchPattern", + "start":19,"end":20,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":9}} + }, + { + "type": "NullMatchPattern", + "start":22,"end":23,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":12}} + }, + { + "type": "NumericLiteral", + "start":25,"end":28,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":17}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":31,"end":40,"loc":{"start":{"line":2,"column":20},"end":{"line":2,"column":29}}, + "body": [ + { + "type": "ExpressionStatement", + "start":33,"end":38,"loc":{"start":{"line":2,"column":22},"end":{"line":2,"column":27}}, + "expression": { + "type": "StringLiteral", + "start":33,"end":38,"loc":{"start":{"line":2,"column":22},"end":{"line":2,"column":27}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":43,"end":64,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}}, + "consequent": { + "type": "BlockStatement", + "start":48,"end":64,"loc":{"start":{"line":3,"column":7},"end":{"line":5,"column":3}}, + "body": [ + { + "type": "ExpressionStatement", + "start":54,"end":60,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":10}}, + "expression": { + "type": "StringLiteral", + "start":54,"end":60,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":10}}, + "extra": { + "rawValue": "name", + "raw": "\"name\"" + }, + "value": "name" + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/input.js new file mode 100644 index 000000000000..a53128a7835a --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/input.js @@ -0,0 +1,7 @@ +let a = match (x) { + when({ z }) { false } +} + +const a = match (z) { + when({ n: 200 }) { "true" } +} + 3 diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/output.json new file mode 100644 index 000000000000..d59652d78459 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/assigned-to-let/output.json @@ -0,0 +1,171 @@ +{ + "type": "File", + "start":0,"end":104,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":5}}, + "errors": [ + "SyntaxError: Identifier 'a' has already been declared. (5:6)" + ], + "program": { + "type": "Program", + "start":0,"end":104,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":5}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":4,"end":45,"loc":{"start":{"line":1,"column":4},"end":{"line":3,"column":1}}, + "id": { + "type": "Identifier", + "start":4,"end":5,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":5},"identifierName":"a"}, + "name": "a" + }, + "init": { + "type": "MatchExpression", + "start":8,"end":45,"loc":{"start":{"line":1,"column":8},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":15,"end":16,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":16},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":22,"end":43,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":23}}, + "test": { + "type": "ObjectMatchPattern", + "start":27,"end":32,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":12}}, + "properties": [ + { + "type": "ObjectProperty", + "start":29,"end":30,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":10}}, + "method": false, + "key": { + "type": "Identifier", + "start":29,"end":30,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":10},"identifierName":"z"}, + "name": "z" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":34,"end":43,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":23}}, + "body": [ + { + "type": "ExpressionStatement", + "start":36,"end":41,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":21}}, + "expression": { + "type": "BooleanLiteral", + "start":36,"end":41,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":21}}, + "value": false + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "kind": "let" + }, + { + "type": "VariableDeclaration", + "start":47,"end":104,"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":5}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":53,"end":104,"loc":{"start":{"line":5,"column":6},"end":{"line":7,"column":5}}, + "id": { + "type": "Identifier", + "start":53,"end":54,"loc":{"start":{"line":5,"column":6},"end":{"line":5,"column":7},"identifierName":"a"}, + "name": "a" + }, + "init": { + "type": "BinaryExpression", + "start":57,"end":104,"loc":{"start":{"line":5,"column":10},"end":{"line":7,"column":5}}, + "left": { + "type": "MatchExpression", + "start":57,"end":100,"loc":{"start":{"line":5,"column":10},"end":{"line":7,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":64,"end":65,"loc":{"start":{"line":5,"column":17},"end":{"line":5,"column":18},"identifierName":"z"}, + "name": "z" + }, + "clauses": [ + { + "type": "MatchClause", + "start":71,"end":98,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":29}}, + "test": { + "type": "ObjectMatchPattern", + "start":76,"end":86,"loc":{"start":{"line":6,"column":7},"end":{"line":6,"column":17}}, + "properties": [ + { + "type": "ObjectProperty", + "start":78,"end":84,"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":15}}, + "method": false, + "key": { + "type": "Identifier", + "start":78,"end":79,"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":10},"identifierName":"n"}, + "name": "n" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":81,"end":84,"loc":{"start":{"line":6,"column":12},"end":{"line":6,"column":15}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":88,"end":98,"loc":{"start":{"line":6,"column":19},"end":{"line":6,"column":29}}, + "body": [ + { + "type": "ExpressionStatement", + "start":90,"end":96,"loc":{"start":{"line":6,"column":21},"end":{"line":6,"column":27}}, + "expression": { + "type": "StringLiteral", + "start":90,"end":96,"loc":{"start":{"line":6,"column":21},"end":{"line":6,"column":27}}, + "extra": { + "rawValue": "true", + "raw": "\"true\"" + }, + "value": "true" + } + } + ], + "directives": [] + } + } + ] + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "start":103,"end":104,"loc":{"start":{"line":7,"column":4},"end":{"line":7,"column":5}}, + "extra": { + "rawValue": 3, + "raw": "3" + }, + "value": 3 + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/input.js new file mode 100644 index 000000000000..6ff5d486171e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/input.js @@ -0,0 +1,3 @@ +match (x) { + when({ status: 200 | 201 }) {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/output.json new file mode 100644 index 000000000000..e53ab1ac3eaa --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/binary-match-pattern/output.json @@ -0,0 +1,78 @@ +{ + "type": "File", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":44,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":32}}, + "test": { + "type": "ObjectMatchPattern", + "start":19,"end":40,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":28}}, + "properties": [ + { + "type": "ObjectProperty", + "start":21,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":26}}, + "method": false, + "key": { + "type": "Identifier", + "start":21,"end":27,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":15},"identifierName":"status"}, + "name": "status" + }, + "computed": false, + "value": { + "type": "BinaryMatchPattern", + "start":29,"end":38,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":26}}, + "left": { + "type": "NumericLiteral", + "start":29,"end":32,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":20}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + }, + "operator": "or", + "right": { + "type": "NumericLiteral", + "start":35,"end":38,"loc":{"start":{"line":2,"column":23},"end":{"line":2,"column":26}}, + "extra": { + "rawValue": 201, + "raw": "201" + }, + "value": 201 + } + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":42,"end":44,"loc":{"start":{"line":2,"column":30},"end":{"line":2,"column":32}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/input.js new file mode 100644 index 000000000000..7349405f7b74 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/input.js @@ -0,0 +1,3 @@ +match (action) { + when (["take", ...{ [computed]: 200 }]) {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/output.json new file mode 100644 index 000000000000..6de48af20ebe --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/computed-object-match-pattern/output.json @@ -0,0 +1,83 @@ +{ + "type": "File", + "start":0,"end":63,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":63,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":63,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":63,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":13,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":13},"identifierName":"action"}, + "name": "action" + }, + "clauses": [ + { + "type": "MatchClause", + "start":19,"end":61,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":44}}, + "test": { + "type": "ArrayMatchPattern", + "start":25,"end":57,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":40}}, + "elements": [ + { + "type": "StringLiteral", + "start":26,"end":32,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":15}}, + "extra": { + "rawValue": "take", + "raw": "\"take\"" + }, + "value": "take" + }, + { + "type": "RestMatchElement", + "start":34,"end":56,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":39}}, + "argument": { + "type": "ObjectMatchPattern", + "start":37,"end":56,"loc":{"start":{"line":2,"column":20},"end":{"line":2,"column":39}}, + "properties": [ + { + "type": "ObjectProperty", + "start":39,"end":54,"loc":{"start":{"line":2,"column":22},"end":{"line":2,"column":37}}, + "method": false, + "computed": true, + "key": { + "type": "Identifier", + "start":40,"end":48,"loc":{"start":{"line":2,"column":23},"end":{"line":2,"column":31},"identifierName":"computed"}, + "name": "computed" + }, + "value": { + "type": "NumericLiteral", + "start":51,"end":54,"loc":{"start":{"line":2,"column":34},"end":{"line":2,"column":37}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":59,"end":61,"loc":{"start":{"line":2,"column":42},"end":{"line":2,"column":44}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/input.js new file mode 100644 index 000000000000..95e53325c7be --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/input.js @@ -0,0 +1,6 @@ +match (x) { + if(isFoo(x)) { "foo" } + if(isBar(x)) "bar" + when({ foo: 100 }) {} + else "foo" +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/output.json new file mode 100644 index 000000000000..4d3b49ed8acb --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/if-clause/output.json @@ -0,0 +1,154 @@ +{ + "type": "File", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":36,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":24}}, + "guard": { + "type": "CallExpression", + "start":17,"end":25,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":13}}, + "callee": { + "type": "Identifier", + "start":17,"end":22,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":10},"identifierName":"isFoo"}, + "name": "isFoo" + }, + "arguments": [ + { + "type": "Identifier", + "start":23,"end":24,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":12},"identifierName":"x"}, + "name": "x" + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":27,"end":36,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":24}}, + "body": [ + { + "type": "ExpressionStatement", + "start":29,"end":34,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":22}}, + "expression": { + "type": "StringLiteral", + "start":29,"end":34,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":22}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":39,"end":57,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":20}}, + "guard": { + "type": "CallExpression", + "start":42,"end":50,"loc":{"start":{"line":3,"column":5},"end":{"line":3,"column":13}}, + "callee": { + "type": "Identifier", + "start":42,"end":47,"loc":{"start":{"line":3,"column":5},"end":{"line":3,"column":10},"identifierName":"isBar"}, + "name": "isBar" + }, + "arguments": [ + { + "type": "Identifier", + "start":48,"end":49,"loc":{"start":{"line":3,"column":11},"end":{"line":3,"column":12},"identifierName":"x"}, + "name": "x" + } + ] + }, + "consequent": { + "type": "ExpressionStatement", + "start":52,"end":57,"loc":{"start":{"line":3,"column":15},"end":{"line":3,"column":20}}, + "expression": { + "type": "StringLiteral", + "start":52,"end":57,"loc":{"start":{"line":3,"column":15},"end":{"line":3,"column":20}}, + "extra": { + "rawValue": "bar", + "raw": "\"bar\"" + }, + "value": "bar" + } + } + }, + { + "type": "MatchClause", + "start":60,"end":81,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":23}}, + "test": { + "type": "ObjectMatchPattern", + "start":65,"end":77,"loc":{"start":{"line":4,"column":7},"end":{"line":4,"column":19}}, + "properties": [ + { + "type": "ObjectProperty", + "start":67,"end":75,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":17}}, + "method": false, + "key": { + "type": "Identifier", + "start":67,"end":70,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":72,"end":75,"loc":{"start":{"line":4,"column":14},"end":{"line":4,"column":17}}, + "extra": { + "rawValue": 100, + "raw": "100" + }, + "value": 100 + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":79,"end":81,"loc":{"start":{"line":4,"column":21},"end":{"line":4,"column":23}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":84,"end":94,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":12}}, + "consequent": { + "type": "ExpressionStatement", + "start":89,"end":94,"loc":{"start":{"line":5,"column":7},"end":{"line":5,"column":12}}, + "expression": { + "type": "StringLiteral", + "start":89,"end":94,"loc":{"start":{"line":5,"column":7},"end":{"line":5,"column":12}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/input.js new file mode 100644 index 000000000000..b5ffeca487b1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/input.js @@ -0,0 +1,3 @@ +match (x) { + when ({ v: 200 | 300 & 400 }) {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/options.json new file mode 100644 index 000000000000..d1d4655d5603 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-binary-match-pattern/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "Different binary match pattern operators cannot be at the same level. (2:23)" +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/input.js new file mode 100644 index 000000000000..825345b4e5d4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/input.js @@ -0,0 +1,7 @@ +match (x) { + when ({ y }) { "yes" } +} = 1 + +match (x) { + when ({ y }) { "yes" } +} += 1 diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/output.json new file mode 100644 index 000000000000..813af7559c73 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/invalid-lhs-assignment/output.json @@ -0,0 +1,157 @@ +{ + "type": "File", + "start":0,"end":87,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":6}}, + "errors": [ + "SyntaxError: Invalid left-hand side in assignment expression. (1:0)", + "SyntaxError: Invalid left-hand side in assignment expression. (5:0)" + ], + "program": { + "type": "Program", + "start":0,"end":87,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":6}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "expression": { + "type": "AssignmentExpression", + "start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "operator": "=", + "left": { + "type": "MatchExpression", + "start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":36,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":24}}, + "test": { + "type": "ObjectMatchPattern", + "start":20,"end":25,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":13}}, + "properties": [ + { + "type": "ObjectProperty", + "start":22,"end":23,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11}}, + "method": false, + "key": { + "type": "Identifier", + "start":22,"end":23,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"y"}, + "name": "y" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":27,"end":36,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":24}}, + "body": [ + { + "type": "ExpressionStatement", + "start":29,"end":34,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":22}}, + "expression": { + "type": "StringLiteral", + "start":29,"end":34,"loc":{"start":{"line":2,"column":17},"end":{"line":2,"column":22}}, + "extra": { + "rawValue": "yes", + "raw": "\"yes\"" + }, + "value": "yes" + } + } + ], + "directives": [] + } + } + ] + }, + "right": { + "type": "NumericLiteral", + "start":41,"end":42,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":5}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + }, + { + "type": "ExpressionStatement", + "start":44,"end":87,"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":6}}, + "expression": { + "type": "AssignmentExpression", + "start":44,"end":87,"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":6}}, + "operator": "+=", + "left": { + "type": "MatchExpression", + "start":44,"end":82,"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":51,"end":52,"loc":{"start":{"line":5,"column":7},"end":{"line":5,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":58,"end":80,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":24}}, + "test": { + "type": "ObjectMatchPattern", + "start":64,"end":69,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":13}}, + "properties": [ + { + "type": "ObjectProperty", + "start":66,"end":67,"loc":{"start":{"line":6,"column":10},"end":{"line":6,"column":11}}, + "method": false, + "key": { + "type": "Identifier", + "start":66,"end":67,"loc":{"start":{"line":6,"column":10},"end":{"line":6,"column":11},"identifierName":"y"}, + "name": "y" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":71,"end":80,"loc":{"start":{"line":6,"column":15},"end":{"line":6,"column":24}}, + "body": [ + { + "type": "ExpressionStatement", + "start":73,"end":78,"loc":{"start":{"line":6,"column":17},"end":{"line":6,"column":22}}, + "expression": { + "type": "StringLiteral", + "start":73,"end":78,"loc":{"start":{"line":6,"column":17},"end":{"line":6,"column":22}}, + "extra": { + "rawValue": "yes", + "raw": "\"yes\"" + }, + "value": "yes" + } + } + ], + "directives": [] + } + } + ] + }, + "right": { + "type": "NumericLiteral", + "start":86,"end":87,"loc":{"start":{"line":7,"column":5},"end":{"line":7,"column":6}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/input.js new file mode 100644 index 000000000000..7cb55f164a4a --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/input.js @@ -0,0 +1,4 @@ +match (x) { + when (n) {} + when ({ foo: bar, baz }) {} +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/output.json new file mode 100644 index 000000000000..ba9a13e0fee8 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/irrefutable-matches/output.json @@ -0,0 +1,86 @@ +{ + "type": "File", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":25,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":13}}, + "test": { + "type": "Identifier", + "start":20,"end":21,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":9},"identifierName":"n"}, + "name": "n" + }, + "consequent": { + "type": "BlockStatement", + "start":23,"end":25,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":13}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":28,"end":55,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":29}}, + "test": { + "type": "ObjectMatchPattern", + "start":34,"end":51,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":25}}, + "properties": [ + { + "type": "ObjectProperty", + "start":36,"end":44,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":18}}, + "method": false, + "key": { + "type": "Identifier", + "start":36,"end":39,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":13},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "value": { + "type": "Identifier", + "start":41,"end":44,"loc":{"start":{"line":3,"column":15},"end":{"line":3,"column":18},"identifierName":"bar"}, + "name": "bar" + } + }, + { + "type": "ObjectProperty", + "start":46,"end":49,"loc":{"start":{"line":3,"column":20},"end":{"line":3,"column":23}}, + "method": false, + "key": { + "type": "Identifier", + "start":46,"end":49,"loc":{"start":{"line":3,"column":20},"end":{"line":3,"column":23},"identifierName":"baz"}, + "name": "baz" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":53,"end":55,"loc":{"start":{"line":3,"column":27},"end":{"line":3,"column":29}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/input.js new file mode 100644 index 000000000000..c16880c7e8db --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/input.js @@ -0,0 +1,11 @@ +match (name) { + when (/abc/) { } + when ("foo") { } + when (100) { } + when (100n) { } + when (true) { } + when (false) { } + when (undefined) { } + when (Infinity) { } + when (null) { } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/output.json new file mode 100644 index 000000000000..f2999a2782f2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/literal-match-patterns/output.json @@ -0,0 +1,178 @@ +{ + "type": "File", + "start":0,"end":189,"loc":{"start":{"line":1,"column":0},"end":{"line":11,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":189,"loc":{"start":{"line":1,"column":0},"end":{"line":11,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":189,"loc":{"start":{"line":1,"column":0},"end":{"line":11,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":189,"loc":{"start":{"line":1,"column":0},"end":{"line":11,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":11,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":11},"identifierName":"name"}, + "name": "name" + }, + "clauses": [ + { + "type": "MatchClause", + "start":17,"end":33,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}}, + "test": { + "type": "RegExpLiteral", + "start":23,"end":28,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":13}}, + "extra": { + "raw": "/abc/" + }, + "pattern": "abc", + "flags": "" + }, + "consequent": { + "type": "BlockStatement", + "start":30,"end":33,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":18}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":36,"end":52,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":18}}, + "test": { + "type": "StringLiteral", + "start":42,"end":47,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":13}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "consequent": { + "type": "BlockStatement", + "start":49,"end":52,"loc":{"start":{"line":3,"column":15},"end":{"line":3,"column":18}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":55,"end":69,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":16}}, + "test": { + "type": "NumericLiteral", + "start":61,"end":64,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":11}}, + "extra": { + "rawValue": 100, + "raw": "100" + }, + "value": 100 + }, + "consequent": { + "type": "BlockStatement", + "start":66,"end":69,"loc":{"start":{"line":4,"column":13},"end":{"line":4,"column":16}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":72,"end":87,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":17}}, + "test": { + "type": "BigIntLiteral", + "start":78,"end":82,"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":12}}, + "extra": { + "rawValue": "100", + "raw": "100n" + }, + "value": "100" + }, + "consequent": { + "type": "BlockStatement", + "start":84,"end":87,"loc":{"start":{"line":5,"column":14},"end":{"line":5,"column":17}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":90,"end":105,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":17}}, + "test": { + "type": "BooleanLiteral", + "start":96,"end":100,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":12}}, + "value": true + }, + "consequent": { + "type": "BlockStatement", + "start":102,"end":105,"loc":{"start":{"line":6,"column":14},"end":{"line":6,"column":17}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":108,"end":124,"loc":{"start":{"line":7,"column":2},"end":{"line":7,"column":18}}, + "test": { + "type": "BooleanLiteral", + "start":114,"end":119,"loc":{"start":{"line":7,"column":8},"end":{"line":7,"column":13}}, + "value": false + }, + "consequent": { + "type": "BlockStatement", + "start":121,"end":124,"loc":{"start":{"line":7,"column":15},"end":{"line":7,"column":18}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":127,"end":147,"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":22}}, + "test": { + "type": "Identifier", + "start":133,"end":142,"loc":{"start":{"line":8,"column":8},"end":{"line":8,"column":17},"identifierName":"undefined"}, + "name": "undefined" + }, + "consequent": { + "type": "BlockStatement", + "start":144,"end":147,"loc":{"start":{"line":8,"column":19},"end":{"line":8,"column":22}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":150,"end":169,"loc":{"start":{"line":9,"column":2},"end":{"line":9,"column":21}}, + "test": { + "type": "Identifier", + "start":156,"end":164,"loc":{"start":{"line":9,"column":8},"end":{"line":9,"column":16},"identifierName":"Infinity"}, + "name": "Infinity" + }, + "consequent": { + "type": "BlockStatement", + "start":166,"end":169,"loc":{"start":{"line":9,"column":18},"end":{"line":9,"column":21}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":172,"end":187,"loc":{"start":{"line":10,"column":2},"end":{"line":10,"column":17}}, + "test": { + "type": "NullLiteral", + "start":178,"end":182,"loc":{"start":{"line":10,"column":8},"end":{"line":10,"column":12}} + }, + "consequent": { + "type": "BlockStatement", + "start":184,"end":187,"loc":{"start":{"line":10,"column":14},"end":{"line":10,"column":17}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/input.js new file mode 100644 index 000000000000..04def8b2c3ae --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/input.js @@ -0,0 +1,9 @@ +match (foo) +{} + +match +(foo) +{} + +match +(foo) {} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/output.json new file mode 100644 index 000000000000..e2def28664c9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/match-NLTH/output.json @@ -0,0 +1,94 @@ +{ + "type": "File", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":8}}, + "errors": [ + "SyntaxError: Missing semicolon. (9:5)" + ], + "program": { + "type": "Program", + "start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":8}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":11,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}}, + "expression": { + "type": "CallExpression", + "start":0,"end":11,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}}, + "callee": { + "type": "Identifier", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5},"identifierName":"match"}, + "name": "match" + }, + "arguments": [ + { + "type": "Identifier", + "start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10},"identifierName":"foo"}, + "name": "foo" + } + ] + } + }, + { + "type": "BlockStatement", + "start":12,"end":14,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":2}}, + "body": [], + "directives": [] + }, + { + "type": "ExpressionStatement", + "start":16,"end":27,"loc":{"start":{"line":4,"column":0},"end":{"line":5,"column":5}}, + "expression": { + "type": "CallExpression", + "start":16,"end":27,"loc":{"start":{"line":4,"column":0},"end":{"line":5,"column":5}}, + "callee": { + "type": "Identifier", + "start":16,"end":21,"loc":{"start":{"line":4,"column":0},"end":{"line":4,"column":5},"identifierName":"match"}, + "name": "match" + }, + "arguments": [ + { + "type": "Identifier", + "start":23,"end":26,"loc":{"start":{"line":5,"column":1},"end":{"line":5,"column":4},"identifierName":"foo"}, + "name": "foo" + } + ] + } + }, + { + "type": "BlockStatement", + "start":28,"end":30,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":2}}, + "body": [], + "directives": [] + }, + { + "type": "ExpressionStatement", + "start":32,"end":43,"loc":{"start":{"line":8,"column":0},"end":{"line":9,"column":5}}, + "expression": { + "type": "CallExpression", + "start":32,"end":43,"loc":{"start":{"line":8,"column":0},"end":{"line":9,"column":5}}, + "callee": { + "type": "Identifier", + "start":32,"end":37,"loc":{"start":{"line":8,"column":0},"end":{"line":8,"column":5},"identifierName":"match"}, + "name": "match" + }, + "arguments": [ + { + "type": "Identifier", + "start":39,"end":42,"loc":{"start":{"line":9,"column":1},"end":{"line":9,"column":4},"identifierName":"foo"}, + "name": "foo" + } + ] + } + }, + { + "type": "BlockStatement", + "start":44,"end":46,"loc":{"start":{"line":9,"column":6},"end":{"line":9,"column":8}}, + "body": [], + "directives": [] + } + ], + "directives": [] + } +} \ No newline at end of file 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/missing-parenthesis-expression-match-pattern/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/options.json new file mode 100644 index 000000000000..5820a09c2e16 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/missing-parenthesis-expression-match-pattern/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "Unexpected token (2:16)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/input.js new file mode 100644 index 000000000000..730e283ac52e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/input.js @@ -0,0 +1,3 @@ +match (foo, bar) { + when ({ x }) { } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/output.json new file mode 100644 index 000000000000..444a9a4d0bfc --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/multiple-parameters-in-match-expression/output.json @@ -0,0 +1,66 @@ +{ + "type": "File", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "SequenceExpression", + "start":7,"end":15,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":15}}, + "expressions": [ + { + "type": "Identifier", + "start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10},"identifierName":"foo"}, + "name": "foo" + }, + { + "type": "Identifier", + "start":12,"end":15,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":15},"identifierName":"bar"}, + "name": "bar" + } + ] + }, + "clauses": [ + { + "type": "MatchClause", + "start":21,"end":37,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}}, + "test": { + "type": "ObjectMatchPattern", + "start":27,"end":32,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":13}}, + "properties": [ + { + "type": "ObjectProperty", + "start":29,"end":30,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11}}, + "method": false, + "key": { + "type": "Identifier", + "start":29,"end":30,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"x"}, + "name": "x" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":34,"end":37,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":18}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/input.js new file mode 100644 index 000000000000..581de37b9810 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/input.js @@ -0,0 +1,9 @@ +match ( + match (foo) { + when (x) { + "foo" + } + } +) { + when ({ x }) { "bar" } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/output.json new file mode 100644 index 000000000000..7591a9e22bc2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-match/output.json @@ -0,0 +1,104 @@ +{ + "type": "File", + "start":0,"end":91,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":91,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":91,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":91,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "discriminant": { + "type": "MatchExpression", + "start":10,"end":60,"loc":{"start":{"line":2,"column":2},"end":{"line":6,"column":3}}, + "discriminant": { + "type": "Identifier", + "start":17,"end":20,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "clauses": [ + { + "type": "MatchClause", + "start":28,"end":56,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":5}}, + "test": { + "type": "Identifier", + "start":34,"end":35,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":11},"identifierName":"x"}, + "name": "x" + }, + "consequent": { + "type": "BlockStatement", + "start":37,"end":56,"loc":{"start":{"line":3,"column":13},"end":{"line":5,"column":5}}, + "body": [ + { + "type": "ExpressionStatement", + "start":45,"end":50,"loc":{"start":{"line":4,"column":6},"end":{"line":4,"column":11}}, + "expression": { + "type": "StringLiteral", + "start":45,"end":50,"loc":{"start":{"line":4,"column":6},"end":{"line":4,"column":11}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "directives": [] + } + } + ] + }, + "clauses": [ + { + "type": "MatchClause", + "start":67,"end":89,"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":24}}, + "test": { + "type": "ObjectMatchPattern", + "start":73,"end":78,"loc":{"start":{"line":8,"column":8},"end":{"line":8,"column":13}}, + "properties": [ + { + "type": "ObjectProperty", + "start":75,"end":76,"loc":{"start":{"line":8,"column":10},"end":{"line":8,"column":11}}, + "method": false, + "key": { + "type": "Identifier", + "start":75,"end":76,"loc":{"start":{"line":8,"column":10},"end":{"line":8,"column":11},"identifierName":"x"}, + "name": "x" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":80,"end":89,"loc":{"start":{"line":8,"column":15},"end":{"line":8,"column":24}}, + "body": [ + { + "type": "ExpressionStatement", + "start":82,"end":87,"loc":{"start":{"line":8,"column":17},"end":{"line":8,"column":22}}, + "expression": { + "type": "StringLiteral", + "start":82,"end":87,"loc":{"start":{"line":8,"column":17},"end":{"line":8,"column":22}}, + "extra": { + "rawValue": "bar", + "raw": "\"bar\"" + }, + "value": "bar" + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/input.js new file mode 100644 index 000000000000..d5b46459cf22 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/input.js @@ -0,0 +1,3 @@ +match (x) { + when ({ y: { x: 100 } }) { "yes" } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/output.json new file mode 100644 index 000000000000..d17d0f7b0022 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/nested-object-match-pattern/output.json @@ -0,0 +1,95 @@ +{ + "type": "File", + "start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":48,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":36}}, + "test": { + "type": "ObjectMatchPattern", + "start":20,"end":37,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":25}}, + "properties": [ + { + "type": "ObjectProperty", + "start":22,"end":35,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":23}}, + "method": false, + "key": { + "type": "Identifier", + "start":22,"end":23,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"y"}, + "name": "y" + }, + "computed": false, + "value": { + "type": "ObjectMatchPattern", + "start":25,"end":35,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":23}}, + "properties": [ + { + "type": "ObjectProperty", + "start":27,"end":33,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":21}}, + "method": false, + "key": { + "type": "Identifier", + "start":27,"end":28,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":16},"identifierName":"x"}, + "name": "x" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":30,"end":33,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":21}}, + "extra": { + "rawValue": 100, + "raw": "100" + }, + "value": 100 + } + } + ] + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":39,"end":48,"loc":{"start":{"line":2,"column":27},"end":{"line":2,"column":36}}, + "body": [ + { + "type": "ExpressionStatement", + "start":41,"end":46,"loc":{"start":{"line":2,"column":29},"end":{"line":2,"column":34}}, + "expression": { + "type": "StringLiteral", + "start":41,"end":46,"loc":{"start":{"line":2,"column":29},"end":{"line":2,"column":34}}, + "extra": { + "rawValue": "yes", + "raw": "\"yes\"" + }, + "value": "yes" + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/input.js new file mode 100644 index 000000000000..e1a8a2cbdb2b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/input.js @@ -0,0 +1,3 @@ +match (name, ...foo) { + when ({ x }) { } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/options.json new file mode 100644 index 000000000000..5628d5f68596 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression-2/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "Spread elements are not allowed in match expressions. (1:13)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/input.js new file mode 100644 index 000000000000..3e3a3f17e8a2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/input.js @@ -0,0 +1,3 @@ +match (...foo) { + when ({ x }) { } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/options.json new file mode 100644 index 000000000000..7eff346e08ca --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/no-rest-in-match-expression/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "Spread elements are not allowed in match expressions. (1:7)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/input.js new file mode 100644 index 000000000000..d11caf26fac4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/input.js @@ -0,0 +1,3 @@ +match (x) { + when ({ colour: "#000000" }) { "yes" } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/output.json new file mode 100644 index 000000000000..764c925e13c2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/object-match-pattern/output.json @@ -0,0 +1,78 @@ +{ + "type": "File", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":52,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":40}}, + "test": { + "type": "ObjectMatchPattern", + "start":20,"end":41,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":29}}, + "properties": [ + { + "type": "ObjectProperty", + "start":22,"end":39,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":27}}, + "method": false, + "key": { + "type": "Identifier", + "start":22,"end":28,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":16},"identifierName":"colour"}, + "name": "colour" + }, + "computed": false, + "value": { + "type": "StringLiteral", + "start":30,"end":39,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":27}}, + "extra": { + "rawValue": "#000000", + "raw": "\"#000000\"" + }, + "value": "#000000" + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":43,"end":52,"loc":{"start":{"line":2,"column":31},"end":{"line":2,"column":40}}, + "body": [ + { + "type": "ExpressionStatement", + "start":45,"end":50,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":38}}, + "expression": { + "type": "StringLiteral", + "start":45,"end":50,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":38}}, + "extra": { + "rawValue": "yes", + "raw": "\"yes\"" + }, + "value": "yes" + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/options.json new file mode 100644 index 000000000000..cbe6d52c288e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["patternMatching"] +} 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/returned-from-function/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/returned-from-function/input.js new file mode 100644 index 000000000000..43bb5ecc9d46 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/returned-from-function/input.js @@ -0,0 +1,9 @@ +function foo() { + return match (x) { + when({ z }) { false } + } +} + +const a = () => match (z) { + when({ n: 200 }) { "true" } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/returned-from-function/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/returned-from-function/output.json new file mode 100644 index 000000000000..c74beb21be94 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/returned-from-function/output.json @@ -0,0 +1,169 @@ +{ + "type": "File", + "start":0,"end":130,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":130,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "FunctionDeclaration", + "start":0,"end":69,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "id": { + "type": "Identifier", + "start":9,"end":12,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":15,"end":69,"loc":{"start":{"line":1,"column":15},"end":{"line":5,"column":1}}, + "body": [ + { + "type": "ReturnStatement", + "start":19,"end":67,"loc":{"start":{"line":2,"column":2},"end":{"line":4,"column":3}}, + "argument": { + "type": "MatchExpression", + "start":26,"end":67,"loc":{"start":{"line":2,"column":9},"end":{"line":4,"column":3}}, + "discriminant": { + "type": "Identifier", + "start":33,"end":34,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":17},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":42,"end":63,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":25}}, + "test": { + "type": "ObjectMatchPattern", + "start":47,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":14}}, + "properties": [ + { + "type": "ObjectProperty", + "start":49,"end":50,"loc":{"start":{"line":3,"column":11},"end":{"line":3,"column":12}}, + "method": false, + "key": { + "type": "Identifier", + "start":49,"end":50,"loc":{"start":{"line":3,"column":11},"end":{"line":3,"column":12},"identifierName":"z"}, + "name": "z" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":54,"end":63,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":25}}, + "body": [ + { + "type": "ExpressionStatement", + "start":56,"end":61,"loc":{"start":{"line":3,"column":18},"end":{"line":3,"column":23}}, + "expression": { + "type": "BooleanLiteral", + "start":56,"end":61,"loc":{"start":{"line":3,"column":18},"end":{"line":3,"column":23}}, + "value": false + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } + }, + { + "type": "VariableDeclaration", + "start":71,"end":130,"loc":{"start":{"line":7,"column":0},"end":{"line":9,"column":1}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":77,"end":130,"loc":{"start":{"line":7,"column":6},"end":{"line":9,"column":1}}, + "id": { + "type": "Identifier", + "start":77,"end":78,"loc":{"start":{"line":7,"column":6},"end":{"line":7,"column":7},"identifierName":"a"}, + "name": "a" + }, + "init": { + "type": "ArrowFunctionExpression", + "start":81,"end":130,"loc":{"start":{"line":7,"column":10},"end":{"line":9,"column":1}}, + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "MatchExpression", + "start":87,"end":130,"loc":{"start":{"line":7,"column":16},"end":{"line":9,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":94,"end":95,"loc":{"start":{"line":7,"column":23},"end":{"line":7,"column":24},"identifierName":"z"}, + "name": "z" + }, + "clauses": [ + { + "type": "MatchClause", + "start":101,"end":128,"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":29}}, + "test": { + "type": "ObjectMatchPattern", + "start":106,"end":116,"loc":{"start":{"line":8,"column":7},"end":{"line":8,"column":17}}, + "properties": [ + { + "type": "ObjectProperty", + "start":108,"end":114,"loc":{"start":{"line":8,"column":9},"end":{"line":8,"column":15}}, + "method": false, + "key": { + "type": "Identifier", + "start":108,"end":109,"loc":{"start":{"line":8,"column":9},"end":{"line":8,"column":10},"identifierName":"n"}, + "name": "n" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":111,"end":114,"loc":{"start":{"line":8,"column":12},"end":{"line":8,"column":15}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":118,"end":128,"loc":{"start":{"line":8,"column":19},"end":{"line":8,"column":29}}, + "body": [ + { + "type": "ExpressionStatement", + "start":120,"end":126,"loc":{"start":{"line":8,"column":21},"end":{"line":8,"column":27}}, + "expression": { + "type": "StringLiteral", + "start":120,"end":126,"loc":{"start":{"line":8,"column":21},"end":{"line":8,"column":27}}, + "extra": { + "rawValue": "true", + "raw": "\"true\"" + }, + "value": "true" + } + } + ], + "directives": [] + } + } + ] + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/input.js new file mode 100644 index 000000000000..c99f3b2724f7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/input.js @@ -0,0 +1,3 @@ +match (z) { + when({ n: 200 }) { "true" } +}.foo diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/output.json new file mode 100644 index 000000000000..0f14584bc891 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/start-member-chain/output.json @@ -0,0 +1,88 @@ +{ + "type": "File", + "start":0,"end":47,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "program": { + "type": "Program", + "start":0,"end":47,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":47,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "expression": { + "type": "MemberExpression", + "start":0,"end":47,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "object": { + "type": "MatchExpression", + "start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"z"}, + "name": "z" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":41,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":29}}, + "test": { + "type": "ObjectMatchPattern", + "start":19,"end":29,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}}, + "properties": [ + { + "type": "ObjectProperty", + "start":21,"end":27,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":15}}, + "method": false, + "key": { + "type": "Identifier", + "start":21,"end":22,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":10},"identifierName":"n"}, + "name": "n" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":24,"end":27,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":15}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":31,"end":41,"loc":{"start":{"line":2,"column":19},"end":{"line":2,"column":29}}, + "body": [ + { + "type": "ExpressionStatement", + "start":33,"end":39,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":27}}, + "expression": { + "type": "StringLiteral", + "start":33,"end":39,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":27}}, + "extra": { + "rawValue": "true", + "raw": "\"true\"" + }, + "value": "true" + } + } + ], + "directives": [] + } + } + ] + }, + "computed": false, + "property": { + "type": "Identifier", + "start":44,"end":47,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5},"identifierName":"foo"}, + "name": "foo" + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/input.js new file mode 100644 index 000000000000..7ce417761978 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/input.js @@ -0,0 +1,3 @@ +match (foo,) { + when ({ x }) { } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/output.json new file mode 100644 index 000000000000..20e2b521abfc --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/trailing-comma-in-match-expression/output.json @@ -0,0 +1,55 @@ +{ + "type": "File", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"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":17,"end":33,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}}, + "test": { + "type": "ObjectMatchPattern", + "start":23,"end":28,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":13}}, + "properties": [ + { + "type": "ObjectProperty", + "start":25,"end":26,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11}}, + "method": false, + "key": { + "type": "Identifier", + "start":25,"end":26,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"x"}, + "name": "x" + }, + "computed": false + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":30,"end":33,"loc":{"start":{"line":2,"column":15},"end":{"line":2,"column":18}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/input.js new file mode 100644 index 000000000000..506c457bdd88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/input.js @@ -0,0 +1,5 @@ +match (x) { + when (+100) { } + when (-100) { } + when (-Infinity) { } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/output.json new file mode 100644 index 000000000000..683ce797f6db --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/unary-match-patterns/output.json @@ -0,0 +1,99 @@ +{ + "type": "File", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "expression": { + "type": "MatchExpression", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"x"}, + "name": "x" + }, + "clauses": [ + { + "type": "MatchClause", + "start":14,"end":29,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":17}}, + "test": { + "type": "UnaryExpression", + "start":20,"end":24,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":12}}, + "operator": "+", + "prefix": true, + "argument": { + "type": "NumericLiteral", + "start":21,"end":24,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12}}, + "extra": { + "rawValue": 100, + "raw": "100" + }, + "value": 100 + } + }, + "consequent": { + "type": "BlockStatement", + "start":26,"end":29,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":17}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":32,"end":47,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":17}}, + "test": { + "type": "UnaryExpression", + "start":38,"end":42,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":12}}, + "operator": "-", + "prefix": true, + "argument": { + "type": "NumericLiteral", + "start":39,"end":42,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":12}}, + "extra": { + "rawValue": 100, + "raw": "100" + }, + "value": 100 + } + }, + "consequent": { + "type": "BlockStatement", + "start":44,"end":47,"loc":{"start":{"line":3,"column":14},"end":{"line":3,"column":17}}, + "body": [], + "directives": [] + } + }, + { + "type": "MatchClause", + "start":50,"end":70,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":22}}, + "test": { + "type": "UnaryExpression", + "start":56,"end":65,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":17}}, + "operator": "-", + "prefix": true, + "argument": { + "type": "Identifier", + "start":57,"end":65,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":17},"identifierName":"Infinity"}, + "name": "Infinity" + } + }, + "consequent": { + "type": "BlockStatement", + "start":67,"end":70,"loc":{"start":{"line":4,"column":19},"end":{"line":4,"column":22}}, + "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 diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/input.js new file mode 100644 index 000000000000..11dc21b79c38 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/input.js @@ -0,0 +1,3 @@ +const a = match (z) { + when({ n: 200 }) { "true" } +} + 3 diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/output.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/output.json new file mode 100644 index 000000000000..f333411b7f8b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/valid-lhs-in-binary-expression/output.json @@ -0,0 +1,104 @@ +{ + "type": "File", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "program": { + "type": "Program", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":5}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":6,"end":57,"loc":{"start":{"line":1,"column":6},"end":{"line":3,"column":5}}, + "id": { + "type": "Identifier", + "start":6,"end":7,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":7},"identifierName":"a"}, + "name": "a" + }, + "init": { + "type": "BinaryExpression", + "start":10,"end":57,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":5}}, + "left": { + "type": "MatchExpression", + "start":10,"end":53,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}}, + "discriminant": { + "type": "Identifier", + "start":17,"end":18,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":18},"identifierName":"z"}, + "name": "z" + }, + "clauses": [ + { + "type": "MatchClause", + "start":24,"end":51,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":29}}, + "test": { + "type": "ObjectMatchPattern", + "start":29,"end":39,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}}, + "properties": [ + { + "type": "ObjectProperty", + "start":31,"end":37,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":15}}, + "method": false, + "key": { + "type": "Identifier", + "start":31,"end":32,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":10},"identifierName":"n"}, + "name": "n" + }, + "computed": false, + "value": { + "type": "NumericLiteral", + "start":34,"end":37,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":15}}, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + } + ] + }, + "consequent": { + "type": "BlockStatement", + "start":41,"end":51,"loc":{"start":{"line":2,"column":19},"end":{"line":2,"column":29}}, + "body": [ + { + "type": "ExpressionStatement", + "start":43,"end":49,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":27}}, + "expression": { + "type": "StringLiteral", + "start":43,"end":49,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":27}}, + "extra": { + "rawValue": "true", + "raw": "\"true\"" + }, + "value": "true" + } + } + ], + "directives": [] + } + } + ] + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "start":56,"end":57,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":5}}, + "extra": { + "rawValue": 3, + "raw": "3" + }, + "value": 3 + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/input.js new file mode 100644 index 000000000000..d3bc9e54b8b4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/input.js @@ -0,0 +1,6 @@ +match (foo) { + when (bar) + { + "foo" + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/options.json new file mode 100644 index 000000000000..e5608879db44 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-newline-after-pattern/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "No line terminator allowed after match pattern. (2:12)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/input.js b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/input.js new file mode 100644 index 000000000000..d2a21fa31ec2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/input.js @@ -0,0 +1,5 @@ +match (foo) { + when (bar); { + "foo" + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/options.json b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/options.json new file mode 100644 index 000000000000..b9f04dabee87 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/pattern-matching/when-semi-after-pattern/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "patternMatching" + ] + ], + "throws": "No line terminator allowed after match pattern. (2:13)" +} \ No newline at end of file diff --git a/packages/babel-plugin-syntax-pattern-matching/.npmignore b/packages/babel-plugin-syntax-pattern-matching/.npmignore new file mode 100644 index 000000000000..f9806945836e --- /dev/null +++ b/packages/babel-plugin-syntax-pattern-matching/.npmignore @@ -0,0 +1,3 @@ +src +test +*.log diff --git a/packages/babel-plugin-syntax-pattern-matching/README.md b/packages/babel-plugin-syntax-pattern-matching/README.md new file mode 100644 index 000000000000..b63e03fcf6a0 --- /dev/null +++ b/packages/babel-plugin-syntax-pattern-matching/README.md @@ -0,0 +1,19 @@ +# @babel/plugin-syntax-pattern-matching + +> Allow parsing of pattern matching syntax + +See our website [@babel/plugin-syntax-pattern-matching](https://babeljs.io/docs/en/babel-plugin-syntax-pattern-matching) for more information. + +## Install + +Using npm: + +```sh +npm install --save-dev @babel/plugin-syntax-pattern-matching +``` + +or using yarn: + +```sh +yarn add @babel/plugin-syntax-pattern-matching --dev +``` diff --git a/packages/babel-plugin-syntax-pattern-matching/package.json b/packages/babel-plugin-syntax-pattern-matching/package.json new file mode 100644 index 000000000000..c227bb729fa7 --- /dev/null +++ b/packages/babel-plugin-syntax-pattern-matching/package.json @@ -0,0 +1,32 @@ +{ + "name": "@babel/plugin-syntax-pattern-matching", + "version": "7.14.5", + "description": "Allow parsing of pattern matching syntax", + "repository": { + "type": "git", + "url": "https://github.com/babel/babel.git", + "directory": "packages/babel-plugin-syntax-pattern-matching" + }, + "homepage": "https://babel.dev/docs/en/next/babel-plugin-syntax-pattern-matching", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "main": "./lib/index.js", + "keywords": [ + "babel-plugin" + ], + "dependencies": { + "@babel/helper-plugin-utils": "workspace:^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "devDependencies": { + "@babel/core": "workspace:*" + }, + "engines": { + "node": ">=6.9.0" + }, + "author": "The Babel Team (https://babel.dev/team)" +} diff --git a/packages/babel-plugin-syntax-pattern-matching/src/index.js b/packages/babel-plugin-syntax-pattern-matching/src/index.js new file mode 100644 index 000000000000..0587f2050b3b --- /dev/null +++ b/packages/babel-plugin-syntax-pattern-matching/src/index.js @@ -0,0 +1,13 @@ +import { declare } from "@babel/helper-plugin-utils"; + +export default declare(api => { + api.assertVersion(7); + + return { + name: "syntax-pattern-matching", + + manipulateOptions(opts, parserOpts) { + parserOpts.plugins.push("patternMatching"); + }, + }; +}); diff --git a/yarn.lock b/yarn.lock index de47d5939637..9ef9ae9f6570 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1899,6 +1899,17 @@ __metadata: languageName: unknown linkType: soft +"@babel/plugin-syntax-pattern-matching@workspace:packages/babel-plugin-syntax-pattern-matching": + version: 0.0.0-use.local + resolution: "@babel/plugin-syntax-pattern-matching@workspace:packages/babel-plugin-syntax-pattern-matching" + dependencies: + "@babel/core": "workspace:*" + "@babel/helper-plugin-utils": "workspace:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + languageName: unknown + linkType: soft + "@babel/plugin-syntax-pipeline-operator@workspace:*, @babel/plugin-syntax-pipeline-operator@workspace:^7.15.0, @babel/plugin-syntax-pipeline-operator@workspace:packages/babel-plugin-syntax-pipeline-operator": version: 0.0.0-use.local resolution: "@babel/plugin-syntax-pipeline-operator@workspace:packages/babel-plugin-syntax-pipeline-operator"