@@ -22,7 +22,10 @@ import {
22
22
isInvalidApplyDiagnostic ,
23
23
AugmentedDiagnostic ,
24
24
InvalidApplyDiagnostic ,
25
+ isUtilityConflictsDiagnostic ,
26
+ UtilityConflictsDiagnostic ,
25
27
} from '../diagnostics/types'
28
+ import { flatten , dedupeBy } from '../../../util/array'
26
29
27
30
async function getDiagnosticsFromCodeActionParams (
28
31
state : State ,
@@ -35,7 +38,11 @@ async function getDiagnosticsFromCodeActionParams(
35
38
return params . context . diagnostics
36
39
. map ( ( diagnostic ) => {
37
40
return diagnostics . find ( ( d ) => {
38
- return rangesEqual ( d . range , diagnostic . range )
41
+ return (
42
+ d . code === diagnostic . code &&
43
+ d . message === diagnostic . message &&
44
+ rangesEqual ( d . range , diagnostic . range )
45
+ )
39
46
} )
40
47
} )
41
48
. filter ( Boolean )
@@ -55,40 +62,46 @@ export async function provideCodeActions(
55
62
codes
56
63
)
57
64
58
- return Promise . all (
59
- diagnostics
60
- . map ( ( diagnostic ) => {
61
- if ( isInvalidApplyDiagnostic ( diagnostic ) ) {
62
- return provideInvalidApplyCodeAction ( state , params , diagnostic )
63
- }
65
+ let actions = diagnostics . map ( ( diagnostic ) => {
66
+ if ( isInvalidApplyDiagnostic ( diagnostic ) ) {
67
+ return provideInvalidApplyCodeActions ( state , params , diagnostic )
68
+ }
64
69
65
- let match = findLast (
66
- / D i d y o u m e a n (?: s o m e t h i n g l i k e ) ? ' (?< replacement > [ ^ ' ] + ) ' \? $ / g,
67
- diagnostic . message
68
- )
70
+ if ( isUtilityConflictsDiagnostic ( diagnostic ) ) {
71
+ return provideUtilityConflictsCodeActions ( state , params , diagnostic )
72
+ }
69
73
70
- if ( ! match ) {
71
- return null
72
- }
74
+ let match = findLast (
75
+ / D i d y o u m e a n (?: s o m e t h i n g l i k e ) ? ' (?< replacement > [ ^ ' ] + ) ' \? $ / g,
76
+ diagnostic . message
77
+ )
73
78
74
- return {
75
- title : `Replace with '${ match . groups . replacement } '` ,
76
- kind : CodeActionKind . QuickFix ,
77
- diagnostics : [ diagnostic ] ,
78
- edit : {
79
- changes : {
80
- [ params . textDocument . uri ] : [
81
- {
82
- range : diagnostic . range ,
83
- newText : match . groups . replacement ,
84
- } ,
85
- ] ,
86
- } ,
79
+ if ( ! match ) {
80
+ return [ ]
81
+ }
82
+
83
+ return [
84
+ {
85
+ title : `Replace with '${ match . groups . replacement } '` ,
86
+ kind : CodeActionKind . QuickFix ,
87
+ diagnostics : [ diagnostic ] ,
88
+ edit : {
89
+ changes : {
90
+ [ params . textDocument . uri ] : [
91
+ {
92
+ range : diagnostic . range ,
93
+ newText : match . groups . replacement ,
94
+ } ,
95
+ ] ,
87
96
} ,
88
- }
89
- } )
90
- . filter ( Boolean )
91
- )
97
+ } ,
98
+ } ,
99
+ ]
100
+ } )
101
+
102
+ return Promise . all ( actions )
103
+ . then ( flatten )
104
+ . then ( ( x ) => dedupeBy ( x , ( item ) => JSON . stringify ( item . edit ) ) )
92
105
}
93
106
94
107
function classNameToAst (
@@ -154,11 +167,56 @@ function classNameToAst(
154
167
return cssObjToAst ( obj , state . modules . postcss )
155
168
}
156
169
157
- async function provideInvalidApplyCodeAction (
170
+ async function provideUtilityConflictsCodeActions (
171
+ state : State ,
172
+ params : CodeActionParams ,
173
+ diagnostic : UtilityConflictsDiagnostic
174
+ ) : Promise < CodeAction [ ] > {
175
+ return [
176
+ {
177
+ title : `Delete '${ diagnostic . className . className } '` ,
178
+ kind : CodeActionKind . QuickFix ,
179
+ diagnostics : [ diagnostic ] ,
180
+ edit : {
181
+ changes : {
182
+ [ params . textDocument . uri ] : [
183
+ {
184
+ range : diagnostic . className . classList . range ,
185
+ newText : removeRangeFromString (
186
+ diagnostic . className . classList . classList ,
187
+ diagnostic . className . relativeRange
188
+ ) ,
189
+ } ,
190
+ ] ,
191
+ } ,
192
+ } ,
193
+ } ,
194
+ {
195
+ title : `Delete '${ diagnostic . otherClassName . className } '` ,
196
+ kind : CodeActionKind . QuickFix ,
197
+ diagnostics : [ diagnostic ] ,
198
+ edit : {
199
+ changes : {
200
+ [ params . textDocument . uri ] : [
201
+ {
202
+ range : diagnostic . className . classList . range ,
203
+ newText : removeRangeFromString (
204
+ diagnostic . className . classList . classList ,
205
+ diagnostic . otherClassName . relativeRange
206
+ ) ,
207
+ } ,
208
+ ] ,
209
+ } ,
210
+ } ,
211
+ } ,
212
+ ]
213
+ }
214
+
215
+ async function provideInvalidApplyCodeActions (
158
216
state : State ,
159
217
params : CodeActionParams ,
160
218
diagnostic : InvalidApplyDiagnostic
161
- ) : Promise < CodeAction > {
219
+ ) : Promise < CodeAction [ ] > {
162
220
let document = state . editor . documents . get ( params . textDocument . uri )
163
221
let documentText = document . getText ( )
164
222
const { postcss } = state . modules
@@ -250,30 +308,32 @@ async function provideInvalidApplyCodeAction(
250
308
] ) . process ( documentText , { from : undefined } )
251
309
252
310
if ( ! change ) {
253
- return null
311
+ return [ ]
254
312
}
255
313
256
- return {
257
- title : 'Extract to new rule.' ,
258
- kind : CodeActionKind . QuickFix ,
259
- diagnostics : [ diagnostic ] ,
260
- edit : {
261
- changes : {
262
- [ params . textDocument . uri ] : [
263
- ...( totalClassNamesInClassList > 1
264
- ? [
265
- {
266
- range : diagnostic . className . classList . range ,
267
- newText : removeRangeFromString (
268
- diagnostic . className . classList . classList ,
269
- diagnostic . className . relativeRange
270
- ) ,
271
- } ,
272
- ]
273
- : [ ] ) ,
274
- change ,
275
- ] ,
314
+ return [
315
+ {
316
+ title : 'Extract to new rule' ,
317
+ kind : CodeActionKind . QuickFix ,
318
+ diagnostics : [ diagnostic ] ,
319
+ edit : {
320
+ changes : {
321
+ [ params . textDocument . uri ] : [
322
+ ...( totalClassNamesInClassList > 1
323
+ ? [
324
+ {
325
+ range : diagnostic . className . classList . range ,
326
+ newText : removeRangeFromString (
327
+ diagnostic . className . classList . classList ,
328
+ diagnostic . className . relativeRange
329
+ ) ,
330
+ } ,
331
+ ]
332
+ : [ ] ) ,
333
+ change ,
334
+ ] ,
335
+ } ,
276
336
} ,
277
337
} ,
278
- }
338
+ ]
279
339
}
0 commit comments