9
9
} from "@eslint-community/eslint-utils" ;
10
10
import type { Rule , AST as ESLintAST , SourceCode } from "eslint" ;
11
11
import type { AST } from "jsonc-eslint-parser" ;
12
+ import type * as ESTree from "estree" ;
12
13
13
14
/**
14
15
* Check if the token is a comma.
@@ -55,14 +56,23 @@ export function* fixForSorting(
55
56
) : IterableIterator < Rule . Fix > {
56
57
const targetInfo = calcTargetInfo ( sourceCode , target ) ;
57
58
58
- const toBeforeToken = to . node
59
- ? sourceCode . getTokenBefore ( getFirstTokenOfNode ( sourceCode , to . node ) ) !
60
- : to . before ;
61
- let insertRange = toBeforeToken . range ;
62
- const toBeforeNextToken = sourceCode . getTokenAfter ( toBeforeToken , {
59
+ const toPrevInfo = getPrevElementInfo ( sourceCode , to ) ;
60
+
61
+ if (
62
+ toPrevInfo . comma &&
63
+ toPrevInfo . last . range ! [ 1 ] <= toPrevInfo . comma . range [ 0 ]
64
+ ) {
65
+ yield fixer . removeRange ( toPrevInfo . comma . range ) ;
66
+ }
67
+
68
+ let insertRange = [
69
+ toPrevInfo . last . range ! [ 1 ] ,
70
+ toPrevInfo . last . range ! [ 1 ] ,
71
+ ] as ESLintAST . Range ;
72
+ const toBeforeNextToken = sourceCode . getTokenAfter ( toPrevInfo . last , {
63
73
includeComments : true ,
64
74
} ) ! ;
65
- if ( toBeforeNextToken . loc ! . start . line - toBeforeToken . loc . end . line > 1 ) {
75
+ if ( toBeforeNextToken . loc ! . start . line - toPrevInfo . last . loc ! . end . line > 1 ) {
66
76
// If there are blank lines, the element is inserted after the blank lines.
67
77
const offset = sourceCode . getIndexFromLoc ( {
68
78
line : toBeforeNextToken . loc ! . start . line - 1 ,
@@ -94,35 +104,41 @@ function calcTargetInfo(
94
104
const nodeLastToken = getLastTokenOfNode ( sourceCode , node ) ;
95
105
96
106
const endInfo = getElementEndInfo ( sourceCode , node ) ;
97
- const prevInfo = getPrevElementInfo ( sourceCode , node ) ;
107
+ const prevInfo = getPrevElementInfo ( sourceCode , { node } ) ;
98
108
99
109
let insertCode : string ;
100
110
101
111
const removeRanges : ESLintAST . Range [ ] = [ ] ;
102
- if ( prevInfo . comma && prevInfo . end <= prevInfo . comma . range [ 0 ] ) {
112
+ if ( prevInfo . comma && prevInfo . last . range ! [ 1 ] <= prevInfo . comma . range [ 0 ] ) {
103
113
insertCode = `${ sourceCode . text . slice (
104
- prevInfo . end ,
114
+ prevInfo . last . range ! [ 1 ] ,
105
115
prevInfo . comma . range [ 0 ] ,
106
116
) } ${ sourceCode . text . slice ( prevInfo . comma . range [ 1 ] , nodeLastToken . range [ 1 ] ) } `;
107
117
removeRanges . push (
108
- [ prevInfo . end , prevInfo . comma . range [ 0 ] ] ,
118
+ [ prevInfo . last . range ! [ 1 ] , prevInfo . comma . range [ 0 ] ] ,
109
119
[ prevInfo . comma . range [ 1 ] , nodeLastToken . range [ 1 ] ] ,
110
120
) ;
111
121
} else {
112
- insertCode = sourceCode . text . slice ( prevInfo . end , nodeLastToken . range [ 1 ] ) ;
113
- removeRanges . push ( [ prevInfo . end , nodeLastToken . range [ 1 ] ] ) ;
122
+ insertCode = sourceCode . text . slice (
123
+ prevInfo . last . range ! [ 1 ] ,
124
+ nodeLastToken . range [ 1 ] ,
125
+ ) ;
126
+ removeRanges . push ( [ prevInfo . last . range ! [ 1 ] , nodeLastToken . range [ 1 ] ] ) ;
114
127
}
115
128
116
129
const hasTrailingComma =
117
- endInfo . comma && endInfo . comma . range [ 1 ] <= endInfo . end ;
130
+ endInfo . comma && endInfo . comma . range [ 1 ] <= endInfo . last . range ! [ 1 ] ;
118
131
if ( ! hasTrailingComma ) {
119
132
insertCode += "," ;
120
133
if ( prevInfo . comma ) {
121
134
removeRanges . push ( prevInfo . comma . range ) ;
122
135
}
123
136
}
124
- insertCode += sourceCode . text . slice ( nodeLastToken . range [ 1 ] , endInfo . end ) ;
125
- removeRanges . push ( [ nodeLastToken . range [ 1 ] , endInfo . end ] ) ;
137
+ insertCode += sourceCode . text . slice (
138
+ nodeLastToken . range [ 1 ] ,
139
+ endInfo . last . range ! [ 1 ] ,
140
+ ) ;
141
+ removeRanges . push ( [ nodeLastToken . range [ 1 ] , endInfo . last . range ! [ 1 ] ] ) ;
126
142
127
143
return {
128
144
insertCode,
@@ -214,8 +230,8 @@ function getElementEndInfo(
214
230
comma : ESLintAST . Token | null ;
215
231
// Next element token
216
232
nextElement : ESLintAST . Token | null ;
217
- // The end of the range of the target element
218
- end : number ;
233
+ // The last token of the target element
234
+ last : ESLintAST . Token | ESTree . Comment ;
219
235
} {
220
236
const lastToken = getLastTokenOfNode ( sourceCode , node ) ;
221
237
const afterToken = sourceCode . getTokenAfter ( lastToken ) ! ;
@@ -224,7 +240,7 @@ function getElementEndInfo(
224
240
return {
225
241
comma : null ,
226
242
nextElement : null ,
227
- end : calcEndWithTrailingComments ( ) ,
243
+ last : getLastTokenWithTrailingComments ( ) ,
228
244
} ;
229
245
}
230
246
const comma = afterToken ;
@@ -235,7 +251,7 @@ function getElementEndInfo(
235
251
return {
236
252
comma,
237
253
nextElement : null ,
238
- end : comma . range [ 1 ] ,
254
+ last : comma ,
239
255
} ;
240
256
}
241
257
if ( isClosingBrace ( nextElement ) || isClosingBracket ( nextElement ) ) {
@@ -244,7 +260,7 @@ function getElementEndInfo(
244
260
return {
245
261
comma,
246
262
nextElement : null ,
247
- end : calcEndWithTrailingComments ( ) ,
263
+ last : getLastTokenWithTrailingComments ( ) ,
248
264
} ;
249
265
}
250
266
@@ -253,7 +269,7 @@ function getElementEndInfo(
253
269
return {
254
270
comma,
255
271
nextElement,
256
- end : comma . range [ 1 ] ,
272
+ last : comma ,
257
273
} ;
258
274
}
259
275
// There are line breaks between the target element and the next element.
@@ -266,34 +282,35 @@ function getElementEndInfo(
266
282
return {
267
283
comma,
268
284
nextElement,
269
- end : comma . range [ 1 ] ,
285
+ last : comma ,
270
286
} ;
271
287
}
272
288
273
289
return {
274
290
comma,
275
291
nextElement,
276
- end : calcEndWithTrailingComments ( ) ,
292
+ last : getLastTokenWithTrailingComments ( ) ,
277
293
} ;
278
294
279
295
/**
280
- * Calculate the end of the target element with trailing comments.
296
+ * Get the last token of the target element with trailing comments.
281
297
*/
282
- function calcEndWithTrailingComments ( ) {
283
- let end = lastToken . range [ 1 ] ;
298
+ function getLastTokenWithTrailingComments ( ) {
299
+ if ( lastToken == null ) return afterToken ;
300
+ let last : ESLintAST . Token | ESTree . Comment = lastToken ;
284
301
let after = sourceCode . getTokenAfter ( lastToken , {
285
302
includeComments : true ,
286
303
} ) ! ;
287
304
while (
288
305
( isCommentToken ( after ) || isComma ( after ) ) &&
289
306
node . loc . end . line === after . loc ! . end . line
290
307
) {
291
- end = after . range ! [ 1 ] ;
308
+ last = after ;
292
309
after = sourceCode . getTokenAfter ( after , {
293
310
includeComments : true ,
294
311
} ) ! ;
295
312
}
296
- return end ;
313
+ return last ;
297
314
}
298
315
}
299
316
@@ -302,23 +319,24 @@ function getElementEndInfo(
302
319
*/
303
320
function getPrevElementInfo (
304
321
sourceCode : SourceCode ,
305
- node : AST . JSONNode ,
322
+ target : Target ,
306
323
) : {
307
324
// Leading comma
308
325
comma : ESLintAST . Token | null ;
309
326
// Previous element token
310
327
prevElement : ESLintAST . Token | null ;
311
- // The end of the range of the target element
312
- end : number ;
328
+ // The last token of the target element
329
+ last : ESLintAST . Token | ESTree . Comment ;
313
330
} {
314
- const firstToken = getFirstTokenOfNode ( sourceCode , node ) ;
315
- const beforeToken = sourceCode . getTokenBefore ( firstToken ) ! ;
331
+ const beforeToken = target . node
332
+ ? sourceCode . getTokenBefore ( getFirstTokenOfNode ( sourceCode , target . node ) ) !
333
+ : target . before ;
316
334
if ( isNotCommaToken ( beforeToken ) ) {
317
335
// If there is no comma, the element is the first element.
318
336
return {
319
337
comma : null ,
320
338
prevElement : null ,
321
- end : beforeToken . range [ 1 ] ,
339
+ last : beforeToken ,
322
340
} ;
323
341
}
324
342
const comma = beforeToken ;
@@ -330,7 +348,7 @@ function getPrevElementInfo(
330
348
return {
331
349
comma,
332
350
prevElement : null ,
333
- end : comma . range [ 1 ] ,
351
+ last : comma ,
334
352
} ;
335
353
}
336
354
@@ -339,6 +357,6 @@ function getPrevElementInfo(
339
357
return {
340
358
comma : endInfo . comma ,
341
359
prevElement,
342
- end : endInfo . end ,
360
+ last : endInfo . last ,
343
361
} ;
344
362
}
0 commit comments