Skip to content

Commit

Permalink
feat: Support regexp modifiers proposal (#15226)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
  • Loading branch information
liuxingbaoyu and nicolo-ribaudo committed Feb 20, 2023
1 parent c292e68 commit 79e1452
Show file tree
Hide file tree
Showing 26 changed files with 182 additions and 25 deletions.
2 changes: 2 additions & 0 deletions lib/regexpu-core.d.ts
Expand Up @@ -6,6 +6,8 @@ declare module "regexpu-core" {
unicodePropertyEscapes?: "transform" | false;
namedGroups?: "transform" | false;
onNamedGroup?: (name: string, index: number) => void;
modifiers?: "transform" | false;
onNewFlags?: (name: string) => void;
};
function rewritePattern(
pattern: string,
Expand Down
Expand Up @@ -19,7 +19,7 @@
],
"dependencies": {
"@babel/helper-annotate-as-pure": "workspace:^",
"regexpu-core": "^5.2.1"
"regexpu-core": "^5.3.1"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
Expand Down
Expand Up @@ -6,6 +6,7 @@ export const FEATURES = Object.freeze({
unicodeSetsFlag_syntax: 1 << 4,
unicodeSetsFlag: 1 << 5,
duplicateNamedCaptureGroups: 1 << 6,
modifiers: 1 << 7,
});

// We can't use a symbol because this needs to always be the same, even if
Expand Down
Expand Up @@ -116,6 +116,13 @@ export function createRegExpFeaturePlugin({
};
}

let newFlags;
if (regexpuOptions.modifiers === "transform") {
regexpuOptions.onNewFlags = flags => {
newFlags = flags;
};
}

node.pattern = rewritePattern(node.pattern, node.flags, regexpuOptions);

if (
Expand All @@ -133,7 +140,7 @@ export function createRegExpFeaturePlugin({
path.replaceWith(call);
}

node.flags = transformFlags(regexpuOptions, node.flags);
node.flags = transformFlags(regexpuOptions, newFlags ?? node.flags);
},
},
};
Expand Down
Expand Up @@ -40,6 +40,7 @@ export function generateRegexpuOptions(
unicodePropertyEscapes: feat("unicodePropertyEscape"),
namedGroups: feat("namedCaptureGroups") || featDuplicateNamedGroups(),
onNamedGroup: () => {},
modifiers: feat("modifiers"),
};
}

Expand Down Expand Up @@ -71,6 +72,10 @@ export function canSkipRegexpu(
return false;
}

