diff --git a/Makefile b/Makefile index 3d4b76e13f7d..7c155119ff07 100644 --- a/Makefile +++ b/Makefile @@ -185,15 +185,16 @@ test-test262-update-allowlist: new-version-checklist: - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!! !!!!!!" - # @echo "!!!!!! Write any message that should !!!!!!" - # @echo "!!!!!! block the release here !!!!!!" - # @echo "!!!!!! !!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @exit 1 + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!! !!!!!!" + @echo "!!!!!! Update minVersion in the wrapRegExp helper, !!!!!!" + @echo "!!!!!! and the requried core version in the duplicate !!!!!!" + @echo "!!!!!! named groups plugin. !!!!!!" + @echo "!!!!!! !!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @exit 1 new-version: $(MAKE) new-version-checklist diff --git a/packages/babel-helper-create-regexp-features-plugin/src/features.ts b/packages/babel-helper-create-regexp-features-plugin/src/features.ts index abe72d0b4729..ed9b6f4ed60a 100644 --- a/packages/babel-helper-create-regexp-features-plugin/src/features.ts +++ b/packages/babel-helper-create-regexp-features-plugin/src/features.ts @@ -5,6 +5,7 @@ export const FEATURES = Object.freeze({ namedCaptureGroups: 1 << 3, unicodeSetsFlag_syntax: 1 << 4, unicodeSetsFlag: 1 << 5, + duplicateNamedCaptureGroups: 1 << 6, }); // We can't use a symbol because this needs to always be the same, even if diff --git a/packages/babel-helper-create-regexp-features-plugin/src/index.ts b/packages/babel-helper-create-regexp-features-plugin/src/index.ts index 060a3638f94d..d1be9056db04 100644 --- a/packages/babel-helper-create-regexp-features-plugin/src/index.ts +++ b/packages/babel-helper-create-regexp-features-plugin/src/index.ts @@ -1,5 +1,11 @@ import rewritePattern from "regexpu-core"; -import { featuresKey, FEATURES, enableFeature, runtimeKey } from "./features"; +import { + featuresKey, + FEATURES, + enableFeature, + runtimeKey, + hasFeature, +} from "./features"; import { generateRegexpuOptions, canSkipRegexpu, transformFlags } from "./util"; import type { NodePath } from "@babel/traverse"; @@ -44,7 +50,7 @@ export function createRegExpFeaturePlugin({ const features = file.get(featuresKey) ?? 0; let newFeatures = enableFeature(features, FEATURES[feature]); - const { useUnicodeFlag, runtime = true } = options; + const { useUnicodeFlag, runtime } = options; if (useUnicodeFlag === false) { newFeatures = enableFeature(newFeatures, FEATURES.unicodeFlag); } @@ -52,8 +58,29 @@ export function createRegExpFeaturePlugin({ file.set(featuresKey, newFeatures); } - if (!runtime) { - file.set(runtimeKey, false); + if (runtime !== undefined) { + if ( + file.has(runtimeKey) && + file.get(runtimeKey) !== runtime && + // TODO(Babel 8): Remove this check. It's necessary because in Babel 7 + // we allow multiple copies of transform-named-capturing-groups-regex + // with conflicting 'runtime' options. + hasFeature(newFeatures, FEATURES.duplicateNamedCaptureGroups) + ) { + throw new Error( + `The 'runtime' option must be the same for ` + + `'@babel/plugin-transform-named-capturing-groups-regex' and ` + + `'@babel/plugin-proposal-duplicate-named-capturing-groups-regex'.`, + ); + } + // TODO(Babel 8): Remove this check and always set it. + // It's necessary because in Babel 7 we allow multiple copies of + // transform-named-capturing-groups-regex with conflicting 'runtime' options. + if (feature === "namedCaptureGroups") { + if (!runtime || !file.has(runtimeKey)) file.set(runtimeKey, runtime); + } else { + file.set(runtimeKey, runtime); + } } if (!file.has(versionKey) || file.get(versionKey) < version) { @@ -71,14 +98,38 @@ export function createRegExpFeaturePlugin({ const regexpuOptions = generateRegexpuOptions(features); if (canSkipRegexpu(node, regexpuOptions)) return; - const namedCaptureGroups: Record = {}; + const namedCaptureGroups: Record = { + __proto__: null, + }; + let hasDuplicateNamedCaptureGroups = false; if (regexpuOptions.namedGroups === "transform") { regexpuOptions.onNamedGroup = (name, index) => { - namedCaptureGroups[name] = index; + const prev = namedCaptureGroups[name]; + if (typeof prev === "number") { + hasDuplicateNamedCaptureGroups = true; + namedCaptureGroups[name] = [prev, index]; + } else if (Array.isArray(prev)) { + prev.push(index); + } else { + namedCaptureGroups[name] = index; + } }; } - node.pattern = rewritePattern(node.pattern, node.flags, regexpuOptions); + let pattern = rewritePattern(node.pattern, node.flags, regexpuOptions); + if ( + !hasDuplicateNamedCaptureGroups && + hasFeature(features, FEATURES.duplicateNamedCaptureGroups) && + !hasFeature(features, FEATURES.namedCaptureGroups) + ) { + // If we only transformed named groups because we want to transform duplicates + // but there are no duplicates, re-transform the regexp without transforming + // named groups. + regexpuOptions.namedGroups = false; + if (canSkipRegexpu(node, regexpuOptions)) return; + pattern = rewritePattern(node.pattern, node.flags, regexpuOptions); + } + node.pattern = pattern; if ( regexpuOptions.namedGroups === "transform" && diff --git a/packages/babel-helper-create-regexp-features-plugin/src/util.ts b/packages/babel-helper-create-regexp-features-plugin/src/util.ts index b4c7e5251dfc..0648767f53dc 100644 --- a/packages/babel-helper-create-regexp-features-plugin/src/util.ts +++ b/packages/babel-helper-create-regexp-features-plugin/src/util.ts @@ -20,7 +20,8 @@ export function generateRegexpuOptions(toTransform: number): RegexpuOptions { feat("unicodeSetsFlag_syntax", "parse"), dotAllFlag: feat("dotAllFlag"), unicodePropertyEscapes: feat("unicodePropertyEscape"), - namedGroups: feat("namedCaptureGroups"), + namedGroups: + feat("namedCaptureGroups") || feat("duplicateNamedCaptureGroups"), onNamedGroup: () => {}, }; } diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/input.mjs b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-false-true/input.mjs similarity index 100% rename from packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/input.mjs rename to packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-false-true/input.mjs diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-false-true/options.json b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-false-true/options.json new file mode 100644 index 000000000000..97779c7e163d --- /dev/null +++ b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-false-true/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["transform-named-capturing-groups-regex", { "runtime": true }], + ["proposal-duplicate-named-capturing-groups-regex", { "runtime": false }] + ], + "throws": "The 'runtime' option must be the same for '@babel/plugin-transform-named-capturing-groups-regex' and '@babel/plugin-proposal-duplicate-named-capturing-groups-regex'." +} diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/input.mjs b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/input.mjs new file mode 100644 index 000000000000..3d7f5b1517b5 --- /dev/null +++ b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/input.mjs @@ -0,0 +1 @@ +/(?\d{4})/ diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/options.json b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/options.json new file mode 100644 index 000000000000..d430ab5acc70 --- /dev/null +++ b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/conflict-true-false/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["transform-named-capturing-groups-regex", { "runtime": false }], + ["proposal-duplicate-named-capturing-groups-regex", { "runtime": true }] + ], + "throws": "The 'runtime' option must be the same for '@babel/plugin-transform-named-capturing-groups-regex' and '@babel/plugin-proposal-duplicate-named-capturing-groups-regex'." +} diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/input.mjs b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/input.mjs new file mode 100644 index 000000000000..3d7f5b1517b5 --- /dev/null +++ b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/input.mjs @@ -0,0 +1 @@ +/(?\d{4})/ diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/options.json b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/options.json similarity index 100% rename from packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/options.json rename to packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/options.json diff --git a/packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/output.mjs b/packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/output.mjs similarity index 100% rename from packages/babel-helper-create-regexp-features-plugin/test/fixtures/plugin-transform-named-capturing-groups-regex/runtime-false-not-overwritten/output.mjs rename to packages/babel-helper-create-regexp-features-plugin/test/fixtures/runtime/plugin-transform-named-capturing-groups-regex-runtime-false-not-overwritten/output.mjs diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index d40d731026b9..07c11f7a6e51 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -39,6 +39,6 @@ export default Object.freeze({ ), wrapRegExp: helper( "7.2.6", - 'import setPrototypeOf from"setPrototypeOf";import inherits from"inherits";export default function _wrapRegExp(){_wrapRegExp=function(re,groups){return new BabelRegExp(re,void 0,groups)};var _super=RegExp.prototype,_groups=new WeakMap;function BabelRegExp(re,flags,groups){var _this=new RegExp(re,flags);return _groups.set(_this,groups||_groups.get(re)),setPrototypeOf(_this,BabelRegExp.prototype)}function buildGroups(result,re){var g=_groups.get(re);return Object.keys(g).reduce((function(groups,name){return groups[name]=result[g[name]],groups}),Object.create(null))}return inherits(BabelRegExp,RegExp),BabelRegExp.prototype.exec=function(str){var result=_super.exec.call(this,str);return result&&(result.groups=buildGroups(result,this)),result},BabelRegExp.prototype[Symbol.replace]=function(str,substitution){if("string"==typeof substitution){var groups=_groups.get(this);return _super[Symbol.replace].call(this,str,substitution.replace(/\\$<([^>]+)>/g,(function(_,name){return"$"+groups[name]})))}if("function"==typeof substitution){var _this=this;return _super[Symbol.replace].call(this,str,(function(){var args=arguments;return"object"!=typeof args[args.length-1]&&(args=[].slice.call(args)).push(buildGroups(args,_this)),substitution.apply(this,args)}))}return _super[Symbol.replace].call(this,str,substitution)},_wrapRegExp.apply(this,arguments)}', + 'import setPrototypeOf from"setPrototypeOf";import inherits from"inherits";export default function _wrapRegExp(){_wrapRegExp=function(re,groups){return new BabelRegExp(re,void 0,groups)};var _super=RegExp.prototype,_groups=new WeakMap;function BabelRegExp(re,flags,groups){var _this=new RegExp(re,flags);return _groups.set(_this,groups||_groups.get(re)),setPrototypeOf(_this,BabelRegExp.prototype)}function buildGroups(result,re){var g=_groups.get(re);return Object.keys(g).reduce((function(groups,name){var i=g[name];if("number"==typeof i)groups[name]=result[i];else{let k=0;for(;void 0===result[i[k]]&&k+1]+)>/g,(function(_,name){return"$"+groups[name]})))}if("function"==typeof substitution){var _this=this;return _super[Symbol.replace].call(this,str,(function(){var args=arguments;return"object"!=typeof args[args.length-1]&&(args=[].slice.call(args)).push(buildGroups(args,_this)),substitution.apply(this,args)}))}return _super[Symbol.replace].call(this,str,substitution)},_wrapRegExp.apply(this,arguments)}', ), }); diff --git a/packages/babel-helpers/src/helpers/wrapRegExp.js b/packages/babel-helpers/src/helpers/wrapRegExp.js index d8e110af2675..f852d9e6cf36 100644 --- a/packages/babel-helpers/src/helpers/wrapRegExp.js +++ b/packages/babel-helpers/src/helpers/wrapRegExp.js @@ -56,7 +56,16 @@ export default function _wrapRegExp() { var g = _groups.get(re); return Object.keys(g).reduce(function (groups, name) { - groups[name] = result[g[name]]; + var i = g[name]; + if (typeof i === "number") groups[name] = result[i]; + else { + // i is an array of indexes + let k = 0; + // if no group matched, we stop at k = i.length - 1 and then + // we store result[i[i.length - 1]] which is undefined. + while (result[i[k]] === undefined && k + 1 < i.length) k++; + groups[name] = result[i[k]]; + } return groups; }, Object.create(null)); } diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/.npmignore b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/.npmignore new file mode 100644 index 000000000000..f9806945836e --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/.npmignore @@ -0,0 +1,3 @@ +src +test +*.log diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/README.md b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/README.md new file mode 100644 index 000000000000..58fec2daa0d2 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/README.md @@ -0,0 +1,19 @@ +# @babel/plugin-proposal-duplicate-named-capturing-groups-regex + +> Compile regular expressions using duplicate named groups to index-based groups. + +See our website [@babel/plugin-proposal-duplicate-named-capturing-groups-regex](https://babeljs.io/docs/en/babel-plugin-proposal-duplicate-named-capturing-groups-regex) for more information. + +## Install + +Using npm: + +```sh +npm install --save-dev @babel/plugin-proposal-duplicate-named-capturing-groups-regex +``` + +or using yarn: + +```sh +yarn add @babel/plugin-proposal-duplicate-named-capturing-groups-regex --dev +``` diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/package.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/package.json new file mode 100644 index 000000000000..92c1c9fcca92 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/package.json @@ -0,0 +1,52 @@ +{ + "name": "@babel/plugin-proposal-duplicate-named-capturing-groups-regex", + "version": "7.18.6", + "description": "Compile regular expressions using duplicate named groups to index-based groups.", + "homepage": "https://babel.dev/docs/en/next/babel-plugin-proposal-duplicate-named-capturing-groups-regex", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "main": "./lib/index.js", + "keywords": [ + "babel-plugin", + "regex", + "regexp", + "regular expressions" + ], + "repository": { + "type": "git", + "url": "https://github.com/babel/babel.git", + "directory": "packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex" + }, + "bugs": "https://github.com/babel/babel/issues", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "workspace:^", + "@babel/helper-plugin-utils": "workspace:^" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + }, + "devDependencies": { + "@babel/core": "workspace:^", + "@babel/helper-plugin-test-runner": "workspace:^", + "core-js": "^3.22.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "author": "The Babel Team (https://babel.dev/team)", + "conditions": { + "USE_ESM": [ + { + "type": "module" + }, + null + ] + }, + "exports": { + ".": "./lib/index.js", + "./package.json": "./package.json" + }, + "type": "commonjs" +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/src/index.ts b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/src/index.ts new file mode 100644 index 000000000000..76d83980f495 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/src/index.ts @@ -0,0 +1,20 @@ +/* eslint-disable @babel/development/plugin-name */ +import { createRegExpFeaturePlugin } from "@babel/helper-create-regexp-features-plugin"; +import { declare } from "@babel/helper-plugin-utils"; + +export interface Options { + runtime?: boolean; +} + +export default declare((api, options: Options) => { + const { runtime } = options; + if (runtime !== undefined && typeof runtime !== "boolean") { + throw new Error("The 'runtime' option must be boolean"); + } + + return createRegExpFeaturePlugin({ + name: "proposal-duplicate-named-capturing-groups-regex", + feature: "duplicateNamedCaptureGroups", + options: { runtime }, + }); +}); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/input.js new file mode 100644 index 000000000000..b6b1233b66a9 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/input.js @@ -0,0 +1 @@ +/(?:(?\d\d\d\d)|(?\d\d))-(?\d\d)/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/output.js new file mode 100644 index 000000000000..f53db765b4ae --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/basic/output.js @@ -0,0 +1,5 @@ +/*#__PURE__*/ +babelHelpers.wrapRegExp(/(?:(\d\d\d\d)|(\d\d))\x2D(\d\d)/, { + year: [1, 2], + month: 3 +}); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/exec.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/exec.js new file mode 100644 index 000000000000..1347ef53e9f1 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/exec.js @@ -0,0 +1,5 @@ +let regexp = /(?a)|(?b)|c/; + +expect("a".match(regexp).groups).toEqual({ named: "a" }); +expect("b".match(regexp).groups).toEqual({ named: "b" }); +expect("c".match(regexp).groups).toEqual({ named: undefined }); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/options.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/options.json new file mode 100644 index 000000000000..cacf4d1974df --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["proposal-duplicate-named-capturing-groups-regex"] +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/input.js new file mode 100644 index 000000000000..873e6d6b0572 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/input.js @@ -0,0 +1 @@ +/(?:(?\d\d\d\d)|(?\d\d)) is \k/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/output.js new file mode 100644 index 000000000000..7351dd79a1e4 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/basic/output.js @@ -0,0 +1 @@ +/(?:(\d\d\d\d)|(\d\d)) is \1\2/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/options.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/options.json new file mode 100644 index 000000000000..d254b9b39da5 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/options.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + ["proposal-duplicate-named-capturing-groups-regex", { "runtime": false }] + ] +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/input.js new file mode 100644 index 000000000000..1d1628ac0978 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/input.js @@ -0,0 +1 @@ +/(?\d\d\d\d) is \k/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/output.js new file mode 100644 index 000000000000..1d1628ac0978 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-not-transformed/output.js @@ -0,0 +1 @@ +/(?\d\d\d\d) is \k/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/input.js new file mode 100644 index 000000000000..1d1628ac0978 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/input.js @@ -0,0 +1 @@ +/(?\d\d\d\d) is \k/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/options.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/options.json new file mode 100644 index 000000000000..247156232ea5 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["proposal-duplicate-named-capturing-groups-regex", { "runtime": false }], + ["transform-named-capturing-groups-regex", { "runtime": false }] + ] +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/output.js new file mode 100644 index 000000000000..cac0bdaaf258 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/syntax/unique-name-with-named-groups-plugin/output.js @@ -0,0 +1 @@ +/(\d\d\d\d) is \1/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/input.js new file mode 100644 index 000000000000..2761445e091b --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/input.js @@ -0,0 +1 @@ +"foo".match(/(?.)\k/); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/output.js new file mode 100644 index 000000000000..779aac3d8537 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/basic/output.js @@ -0,0 +1,3 @@ +"foo".match( /*#__PURE__*/babelHelpers.wrapRegExp(/(.)\1/, { + double: 1 +})); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/input.js new file mode 100644 index 000000000000..00a7c78b9344 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/input.js @@ -0,0 +1 @@ +/no-groups-\(?looks\)\u{10000}/u; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/options.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/options.json new file mode 100644 index 000000000000..148c4e8cb79c --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "transform-named-capturing-groups-regex", + "transform-unicode-regex" + ] +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/output.js new file mode 100644 index 000000000000..af299f8fceaf --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group-unicode/output.js @@ -0,0 +1 @@ +/no\x2Dgroups\x2D\(?looks\)(?:\uD800\uDC00)/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/input.js new file mode 100644 index 000000000000..4c55ef0dbe17 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/input.js @@ -0,0 +1 @@ +/no-groups-\(?looks\)/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/output.js new file mode 100644 index 000000000000..6fe7c2ef533c --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/looks-like-a-group/output.js @@ -0,0 +1 @@ +/no\x2Dgroups\x2D\(?looks\)/; diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/input.js new file mode 100644 index 000000000000..581032632ae1 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/input.js @@ -0,0 +1 @@ +"foo".match(/(.)\1/); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/output.js new file mode 100644 index 000000000000..c545e42ac5ca --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/only-when-named-groups/output.js @@ -0,0 +1 @@ +"foo".match(/(.)\1/); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/options.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/options.json new file mode 100644 index 000000000000..8b8fe93e5deb --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-named-capturing-groups-regex"] +} diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/input.js new file mode 100644 index 000000000000..86639f6f7e17 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/input.js @@ -0,0 +1 @@ +"abba".match(/(.)(?.)\k\1/); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/output.js new file mode 100644 index 000000000000..16f5e24236b2 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/skips-anonymous-capturing-groups/output.js @@ -0,0 +1,3 @@ +"abba".match( /*#__PURE__*/babelHelpers.wrapRegExp(/(.)(.)\2\1/, { + n: 2 +})); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/input.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/input.js new file mode 100644 index 000000000000..3e26e4ee498a --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/input.js @@ -0,0 +1 @@ +/^(?.)\k$/.test("aa"); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/output.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/output.js new file mode 100644 index 000000000000..808fc64e4f90 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/wrapper/test-method/output.js @@ -0,0 +1 @@ +/^(.)\1$/.test("aa"); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/index.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/index.js new file mode 100644 index 000000000000..21a55ce6b5e7 --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/index.js @@ -0,0 +1,3 @@ +import runner from "@babel/helper-plugin-test-runner"; + +runner(import.meta.url); diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/package.json b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/package.json new file mode 100644 index 000000000000..5ffd9800b97c --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/package.json @@ -0,0 +1 @@ +{ "type": "module" } diff --git a/packages/babel-plugin-transform-named-capturing-groups-regex/src/index.ts b/packages/babel-plugin-transform-named-capturing-groups-regex/src/index.ts index 0cd52bba1b09..f81e9867cada 100644 --- a/packages/babel-plugin-transform-named-capturing-groups-regex/src/index.ts +++ b/packages/babel-plugin-transform-named-capturing-groups-regex/src/index.ts @@ -7,8 +7,8 @@ export interface Options { } export default declare((api, options: Options) => { - const { runtime = true } = options; - if (typeof runtime !== "boolean") { + const { runtime } = options; + if (runtime !== undefined && typeof runtime !== "boolean") { throw new Error("The 'runtime' option must be boolean"); } diff --git a/yarn.lock b/yarn.lock index 8bc9ef5373e4..9c50928b21fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -317,7 +317,7 @@ __metadata: gensync: ^1.0.0-beta.2 json5: ^2.2.1 semver: ^6.3.0 - checksum: c7ee5b2c10bc5b0325e31fb5da4cb4bc03f9d5f5c00ec3481a018917bcc6b7b040de0690c606a424f57e5fc26d218d64e7718d0e5d7d8614d39c8cd898fab9b3 + checksum: bcc057bf6edbc4299bc759a292686d48e76d18617adb2327b38667a4972bb2ab1527c23b51168b37183d2fdb4218ac1f18319466d2c30837d469e9136dfd0dab languageName: node linkType: hard @@ -452,7 +452,7 @@ __metadata: "@babel/types": ^7.18.13 "@jridgewell/gen-mapping": ^0.3.2 jsesc: ^2.5.1 - checksum: 27f5e7eb774e4d76ee75dc96e3e1bd26cc0ee7cea13a8f7342b716319c0a4d4e26fc49aa8f19316f7c99383da55eeb2a866c6e034e9deacad58a9de9ed6004fb + checksum: b98ef678ad07bc3af76a041517ce49cc9a5ed0b943e4359aa86af3320a0b0525f9d902cbf1969b37d0bf104bcd89af31c2f35408b8dabff038543d281b416733 languageName: node linkType: hard @@ -569,7 +569,7 @@ __metadata: "@babel/helper-split-export-declaration": ^7.18.6 peerDependencies: "@babel/core": ^7.0.0 - checksum: 3d2da92a54b885b211a747a8c553bb0190895d140cd1daab5d9945b2b271817d9d288a512364085e9fad19bd503921cd85fcc12f98df67b39b27f5655eb9d058 + checksum: 000fb88ef4cc674a08d0b4f7b76db52e3f72fb0f0128d4881c140f640da2a8819601f1646e9956f7b6359d2d0b4ef155821c63f8f352c761ea82fff8e9ff7dc9 languageName: node linkType: hard @@ -1097,7 +1097,7 @@ __metadata: resolution: "@babel/parser@npm:7.18.13" bin: parser: ./bin/babel-parser.js - checksum: 8b41c35607668495d67d9a7c5f61768aaab26acf887efdadc2781aed54046981480ef40aeda0b84d61aed02cf0c4ff4b028d5f83ab85e17e2ddff318f9243b8b + checksum: e4d14756503a0f42936b7b1fa1bf8ece6208e56cd9b0294b51bb2ad37796dac6cc8cc912d4fcbc7cc82d7ac0aed4febb1dde0197caacca160e7ae153e93ffe69 languageName: node linkType: hard @@ -1358,6 +1358,20 @@ __metadata: languageName: unknown linkType: soft +"@babel/plugin-proposal-duplicate-named-capturing-groups-regex@workspace:packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex": + version: 0.0.0-use.local + resolution: "@babel/plugin-proposal-duplicate-named-capturing-groups-regex@workspace:packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex" + dependencies: + "@babel/core": "workspace:^" + "@babel/helper-create-regexp-features-plugin": "workspace:^" + "@babel/helper-plugin-test-runner": "workspace:^" + "@babel/helper-plugin-utils": "workspace:^" + core-js: ^3.22.1 + peerDependencies: + "@babel/core": ^7.0.0 + languageName: unknown + linkType: soft + "@babel/plugin-proposal-dynamic-import@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-proposal-dynamic-import@npm:7.18.6" @@ -2347,7 +2361,7 @@ __metadata: "@babel/helper-plugin-utils": ^7.18.9 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 83e44ec93a4cfbf69376db8836d00ec803820081bf0f8b6cea73a9b3cd320b8285768d5b385744af4a27edda4b6502245c52d3ed026ea61356faf57bfe78effb + checksum: a1e49ee0279234d61721b4099b6ddd37b528bdaa4fa4186e41f8408bfd6b54f61af9148ffd0725346c88713ca5a826e0460e08fe379dfa03ce65001432d88790 languageName: node linkType: hard @@ -3741,7 +3755,7 @@ __metadata: "@babel/types": ^7.18.13 debug: ^4.1.0 globals: ^11.1.0 - checksum: 1a2ef738fac4968feba6385787a3f8f7357d08e7739ecc5b37d8ff5668935253a03290f700f02a85ccfd369d5898625f0722d7733bff2ef91504f6cd8b836f19 + checksum: 6b31fd3ab79131b8830c5fede49eb2687ff3e1ee1527a77ee476274188a6ecfda65665a6d5759c6cb5469b798d0b28b4cf3df1ea3bb55f11946e8eea30c746a8 languageName: node linkType: hard @@ -3770,7 +3784,7 @@ __metadata: "@babel/helper-string-parser": ^7.18.10 "@babel/helper-validator-identifier": ^7.18.6 to-fast-properties: ^2.0.0 - checksum: abc3ad1f3b6864df0ea0e778bcdf7d2c5ee2293811192962d50e8a8c05c1aeec90a48275f53b2a45aad882ed8bef9477ae1f8e70ac1d44d039e14930d1388dcc + checksum: 1505b9cc1100da3876401c9c282dc266091a90e2732be7a0b3028d3e56046f079ff12c6d7b026f4ab3894fbfec9116122a0d5920352628b1cf11db30a2d91c39 languageName: node linkType: hard