@@ -2151,94 +2151,111 @@ fn gen_class_expr<'a>(node: &'a ClassExpr, context: &mut Context<'a>) -> PrintIt
2151
2151
}
2152
2152
2153
2153
fn gen_conditional_expr < ' a > ( node : & ' a CondExpr , context : & mut Context < ' a > ) -> PrintItems {
2154
- let operator_token = context. token_finder . get_first_operator_after ( & node. test , "?" ) . unwrap ( ) ;
2155
- let force_new_lines = !context. config . conditional_expression_prefer_single_line
2156
- && ( node_helpers:: get_use_new_lines_for_nodes ( & node. test , & node. cons , context. program )
2157
- || node_helpers:: get_use_new_lines_for_nodes ( & node. cons , & node. alt , context. program ) ) ;
2158
- let operator_position = get_operator_position ( node, operator_token, context) ;
2154
+ let question_token = context. token_finder . get_first_operator_after ( & node. test , "?" ) . unwrap ( ) ;
2155
+ let colon_token = context. token_finder . get_first_operator_after ( & node. cons , ":" ) . unwrap ( ) ;
2156
+ let line_per_expression = context. config . conditional_expression_line_per_expression ;
2157
+ let has_newline_test_cons = node_helpers:: get_use_new_lines_for_nodes ( & node. test , & node. cons , context. program ) ;
2158
+ let has_newline_const_alt = node_helpers:: get_use_new_lines_for_nodes ( & node. cons , & node. alt , context. program ) ;
2159
+ let mut force_test_cons_newline = !context. config . conditional_expression_prefer_single_line && has_newline_test_cons;
2160
+ let mut force_cons_alt_newline = !context. config . conditional_expression_prefer_single_line && has_newline_const_alt;
2161
+ if line_per_expression && ( force_test_cons_newline || force_cons_alt_newline) {
2162
+ // for line per expression, if one is true then both should be true
2163
+ force_test_cons_newline = true ;
2164
+ force_cons_alt_newline = true ;
2165
+ }
2166
+
2167
+ let operator_position = get_operator_position ( node, question_token, context) ;
2159
2168
let top_most_data = get_top_most_data ( node, context) ;
2160
2169
let before_alternate_ln = LineNumber :: new ( "beforeAlternate" ) ;
2161
2170
let end_ln = LineNumber :: new ( "endConditionalExpression" ) ;
2171
+ let question_comment_items = gen_token_comments ( question_token, context, top_most_data. il ) ;
2172
+ let colon_comment_items = gen_token_comments ( colon_token, context, top_most_data. il ) ;
2162
2173
let mut items = PrintItems :: new ( ) ;
2163
2174
2164
2175
if top_most_data. is_top_most {
2165
- items. push_info ( top_most_data. top_most_ln ) ;
2166
- items. push_info ( top_most_data. top_most_il ) ;
2176
+ items. push_info ( top_most_data. ln ) ;
2177
+ items. push_info ( top_most_data. il ) ;
2167
2178
}
2168
2179
2169
- items . extend ( ir_helpers :: new_line_group ( with_queued_indent ( gen_node_with_inner_gen (
2170
- node . test . into ( ) ,
2171
- context ,
2172
- {
2173
- move | mut items , _| {
2174
- if operator_position == OperatorPosition :: SameLine {
2175
- items . push_str ( " ?" ) ;
2176
- }
2177
- items
2178
- }
2179
- } ,
2180
- ) ) ) ) ;
2180
+ let top_most_il = top_most_data . il ;
2181
+
2182
+ items . extend ( ir_helpers :: new_line_group ( with_queued_indent ( {
2183
+ let mut items = gen_node ( node . test . into ( ) , context ) ;
2184
+ if operator_position == OperatorPosition :: SameLine {
2185
+ items . push_str ( " ?" ) ;
2186
+ }
2187
+ items . extend ( question_comment_items . trailing_line ) ;
2188
+ items
2189
+ } ) ) ) ;
2190
+
2191
+ items . extend ( question_comment_items . previous_lines ) ;
2181
2192
2182
2193
items. push_anchor ( LineNumberAnchor :: new ( end_ln) ) ;
2183
2194
items. push_anchor ( LineNumberAnchor :: new ( before_alternate_ln) ) ;
2184
2195
2185
- let multi_line_reevaluation = if force_new_lines {
2196
+ let multi_line_reevaluation = if force_test_cons_newline {
2186
2197
items. push_signal ( Signal :: NewLine ) ;
2187
2198
None
2188
- } else {
2189
- let mut condition = conditions:: new_line_if_multiple_lines_space_or_new_line_otherwise ( top_most_data. top_most_ln , Some ( before_alternate_ln) ) ;
2199
+ } else if line_per_expression {
2200
+ let mut condition = conditions:: new_line_if_multiple_lines_space_or_new_line_otherwise ( top_most_data. ln , Some ( before_alternate_ln) ) ;
2190
2201
let reevaluation = condition. create_reevaluation ( ) ;
2191
2202
items. push_condition ( condition) ;
2192
2203
Some ( reevaluation)
2204
+ } else {
2205
+ items. push_signal ( Signal :: SpaceOrNewLine ) ;
2206
+ None
2193
2207
} ;
2194
2208
2195
2209
let cons_and_alt_items = {
2196
2210
let mut items = PrintItems :: new ( ) ;
2197
2211
2198
2212
// add any preceeding comments of the question token
2199
2213
items. extend ( {
2200
- let operator_token_leading_comments = get_leading_comments_on_previous_lines ( & operator_token . range ( ) , context) ;
2214
+ let operator_token_leading_comments = get_leading_comments_on_previous_lines ( & question_token . range ( ) , context) ;
2201
2215
let mut items = gen_comment_collection ( operator_token_leading_comments. into_iter ( ) , None , None , context) ;
2202
2216
if !items. is_empty ( ) {
2203
2217
items. push_signal ( Signal :: NewLine ) ;
2204
2218
}
2205
2219
items
2206
2220
} ) ;
2207
2221
2208
- if operator_position == OperatorPosition :: NextLine {
2209
- items. push_str ( "? " ) ;
2210
- }
2211
- items. extend ( ir_helpers:: new_line_group ( gen_node_with_inner_gen ( node. cons . into ( ) , context, {
2212
- move |mut items, _| {
2213
- if operator_position == OperatorPosition :: SameLine {
2214
- items. push_str ( " :" ) ;
2215
- items
2216
- } else {
2217
- conditions:: indent_if_start_of_line ( items) . into ( )
2218
- }
2222
+ items. push_condition ( {
2223
+ let mut items = PrintItems :: new ( ) ;
2224
+ items. extend ( question_comment_items. leading_line ) ;
2225
+ if operator_position == OperatorPosition :: NextLine {
2226
+ items. push_str ( "? " ) ;
2219
2227
}
2220
- } ) ) ) ;
2228
+ items. extend ( gen_node ( node. cons . into ( ) , context) ) ;
2229
+ if operator_position == OperatorPosition :: SameLine {
2230
+ items. push_str ( " :" ) ;
2231
+ }
2232
+ items. extend ( colon_comment_items. trailing_line ) ;
2233
+ indent_if_sol_and_same_indent_as_top_most ( ir_helpers:: new_line_group ( items) , top_most_il)
2234
+ } ) ;
2221
2235
2222
- if force_new_lines {
2236
+ items. extend ( colon_comment_items. previous_lines ) ;
2237
+
2238
+ if force_cons_alt_newline {
2223
2239
items. push_signal ( Signal :: NewLine ) ;
2224
- } else {
2240
+ } else if line_per_expression {
2225
2241
items. push_condition ( conditions:: new_line_if_multiple_lines_space_or_new_line_otherwise (
2226
- top_most_data. top_most_ln ,
2242
+ top_most_data. ln ,
2227
2243
Some ( before_alternate_ln) ,
2228
2244
) ) ;
2245
+ } else {
2246
+ items. push_signal ( Signal :: SpaceOrNewLine ) ;
2229
2247
}
2230
2248
2231
- if operator_position == OperatorPosition :: NextLine {
2232
- items. push_str ( ": " ) ;
2233
- }
2234
- items. push_info ( before_alternate_ln) ;
2235
- items. extend ( ir_helpers:: new_line_group ( gen_node_with_inner_gen ( node. alt . into ( ) , context, |items, _| {
2249
+ items. push_condition ( {
2250
+ let mut items = PrintItems :: new ( ) ;
2251
+ items. extend ( colon_comment_items. leading_line ) ;
2236
2252
if operator_position == OperatorPosition :: NextLine {
2237
- conditions:: indent_if_start_of_line ( items) . into ( )
2238
- } else {
2239
- items
2253
+ items. push_str ( ": " ) ;
2240
2254
}
2241
- } ) ) ) ;
2255
+ items. push_info ( before_alternate_ln) ;
2256
+ items. extend ( gen_node ( node. alt . into ( ) , context) ) ;
2257
+ indent_if_sol_and_same_indent_as_top_most ( ir_helpers:: new_line_group ( items) , top_most_il)
2258
+ } ) ;
2242
2259
items. push_info ( end_ln) ;
2243
2260
2244
2261
if let Some ( reevaluation) = multi_line_reevaluation {
@@ -2251,9 +2268,69 @@ fn gen_conditional_expr<'a>(node: &'a CondExpr, context: &mut Context<'a>) -> Pr
2251
2268
if top_most_data. is_top_most {
2252
2269
items. push_condition ( conditions:: indent_if_start_of_line ( cons_and_alt_items) ) ;
2253
2270
} else {
2254
- let cons_and_alt_items = cons_and_alt_items. into_rc_path ( ) ;
2255
- let top_most_il = top_most_data. top_most_il ;
2256
- items. push_condition ( if_true_or (
2271
+ items. push_condition ( indent_if_sol_and_same_indent_as_top_most ( cons_and_alt_items, top_most_data. il ) ) ;
2272
+ }
2273
+
2274
+ return items;
2275
+
2276
+ struct TokenComments {
2277
+ previous_lines : PrintItems ,
2278
+ leading_line : PrintItems ,
2279
+ trailing_line : PrintItems ,
2280
+ }
2281
+
2282
+ fn gen_token_comments ( token : & TokenAndSpan , context : & mut Context , top_most_il : IndentLevel ) -> TokenComments {
2283
+ let token_line = token. end_line_fast ( context. program ) ;
2284
+ let previous_token = token. previous_token_fast ( context. program ) . unwrap ( ) ;
2285
+ let next_token = token. next_token_fast ( context. program ) . unwrap ( ) ;
2286
+ let previous_token_line = previous_token. end_line_fast ( context. program ) ;
2287
+ let next_token_line = next_token. start_line_fast ( context. program ) ;
2288
+ if token_line > previous_token_line {
2289
+ TokenComments {
2290
+ previous_lines : {
2291
+ let leading_comments = token. leading_comments_fast ( context. program ) . filter ( |c| {
2292
+ let comment_line = c. start_line_fast ( context. program ) ;
2293
+ comment_line > previous_token_line && comment_line < next_token_line
2294
+ } ) ;
2295
+ let trailing_comments = token
2296
+ . trailing_comments_fast ( context. program )
2297
+ . filter ( |c| c. start_line_fast ( context. program ) < next_token_line) ;
2298
+ let items = gen_comments_as_statements ( leading_comments. chain ( trailing_comments) , None , context) ;
2299
+ if items. is_empty ( ) {
2300
+ items
2301
+ } else {
2302
+ let mut new_items = PrintItems :: new ( ) ;
2303
+ new_items. push_signal ( Signal :: NewLine ) ;
2304
+ new_items. push_condition ( indent_if_sol_and_same_indent_as_top_most ( items, top_most_il) ) ;
2305
+ new_items
2306
+ }
2307
+ } ,
2308
+ leading_line : if token_line < next_token_line {
2309
+ gen_leading_comments_same_line ( & token. range ( ) , context)
2310
+ } else {
2311
+ PrintItems :: new ( )
2312
+ } ,
2313
+ trailing_line : PrintItems :: new ( ) ,
2314
+ }
2315
+ } else if token_line < next_token_line {
2316
+ TokenComments {
2317
+ previous_lines : PrintItems :: new ( ) ,
2318
+ leading_line : PrintItems :: new ( ) ,
2319
+ trailing_line : gen_trailing_comments_same_line ( & token. range ( ) , context) ,
2320
+ }
2321
+ } else {
2322
+ // do nothing
2323
+ TokenComments {
2324
+ previous_lines : PrintItems :: new ( ) ,
2325
+ leading_line : PrintItems :: new ( ) ,
2326
+ trailing_line : PrintItems :: new ( ) ,
2327
+ }
2328
+ }
2329
+ }
2330
+
2331
+ fn indent_if_sol_and_same_indent_as_top_most ( items : PrintItems , top_most_il : IndentLevel ) -> Condition {
2332
+ let items = items. into_rc_path ( ) ;
2333
+ if_true_or (
2257
2334
"indentIfSameIndentationAsTopMostAndStartOfLine" ,
2258
2335
Rc :: new ( move |context| {
2259
2336
if context. writer_info . is_start_of_line ( ) {
@@ -2263,16 +2340,14 @@ fn gen_conditional_expr<'a>(node: &'a CondExpr, context: &mut Context<'a>) -> Pr
2263
2340
Some ( false )
2264
2341
}
2265
2342
} ) ,
2266
- with_indent ( cons_and_alt_items . into ( ) ) ,
2267
- cons_and_alt_items . into ( ) ,
2268
- ) ) ;
2343
+ with_indent ( items . into ( ) ) ,
2344
+ items . into ( ) ,
2345
+ )
2269
2346
}
2270
2347
2271
- return items;
2272
-
2273
2348
struct TopMostData {
2274
- top_most_ln : LineNumber ,
2275
- top_most_il : IndentLevel ,
2349
+ ln : LineNumber ,
2350
+ il : IndentLevel ,
2276
2351
is_top_most : bool ,
2277
2352
}
2278
2353
@@ -2298,8 +2373,8 @@ fn gen_conditional_expr<'a>(node: &'a CondExpr, context: &mut Context<'a>) -> Pr
2298
2373
2299
2374
return TopMostData {
2300
2375
is_top_most,
2301
- top_most_ln,
2302
- top_most_il,
2376
+ ln : top_most_ln,
2377
+ il : top_most_il,
2303
2378
} ;
2304
2379
2305
2380
fn get_or_set_top_most_ln ( top_most_expr_start : SourcePos , is_top_most : bool , context : & mut Context ) -> ( LineNumber , IndentLevel ) {
@@ -5947,7 +6022,7 @@ fn get_trailing_comments_on_same_line<'a>(node: &dyn SourceRanged, context: &mut
5947
6022
} else {
5948
6023
let node_start_line = node. start_line_fast ( context. program ) ;
5949
6024
trailing_comments
5950
- . take_while ( |c| c. kind == CommentKind :: Block || c . start_line_fast ( context. program ) == node_start_line)
6025
+ . take_while ( |c| c. start_line_fast ( context. program ) == node_start_line)
5951
6026
. collect :: < Vec < _ > > ( )
5952
6027
}
5953
6028
}
0 commit comments