Skip to content

Commit 04829b9

Browse files
Improve sort-flags to fix unknown patterns (#338)
* Improve `sort-flags` to fix unknown patterns * Added test for non-owned pattern
1 parent 88cbfc9 commit 04829b9

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

lib/rules/sort-flags.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export default createRule("sort-flags", {
4242
loc: getFlagsLocation(),
4343
messageId: "sortFlags",
4444
data: { flags: flagsString, sortedFlags },
45-
fix: fixReplaceFlags(sortedFlags),
45+
fix: fixReplaceFlags(sortedFlags, false),
4646
})
4747
}
4848
}

lib/utils/index.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type RegExpContextBase = {
7171

7272
fixReplaceFlags: (
7373
newFlags: string | (() => string | null),
74+
includePattern?: boolean,
7475
) => (fixer: Rule.RuleFixer) => Rule.Fix[] | Rule.Fix | null
7576

7677
/**
@@ -118,6 +119,7 @@ type UnparsableRegExpContextBase = {
118119

119120
fixReplaceFlags: (
120121
newFlags: string | (() => string | null),
122+
includePattern?: boolean,
121123
) => (fixer: Rule.RuleFixer) => Rule.Fix[] | Rule.Fix | null
122124
}
123125
export type RegExpContextForInvalid = {
@@ -609,12 +611,13 @@ function buildRegExpContextBase({
609611
fixReplaceQuant: (qNode, replacement) => {
610612
return fixReplaceQuant(patternSource, qNode, replacement)
611613
},
612-
fixReplaceFlags: (newFlags) => {
614+
fixReplaceFlags: (newFlags, includePattern) => {
613615
return fixReplaceFlags(
614616
patternSource,
615617
regexpNode,
616618
flagsNode,
617619
newFlags,
620+
includePattern ?? true,
618621
)
619622
},
620623
getUsageOfPattern: () =>
@@ -665,15 +668,13 @@ function buildUnparsableRegExpContextBase({
665668
getFlagLocation: (flag) =>
666669
getFlagLocation(sourceCode, regexpNode, flagsNode, flag),
667670

668-
fixReplaceFlags: (newFlags) => {
669-
if (!patternSource) {
670-
return () => null
671-
}
671+
fixReplaceFlags: (newFlags, includePattern) => {
672672
return fixReplaceFlags(
673673
patternSource,
674674
regexpNode,
675675
flagsNode,
676676
newFlags,
677+
includePattern ?? true,
677678
)
678679
},
679680
}
@@ -863,14 +864,35 @@ function fixReplaceQuant(
863864

864865
/**
865866
* Returns a new fixer that replaces the current flags with the given flags.
867+
*
868+
* @param includePattern Whether the whole pattern is to be included in the fix.
869+
*
870+
* Fixes that change the pattern generally assume that the flags don't change,
871+
* so changing the flags should conflict with all pattern fixes.
866872
*/
867873
function fixReplaceFlags(
868-
patternSource: PatternSource,
874+
patternSource: PatternSource | null,
869875
regexpNode: ESTree.CallExpression | ESTree.RegExpLiteral,
870876
flagsNode: ESTree.Expression | null,
871877
replacement: string | (() => string | null),
878+
includePattern: boolean,
872879
) {
873880
return (fixer: Rule.RuleFixer): Rule.Fix[] | Rule.Fix | null => {
881+
let patternFix = null
882+
if (includePattern) {
883+
if (!patternSource) {
884+
return null
885+
}
886+
const patternRange = patternSource.getReplaceRange({
887+
start: 0,
888+
end: patternSource.value.length,
889+
})
890+
if (patternRange == null) {
891+
return null
892+
}
893+
patternFix = patternRange.replace(fixer, patternSource.value)
894+
}
895+
874896
let newFlags
875897
if (typeof replacement === "string") {
876898
newFlags = replacement
@@ -916,18 +938,10 @@ function fixReplaceFlags(
916938
)
917939
}
918940

919-
// fixes that change the pattern generally assume that flags don't
920-
// change, so we have to create conflicts.
921-
922-
const patternRange = patternSource.getReplaceRange({
923-
start: 0,
924-
end: patternSource.value.length,
925-
})
926-
if (patternRange == null) {
927-
return null
941+
if (!patternFix) {
942+
return flagsFix
928943
}
929-
930-
return [patternRange.replace(fixer, patternSource.value), flagsFix]
944+
return [patternFix, flagsFix]
931945
}
932946
}
933947

tests/lib/rules/sort-flags.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,27 @@ tester.run("sort-flags", rule as any, {
7171
},
7272
],
7373
},
74+
{
75+
// sort flags even on unknown
76+
code: String.raw`RegExp('a' + b, 'us');`,
77+
output: String.raw`RegExp('a' + b, 'su');`,
78+
errors: [
79+
{
80+
message: "The flags 'us' should be in the order 'su'.",
81+
column: 18,
82+
},
83+
],
84+
},
85+
{
86+
// sort flags even on non-owned pattern
87+
code: String.raw`var a = "foo"; RegExp(foo, 'us'); RegExp(foo, 'u');`,
88+
output: String.raw`var a = "foo"; RegExp(foo, 'su'); RegExp(foo, 'u');`,
89+
errors: [
90+
{
91+
message: "The flags 'us' should be in the order 'su'.",
92+
column: 29,
93+
},
94+
],
95+
},
7496
],
7597
})

0 commit comments

Comments
 (0)