]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-regex-spaces.js
6d74aabe2632b34a24f3a18904d222dda34ca4b2
2 * @fileoverview Rule to count multiple spaces in regular expressions
3 * @author Matt DuVall <http://www.mattduvall.com/>
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils
= require("./utils/ast-utils");
13 const regexpp
= require("regexpp");
15 //------------------------------------------------------------------------------
17 //------------------------------------------------------------------------------
19 const regExpParser
= new regexpp
.RegExpParser();
20 const DOUBLE_SPACE
= / {2}/u
;
23 * Check if node is a string
24 * @param {ASTNode} node node to evaluate
25 * @returns {boolean} True if its a string
28 function isString(node
) {
29 return node
&& node
.type
=== "Literal" && typeof node
.value
=== "string";
32 //------------------------------------------------------------------------------
34 //------------------------------------------------------------------------------
36 /** @type {import('../shared/types').Rule} */
42 description
: "Disallow multiple spaces in regular expressions",
44 url
: "https://eslint.org/docs/rules/no-regex-spaces"
51 multipleSpaces
: "Spaces are hard to count. Use {{{length}}}."
58 * Validate regular expression
59 * @param {ASTNode} nodeToReport Node to report.
60 * @param {string} pattern Regular expression pattern to validate.
61 * @param {string} rawPattern Raw representation of the pattern in the source code.
62 * @param {number} rawPatternStartRange Start range of the pattern in the source code.
63 * @param {string} flags Regular expression flags.
67 function checkRegex(nodeToReport
, pattern
, rawPattern
, rawPatternStartRange
, flags
) {
69 // Skip if there are no consecutive spaces in the source code, to avoid reporting e.g., RegExp(' \ ').
70 if (!DOUBLE_SPACE
.test(rawPattern
)) {
74 const characterClassNodes
= [];
78 regExpAST
= regExpParser
.parsePattern(pattern
, 0, pattern
.length
, flags
.includes("u"));
81 // Ignore regular expressions with syntax errors
85 regexpp
.visitRegExpAST(regExpAST
, {
86 onCharacterClassEnter(ccNode
) {
87 characterClassNodes
.push(ccNode
);
91 const spacesPattern
= /( {2,})(?: [+*{?]|[^+*{?]|$)/gu;
94 while ((match
= spacesPattern
.exec(pattern
))) {
95 const { 1: { length
}, index
} = match
;
97 // Report only consecutive spaces that are not in character classes.
99 characterClassNodes
.every(({ start
, end
}) => index
< start
|| end
<= index
)
103 messageId
: "multipleSpaces",
106 if (pattern
!== rawPattern
) {
109 return fixer
.replaceTextRange(
110 [rawPatternStartRange
+ index
, rawPatternStartRange
+ index
+ length
],
116 // Report only the first occurrence of consecutive spaces
123 * Validate regular expression literals
124 * @param {ASTNode} node node to validate
128 function checkLiteral(node
) {
130 const pattern
= node
.regex
.pattern
;
131 const rawPattern
= node
.raw
.slice(1, node
.raw
.lastIndexOf("/"));
132 const rawPatternStartRange
= node
.range
[0] + 1;
133 const flags
= node
.regex
.flags
;
139 rawPatternStartRange
,
146 * Validate strings passed to the RegExp constructor
147 * @param {ASTNode} node node to validate
151 function checkFunction(node
) {
152 const scope
= context
.getScope();
153 const regExpVar
= astUtils
.getVariableByName(scope
, "RegExp");
154 const shadowed
= regExpVar
&& regExpVar
.defs
.length
> 0;
155 const patternNode
= node
.arguments
[0];
156 const flagsNode
= node
.arguments
[1];
158 if (node
.callee
.type
=== "Identifier" && node
.callee
.name
=== "RegExp" && isString(patternNode
) && !shadowed
) {
159 const pattern
= patternNode
.value
;
160 const rawPattern
= patternNode
.raw
.slice(1, -1);
161 const rawPatternStartRange
= patternNode
.range
[0] + 1;
162 const flags
= isString(flagsNode
) ? flagsNode
.value
: "";
168 rawPatternStartRange
,
175 Literal
: checkLiteral
,
176 CallExpression
: checkFunction
,
177 NewExpression
: checkFunction