Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb6ab8b2

Browse files
feat:require-unicode-regexp add suggestions (#17007)
* feat: `require-unicode-regexp` add suggestions* Review fixups: invalid patterns; sequence expressions* I promise I know how CJS modules work* Handled non-string literals* Update lib/rules/require-unicode-regexp.jsCo-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>* Don't concatenate + 'u'* Test the new cases* Touch up regular-expressions.js templating* Add myself as author to regular-expressions.js---------Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
1 parent4dd8d52 commitb6ab8b2

File tree

5 files changed

+297
-51
lines changed

5 files changed

+297
-51
lines changed

‎lib/rules/no-misleading-character-class.js

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44
"use strict";
55

66
const{CALL,CONSTRUCT, ReferenceTracker, getStringIfConstant}=require("@eslint-community/eslint-utils");
7-
const{RegExpValidator,RegExpParser, visitRegExpAST}=require("@eslint-community/regexpp");
7+
const{ RegExpParser, visitRegExpAST}=require("@eslint-community/regexpp");
88
const{ isCombiningCharacter, isEmojiModifier, isRegionalIndicatorSymbol, isSurrogatePair}=require("./utils/unicode");
99
constastUtils=require("./utils/ast-utils.js");
10+
const{ isValidWithUnicodeFlag}=require("./utils/regular-expressions");
1011

1112
//------------------------------------------------------------------------------
1213
// Helpers
1314
//------------------------------------------------------------------------------
1415

15-
constREGEXPP_LATEST_ECMA_VERSION=2022;
16-
1716
/**
1817
* Iterate character sequences of a given nodes.
1918
*
@@ -185,38 +184,10 @@ module.exports = {
185184
}
186185
}
187186

188-
/**
189-
* Checks if the given regular expression pattern would be valid with the `u` flag.
190-
*@param {string} pattern The regular expression pattern to verify.
191-
*@returns {boolean} `true` if the pattern would be valid with the `u` flag.
192-
* `false` if the pattern would be invalid with the `u` flag or the configured
193-
* ecmaVersion doesn't support the `u` flag.
194-
*/
195-
functionisValidWithUnicodeFlag(pattern){
196-
const{ ecmaVersion}=context.languageOptions;
197-
198-
// ecmaVersion <= 5 doesn't support the 'u' flag
199-
if(ecmaVersion<=5){
200-
returnfalse;
201-
}
202-
203-
constvalidator=newRegExpValidator({
204-
ecmaVersion:Math.min(ecmaVersion,REGEXPP_LATEST_ECMA_VERSION)
205-
});
206-
207-
try{
208-
validator.validatePattern(pattern,void0,void0,/* uFlag = */true);
209-
}catch{
210-
returnfalse;
211-
}
212-
213-
returntrue;
214-
}
215-
216187
return{
217188
"Literal[regex]"(node){
218189
verify(node,node.regex.pattern,node.regex.flags,fixer=>{
219-
if(!isValidWithUnicodeFlag(node.regex.pattern)){
190+
if(!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion,node.regex.pattern)){
220191
returnnull;
221192
}
222193

@@ -242,7 +213,7 @@ module.exports = {
242213
if(typeofpattern==="string"){
243214
verify(refNode,pattern,flags||"",fixer=>{
244215

245-
if(!isValidWithUnicodeFlag(pattern)){
216+
if(!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion,pattern)){
246217
returnnull;
247218
}
248219

‎lib/rules/prefer-regex-literals.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ const astUtils = require("./utils/ast-utils");
1313
const{CALL,CONSTRUCT, ReferenceTracker, findVariable}=require("@eslint-community/eslint-utils");
1414
const{ RegExpValidator, visitRegExpAST, RegExpParser}=require("@eslint-community/regexpp");
1515
const{ canTokensBeAdjacent}=require("./utils/ast-utils");
16+
const{REGEXPP_LATEST_ECMA_VERSION}=require("./utils/regular-expressions");
1617

1718
//------------------------------------------------------------------------------
1819
// Helpers
1920
//------------------------------------------------------------------------------
2021

21-
constREGEXPP_LATEST_ECMA_VERSION=2022;
22-
2322
/**
2423
* Determines whether the given node is a string literal.
2524
*@param {ASTNode} node Node to check.

‎lib/rules/require-unicode-regexp.js

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const {
1515
ReferenceTracker,
1616
getStringIfConstant
1717
}=require("@eslint-community/eslint-utils");
18+
constastUtils=require("./utils/ast-utils.js");
19+
const{ isValidWithUnicodeFlag}=require("./utils/regular-expressions");
1820

1921
//------------------------------------------------------------------------------
2022
// Rule Definition
@@ -31,7 +33,10 @@ module.exports = {
3133
url:"https://eslint.org/docs/rules/require-unicode-regexp"
3234
},
3335

36+
hasSuggestions:true,
37+
3438
messages:{
39+
addUFlag:"Add the 'u' flag.",
3540
requireUFlag:"Use the 'u' flag."
3641
},
3742

@@ -47,7 +52,20 @@ module.exports = {
4752
constflags=node.regex.flags||"";
4853

4954
if(!flags.includes("u")){
50-
context.report({ node,messageId:"requireUFlag"});
55+
context.report({
56+
messageId:"requireUFlag",
57+
node,
58+
suggest:isValidWithUnicodeFlag(context.languageOptions.ecmaVersion,node.regex.pattern)
59+
?[
60+
{
61+
fix(fixer){
62+
returnfixer.insertTextAfter(node,"u");
63+
},
64+
messageId:"addUFlag"
65+
}
66+
]
67+
:null
68+
});
5169
}
5270
},
5371

@@ -59,11 +77,46 @@ module.exports = {
5977
};
6078

6179
for(const{node:refNode}oftracker.iterateGlobalReferences(trackMap)){
62-
constflagsNode=refNode.arguments[1];
80+
const[patternNode,flagsNode]=refNode.arguments;
81+
constpattern=getStringIfConstant(patternNode,scope);
6382
constflags=getStringIfConstant(flagsNode,scope);
6483

6584
if(!flagsNode||(typeofflags==="string"&&!flags.includes("u"))){
66-
context.report({node:refNode,messageId:"requireUFlag"});
85+
context.report({
86+
messageId:"requireUFlag",
87+
node:refNode,
88+
suggest:typeofpattern==="string"&&isValidWithUnicodeFlag(context.languageOptions.ecmaVersion,pattern)
89+
?[
90+
{
91+
fix(fixer){
92+
if(flagsNode){
93+
if((flagsNode.type==="Literal"&&typeofflagsNode.value==="string")||flagsNode.type==="TemplateLiteral"){
94+
constflagsNodeText=sourceCode.getText(flagsNode);
95+
96+
returnfixer.replaceText(flagsNode,[
97+
flagsNodeText.slice(0,flagsNodeText.length-1),
98+
flagsNodeText.slice(flagsNodeText.length-1)
99+
].join("u"));
100+
}
101+
102+
// We intentionally don't suggest concatenating + "u" to non-literals
103+
returnnull;
104+
}
105+
106+
constpenultimateToken=sourceCode.getLastToken(refNode,{skip:1});// skip closing parenthesis
107+
108+
returnfixer.insertTextAfter(
109+
penultimateToken,
110+
astUtils.isCommaToken(penultimateToken)
111+
?' "u",'
112+
:', "u"'
113+
);
114+
},
115+
messageId:"addUFlag"
116+
}
117+
]
118+
:null
119+
});
67120
}
68121
}
69122
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
*@fileoverview Common utils for regular expressions.
3+
*@author Josh Goldberg
4+
*@author Toru Nagashima
5+
*/
6+
7+
"use strict";
8+
9+
const{ RegExpValidator}=require("@eslint-community/regexpp");
10+
11+
constREGEXPP_LATEST_ECMA_VERSION=2022;
12+
13+
/**
14+
* Checks if the given regular expression pattern would be valid with the `u` flag.
15+
*@param {number} ecmaVersion ECMAScript version to parse in.
16+
*@param {string} pattern The regular expression pattern to verify.
17+
*@returns {boolean} `true` if the pattern would be valid with the `u` flag.
18+
* `false` if the pattern would be invalid with the `u` flag or the configured
19+
* ecmaVersion doesn't support the `u` flag.
20+
*/
21+
functionisValidWithUnicodeFlag(ecmaVersion,pattern){
22+
if(ecmaVersion<=5){// ecmaVersion <= 5 doesn't support the 'u' flag
23+
returnfalse;
24+
}
25+
26+
constvalidator=newRegExpValidator({
27+
ecmaVersion:Math.min(ecmaVersion,REGEXPP_LATEST_ECMA_VERSION)
28+
});
29+
30+
try{
31+
validator.validatePattern(pattern,void0,void0,/* uFlag = */true);
32+
}catch{
33+
returnfalse;
34+
}
35+
36+
returntrue;
37+
}
38+
39+
module.exports={
40+
isValidWithUnicodeFlag,
41+
REGEXPP_LATEST_ECMA_VERSION
42+
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp