Skip to content

Commit dd474bb

Browse files
committed
refactor: replace regexp loops with regexpGroupMatchers
1 parent cb9a52f commit dd474bb

19 files changed

+137
-199
lines changed

lib/rules/attribute-hyphenation.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
const utils = require('../utils')
88
const casing = require('../utils/casing')
9-
const { toRegExp } = require('../utils/regexp')
9+
const { toRegExpGroupMatcher } = require('../utils/regexp')
1010
const svgAttributes = require('../utils/svg-attributes-weird-case.json')
1111

1212
/**
@@ -79,11 +79,7 @@ module.exports = {
7979
const option = context.options[0]
8080
const optionsPayload = context.options[1]
8181
const useHyphenated = option !== 'never'
82-
/** @type {RegExp[]} */
83-
const ignoredTagsRegexps = (
84-
(optionsPayload && optionsPayload.ignoreTags) ||
85-
[]
86-
).map(toRegExp)
82+
const ignoredTagsMatcher = toRegExpGroupMatcher(optionsPayload?.ignoreTags)
8783
const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes]
8884

8985
if (optionsPayload && optionsPayload.ignore) {
@@ -142,17 +138,12 @@ module.exports = {
142138
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
143139
}
144140

145-
/** @param {string} name */
146-
function isIgnoredTagName(name) {
147-
return ignoredTagsRegexps.some((re) => re.test(name))
148-
}
149-
150141
return utils.defineTemplateBodyVisitor(context, {
151142
VAttribute(node) {
152143
const element = node.parent.parent
153144
if (
154145
(!utils.isCustomComponent(element) && element.name !== 'slot') ||
155-
isIgnoredTagName(element.rawName)
146+
ignoredTagsMatcher(element.rawName)
156147
)
157148
return
158149

lib/rules/component-name-in-template-casing.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
const utils = require('../utils')
88
const casing = require('../utils/casing')
9-
const { toRegExp } = require('../utils/regexp')
9+
const { toRegExpGroupMatcher } = require('../utils/regexp')
1010

1111
const allowedCaseOptions = ['PascalCase', 'kebab-case']
1212
const defaultCase = 'PascalCase'
@@ -81,8 +81,7 @@ module.exports = {
8181
const caseType = allowedCaseOptions.includes(caseOption)
8282
? caseOption
8383
: defaultCase
84-
/** @type {RegExp[]} */
85-
const ignores = (options.ignores || []).map(toRegExp)
84+
const ignoreMatcher = toRegExpGroupMatcher(options.ignores)
8685
/** @type {string[]} */
8786
const globals = (options.globals || []).map(casing.pascalCase)
8887
const registeredComponentsOnly = options.registeredComponentsOnly !== false
@@ -116,7 +115,7 @@ module.exports = {
116115
* @returns {boolean} `true` if the given node is the verification target node.
117116
*/
118117
function isVerifyTarget(node) {
119-
if (ignores.some((re) => re.test(node.rawName))) {
118+
if (ignoreMatcher(node.rawName)) {
120119
// ignore
121120
return false
122121
}

lib/rules/custom-event-name-casing.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
const { findVariable } = require('@eslint-community/eslint-utils')
88
const utils = require('../utils')
99
const casing = require('../utils/casing')
10-
const { toRegExp } = require('../utils/regexp')
10+
const { toRegExpGroupMatcher } = require('../utils/regexp')
1111

1212
/**
1313
* @typedef {import('../utils').VueObjectData} VueObjectData
@@ -92,8 +92,7 @@ module.exports = {
9292
const caseType = context.options[0] || DEFAULT_CASE
9393
const objectOption = context.options[1] || {}
9494
const caseChecker = casing.getChecker(caseType)
95-
/** @type {RegExp[]} */
96-
const ignores = (objectOption.ignores || []).map(toRegExp)
95+
const ignoreMatcher = toRegExpGroupMatcher(objectOption.ignores)
9796

9897
/**
9998
* Check whether the given event name is valid.
@@ -109,7 +108,7 @@ module.exports = {
109108
*/
110109
function verify(nameWithLoc) {
111110
const name = nameWithLoc.name
112-
if (isValidEventName(name) || ignores.some((re) => re.test(name))) {
111+
if (isValidEventName(name) || ignoreMatcher(name)) {
113112
return
114113
}
115114
context.report({

lib/rules/no-restricted-block.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,16 @@ const regexp = require('../utils/regexp')
1212
* @property {string} [message]
1313
*/
1414

15-
/**
16-
* @param {string} str
17-
* @returns {(str: string) => boolean}
18-
*/
19-
function buildMatcher(str) {
20-
if (regexp.isRegExp(str)) {
21-
const re = regexp.toRegExp(str)
22-
return (s) => {
23-
re.lastIndex = 0
24-
return re.test(s)
25-
}
26-
}
27-
return (s) => s === str
28-
}
2915
/**
3016
* @param {any} option
3117
* @returns {ParsedOption}
3218
*/
3319
function parseOption(option) {
3420
if (typeof option === 'string') {
35-
const matcher = buildMatcher(option)
21+
const matcher = regexp.toRegExp(option, { remove: 'g' })
3622
return {
3723
test(block) {
38-
return matcher(block.rawName)
24+
return matcher.test(block.rawName)
3925
}
4026
}
4127
}

lib/rules/no-restricted-class.js

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,15 @@ const regexp = require('../utils/regexp')
1212
* @param {string} className
1313
* @param {*} node
1414
* @param {RuleContext} context
15-
* @param {Set<string>} forbiddenClasses
16-
* @param {Array<RegExp>} forbiddenClassesRegexps
15+
* @param {(name: string) => boolean} forbiddenGroupMatcher
1716
*/
1817
const reportForbiddenClass = (
1918
className,
2019
node,
2120
context,
22-
forbiddenClasses,
23-
forbiddenClassesRegexps
21+
forbiddenGroupMatcher
2422
) => {
25-
if (
26-
forbiddenClasses.has(className) ||
27-
forbiddenClassesRegexps.some((re) => re.test(className))
28-
) {
23+
if (forbiddenGroupMatcher(className)) {
2924
const loc = node.value ? node.value.loc : node.loc
3025
context.report({
3126
node,
@@ -123,24 +118,16 @@ module.exports = {
123118

124119
/** @param {RuleContext} context */
125120
create(context) {
126-
const forbiddenClasses = new Set(context.options || [])
127-
const forbiddenClassesRegexps = (context.options || [])
128-
.filter((cl) => regexp.isRegExp(cl))
129-
.map((cl) => regexp.toRegExp(cl))
121+
const { options = [] } = context
122+
const forbiddenGroupMatcher = regexp.toRegExpGroupMatcher(options)
130123

131124
return utils.defineTemplateBodyVisitor(context, {
132125
/**
133126
* @param {VAttribute & { value: VLiteral } } node
134127
*/
135128
'VAttribute[directive=false][key.name="class"][value!=null]'(node) {
136129
for (const className of node.value.value.split(/\s+/)) {
137-
reportForbiddenClass(
138-
className,
139-
node,
140-
context,
141-
forbiddenClasses,
142-
forbiddenClassesRegexps
143-
)
130+
reportForbiddenClass(className, node, context, forbiddenGroupMatcher)
144131
}
145132
},
146133

@@ -159,8 +146,7 @@ module.exports = {
159146
className,
160147
reportNode,
161148
context,
162-
forbiddenClasses,
163-
forbiddenClassesRegexps
149+
forbiddenGroupMatcher
164150
)
165151
}
166152
}

lib/rules/no-restricted-component-names.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const { isRegExp, toRegExp } = require('../utils/regexp')
2222
*/
2323
function buildMatcher(str) {
2424
if (isRegExp(str)) {
25-
const regex = toRegExp(str)
25+
const regex = toRegExp(str, { remove: 'g' })
2626
return (s) => regex.test(s)
2727
}
2828
return (s) => s === casing.pascalCase(str) || s === casing.kebabCase(str)

lib/rules/no-restricted-component-options.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,6 @@ const regexp = require('../utils/regexp')
2323
* @typedef { (node: Property | SpreadElement) => (MatchResult | null) } Tester
2424
*/
2525

26-
/**
27-
* @param {string} str
28-
* @returns {Matcher}
29-
*/
30-
function buildMatcher(str) {
31-
if (regexp.isRegExp(str)) {
32-
const re = regexp.toRegExp(str)
33-
return (s) => {
34-
re.lastIndex = 0
35-
return re.test(s)
36-
}
37-
}
38-
return (s) => s === str
39-
}
40-
4126
/**
4227
* @param {string | string[] | { name: string | string[], message?: string } } option
4328
* @returns {ParsedOption}
@@ -65,7 +50,8 @@ function parseOption(option) {
6550
if (name === '*') {
6651
steps.push({ wildcard: true })
6752
} else {
68-
steps.push({ test: buildMatcher(name) })
53+
const matcher = regexp.toRegExp(name, { remove: 'g' })
54+
steps.push({ test: (value) => matcher.test(value) })
6955
}
7056
}
7157
const message = option.message

lib/rules/no-restricted-custom-event.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,16 @@ const regexp = require('../utils/regexp')
1515
* @property {string|undefined} [suggest]
1616
*/
1717

18-
/**
19-
* @param {string} str
20-
* @returns {(str: string) => boolean}
21-
*/
22-
function buildMatcher(str) {
23-
if (regexp.isRegExp(str)) {
24-
const re = regexp.toRegExp(str)
25-
return (s) => {
26-
re.lastIndex = 0
27-
return re.test(s)
28-
}
29-
}
30-
return (s) => s === str
31-
}
3218
/**
3319
* @param {string|{event: string, message?: string, suggest?: string}} option
3420
* @returns {ParsedOption}
3521
*/
3622
function parseOption(option) {
3723
if (typeof option === 'string') {
38-
const matcher = buildMatcher(option)
24+
const matcher = regexp.toRegExp(option, { remove: 'g' })
3925
return {
4026
test(name) {
41-
return matcher(name)
27+
return matcher.test(name)
4228
}
4329
}
4430
}

lib/rules/no-restricted-props.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,16 @@ const regexp = require('../utils/regexp')
1818
* @property {string|undefined} [suggest]
1919
*/
2020

21-
/**
22-
* @param {string} str
23-
* @returns {(str: string) => boolean}
24-
*/
25-
function buildMatcher(str) {
26-
if (regexp.isRegExp(str)) {
27-
const re = regexp.toRegExp(str)
28-
return (s) => {
29-
re.lastIndex = 0
30-
return re.test(s)
31-
}
32-
}
33-
return (s) => s === str
34-
}
3521
/**
3622
* @param {string|{name:string, message?: string, suggest?:string}} option
3723
* @returns {ParsedOption}
3824
*/
3925
function parseOption(option) {
4026
if (typeof option === 'string') {
41-
const matcher = buildMatcher(option)
27+
const matcher = regexp.toRegExp(option, { remove: 'g' })
4228
return {
4329
test(name) {
44-
return matcher(name)
30+
return matcher.test(name)
4531
}
4632
}
4733
}

lib/rules/no-restricted-static-attribute.js

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,16 @@ const regexp = require('../utils/regexp')
1515
* @property {string} [message]
1616
*/
1717

18-
/**
19-
* @param {string} str
20-
* @returns {(str: string) => boolean}
21-
*/
22-
function buildMatcher(str) {
23-
if (regexp.isRegExp(str)) {
24-
const re = regexp.toRegExp(str)
25-
return (s) => {
26-
re.lastIndex = 0
27-
return re.test(s)
28-
}
29-
}
30-
return (s) => s === str
31-
}
3218
/**
3319
* @param {any} option
3420
* @returns {ParsedOption}
3521
*/
3622
function parseOption(option) {
3723
if (typeof option === 'string') {
38-
const matcher = buildMatcher(option)
24+
const matcher = regexp.toRegExp(option, { remove: 'g' })
3925
return {
4026
test({ key }) {
41-
return matcher(key.rawName)
27+
return matcher.test(key.rawName)
4228
}
4329
}
4430
}
@@ -53,25 +39,25 @@ function parseOption(option) {
5339
return node.value == null || node.value.value === node.key.rawName
5440
}
5541
} else {
56-
const valueMatcher = buildMatcher(option.value)
42+
const valueMatcher = regexp.toRegExp(option.value, { remove: 'g' })
5743
parsed.test = (node) => {
5844
if (!keyTest(node)) {
5945
return false
6046
}
61-
return node.value != null && valueMatcher(node.value.value)
47+
return node.value != null && valueMatcher.test(node.value.value)
6248
}
6349
}
6450
parsed.useValue = true
6551
}
6652
if (option.element) {
6753
const argTest = parsed.test
68-
const tagMatcher = buildMatcher(option.element)
54+
const tagMatcher = regexp.toRegExp(option.element, { remove: 'g' })
6955
parsed.test = (node) => {
7056
if (!argTest(node)) {
7157
return false
7258
}
7359
const element = node.parent.parent
74-
return tagMatcher(element.rawName)
60+
return tagMatcher.test(element.rawName)
7561
}
7662
parsed.useElement = true
7763
}

0 commit comments

Comments
 (0)