From 7968d4a19963dd87d6deda94aad8a659504dd77f Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 28 Oct 2022 12:26:41 -0700 Subject: [PATCH] Handle multiple named groups in wrapRegExp replace() Previously, the [Symbol.replace] implementation in BabelRegExp assumed that the groups object property values were only numbers. With the duplicate named capturing groups plugin, they can be arrays of numbers as well. In the case of a duplicate named capturing group, the replacement pattern $ can be replaced by the concatenation of the pattern indices that have that name: e.g., $1$2. --- packages/babel-helpers/src/helpers-generated.ts | 2 +- packages/babel-helpers/src/helpers/wrapRegExp.js | 3 ++- .../test/fixtures/runtime/replace.js | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/replace.js diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index 868853fe138c..79c85f6243c5 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -59,6 +59,6 @@ export default Object.freeze({ ), wrapRegExp: helper( "7.19.0", - '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{for(var k=0;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)}', + '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{for(var k=0;void 0===result[i[k]]&&k+1]+)>/g,(function(_,name){var group=groups[name];return"$"+(Array.isArray(group)?group.join("$"):group)})))}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 8d82f4f7d781..12df17bff2c2 100644 --- a/packages/babel-helpers/src/helpers/wrapRegExp.js +++ b/packages/babel-helpers/src/helpers/wrapRegExp.js @@ -31,7 +31,8 @@ export default function _wrapRegExp() { this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) { - return "$" + groups[name]; + var group = groups[name]; + return "$" + (Array.isArray(group) ? group.join("$") : group); }) ); } else if (typeof substitution === "function") { diff --git a/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/replace.js b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/replace.js new file mode 100644 index 000000000000..92c0d1dff1bb --- /dev/null +++ b/packages/babel-plugin-proposal-duplicate-named-capturing-groups-regex/test/fixtures/runtime/replace.js @@ -0,0 +1,5 @@ +let regexp = /(?a)|(?b)|c/; + +expect("a".replace(regexp, "[$]")).toEqual("[a]"); +expect("b".replace(regexp, "[$]")).toEqual("[b]"); +expect("c".replace(regexp, "[$]")).toEqual("[]");