Skip to content

Commit 1f28c08

Browse files
committed
feat: autofix errors
1 parent c709f52 commit 1f28c08

File tree

4 files changed

+169
-11
lines changed

4 files changed

+169
-11
lines changed

rules/sort-switch-case.ts

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
250250
: makeFixes({
251251
sortedNodes: sortedSortingNodeGroupsForBlockSort,
252252
nodes: sortingNodeGroupsForBlockSortFlat,
253+
hasCommentAboveMissing: false,
253254
sourceCode,
254255
fixer,
255256
}),

utils/make-comment-above-fixes.ts

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import type { TSESLint } from '@typescript-eslint/utils'
2+
3+
import type {
4+
DeprecatedCustomGroupsOption,
5+
CustomGroupsOption,
6+
GroupsOptions,
7+
} from '../types/common-options'
8+
import type { SortingNode } from '../types/sorting-node'
9+
10+
import { getCommentAboveThatShouldExist } from './get-comment-above-that-should-exist'
11+
import { isCommentAboveOption } from './is-comment-above-option'
12+
import { getCommentsBefore } from './get-comments-before'
13+
import { getGroupIndex } from './get-group-index'
14+
15+
interface MakeCommentAboveFixesParameters {
16+
options: {
17+
customGroups?: DeprecatedCustomGroupsOption | CustomGroupsOption
18+
groups: GroupsOptions<string>
19+
}
20+
sourceCode: TSESLint.SourceCode
21+
sortedNodes: SortingNode[]
22+
fixer: TSESLint.RuleFixer
23+
}
24+
25+
export let makeCommentAboveFixes = ({
26+
sortedNodes,
27+
sourceCode,
28+
options,
29+
fixer,
30+
}: MakeCommentAboveFixesParameters): TSESLint.RuleFix[] => {
31+
let allAutoAddedComments = new Set(
32+
options.groups
33+
.filter(group => isCommentAboveOption(group))
34+
.map(({ commentAbove }) => commentAbove),
35+
)
36+
37+
let fixes: TSESLint.RuleFix[] = []
38+
39+
let firstNodeFixes = makeCommentAboveFix({
40+
nextSortedSortingNode: sortedNodes[0]!,
41+
sortedSortingNode: null,
42+
allAutoAddedComments,
43+
sourceCode,
44+
options,
45+
fixer,
46+
})
47+
fixes.push(...firstNodeFixes)
48+
49+
for (let i = 0; i < sortedNodes.length - 1; i++) {
50+
let sortedSortingNode = sortedNodes.at(i) ?? null
51+
let nextSortedSortingNode = sortedNodes.at(i + 1)!
52+
53+
let nodeFixes = makeCommentAboveFix({
54+
nextSortedSortingNode,
55+
allAutoAddedComments,
56+
sortedSortingNode,
57+
sourceCode,
58+
options,
59+
fixer,
60+
})
61+
fixes.push(...nodeFixes)
62+
}
63+
64+
return fixes
65+
}
66+
67+
let makeCommentAboveFix = ({
68+
nextSortedSortingNode,
69+
allAutoAddedComments,
70+
sortedSortingNode,
71+
sourceCode,
72+
options,
73+
fixer,
74+
}: {
75+
sortedSortingNode: SortingNode | null
76+
nextSortedSortingNode: SortingNode
77+
allAutoAddedComments: Set<string>
78+
} & Pick<
79+
MakeCommentAboveFixesParameters,
80+
'sourceCode' | 'options' | 'fixer'
81+
>): TSESLint.RuleFix[] => {
82+
let leftGroupIndex = sortedSortingNode
83+
? getGroupIndex(options.groups, sortedSortingNode)
84+
: -1
85+
let rightGroupIndex = getGroupIndex(options.groups, nextSortedSortingNode)
86+
87+
let commentAboveThatShouldExist = getCommentAboveThatShouldExist({
88+
options: {
89+
...options,
90+
groups: options.groups,
91+
},
92+
sortingNode: nextSortedSortingNode,
93+
rightGroupIndex,
94+
leftGroupIndex,
95+
sourceCode,
96+
})
97+
let commentsBefore = getCommentsBefore({
98+
node: nextSortedSortingNode.node,
99+
sourceCode,
100+
})
101+
102+
let autoAddedCommentsAboveToRemove = commentsBefore
103+
.filter(
104+
comment =>
105+
!commentAboveThatShouldExist?.comment ||
106+
comment.value.slice(1) !== commentAboveThatShouldExist.comment,
107+
)
108+
.filter(
109+
comment =>
110+
comment.type === 'Line' &&
111+
allAutoAddedComments.has(comment.value.slice(1)),
112+
)
113+
114+
let fixes: TSESLint.RuleFix[] = []
115+
for (let autoAddedCommentAboveToRemove of autoAddedCommentsAboveToRemove) {
116+
let nextToken = sourceCode.getTokenAfter(autoAddedCommentAboveToRemove)
117+
let rangeEnd = nextToken
118+
? nextToken.range[0]
119+
: autoAddedCommentAboveToRemove.range[1]
120+
fixes.push(
121+
fixer.removeRange([autoAddedCommentAboveToRemove.range[0], rangeEnd]),
122+
)
123+
}
124+
125+
if (commentAboveThatShouldExist && !commentAboveThatShouldExist.exists) {
126+
let nodeToPutCommentBefore = commentsBefore[0] ?? nextSortedSortingNode.node
127+
fixes.push(
128+
fixer.insertTextBeforeRange(
129+
nodeToPutCommentBefore.range,
130+
`// ${commentAboveThatShouldExist.comment}\n`,
131+
),
132+
)
133+
}
134+
135+
return fixes
136+
}

