From e76f24175420ad65cd04cf1fba47a943c527dd78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 31 Dec 2021 18:44:58 +0100 Subject: [PATCH] Add parser support for the "regexp unicode sets" proposal (#14086) --- .../babel-parser/src/parser/error-message.js | 2 ++ packages/babel-parser/src/tokenizer/index.js | 12 ++++++++ .../_no-plugin/regexp-unicode-sets/input.js | 1 + .../regexp-unicode-sets/options.json | 3 ++ .../regexp-unicode-sets/basic/input.js | 1 + .../regexp-unicode-sets/basic/output.json | 26 +++++++++++++++++ .../regexp-unicode-sets/options.json | 3 ++ .../regexp-unicode-sets/uv-error/input.js | 1 + .../regexp-unicode-sets/uv-error/output.json | 29 +++++++++++++++++++ .../regexp-unicode-sets/vu-error/input.js | 1 + .../regexp-unicode-sets/vu-error/output.json | 29 +++++++++++++++++++ .../babel-parser/typings/babel-parser.d.ts | 1 + 12 files changed, 109 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/output.json diff --git a/packages/babel-parser/src/parser/error-message.js b/packages/babel-parser/src/parser/error-message.js index 9bcc55e28b07..3cdd01309785 100644 --- a/packages/babel-parser/src/parser/error-message.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -76,6 +76,8 @@ export const ErrorMessages = makeErrorTemplates( ImportCallArity: "`import()` requires exactly %0.", ImportCallNotNewExpression: "Cannot use new with import(...).", ImportCallSpreadArgument: "`...` is not allowed in `import()`.", + IncompatibleRegExpUVFlags: + "The 'u' and 'v' regular expression flags cannot be enabled at the same time.", InvalidBigIntLiteral: "Invalid BigIntLiteral.", InvalidCodePoint: "Code point out of bounds.", InvalidCoverInitializedName: "Invalid shorthand property initializer.", diff --git a/packages/babel-parser/src/tokenizer/index.js b/packages/babel-parser/src/tokenizer/index.js index 9a647a68775d..ea3bd15aebce 100644 --- a/packages/babel-parser/src/tokenizer/index.js +++ b/packages/babel-parser/src/tokenizer/index.js @@ -33,6 +33,8 @@ const VALID_REGEX_FLAGS = new Set([ charCodes.lowercaseY, charCodes.lowercaseU, charCodes.lowercaseD, + // This is only valid when using the regexpUnicodeSets plugin + charCodes.lowercaseV, ]); // The following character codes are forbidden from being @@ -1071,6 +1073,16 @@ export default class Tokenizer extends ParserErrors { const char = String.fromCharCode(cp); if (VALID_REGEX_FLAGS.has(cp)) { + if (cp === charCodes.lowercaseV) { + this.expectPlugin("regexpUnicodeSets", pos + 1); + if (mods.includes("u")) { + this.raise(pos + 1, Errors.IncompatibleRegExpUVFlags); + } + } else if (cp === charCodes.lowercaseU) { + if (mods.includes("v")) { + this.raise(pos + 1, Errors.IncompatibleRegExpUVFlags); + } + } if (mods.includes(char)) { this.raise(pos + 1, Errors.DuplicateRegExpFlags); } diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/input.js b/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/input.js new file mode 100644 index 000000000000..04ee6ccf77ed --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/input.js @@ -0,0 +1 @@ +/a/v; diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/options.json b/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/options.json new file mode 100644 index 000000000000..a9aa871d03c7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/regexp-unicode-sets/options.json @@ -0,0 +1,3 @@ +{ + "throws": "This experimental syntax requires enabling the parser plugin: \"regexpUnicodeSets\". (1:4)" +} diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/input.js b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/input.js new file mode 100644 index 000000000000..04ee6ccf77ed --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/input.js @@ -0,0 +1 @@ +/a/v; diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/output.json b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/output.json new file mode 100644 index 000000000000..adff3b4ea2b3 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/basic/output.json @@ -0,0 +1,26 @@ +{ + "type": "File", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "program": { + "type": "Program", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "expression": { + "type": "RegExpLiteral", + "start":0,"end":4,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":4}}, + "extra": { + "raw": "/a/v" + }, + "pattern": "a", + "flags": "v" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/options.json b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/options.json new file mode 100644 index 000000000000..a027295978f0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["regexpUnicodeSets"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/input.js b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/input.js new file mode 100644 index 000000000000..5dcdc60dfb77 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/input.js @@ -0,0 +1 @@ +/a/ugv; diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/output.json b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/output.json new file mode 100644 index 000000000000..7ab6bdf31805 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/uv-error/output.json @@ -0,0 +1,29 @@ +{ + "type": "File", + "start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}}, + "errors": [ + "SyntaxError: The 'u' and 'v' regular expression flags cannot be enabled at the same time. (1:6)" + ], + "program": { + "type": "Program", + "start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}}, + "expression": { + "type": "RegExpLiteral", + "start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}}, + "extra": { + "raw": "/a/ugv" + }, + "pattern": "a", + "flags": "ugv" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/input.js b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/input.js new file mode 100644 index 000000000000..ce76d00a00c9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/input.js @@ -0,0 +1 @@ +/a/vu; diff --git a/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/output.json b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/output.json new file mode 100644 index 000000000000..5a9ed737f651 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/regexp-unicode-sets/vu-error/output.json @@ -0,0 +1,29 @@ +{ + "type": "File", + "start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}}, + "errors": [ + "SyntaxError: The 'u' and 'v' regular expression flags cannot be enabled at the same time. (1:5)" + ], + "program": { + "type": "Program", + "start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":6,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":6}}, + "expression": { + "type": "RegExpLiteral", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "extra": { + "raw": "/a/vu" + }, + "pattern": "a", + "flags": "vu" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/typings/babel-parser.d.ts b/packages/babel-parser/typings/babel-parser.d.ts index 3a3b3af22cdf..d1f5b3be5cbc 100644 --- a/packages/babel-parser/typings/babel-parser.d.ts +++ b/packages/babel-parser/typings/babel-parser.d.ts @@ -153,6 +153,7 @@ export type ParserPlugin = | "pipelineOperator" | "placeholders" | "privateIn" // Enabled by default + | "regexpUnicodeSets" | "throwExpressions" | "topLevelAwait" | "typescript"