Skip to content

Commit 4a13302

Browse files
authored
Fixed false positives for hasIndices in regexp/no-unused-capturing-group (#676)
1 parent 34ba766 commit 4a13302

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

.changeset/thick-numbers-fry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-regexp": patch
3+
---
4+
5+
Fixed false positives for hasIndices in `regexp/no-unused-capturing-group`

lib/utils/extract-capturing-group-references.ts

+26-5
Original file line numberDiff line numberDiff line change
@@ -641,12 +641,12 @@ function* iterateForRegExpMatchArrayReference(
641641
for (const namedRef of ref.extractPropertyReferences()) {
642642
yield getNamedArrayRef(namedRef)
643643
}
644+
} else if (ref.name === "indices") {
645+
for (const indicesRef of ref.extractPropertyReferences()) {
646+
yield* iterateForRegExpIndicesArrayReference(indicesRef)
647+
}
644648
} else {
645-
if (
646-
ref.name === "input" ||
647-
ref.name === "index" ||
648-
ref.name === "indices"
649-
) {
649+
if (ref.name === "input" || ref.name === "index") {
650650
return
651651
}
652652
yield getIndexArrayRef(ref)
@@ -660,6 +660,27 @@ function* iterateForRegExpMatchArrayReference(
660660
}
661661
}
662662

663+
/** Iterate the capturing group references for RegExpIndicesArray reference. */
664+
function* iterateForRegExpIndicesArrayReference(
665+
ref: PropertyReference,
666+
): Iterable<CapturingGroupReference> {
667+
if (hasNameRef(ref)) {
668+
if (ref.name === "groups") {
669+
for (const namedRef of ref.extractPropertyReferences()) {
670+
yield getNamedArrayRef(namedRef)
671+
}
672+
} else {
673+
yield getIndexArrayRef(ref)
674+
}
675+
} else {
676+
yield {
677+
type: "UnknownRef",
678+
kind: "array",
679+
prop: ref,
680+
}
681+
}
682+
}
683+
663684
/** Iterate the capturing group references for Array method of String.prototype.matchAll(). */
664685
function* iterateForArrayMethodOfStringMatchAll(
665686
node: CallExpression,

tests/lib/rules/no-unused-capturing-group.ts

+31
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ tester.run("no-unused-capturing-group", rule as any, {
152152
const text = 'Lorem ipsum dolor sit amet'
153153
const replaced = text.replace(/([\q{Lorem|ipsum}])/vg, '**$1**')
154154
`,
155+
// hasIndices
156+
String.raw`const re = /(foo)/d
157+
console.log(re.exec('foo').indices[1])
158+
`,
159+
String.raw`const re = /(?<f>foo)/d
160+
console.log(re.exec('foo').indices.groups.f)
161+
`,
162+
String.raw`const re = /(foo)/d
163+
console.log(re.exec('foo').indices[unknown])
164+
`,
155165
],
156166
invalid: [
157167
{
@@ -546,5 +556,26 @@ tester.run("no-unused-capturing-group", rule as any, {
546556
options: [{ fixable: true }],
547557
errors: ["Capturing group number 1 is defined but never used."],
548558
},
559+
// hasIndices
560+
{
561+
code: String.raw`const re = /(foo)/d
562+
console.log(re.exec('foo').indices[2])
563+
`,
564+
output: String.raw`const re = /(?:foo)/d
565+
console.log(re.exec('foo').indices[2])
566+
`,
567+
options: [{ fixable: true }],
568+
errors: ["Capturing group number 1 is defined but never used."],
569+
},
570+
{
571+
code: String.raw`const re = /(?<f>foo)/d
572+
console.log(re.exec('foo').indices.groups.x)
573+
`,
574+
output: String.raw`const re = /(?:foo)/d
575+
console.log(re.exec('foo').indices.groups.x)
576+
`,
577+
options: [{ fixable: true }],
578+
errors: ["Capturing group 'f' is defined but never used."],
579+
},
549580
],
550581
})

0 commit comments

Comments
 (0)