utils/make-fixes.ts

+31-11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { SortingNode } from '../types/sorting-node'
1212

1313
import { makeNewlinesBetweenFixes } from './make-newlines-between-fixes'
1414
import { makeCommentAfterFixes } from './make-comment-after-fixes'
15+
import { makeCommentAboveFixes } from './make-comment-above-fixes'
1516
import { makeOrderFixes } from './make-order-fixes'
1617

1718
export interface MakeFixesParameters<T extends SortingNode> {
@@ -24,6 +25,7 @@ export interface MakeFixesParameters<T extends SortingNode> {
2425
newlinesBetweenValueGetter?: NewlinesBetweenValueGetter<T>
2526
ignoreFirstNodeHighestBlockComment?: boolean
2627
sourceCode: TSESLint.SourceCode
28+
hasCommentAboveMissing: boolean
2729
fixer: TSESLint.RuleFixer
2830
sortedNodes: T[]
2931
nodes: T[]
@@ -32,6 +34,7 @@ export interface MakeFixesParameters<T extends SortingNode> {
3234
export let makeFixes = <T extends SortingNode>({
3335
ignoreFirstNodeHighestBlockComment,
3436
newlinesBetweenValueGetter,
37+
hasCommentAboveMissing,
3538
sortedNodes,
3639
sourceCode,
3740
options,
@@ -53,26 +56,43 @@ export let makeFixes = <T extends SortingNode>({
5356
nodes,
5457
fixer,
5558
})
56-
if (
57-
commentAfterFixes.length > 0 ||
58-
!options?.groups ||
59-
!options.newlinesBetween
60-
) {
59+
if (commentAfterFixes.length > 0) {
6160
return [...orderFixes, ...commentAfterFixes]
6261
}
6362

64-
let newlinesFixes = makeNewlinesBetweenFixes({
63+
if (options?.groups && options.newlinesBetween) {
64+
let newlinesFixes = makeNewlinesBetweenFixes({
65+
options: {
66+
...options,
67+
newlinesBetween: options.newlinesBetween,
68+
groups: options.groups,
69+
},
70+
newlinesBetweenValueGetter,
71+
sortedNodes,
72+
sourceCode,
73+
fixer,
74+
nodes,
75+
})
76+
if (newlinesFixes.length > 0) {
77+
return [...orderFixes, ...newlinesFixes]
78+
}
79+
}
80+
81+
if (orderFixes.length > 0) {
82+
return orderFixes
83+
}
84+
85+
if (!hasCommentAboveMissing || !options?.groups) {
86+
return []
87+
}
88+
89+
return makeCommentAboveFixes({
6590
options: {
6691
...options,
67-
newlinesBetween: options.newlinesBetween,
6892
groups: options.groups,
6993
},
70-
newlinesBetweenValueGetter,
7194
sortedNodes,
7295
sourceCode,
7396
fixer,
74-
nodes,
7597
})
76-
77-
return [...orderFixes, ...newlinesFixes]
7898
}

utils/report-errors.ts

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export let reportErrors = <MessageIds extends string, T extends SortingNode>({
7171
},
7272
fix: (fixer: TSESLint.RuleFixer) =>
7373
makeFixes({
74+
hasCommentAboveMissing: !!commentAboveMissing,
7475
ignoreFirstNodeHighestBlockComment,
7576
newlinesBetweenValueGetter,
7677
sortedNodes,

0 commit comments

Comments
 (0)