Skip to content

Commit b7fad2b

Browse files
feat: prefer-regex-literals support v flag (#17410)
* feat: `prefer-regex-literals` support `v` flag * Update tests/lib/rules/prefer-regex-literals.js Co-authored-by: Milos Djermanovic <[email protected]> --------- Co-authored-by: Milos Djermanovic <[email protected]>
1 parent a6a3ad4 commit b7fad2b

3 files changed

Lines changed: 191 additions & 5 deletions

File tree

lib/rules/prefer-regex-literals.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ module.exports = {
241241
/**
242242
* Returns a ecmaVersion compatible for regexpp.
243243
* @param {number} ecmaVersion The ecmaVersion to convert.
244-
* @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
244+
* @returns {import("@eslint-community/regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
245245
*/
246246
function getRegexppEcmaVersion(ecmaVersion) {
247247
if (ecmaVersion <= 5) {
@@ -297,7 +297,10 @@ module.exports = {
297297
const validator = new RegExpValidator({ ecmaVersion: regexppEcmaVersion });
298298

299299
try {
300-
validator.validatePattern(pattern, 0, pattern.length, flags ? flags.includes("u") : false);
300+
validator.validatePattern(pattern, 0, pattern.length, {
301+
unicode: flags ? flags.includes("u") : false,
302+
unicodeSets: flags ? flags.includes("v") : false
303+
});
301304
if (flags) {
302305
validator.validateFlags(flags);
303306
}
@@ -461,7 +464,10 @@ module.exports = {
461464
if (regexContent && !noFix) {
462465
let charIncrease = 0;
463466

464-
const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
467+
const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, {
468+
unicode: flags ? flags.includes("u") : false,
469+
unicodeSets: flags ? flags.includes("v") : false
470+
});
465471

466472
visitRegExpAST(ast, {
467473
onCharacterEnter(characterNode) {

lib/rules/utils/regular-expressions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
const { RegExpValidator } = require("@eslint-community/regexpp");
1010

11-
const REGEXPP_LATEST_ECMA_VERSION = 2022;
11+
const REGEXPP_LATEST_ECMA_VERSION = 2024;
1212

1313
/**
1414
* Checks if the given regular expression pattern would be valid with the `u` flag.

tests/lib/rules/prefer-regex-literals.js

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ ruleTester.run("prefer-regex-literals", rule, {
134134
{
135135
code: "class C { #RegExp; foo() { globalThis.#RegExp('a'); } }",
136136
env: { es2020: true }
137-
}
137+
},
138+
139+
// ES2024
140+
"new RegExp('[[A--B]]' + a, 'v')"
138141
],
139142

140143
invalid: [
@@ -2808,6 +2811,183 @@ ruleTester.run("prefer-regex-literals", rule, {
28082811
suggestions: null
28092812
}
28102813
]
2814+
},
2815+
2816+
// ES2024
2817+
{
2818+
code: "new RegExp('[[A--B]]', 'v')",
2819+
parserOptions: { ecmaVersion: 2024 },
2820+
errors: [
2821+
{
2822+
messageId: "unexpectedRegExp",
2823+
suggestions: [
2824+
{
2825+
messageId: "replaceWithLiteral",
2826+
output: "/[[A--B]]/v"
2827+
}
2828+
]
2829+
}
2830+
]
2831+
},
2832+
{
2833+
code: "new RegExp('[[A--B]]', 'v')",
2834+
parserOptions: { ecmaVersion: 2023 },
2835+
errors: [
2836+
{
2837+
messageId: "unexpectedRegExp",
2838+
suggestions: null
2839+
}
2840+
]
2841+
},
2842+
{
2843+
code: "new RegExp('[[A&&&]]', 'v')",
2844+
parserOptions: { ecmaVersion: 2024 },
2845+
errors: [
2846+
{
2847+
messageId: "unexpectedRegExp",
2848+
suggestions: null
2849+
}
2850+
]
2851+
},
2852+
{
2853+
code: "new RegExp('a', 'uv')",
2854+
parserOptions: { ecmaVersion: 2024 },
2855+
errors: [
2856+
{
2857+
messageId: "unexpectedRegExp",
2858+
suggestions: null
2859+
}
2860+
]
2861+
},
2862+
{
2863+
code: "new RegExp(/a/, 'v')",
2864+
options: [{ disallowRedundantWrapping: true }],
2865+
parserOptions: { ecmaVersion: 2024 },
2866+
errors: [
2867+
{
2868+
messageId: "unexpectedRedundantRegExpWithFlags",
2869+
suggestions: [
2870+
{
2871+
messageId: "replaceWithLiteralAndFlags",
2872+
output: "/a/v",
2873+
data: {
2874+
flags: "v"
2875+
}
2876+
}
2877+
]
2878+
}
2879+
]
2880+
},
2881+
{
2882+
code: "new RegExp(/a/, 'v')",
2883+
options: [{ disallowRedundantWrapping: true }],
2884+
parserOptions: { ecmaVersion: 2023 },
2885+
errors: [
2886+
{
2887+
messageId: "unexpectedRedundantRegExpWithFlags",
2888+
suggestions: null
2889+
}
2890+
]
2891+
},
2892+
{
2893+
code: "new RegExp(/a/g, 'v')",
2894+
options: [{ disallowRedundantWrapping: true }],
2895+
parserOptions: { ecmaVersion: 2024 },
2896+
errors: [
2897+
{
2898+
messageId: "unexpectedRedundantRegExpWithFlags",
2899+
suggestions: [
2900+
{
2901+
messageId: "replaceWithLiteralAndFlags",
2902+
output: "/a/v",
2903+
data: {
2904+
flags: "v"
2905+
}
2906+
},
2907+
{
2908+
messageId: "replaceWithIntendedLiteralAndFlags",
2909+
output: "/a/gv",
2910+
data: {
2911+
flags: "gv"
2912+
}
2913+
}
2914+
]
2915+
}
2916+
]
2917+
},
2918+
{
2919+
code: "new RegExp(/[[A--B]]/v, 'g')",
2920+
options: [{ disallowRedundantWrapping: true }],
2921+
parserOptions: { ecmaVersion: 2024 },
2922+
errors: [
2923+
{
2924+
messageId: "unexpectedRedundantRegExpWithFlags",
2925+
suggestions: [
2926+
{
2927+
messageId: "replaceWithIntendedLiteralAndFlags",
2928+
output: "/[[A--B]]/vg",
2929+
data: {
2930+
flags: "vg"
2931+
}
2932+
}
2933+
2934+
// suggestion with flags `g` would be invalid
2935+
]
2936+
}
2937+
]
2938+
},
2939+
{
2940+
code: "new RegExp(/a/u, 'v')",
2941+
options: [{ disallowRedundantWrapping: true }],
2942+
parserOptions: { ecmaVersion: 2024 },
2943+
errors: [
2944+
{
2945+
messageId: "unexpectedRedundantRegExpWithFlags",
2946+
suggestions: [
2947+
{
2948+
messageId: "replaceWithLiteralAndFlags",
2949+
output: "/a/v",
2950+
data: {
2951+
flags: "v"
2952+
}
2953+
}
2954+
2955+
// suggestion with merged flags `uv` would be invalid
2956+
]
2957+
}
2958+
]
2959+
},
2960+
{
2961+
code: "new RegExp(/a/v, 'u')",
2962+
options: [{ disallowRedundantWrapping: true }],
2963+
parserOptions: { ecmaVersion: 2024 },
2964+
errors: [
2965+
{
2966+
messageId: "unexpectedRedundantRegExpWithFlags",
2967+
suggestions: [
2968+
{
2969+
messageId: "replaceWithLiteralAndFlags",
2970+
output: "/a/u",
2971+
data: {
2972+
flags: "u"
2973+
}
2974+
}
2975+
2976+
// suggestion with merged flags `vu` would be invalid
2977+
]
2978+
}
2979+
]
2980+
},
2981+
{
2982+
code: "new RegExp(/[[A--B]]/v, 'u')",
2983+
options: [{ disallowRedundantWrapping: true }],
2984+
parserOptions: { ecmaVersion: 2024 },
2985+
errors: [
2986+
{
2987+
messageId: "unexpectedRedundantRegExpWithFlags",
2988+
suggestions: null
2989+
}
2990+
]
28112991
}
28122992
]
28132993
});

0 commit comments

Comments
 (0)