Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support regexp modifiers proposal #15226

Merged
merged 10 commits into from Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line of code was copied from another plugin, I'm not sure what it does.😞

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This plugin doesn't technically require @babel/core 7.19.0, but hopefully this will encourage people to upgrade 😉


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