Skip to content

Commit 0e61e73

Browse files
authored
Add support for string literal to regexp/no-empty-alternative (#633)
1 parent 1ae35e6 commit 0e61e73

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

.changeset/cold-nails-teach.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-regexp": minor
3+
---
4+
5+
Add support for string literal to `regexp/no-empty-alternative`

docs/rules/no-empty-alternative.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ var foo = /a+|b*/
3737
var foo = /a+|b+|/
3838
var foo = /\|\||\|||\|\|\|/
3939
var foo = /a(?:a|bc|def|h||ij|k)/
40+
var foo = /[abc\q{def|}]/v
4041
```
4142

4243
</eslint-code-block>

lib/rules/no-empty-alternative.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { RegExpVisitor } from "@eslint-community/regexpp/visitor"
22
import type {
33
Alternative,
44
CapturingGroup,
5+
ClassStringDisjunction,
56
Group,
67
Pattern,
78
} from "@eslint-community/regexpp/ast"
@@ -73,8 +74,15 @@ export default createRule("no-empty-alternative", {
7374
getRegexpLocation,
7475
fixReplaceNode,
7576
}: RegExpContext): RegExpVisitor.Handlers {
76-
function verifyAlternatives(
77-
regexpNode: CapturingGroup | Group | Pattern,
77+
function verifyAlternatives<
78+
N extends
79+
| CapturingGroup
80+
| Group
81+
| Pattern
82+
| ClassStringDisjunction,
83+
>(
84+
regexpNode: N,
85+
suggestFixer: (alt: N["alternatives"][number]) => string | null,
7886
) {
7987
if (regexpNode.alternatives.length >= 2) {
8088
// We want to have at least two alternatives because the zero alternatives isn't possible because of
@@ -96,7 +104,7 @@ export default createRule("no-empty-alternative", {
96104
end: index + 1,
97105
})
98106

99-
const fixed = getFixedNode(regexpNode, alt)
107+
const fixed = suggestFixer(alt)
100108

101109
context.report({
102110
node,
@@ -122,9 +130,20 @@ export default createRule("no-empty-alternative", {
122130
}
123131

124132
return {
125-
onGroupEnter: verifyAlternatives,
126-
onCapturingGroupEnter: verifyAlternatives,
127-
onPatternEnter: verifyAlternatives,
133+
onGroupEnter: (gNode) =>
134+
verifyAlternatives(gNode, (alt) =>
135+
getFixedNode(gNode, alt),
136+
),
137+
onCapturingGroupEnter: (cgNode) =>
138+
verifyAlternatives(cgNode, (alt) =>
139+
getFixedNode(cgNode, alt),
140+
),
141+
onPatternEnter: (pNode) =>
142+
verifyAlternatives(pNode, (alt) =>
143+
getFixedNode(pNode, alt),
144+
),
145+
onClassStringDisjunctionEnter: (csdNode) =>
146+
verifyAlternatives(csdNode, () => null),
128147
}
129148
}
130149

tests/lib/rules/no-empty-alternative.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import rule from "../../../lib/rules/no-empty-alternative"
33

44
const tester = new RuleTester({
55
parserOptions: {
6-
ecmaVersion: 2020,
6+
ecmaVersion: "latest",
77
sourceType: "module",
88
},
99
})
1010

1111
tester.run("no-empty-alternative", rule as any, {
12-
valid: [`/()|(?:)|(?=)/`, `/(?:)/`, `/a*|b+/`],
12+
valid: [`/()|(?:)|(?=)/`, `/(?:)/`, `/a*|b+/`, String.raw`/[\q{a|b}]/v`],
1313
invalid: [
1414
{
1515
code: `/|||||/`,
@@ -68,5 +68,35 @@ tester.run("no-empty-alternative", rule as any, {
6868
},
6969
],
7070
},
71+
{
72+
code: String.raw`/[\q{a|}]/v`,
73+
errors: [
74+
{
75+
messageId: "empty",
76+
column: 7,
77+
suggestions: [],
78+
},
79+
],
80+
},
81+
{
82+
code: String.raw`/[\q{|a}]/v`,
83+
errors: [
84+
{
85+
messageId: "empty",
86+
column: 6,
87+
suggestions: [],
88+
},
89+
],
90+
},
91+
{
92+
code: String.raw`/[\q{a||b}]/v`,
93+
errors: [
94+
{
95+
messageId: "empty",
96+
column: 8,
97+
suggestions: [],
98+
},
99+
],
100+
},
71101
],
72102
})

0 commit comments

Comments
 (0)