Skip to content

Commit

Permalink
support the v regular expression literal flag
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 17, 2022
1 parent a7659c3 commit b5ec405
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@

This fix was contributed by [@fz6m](https://github.com/fz6m).

* Add support for the `v` flag in regular expression literals

People are currently working on adding a `v` flag to JavaScript regular expresions. You can read more about this flag here: https://v8.dev/features/regexp-v-flag. This release adds support for parsing this flag, so esbuild will now no longer consider regular expression literals with this flag to be a syntax error. If the target is set to something other than `esnext`, esbuild will transform regular expression literals containing this flag into a `new RegExp()` constructor call so the resulting code doesn't have a syntax error. This enables you to provide a polyfill for `RegExp` that implements the `v` flag to get your code to work at run-time. While esbuild doesn't typically adopt proposals until they're already shipping in a real JavaScript run-time, I'm adding it now because a) esbuild's implementation doesn't need to change as the proposal evolves, b) this isn't really new syntax since regular expression literals already have flags, and c) esbuild's implementation is a trivial pass-through anyway.

## 0.16.8

* Allow plugins to resolve injected files ([#2754](https://github.com/evanw/esbuild/issues/2754))
Expand Down
3 changes: 3 additions & 0 deletions internal/compat/js_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const (
RegexpLookbehindAssertions
RegexpMatchIndices
RegexpNamedCaptureGroups
RegexpSetNotation
RegexpStickyAndUnicodeFlags
RegexpUnicodePropertyEscapes
RestArgument
Expand Down Expand Up @@ -152,6 +153,7 @@ var StringToJSFeature = map[string]JSFeature{
"regexp-lookbehind-assertions": RegexpLookbehindAssertions,
"regexp-match-indices": RegexpMatchIndices,
"regexp-named-capture-groups": RegexpNamedCaptureGroups,
"regexp-set-notation": RegexpSetNotation,
"regexp-sticky-and-unicode-flags": RegexpStickyAndUnicodeFlags,
"regexp-unicode-property-escapes": RegexpUnicodePropertyEscapes,
"rest-argument": RestArgument,
Expand Down Expand Up @@ -633,6 +635,7 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{
Opera: {{start: v{51, 0, 0}}},
Safari: {{start: v{11, 1, 0}}},
},
RegexpSetNotation: {},
RegexpStickyAndUnicodeFlags: {
Chrome: {{start: v{50, 0, 0}}},
Deno: {{start: v{1, 0, 0}}},
Expand Down
2 changes: 1 addition & 1 deletion internal/js_lexer/js_lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2042,7 +2042,7 @@ func (lexer *Lexer) ScanRegExp() {
bits := uint32(0)
for js_ast.IsIdentifierContinue(lexer.codePoint) {
switch lexer.codePoint {
case 'd', 'g', 'i', 'm', 's', 'u', 'y':
case 'd', 'g', 'i', 'm', 's', 'u', 'v', 'y':
bit := uint32(1) << uint32(lexer.codePoint-'a')
if (bit & bits) != 0 {
// Reject duplicate flags
Expand Down
6 changes: 6 additions & 0 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11643,6 +11643,12 @@ pattern:
}
feature = compat.RegexpMatchIndices

case 'v':
if !p.options.unsupportedJSFeatures.Has(compat.RegexpSetNotation) {
continue // This is from a proposal: https://github.com/tc39/proposal-regexp-v-flag
}
feature = compat.RegexpSetNotation

default:
// Unknown flags are never supported
}
Expand Down
1 change: 1 addition & 0 deletions scripts/compat-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ mergeVersions('ClassStaticField', { es2022: true })
mergeVersions('TopLevelAwait', { es2022: true })
mergeVersions('ArbitraryModuleNamespaceNames', { es2022: true })
mergeVersions('RegexpMatchIndices', { es2022: true })
mergeVersions('RegexpSetNotation', {})
mergeVersions('ImportAssertions', {})

// Manually copied from https://caniuse.com/?search=export%20*%20as
Expand Down
4 changes: 4 additions & 0 deletions scripts/js-api-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5453,6 +5453,10 @@ let transformTests = {
// RegExpMatchIndices
check('es2022', `x1 = /y/d`, `x1 = /y/d;\n`),
check('es2021', `x2 = /y/d`, `x2 = new RegExp("y", "d");\n`),

// RegExpSetNotation
check('esnext', `x1 = /[\\p{White_Space}&&\\p{ASCII}]/v`, `x1 = /[\\p{White_Space}&&\\p{ASCII}]/v;\n`),
check('es2022', `x2 = /[\\p{White_Space}&&\\p{ASCII}]/v`, `x2 = new RegExp("[\\\\p{White_Space}&&\\\\p{ASCII}]", "v");\n`),
])
},

Expand Down

0 comments on commit b5ec405

Please sign in to comment.