Skip to content

Commit 2262039

Browse files
authored
Fix wrong autofix for non-RegExp arguments in regexp/prefer-regexp-test rule (#125)
1 parent bc71379 commit 2262039

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

lib/rules/prefer-regexp-test.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@ export default createRule("prefer-regexp-test", {
4343
}
4444
const arg = node.arguments[0]
4545
const evaluated = getStaticValue(arg, context.getScope())
46-
if (
47-
evaluated &&
48-
evaluated.value instanceof RegExp &&
49-
evaluated.value.flags.includes("g")
50-
) {
51-
return
46+
let argIsRegExp = true
47+
if (evaluated && evaluated.value instanceof RegExp) {
48+
if (evaluated.value.flags.includes("g")) {
49+
return
50+
}
51+
} else if (!typeTracer.isRegExp(arg)) {
52+
// Not RegExp
53+
// String.prototype.match function allows non-RegExp arguments
54+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#a_non-regexp_object_as_the_parameter
55+
argIsRegExp = false
5256
}
5357

5458
const memberExpr = node.callee
@@ -57,6 +61,13 @@ export default createRule("prefer-regexp-test", {
5761
messageId: "disallow",
5862
data: { target: "String#match" },
5963
fix(fixer) {
64+
if (!argIsRegExp) {
65+
// If the argument is not RegExp, it will not be autofix.
66+
// Must use `new RegExp()` before fixing it.
67+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#a_non-regexp_object_as_the_parameter
68+
// When the regexp parameter is a string or a number, it is implicitly converted to a RegExp by using new RegExp(regexp).
69+
return null
70+
}
6071
if (
6172
node.arguments.length !== 1 ||
6273
hasSideEffect(memberExpr, sourceCode) ||

tests/lib/rules/prefer-regexp-test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,48 @@ tester.run("prefer-regexp-test", rule as any, {
143143
"Use the `RegExp#test()` method instead of `RegExp#exec`, if you need a boolean.",
144144
],
145145
},
146+
{
147+
code: `
148+
const text = 'something';
149+
if (text.match()) {}
150+
const pattern1 = 'some';
151+
if (text.match(pattern1)) {}
152+
const pattern2 = Infinity;
153+
if (text.match(pattern2)) {}
154+
`,
155+
output: null,
156+
errors: [
157+
"Use the `RegExp#test()` method instead of `String#match`, if you need a boolean.",
158+
"Use the `RegExp#test()` method instead of `String#match`, if you need a boolean.",
159+
],
160+
},
161+
{
162+
code: `
163+
const text = 'something';
164+
const pattern = getPattern();
165+
if (text.match(pattern)) {}
166+
`,
167+
output: null,
168+
errors: [
169+
"Use the `RegExp#test()` method instead of `String#match`, if you need a boolean.",
170+
],
171+
},
172+
{
173+
code: `
174+
const text = 'something';
175+
/** @type {RegExp} */
176+
const pattern = getPattern();
177+
if (text.match(pattern)) {}
178+
`,
179+
output: `
180+
const text = 'something';
181+
/** @type {RegExp} */
182+
const pattern = getPattern();
183+
if (pattern.test(text)) {}
184+
`,
185+
errors: [
186+
"Use the `RegExp#test()` method instead of `String#match`, if you need a boolean.",
187+
],
188+
},
146189
],
147190
})

0 commit comments

Comments
 (0)