Skip to content

Commit aca1d21

Browse files
Updated prefer-d using regexp-ast-analysis (#156)
1 parent d65e980 commit aca1d21

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

lib/rules/prefer-d.ts

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import type { RegExpVisitor } from "regexpp/visitor"
2-
import type { CharacterClass, CharacterClassRange } from "regexpp/ast"
32
import type { RegExpContext } from "../utils"
43
import {
54
createRule,
65
defineRegexpVisitor,
76
CP_DIGIT_ZERO,
87
CP_DIGIT_NINE,
98
} from "../utils"
9+
import { Chars } from "regexp-ast-analysis"
1010

1111
export default createRule("prefer-d", {
1212
meta: {
@@ -28,38 +28,64 @@ export default createRule("prefer-d", {
2828
*/
2929
function createVisitor({
3030
node,
31+
flags,
3132
getRegexpLocation,
3233
fixReplaceNode,
34+
toCharSet,
3335
}: RegExpContext): RegExpVisitor.Handlers {
36+
let reportedCharacterClass = false
37+
3438
return {
35-
onCharacterClassRangeEnter(ccrNode: CharacterClassRange) {
39+
onCharacterClassEnter(ccNode) {
40+
const charSet = toCharSet(ccNode)
41+
42+
let predefined: string | undefined = undefined
43+
if (charSet.equals(Chars.digit(flags))) {
44+
predefined = "\\d"
45+
} else if (charSet.equals(Chars.digit(flags).negate())) {
46+
predefined = "\\D"
47+
}
48+
49+
if (predefined) {
50+
reportedCharacterClass = true
51+
52+
context.report({
53+
node,
54+
loc: getRegexpLocation(ccNode),
55+
messageId: "unexpected",
56+
data: {
57+
type: "character class",
58+
expr: ccNode.raw,
59+
instead: predefined,
60+
},
61+
fix: fixReplaceNode(ccNode, predefined),
62+
})
63+
}
64+
},
65+
onCharacterClassLeave() {
66+
reportedCharacterClass = false
67+
},
68+
onCharacterClassRangeEnter(ccrNode) {
69+
if (reportedCharacterClass) {
70+
return
71+
}
72+
3673
if (
3774
ccrNode.min.value === CP_DIGIT_ZERO &&
3875
ccrNode.max.value === CP_DIGIT_NINE
3976
) {
40-
let reportNode: CharacterClass | CharacterClassRange,
41-
instead: string
42-
const ccNode = ccrNode.parent
43-
if (ccNode.elements.length === 1) {
44-
reportNode = ccNode
45-
instead = ccNode.negate ? "\\D" : "\\d"
46-
} else {
47-
reportNode = ccrNode
48-
instead = "\\d"
49-
}
77+
const instead = "\\d"
78+
5079
context.report({
5180
node,
52-
loc: getRegexpLocation(reportNode),
81+
loc: getRegexpLocation(ccrNode),
5382
messageId: "unexpected",
5483
data: {
55-
type:
56-
reportNode.type === "CharacterClass"
57-
? "character class"
58-
: "character class range",
59-
expr: reportNode.raw,
84+
type: "character class range",
85+
expr: ccrNode.raw,
6086
instead,
6187
},
62-
fix: fixReplaceNode(reportNode, instead),
88+
fix: fixReplaceNode(ccrNode, instead),
6389
})
6490
}
6591
},

0 commit comments

Comments
 (0)