@@ -23,13 +23,20 @@ where
23
23
}
24
24
}
25
25
26
+ #[ allow( clippy:: range_plus_one, clippy:: too_many_lines) ]
26
27
pub fn sort < F > ( node : & SyntaxNode , transform : F )
27
28
where
28
29
F : Fn ( & str ) -> String ,
29
30
{
30
31
for array in node. children_with_tokens ( ) {
31
32
if array. kind ( ) == ARRAY {
32
33
let array_node = array. as_node ( ) . unwrap ( ) ;
34
+ let has_trailing_comma = array_node
35
+ . children_with_tokens ( )
36
+ . map ( |x| x. kind ( ) )
37
+ . filter ( |x| * x == COMMA || * x == VALUE )
38
+ . last ( )
39
+ == Some ( COMMA ) ;
33
40
let mut value_set = Vec :: < Vec < SyntaxElement > > :: new ( ) ;
34
41
let entry_set = RefCell :: new ( Vec :: < SyntaxElement > :: new ( ) ) ;
35
42
let mut key_to_pos = HashMap :: < String , usize > :: new ( ) ;
@@ -44,20 +51,12 @@ where
44
51
} ;
45
52
let mut entries = Vec :: < SyntaxElement > :: new ( ) ;
46
53
let mut has_value = false ;
47
- let mut previous_is_value = false ;
48
54
let mut previous_is_bracket_open = false ;
49
55
let mut entry_value = String :: new ( ) ;
50
56
let mut count = 0 ;
51
57
52
58
for entry in array_node. children_with_tokens ( ) {
53
59
count += 1 ;
54
- if previous_is_value {
55
- // make sure ends with trailing comma
56
- previous_is_value = false ;
57
- if entry. kind ( ) != COMMA {
58
- entry_set. borrow_mut ( ) . push ( make_comma ( ) ) ;
59
- }
60
- }
61
60
if previous_is_bracket_open {
62
61
// make sure ends with trailing comma
63
62
if entry. kind ( ) == NEWLINE || entry. kind ( ) == WHITESPACE {
100
99
return ;
101
100
}
102
101
entry_set. borrow_mut ( ) . push ( entry) ;
103
- previous_is_value = true ;
102
+ entry_set . borrow_mut ( ) . push ( make_comma ( ) ) ;
104
103
}
105
104
NEWLINE => {
106
105
entry_set. borrow_mut ( ) . push ( entry) ;
@@ -109,6 +108,7 @@ where
109
108
has_value = false ;
110
109
}
111
110
}
111
+ COMMA => { }
112
112
_ => {
113
113
entry_set. borrow_mut ( ) . push ( entry) ;
114
114
}
@@ -123,6 +123,16 @@ where
123
123
}
124
124
entries. extend ( end) ;
125
125
array_node. splice_children ( 0 ..count, entries) ;
126
+ if !has_trailing_comma {
127
+ if let Some ( ( i, _) ) = array_node
128
+ . children_with_tokens ( )
129
+ . enumerate ( )
130
+ . filter ( |( _, x) | x. kind ( ) == COMMA )
131
+ . last ( )
132
+ {
133
+ array_node. splice_children ( i..i + 1 , vec ! [ ] ) ;
134
+ }
135
+ }
126
136
}
127
137
}
128
138
}
@@ -211,30 +221,23 @@ mod tests {
211
221
a = []
212
222
" } ,
213
223
indoc ! { r"
214
- a = [
215
- ]
224
+ a = []
216
225
" }
217
226
) ]
218
227
#[ case:: single(
219
228
indoc ! { r#"
220
229
a = ["A"]
221
230
"# } ,
222
231
indoc ! { r#"
223
- a = [
224
- "A",
225
- ]
232
+ a = ["A"]
226
233
"# }
227
234
) ]
228
235
#[ case:: newline_single(
229
236
indoc ! { r#"
230
- a = [
231
- "A"
232
- ]
237
+ a = ["A"]
233
238
"# } ,
234
239
indoc ! { r#"
235
- a = [
236
- "A",
237
- ]
240
+ a = ["A"]
238
241
"# }
239
242
) ]
240
243
#[ case:: newline_single_comment(
@@ -250,6 +253,14 @@ mod tests {
250
253
]
251
254
"# }
252
255
) ]
256
+ #[ case:: double(
257
+ indoc ! { r#"
258
+ a = ["A", "B"]
259
+ "# } ,
260
+ indoc ! { r#"
261
+ a = ["A", "B"]
262
+ "# }
263
+ ) ]
253
264
#[ case:: increasing(
254
265
indoc ! { r#"
255
266
a=["B", "D",
@@ -284,10 +295,31 @@ mod tests {
284
295
}
285
296
}
286
297
let opt = Options {
287
- column_width : 1 ,
298
+ column_width : 120 ,
288
299
..Options :: default ( )
289
300
} ;
290
301
let res = format_syntax ( root_ast, opt) ;
291
302
assert_eq ! ( res, expected) ;
292
303
}
304
+
305
+ #[ rstest]
306
+ #[ case:: reorder_no_trailing_comma(
307
+ indoc ! { r#"a=["B","A"]"# } ,
308
+ indoc ! { r#"a=["A","B"]"# }
309
+ ) ]
310
+ fn test_reorder_no_trailing_comma ( #[ case] start : & str , #[ case] expected : & str ) {
311
+ let root_ast = parse ( start) . into_syntax ( ) . clone_for_update ( ) ;
312
+ for children in root_ast. children_with_tokens ( ) {
313
+ if children. kind ( ) == ENTRY {
314
+ for entry in children. as_node ( ) . unwrap ( ) . children_with_tokens ( ) {
315
+ if entry. kind ( ) == VALUE {
316
+ sort ( entry. as_node ( ) . unwrap ( ) , str:: to_lowercase) ;
317
+ }
318
+ }
319
+ }
320
+ }
321
+ let mut res = root_ast. to_string ( ) ;
322
+ res. retain ( |x| !x. is_whitespace ( ) ) ;
323
+ assert_eq ! ( res, expected) ;
324
+ }
293
325
}
0 commit comments