Skip to content

Commit a2e49a7

Browse files
ST-DDTFloEdelmann
andauthored
refactor: use regexp-groups to simplify ignores (#2776)
Co-authored-by: Flo Edelmann <git@flo-edelmann.de>
1 parent 08ef531 commit a2e49a7

20 files changed

+219
-215
lines changed

lib/rules/attribute-hyphenation.js

Lines changed: 2 additions & 11 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 isIgnoredTagName = toRegExpGroupMatcher(optionsPayload?.ignoreTags)
8783
const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes]
8884

8985
if (optionsPayload && optionsPayload.ignore) {
@@ -142,11 +138,6 @@ 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

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 isIgnored = 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 (isIgnored(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 isIgnored = 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) || isIgnored(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 & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,10 @@ 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} isForbiddenClass
1716
*/
18-
const reportForbiddenClass = (
19-
className,
20-
node,
21-
context,
22-
forbiddenClasses,
23-
forbiddenClassesRegexps
24-
) => {
25-
if (
26-
forbiddenClasses.has(className) ||
27-
forbiddenClassesRegexps.some((re) => re.test(className))
28-
) {
17+
const reportForbiddenClass = (className, node, context, isForbiddenClass) => {
18+
if (isForbiddenClass(className)) {
2919
const loc = node.value ? node.value.loc : node.loc
3020
context.report({
3121
node,
@@ -123,24 +113,16 @@ module.exports = {
123113

124114
/** @param {RuleContext} context */
125115
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))
116+
const { options = [] } = context
117+
const isForbiddenClass = regexp.toRegExpGroupMatcher(options)
130118

131119
return utils.defineTemplateBodyVisitor(context, {
132120
/**
133121
* @param {VAttribute & { value: VLiteral } } node
134122
*/
135123
'VAttribute[directive=false][key.name="class"][value!=null]'(node) {
136124
for (const className of node.value.value.split(/\s+/)) {
137-
reportForbiddenClass(
138-
className,
139-
node,
140-
context,
141-
forbiddenClasses,
142-
forbiddenClassesRegexps
143-
)
125+
reportForbiddenClass(className, node, context, isForbiddenClass)
144126
}
145127
},
146128

@@ -155,13 +137,7 @@ module.exports = {
155137
for (const { className, reportNode } of extractClassNames(
156138
/** @type {Expression} */ (node.expression)
157139
)) {
158-
reportForbiddenClass(
159-
className,
160-
reportNode,
161-
context,
162-
forbiddenClasses,
163-
forbiddenClassesRegexps
164-
)
140+
reportForbiddenClass(className, reportNode, context, isForbiddenClass)
165141
}
166142
}
167143
})

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)