if (options.modifiers === "transform" && /\(\?[\w-]+:/.test(pattern)) {
return false;
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions packages/babel-plugin-proposal-regexp-modifiers/.npmignore
@@ -0,0 +1,3 @@
src
test
*.log
19 changes: 19 additions & 0 deletions packages/babel-plugin-proposal-regexp-modifiers/README.md
@@ -0,0 +1,19 @@
# @babel/plugin-proposal-regexp-modifiers

> Compile regular expressions using duplicate named groups to index-based groups.
See our website [@babel/plugin-proposal-regexp-modifiers](https://babeljs.io/docs/en/babel-plugin-proposal-regexp-modifiers) for more information.

## Install

Using npm:

```sh
npm install --save-dev @babel/plugin-proposal-regexp-modifiers
```

or using yarn:

```sh
yarn add @babel/plugin-proposal-regexp-modifiers --dev
```
50 changes: 50 additions & 0 deletions packages/babel-plugin-proposal-regexp-modifiers/package.json
@@ -0,0 +1,50 @@
{
"name": "@babel/plugin-proposal-regexp-modifiers",
"version": "7.19.1",
"description": "Compile inline regular expression modifiers",
"homepage": "https://babel.dev/docs/en/next/babel-plugin-proposal-regexp-modifiers",
"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-regexp-modifiers"
},
"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:^"
},
"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"
}
12 changes: 12 additions & 0 deletions packages/babel-plugin-proposal-regexp-modifiers/src/index.ts
@@ -0,0 +1,12 @@
/* eslint-disable @babel/development/plugin-name */
import { createRegExpFeaturePlugin } from "@babel/helper-create-regexp-features-plugin";
import { declare } from "@babel/helper-plugin-utils";

export default declare(api => {
api.assertVersion("^7.19.0");

return createRegExpFeaturePlugin({
name: "proposal-regexp-modifiers",
feature: "modifiers",
});
});
@@ -0,0 +1,3 @@
let regex = /(?ims:^[a-z])/u;

expect(regex.test("\u017F")).toBeTruthy();
@@ -0,0 +1,2 @@
/(?ims:^[a-z])/u;
/(?-ims:^[a-z].)(^[a-z].)/uims;
@@ -0,0 +1,4 @@
{
"plugins": ["proposal-regexp-modifiers", "transform-unicode-regex"],
"minNodeVersion": "8.0.0"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,11 @@
let regex = /(?ims:^[a-z].1$)/

expect(regex.test("Ax1")).toBeTruthy();
expect(regex.test("ax1")).toBeTruthy();
expect(regex.test("ax2")).toBeFalsy();
expect(regex.test("1ax1")).toBeFalsy();

expect(regex.test("a\r1")).toBeTruthy();
expect(regex.test("a\r\n1")).toBeFalsy();

expect(regex.test("\nax1\n\n\n\n\n\n\n\n\n")).toBeTruthy();
@@ -0,0 +1,4 @@
{
"plugins": ["proposal-regexp-modifiers"],
"minNodeVersion": "8.0.0"
}
@@ -0,0 +1,2 @@
/(?ims:^[a-z]1$)/;
/(?-ims:^[a-z].1$)(^[a-z].)/ims;
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-regexp-modifiers"]
}
@@ -0,0 +1,2 @@
/(?:(?:^|(?<=[\n\r\u2028\u2029]))[A-Za-z]1(?:$|(?=[\n\r\u2028\u2029])))/;
/(?:^[a-z].1$)((?:^|(?<=[\n\r\u2028\u2029]))[A-Za-z][\s\S])/;
3 changes: 3 additions & 0 deletions packages/babel-plugin-proposal-regexp-modifiers/test/index.js
@@ -0,0 +1,3 @@
import runner from "@babel/helper-plugin-test-runner";

runner(import.meta.url);
@@ -0,0 +1 @@
{ "type": "module" }
1 change: 1 addition & 0 deletions packages/babel-standalone/package.json
Expand Up @@ -35,6 +35,7 @@
"@babel/plugin-proposal-private-methods": "workspace:^",
"@babel/plugin-proposal-private-property-in-object": "workspace:^",
"@babel/plugin-proposal-record-and-tuple": "workspace:^",
"@babel/plugin-proposal-regexp-modifiers": "workspace:^",
"@babel/plugin-proposal-throw-expressions": "workspace:^",
"@babel/plugin-proposal-unicode-property-regex": "workspace:^",
"@babel/plugin-proposal-unicode-sets-regex": "workspace:^",
Expand Down
1 change: 1 addition & 0 deletions packages/babel-standalone/scripts/pluginConfig.json
Expand Up @@ -59,6 +59,7 @@
"proposal-private-methods",
"proposal-private-property-in-object",
"proposal-record-and-tuple",
"proposal-regexp-modifiers",
"proposal-throw-expressions",
"proposal-unicode-property-regex",
"proposal-unicode-sets-regex",
Expand Down
3 changes: 3 additions & 0 deletions packages/babel-standalone/src/generated/plugins.ts
Expand Up @@ -43,6 +43,7 @@ import proposalPipelineOperator from "@babel/plugin-proposal-pipeline-operator";
import proposalPrivateMethods from "@babel/plugin-proposal-private-methods";
import proposalPrivatePropertyInObject from "@babel/plugin-proposal-private-property-in-object";
import proposalRecordAndTuple from "@babel/plugin-proposal-record-and-tuple";
import proposalRegexpModifiers from "@babel/plugin-proposal-regexp-modifiers";
import proposalThrowExpressions from "@babel/plugin-proposal-throw-expressions";
import proposalUnicodePropertyRegex from "@babel/plugin-proposal-unicode-property-regex";
import proposalUnicodeSetsRegex from "@babel/plugin-proposal-unicode-sets-regex";
Expand Down Expand Up @@ -145,6 +146,7 @@ export {
proposalPrivateMethods,
proposalPrivatePropertyInObject,
proposalRecordAndTuple,
proposalRegexpModifiers,
proposalThrowExpressions,
proposalUnicodePropertyRegex,
proposalUnicodeSetsRegex,
Expand Down Expand Up @@ -249,6 +251,7 @@ export const all: { [k: string]: any } = {
"proposal-private-methods": proposalPrivateMethods,
"proposal-private-property-in-object": proposalPrivatePropertyInObject,
"proposal-record-and-tuple": proposalRecordAndTuple,
"proposal-regexp-modifiers": proposalRegexpModifiers,
"proposal-throw-expressions": proposalThrowExpressions,
"proposal-unicode-property-regex": proposalUnicodePropertyRegex,
"proposal-unicode-sets-regex": proposalUnicodeSetsRegex,
Expand Down
35 changes: 17 additions & 18 deletions packages/babel-standalone/src/preset-stage-3.ts
Expand Up @@ -8,8 +8,7 @@ export default (_: any, opts: any = {}) => {
decoratorsBeforeExport,
} = opts;

// todo(flow->ts) improve types
const plugins: any[] = [
const plugins = [
babelPlugins.syntaxImportAssertions,
babelPlugins.proposalUnicodeSetsRegex,
babelPlugins.proposalDuplicateNamedCapturingGroupsRegex,
Expand All @@ -20,23 +19,23 @@ export default (_: any, opts: any = {}) => {
decoratorsBeforeExport,
},
],
];

if (!process.env.BABEL_8_BREAKING) {
babelPlugins.proposalRegexpModifiers,
// These are Stage 4
plugins.push(
babelPlugins.proposalExportNamespaceFrom,
babelPlugins.proposalLogicalAssignmentOperators,
[babelPlugins.proposalOptionalChaining, { loose }],
[babelPlugins.proposalNullishCoalescingOperator, { loose }],
[babelPlugins.proposalClassProperties, { loose }],
babelPlugins.proposalJsonStrings,
babelPlugins.proposalNumericSeparator,
[babelPlugins.proposalPrivateMethods, { loose }],
babelPlugins.proposalPrivatePropertyInObject,
babelPlugins.proposalClassStaticBlock,
);
}
...(process.env.BABEL_8_BREAKING
? []
: [
babelPlugins.proposalExportNamespaceFrom,
babelPlugins.proposalLogicalAssignmentOperators,
[babelPlugins.proposalOptionalChaining, { loose }],
[babelPlugins.proposalNullishCoalescingOperator, { loose }],
[babelPlugins.proposalClassProperties, { loose }],
babelPlugins.proposalJsonStrings,
babelPlugins.proposalNumericSeparator,
[babelPlugins.proposalPrivateMethods, { loose }],
babelPlugins.proposalPrivatePropertyInObject,
babelPlugins.proposalClassStaticBlock,
]),
];

return { plugins };
};
4 changes: 4 additions & 0 deletions tsconfig.json
Expand Up @@ -67,6 +67,7 @@
"./packages/babel-plugin-proposal-private-methods/src/**/*.ts",
"./packages/babel-plugin-proposal-private-property-in-object/src/**/*.ts",
"./packages/babel-plugin-proposal-record-and-tuple/src/**/*.ts",
"./packages/babel-plugin-proposal-regexp-modifiers/src/**/*.ts",
"./packages/babel-plugin-proposal-throw-expressions/src/**/*.ts",
"./packages/babel-plugin-proposal-unicode-property-regex/src/**/*.ts",
"./packages/babel-plugin-proposal-unicode-sets-regex/src/**/*.ts",
Expand Down Expand Up @@ -367,6 +368,9 @@
"@babel/plugin-proposal-record-and-tuple": [
"./packages/babel-plugin-proposal-record-and-tuple/src"
],
"@babel/plugin-proposal-regexp-modifiers": [
"./packages/babel-plugin-proposal-regexp-modifiers/src"
],
"@babel/plugin-proposal-throw-expressions": [
"./packages/babel-plugin-proposal-throw-expressions/src"
],
Expand Down
23 changes: 18 additions & 5 deletions yarn.lock
Expand Up @@ -636,7 +636,7 @@ __metadata:
"@babel/core": "workspace:^"
"@babel/helper-annotate-as-pure": "workspace:^"
"@babel/helper-plugin-test-runner": "workspace:^"
regexpu-core: ^5.2.1
regexpu-core: ^5.3.1
peerDependencies:
"@babel/core": ^7.0.0
languageName: unknown
Expand Down Expand Up @@ -1764,6 +1764,18 @@ __metadata:
languageName: unknown
linkType: soft

"@babel/plugin-proposal-regexp-modifiers@workspace:^, @babel/plugin-proposal-regexp-modifiers@workspace:packages/babel-plugin-proposal-regexp-modifiers":
version: 0.0.0-use.local
resolution: "@babel/plugin-proposal-regexp-modifiers@workspace:packages/babel-plugin-proposal-regexp-modifiers"
dependencies:
"@babel/core": "workspace:^"
"@babel/helper-create-regexp-features-plugin": "workspace:^"
"@babel/helper-plugin-utils": "workspace:^"
peerDependencies:
"@babel/core": ^7.0.0
languageName: unknown
linkType: soft

"@babel/plugin-proposal-throw-expressions@workspace:^, @babel/plugin-proposal-throw-expressions@workspace:packages/babel-plugin-proposal-throw-expressions":
version: 0.0.0-use.local
resolution: "@babel/plugin-proposal-throw-expressions@workspace:packages/babel-plugin-proposal-throw-expressions"
Expand Down Expand Up @@ -3683,6 +3695,7 @@ __metadata:
"@babel/plugin-proposal-private-methods": "workspace:^"
"@babel/plugin-proposal-private-property-in-object": "workspace:^"
"@babel/plugin-proposal-record-and-tuple": "workspace:^"
"@babel/plugin-proposal-regexp-modifiers": "workspace:^"
"@babel/plugin-proposal-throw-expressions": "workspace:^"
"@babel/plugin-proposal-unicode-property-regex": "workspace:^"
"@babel/plugin-proposal-unicode-sets-regex": "workspace:^"
Expand Down Expand Up @@ -13121,17 +13134,17 @@ fsevents@^1.2.7:
languageName: node
linkType: hard

"regexpu-core@npm:^5.2.1":
version: 5.3.0
resolution: "regexpu-core@npm:5.3.0"
"regexpu-core@npm:^5.2.1, regexpu-core@npm:^5.3.1":
version: 5.3.1
resolution: "regexpu-core@npm:5.3.1"
dependencies:
"@babel/regjsgen": ^0.8.0
regenerate: ^1.4.2
regenerate-unicode-properties: ^10.1.0
regjsparser: ^0.9.1
unicode-match-property-ecmascript: ^2.0.0
unicode-match-property-value-ecmascript: ^2.1.0
checksum: f3c7921543ebda919c53fdbbf3a9cebbecbf8ad65b30e423d7eaef35484e08cbc919f9e8334f4693a72206f583d4f2b48d4415483f6e6e8c81f0046e3a23c66f
checksum: 446fbbb79059afcd64d11ea573276e2df97ee7ad45aa452834d3b2aef7edf7bfe206c310f57f9345d8c95bfedbf9c16a9529f9219a05ae6a6b0d6f0dbe523b33
languageName: node
linkType: hard

Expand Down

0 comments on commit 79e1452

Please sign in to comment.