@@ -21,7 +21,7 @@ use crate::{
21
21
generated:: ast_nodes:: { AstNode , AstNodes } ,
22
22
utils:: {
23
23
call_expression:: is_test_call_expression, is_long_curried_call,
24
- member_chain:: simple_argument:: SimpleArgument , write_arguments_multi_line ,
24
+ member_chain:: simple_argument:: SimpleArgument ,
25
25
} ,
26
26
write,
27
27
write:: {
@@ -44,13 +44,15 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
44
44
fn fmt ( & self , f : & mut Formatter < ' _ , ' a > ) -> FormatResult < ( ) > {
45
45
let l_paren_token = "(" ;
46
46
let r_paren_token = ")" ;
47
+ let call_like_span = self . parent . span ( ) ;
48
+
47
49
if self . is_empty ( ) {
48
50
return write ! (
49
51
f,
50
52
[
51
53
l_paren_token,
52
54
// `call/* comment1 */(/* comment2 */)` Both comments are dangling comments.
53
- format_dangling_comments( self . parent . span ( ) ) . with_soft_block_indent( ) ,
55
+ format_dangling_comments( call_like_span ) . with_soft_block_indent( ) ,
54
56
r_paren_token
55
57
]
56
58
) ;
@@ -59,26 +61,24 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
59
61
let call_expression =
60
62
if let AstNodes :: CallExpression ( call) = self . parent { Some ( call) } else { None } ;
61
63
62
- let ( is_commonjs_or_amd_call, is_test_call) = if let Some ( call) = call_expression {
63
- ( is_commonjs_or_amd_call ( self , call) , is_test_call_expression ( call) )
64
- } else {
65
- ( false , false )
66
- } ;
67
-
68
- let is_first_arg_string_literal_or_template = self . len ( ) != 2
69
- || matches ! (
70
- self . as_ref( ) . first( ) ,
71
- Some (
72
- Argument :: StringLiteral ( _)
73
- | Argument :: TemplateLiteral ( _)
74
- | Argument :: TaggedTemplateExpression ( _)
75
- )
76
- ) ;
64
+ let ( is_commonjs_or_amd_call, is_test_call) = call_expression
65
+ . map ( |call| ( is_commonjs_or_amd_call ( self , call) , is_test_call_expression ( call) ) )
66
+ . unwrap_or_default ( ) ;
77
67
78
68
if is_commonjs_or_amd_call
79
69
|| is_multiline_template_only_args ( self , f. source_text ( ) )
80
70
|| is_react_hook_with_deps_array ( self , f. comments ( ) )
81
- || ( is_test_call && is_first_arg_string_literal_or_template)
71
+ || ( is_test_call && {
72
+ self . len ( ) != 2
73
+ || matches ! (
74
+ self . as_ref( ) . first( ) ,
75
+ Some (
76
+ Argument :: StringLiteral ( _)
77
+ | Argument :: TemplateLiteral ( _)
78
+ | Argument :: TaggedTemplateExpression ( _)
79
+ )
80
+ )
81
+ } )
82
82
{
83
83
return write ! (
84
84
f,
@@ -98,27 +98,26 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
98
98
) ;
99
99
}
100
100
101
- let mut has_empty_line = false ;
102
-
103
101
let has_empty_line = self . iter ( ) . any ( |arg| get_lines_before ( arg. span ( ) , f) > 1 ) ;
104
-
105
102
if has_empty_line || is_function_composition_args ( self ) {
106
103
return format_all_args_broken_out ( self , true , f) ;
107
104
}
108
105
109
- if let Some ( group_layout) = arguments_grouped_layout ( self , f) {
106
+ if let Some ( group_layout) = arguments_grouped_layout ( call_like_span , self , f) {
110
107
write_grouped_arguments ( self , group_layout, f)
111
108
} else if call_expression. is_some_and ( |call| is_long_curried_call ( call) ) {
112
109
write ! (
113
110
f,
114
111
[
115
112
l_paren_token,
116
113
soft_block_indent( & format_once( |f| {
117
- write_arguments_multi_line(
118
- FormatSeparatedIter :: new( self . iter( ) , "," )
119
- . with_trailing_separator( TrailingSeparator :: Omit ) ,
120
- f,
121
- )
114
+ f. join_with( soft_line_break_or_space( ) )
115
+ . entries_with_trailing_separator(
116
+ self . iter( ) ,
117
+ "," ,
118
+ TrailingSeparator :: Allowed ,
119
+ )
120
+ . finish( )
122
121
} ) ) ,
123
122
r_paren_token,
124
123
]
@@ -175,11 +174,9 @@ pub fn is_function_composition_args(args: &[Argument<'_>]) -> bool {
175
174
176
175
fn format_all_elements_broken_out < ' a , ' b > (
177
176
elements : impl Iterator < Item = ( FormatResult < Option < FormatElement < ' a > > > , usize ) > ,
178
- node : & ' b AstNode < ' a , ArenaVec < ' a , Argument < ' a > > > ,
179
177
expand : bool ,
180
178
mut buffer : impl Buffer < ' a > ,
181
179
) -> FormatResult < ( ) > {
182
- let is_inside_import = matches ! ( node. parent, AstNodes :: ImportExpression ( _) ) ;
183
180
write ! (
184
181
buffer,
185
182
[ group( & format_args!(
@@ -198,7 +195,7 @@ fn format_all_elements_broken_out<'a, 'b>(
198
195
}
199
196
}
200
197
201
- write!( f, [ ( !is_inside_import ) . then_some ( FormatTrailingCommas :: All ) ] )
198
+ write!( f, FormatTrailingCommas :: All )
202
199
} ) ) ,
203
200
")" ,
204
201
) )
@@ -211,7 +208,6 @@ fn format_all_args_broken_out<'a, 'b>(
211
208
expand : bool ,
212
209
mut buffer : impl Buffer < ' a > ,
213
210
) -> FormatResult < ( ) > {
214
- let is_inside_import = matches ! ( node. parent, AstNodes :: ImportExpression ( _) ) ;
215
211
let last_index = node. len ( ) - 1 ;
216
212
write ! (
217
213
buffer,
@@ -229,7 +225,7 @@ fn format_all_args_broken_out<'a, 'b>(
229
225
write!( f, [ argument, ( index != last_index) . then_some( "," ) ] ) ?;
230
226
}
231
227
232
- write!( f, [ ( !is_inside_import ) . then_some ( FormatTrailingCommas :: All ) ] )
228
+ write!( f, FormatTrailingCommas :: All )
233
229
} ) ) ,
234
230
")" ,
235
231
) )
@@ -238,20 +234,25 @@ fn format_all_args_broken_out<'a, 'b>(
238
234
}
239
235
240
236
pub fn arguments_grouped_layout (
241
- args : & AstNode < ArenaVec < Argument > > ,
237
+ call_like_span : Span ,
238
+ args : & [ Argument ] ,
242
239
f : & Formatter < ' _ , ' _ > ,
243
240
) -> Option < GroupedCallArgumentLayout > {
244
- if should_group_first_argument ( args, f) {
241
+ if should_group_first_argument ( call_like_span , args, f) {
245
242
Some ( GroupedCallArgumentLayout :: GroupedFirstArgument )
246
- } else if should_group_last_argument ( args, f) {
243
+ } else if should_group_last_argument ( call_like_span , args, f) {
247
244
Some ( GroupedCallArgumentLayout :: GroupedLastArgument )
248
245
} else {
249
246
None
250
247
}
251
248
}
252
249
253
250
/// Checks if the first argument requires grouping
254
- fn should_group_first_argument ( args : & AstNode < ArenaVec < Argument > > , f : & Formatter < ' _ , ' _ > ) -> bool {
251
+ fn should_group_first_argument (
252
+ call_like_span : Span ,
253
+ args : & [ Argument ] ,
254
+ f : & Formatter < ' _ , ' _ > ,
255
+ ) -> bool {
255
256
let mut iter = args. iter ( ) ;
256
257
match ( iter. next ( ) . and_then ( |a| a. as_expression ( ) ) , iter. next ( ) . and_then ( |a| a. as_expression ( ) ) )
257
258
{
@@ -279,7 +280,6 @@ fn should_group_first_argument(args: &AstNode<ArenaVec<Argument>>, f: &Formatter
279
280
return false ;
280
281
}
281
282
282
- let call_like_span = args. parent . span ( ) ;
283
283
!f. comments ( ) . has_comments ( call_like_span. start , first. span ( ) , second. span ( ) . start )
284
284
&& !can_group_expression_argument ( second, f)
285
285
&& is_relatively_short_argument ( second)
@@ -289,8 +289,12 @@ fn should_group_first_argument(args: &AstNode<ArenaVec<Argument>>, f: &Formatter
289
289
}
290
290
291
291
/// Checks if the last argument should be grouped.
292
- fn should_group_last_argument ( args : & AstNode < ArenaVec < Argument > > , f : & Formatter < ' _ , ' _ > ) -> bool {
293
- let mut iter = args. as_ref ( ) . iter ( ) ;
292
+ fn should_group_last_argument (
293
+ call_like_span : Span ,
294
+ args : & [ Argument ] ,
295
+ f : & Formatter < ' _ , ' _ > ,
296
+ ) -> bool {
297
+ let mut iter = args. iter ( ) ;
294
298
let last = iter. next_back ( ) ;
295
299
296
300
match last. and_then ( |arg| arg. as_expression ( ) ) {
@@ -303,7 +307,6 @@ fn should_group_last_argument(args: &AstNode<ArenaVec<Argument>>, f: &Formatter<
303
307
// }
304
308
}
305
309
306
- let call_like_span = args. parent . span ( ) ;
307
310
let previous_span = penultimate. map_or ( call_like_span. start , |a| a. span ( ) . end ) ;
308
311
if f. comments ( ) . has_comments ( previous_span, last. span ( ) , call_like_span. end ) {
309
312
return false ;
@@ -595,13 +598,10 @@ fn write_grouped_arguments<'a>(
595
598
// which would lead to a wrong line count.
596
599
let lines_before = get_lines_before ( argument. span ( ) , f) ;
597
600
598
- let interned = f. intern (
599
- & format_once ( |f| {
600
- format_argument. fmt ( f) ?;
601
- write ! ( f, ( last_index != index) . then_some( "," ) )
602
- } )
603
- . memoized ( ) ,
604
- ) ;
601
+ let interned = f. intern ( & format_once ( |f| {
602
+ format_argument. fmt ( f) ?;
603
+ write ! ( f, ( last_index != index) . then_some( "," ) )
604
+ } ) ) ;
605
605
606
606
let break_type =
607
607
if is_grouped_argument { & mut grouped_breaks } else { & mut non_grouped_breaks } ;
@@ -618,7 +618,7 @@ fn write_grouped_arguments<'a>(
618
618
// If any of the not grouped elements break, then fall back to the variant where
619
619
// all arguments are printed in expanded mode.
620
620
if non_grouped_breaks {
621
- return format_all_elements_broken_out ( elements. into_iter ( ) , node , true , f) ;
621
+ return format_all_elements_broken_out ( elements. into_iter ( ) , true , f) ;
622
622
}
623
623
624
624
// We now cache the delimiter tokens. This is needed because `[crate::best_fitting]` will try to
@@ -631,7 +631,7 @@ fn write_grouped_arguments<'a>(
631
631
let mut buffer = VecBuffer :: new ( f. state_mut ( ) ) ;
632
632
buffer. write_element ( FormatElement :: Tag ( Tag :: StartEntry ) ) ?;
633
633
634
- format_all_elements_broken_out ( elements. iter ( ) . cloned ( ) , node , true , & mut buffer) ;
634
+ format_all_elements_broken_out ( elements. iter ( ) . cloned ( ) , true , & mut buffer) ;
635
635
636
636
buffer. write_element ( FormatElement :: Tag ( Tag :: EndEntry ) ) ?;
637
637
0 commit comments