Skip to content

Commit 90e382d

Browse files
authored
Add es-x/no-regexp-modifiers rule (#208)
1 parent 8d6bff8 commit 90e382d

File tree

8 files changed

+156
-2
lines changed

8 files changed

+156
-2
lines changed

docs/rules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ There is a config that enables the rules in this category: [`no-new-in-esnext`]
1111
| Rule ID | Description | |
1212
|:--------|:------------|:--:|
1313
| [es-x/no-regexp-duplicate-named-capturing-groups](./no-regexp-duplicate-named-capturing-groups.md) | disallow RegExp duplicate named capturing groups. | |
14+
| [es-x/no-regexp-modifiers](./no-regexp-modifiers.md) | disallow RegExp Modifiers. | |
1415
| [es-x/no-set-prototype-difference](./no-set-prototype-difference.md) | disallow the `Set.prototype.difference` method. | |
1516
| [es-x/no-set-prototype-intersection](./no-set-prototype-intersection.md) | disallow the `Set.prototype.intersection` method. | |
1617
| [es-x/no-set-prototype-isdisjointfrom](./no-set-prototype-isdisjointfrom.md) | disallow the `Set.prototype.isDisjointFrom` method. | |

docs/rules/no-regexp-modifiers.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: "es-x/no-regexp-modifiers"
3+
description: "disallow RegExp Modifiers"
4+
---
5+
6+
# es-x/no-regexp-modifiers
7+
> disallow RegExp Modifiers
8+
9+
- ❗ <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
10+
- ✅ The following configurations enable this rule: [no-new-in-esnext]
11+
12+
This rule reports ES2025 [RegExp Modifiers](https://github.com/tc39/proposal-regexp-modifiers) as errors.
13+
14+
## 💡 Examples
15+
16+
⛔ Examples of **incorrect** code for this rule:
17+
18+
<eslint-playground type="bad">
19+
20+
```js
21+
/*eslint es-x/no-regexp-modifiers: error */
22+
const re1 = /^[a-z](?-i:[a-z])$/i;
23+
const re2 = /^(?i:[a-z])[a-z]$/;
24+
```
25+
26+
</eslint-playground>
27+
28+
## 📚 References
29+
30+
- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-regexp-modifiers.js)
31+
- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-regexp-modifiers.js)
32+
33+
[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext

lib/configs/flat/no-new-in-esnext.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
},
1313
rules: {
1414
"es-x/no-regexp-duplicate-named-capturing-groups": "error",
15+
"es-x/no-regexp-modifiers": "error",
1516
"es-x/no-set-prototype-difference": "error",
1617
"es-x/no-set-prototype-intersection": "error",
1718
"es-x/no-set-prototype-isdisjointfrom": "error",

lib/configs/no-new-in-esnext.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
plugins: ["es-x"],
99
rules: {
1010
"es-x/no-regexp-duplicate-named-capturing-groups": "error",
11+
"es-x/no-regexp-modifiers": "error",
1112
"es-x/no-set-prototype-difference": "error",
1213
"es-x/no-set-prototype-intersection": "error",
1314
"es-x/no-set-prototype-isdisjointfrom": "error",

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ module.exports = {
297297
"no-regexp-d-flag": require("./rules/no-regexp-d-flag"),
298298
"no-regexp-duplicate-named-capturing-groups": require("./rules/no-regexp-duplicate-named-capturing-groups"),
299299
"no-regexp-lookbehind-assertions": require("./rules/no-regexp-lookbehind-assertions"),
300+
"no-regexp-modifiers": require("./rules/no-regexp-modifiers"),
300301
"no-regexp-named-capture-groups": require("./rules/no-regexp-named-capture-groups"),
301302
"no-regexp-prototype-compile": require("./rules/no-regexp-prototype-compile"),
302303
"no-regexp-prototype-flags": require("./rules/no-regexp-prototype-flags"),

lib/rules/no-regexp-modifiers.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"use strict"
2+
3+
const { getSourceCode } = require("eslint-compat-utils")
4+
const { defineRegExpHandler } = require("../util/define-regexp-handler")
5+
6+
module.exports = {
7+
meta: {
8+
docs: {
9+
description: "disallow RegExp Modifiers.",
10+
category: "ES2025",
11+
recommended: false,
12+
url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-regexp-modifiers.html",
13+
},
14+
fixable: null,
15+
messages: {
16+
forbidden: "ES2025 RegExp Modifiers are forbidden.",
17+
},
18+
schema: [],
19+
type: "problem",
20+
},
21+
create(context) {
22+
return defineRegExpHandler(context, (node) => {
23+
const found = []
24+
return {
25+
onPatternEnter() {
26+
found.length = 0
27+
},
28+
onModifiersLeave(start, end) {
29+
found.push({ start, end })
30+
},
31+
onExit() {
32+
for (const { start, end } of found) {
33+
const sourceCode = getSourceCode(context)
34+
context.report({
35+
node,
36+
loc:
37+
node.type === "Literal"
38+
? {
39+
start: sourceCode.getLocFromIndex(
40+
node.range[0] +
41+
1 /* slash */ +
42+
start,
43+
),
44+
end: sourceCode.getLocFromIndex(
45+
node.range[0] +
46+
1 /* slash */ +
47+
end,
48+
),
49+
}
50+
: null,
51+
messageId: "forbidden",
52+
})
53+
}
54+
},
55+
}
56+
})
57+
},
58+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
},
1515
"dependencies": {
1616
"@eslint-community/eslint-utils": "^4.1.2",
17-
"@eslint-community/regexpp": "^4.11.0",
17+
"@eslint-community/regexpp": "^4.12.1",
1818
"eslint-compat-utils": "^0.5.1"
1919
},
2020
"devDependencies": {
@@ -26,7 +26,7 @@
2626
"eslint-plugin-n": "^17.8.1",
2727
"eslint-plugin-prettier": "^5.0.0",
2828
"eslint-plugin-vue": "^9.25.0",
29-
"espree": "^10.1.0",
29+
"espree": "^10.3.0",
3030
"globals": "^15.0.0",
3131
"jsdom": "^25.0.0",
3232
"mocha": "^10.0.0",
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"use strict"
2+
3+
const RuleTester = require("../../tester")
4+
const rule = require("../../../lib/rules/no-regexp-modifiers.js")
5+
6+
if (!RuleTester.isSupported(2025)) {
7+
//eslint-disable-next-line no-console
8+
console.log("Skip the tests of no-regexp-modifiers.")
9+
return
10+
}
11+
12+
new RuleTester().run("no-regexp-modifiers", rule, {
13+
valid: [
14+
String.raw`/(a)/i`,
15+
String.raw`/(?:a)/i`,
16+
String.raw`/(?<x>a)/`,
17+
String.raw`new RegExp("(a)", "i")`,
18+
String.raw`new RegExp("(?:a)", "i")`,
19+
String.raw`new RegExp("(?<x>a)")`,
20+
],
21+
invalid: [
22+
{
23+
code: String.raw`/(?m:a)/i`,
24+
errors: [
25+
{
26+
message: "ES2025 RegExp Modifiers are forbidden.",
27+
column: 4,
28+
},
29+
],
30+
},
31+
{
32+
code: String.raw`/(?m-i:a)/i`,
33+
errors: [
34+
{
35+
message: "ES2025 RegExp Modifiers are forbidden.",
36+
column: 4,
37+
},
38+
],
39+
},
40+
{
41+
code: String.raw`/(?m-:a)/i`,
42+
errors: [
43+
{
44+
message: "ES2025 RegExp Modifiers are forbidden.",
45+
column: 4,
46+
},
47+
],
48+
},
49+
{
50+
code: String.raw`/(?-i:a)/i`,
51+
errors: [
52+
{
53+
message: "ES2025 RegExp Modifiers are forbidden.",
54+
column: 4,
55+
},
56+
],
57+
},
58+
],
59+
})

0 commit comments

Comments
 (0)