@@ -220,30 +220,22 @@ impl<'a> FormatWrite<'a> for AstNode<'a, TSIndexSignatureName<'a>> {
220220
221221impl < ' a > Format < ' a > for AstNode < ' a , Vec < ' a , TSClassImplements < ' a > > > {
222222 fn fmt ( & self , f : & mut Formatter < ' _ , ' a > ) -> FormatResult < ( ) > {
223- write ! (
224- f,
225- [
226- "implements" ,
227- group( & soft_line_indent_or_space( & format_once( |f| {
228- let last_index = self . len( ) . saturating_sub( 1 ) ;
229- let mut joiner = f. join_with( soft_line_break_or_space( ) ) ;
230-
231- for ( i, heritage) in FormatSeparatedIter :: new( self . into_iter( ) , "," )
232- . with_trailing_separator( TrailingSeparator :: Disallowed )
233- . enumerate( )
234- {
235- if i == last_index {
236- // The trailing comments of the last heritage should be printed inside the class declaration
237- joiner. entry( & FormatNodeWithoutTrailingComments ( & heritage) ) ;
238- } else {
239- joiner. entry( & heritage) ;
240- }
241- }
223+ let last_index = self . len ( ) . saturating_sub ( 1 ) ;
224+ let mut joiner = f. join_with ( soft_line_break_or_space ( ) ) ;
242225
243- joiner. finish( )
244- } ) ) )
245- ]
246- )
226+ for ( i, heritage) in FormatSeparatedIter :: new ( self . into_iter ( ) , "," )
227+ . with_trailing_separator ( TrailingSeparator :: Disallowed )
228+ . enumerate ( )
229+ {
230+ if i == last_index {
231+ // The trailing comments of the last heritage should be printed inside the class declaration
232+ joiner. entry ( & FormatNodeWithoutTrailingComments ( & heritage) ) ;
233+ } else {
234+ joiner. entry ( & heritage) ;
235+ }
236+ }
237+
238+ joiner. finish ( )
247239 }
248240}
249241
@@ -303,26 +295,6 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
303295 }
304296
305297 write ! ( f, "class" ) ?;
306- let indent_only_heritage = ( ( implements. is_empty ( ) && super_class. is_some ( ) )
307- || ( !implements. is_empty ( ) && super_class. is_none ( ) ) )
308- && type_parameters. as_ref ( ) . is_some_and ( |type_parameters| {
309- let current_node_end = type_parameters. span . end ;
310- let next_node_start = super_class
311- . map ( GetSpan :: span)
312- . or ( implements. first ( ) . map ( GetSpan :: span) )
313- . unwrap ( )
314- . start ;
315- !f. comments ( )
316- . comments_in_range ( current_node_end, next_node_start)
317- . iter ( )
318- . any ( |c| c. is_line ( ) )
319- } ) ;
320-
321- let type_parameters_id = if indent_only_heritage && !implements. is_empty ( ) {
322- Some ( f. group_id ( "type_parameters" ) )
323- } else {
324- None
325- } ;
326298
327299 let head = format_with ( |f| {
328300 if let Some ( id) = self . id ( ) {
@@ -339,6 +311,7 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
339311 }
340312
341313 if let Some ( type_parameters) = & type_parameters {
314+ let type_parameters_id = Some ( f. group_id ( "type_parameters" ) ) ;
342315 write ! (
343316 f,
344317 FormatTSTypeParameters :: new(
@@ -364,8 +337,8 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
364337 // after the class name, maintaining their position before the extends clause.
365338 if let Some ( super_class) = & super_class {
366339 let comments = f. context ( ) . comments ( ) . comments_before ( super_class. span ( ) . start ) ;
367- if comments. iter ( ) . any ( |c| c . is_line ( ) ) {
368- FormatTrailingComments :: Comments ( comments) . fmt ( f) ?;
340+ if comments. iter ( ) . any ( |c| f . comments ( ) . is_own_line_comment ( c ) ) {
341+ indent ( & FormatTrailingComments :: Comments ( comments) ) . fmt ( f) ?;
369342 }
370343 }
371344
@@ -418,78 +391,86 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
418391 } ) ;
419392
420393 if matches ! ( extends. grand_parent( ) , AstNodes :: AssignmentExpression ( _) ) {
421- if has_trailing_comments {
422- write ! ( f, [ token( "(" ) , & content, token( ")" ) ] )
423- } else {
424- let content = content. memoized ( ) ;
425- write ! (
426- f,
427- [
428- if_group_breaks( & format_args!(
429- token( "(" ) ,
430- & soft_block_indent( & content) ,
431- token( ")" ) ,
432- ) ) ,
433- if_group_fits_on_line( & content)
434- ]
435- )
436- }
394+ let content = content. memoized ( ) ;
395+ write ! (
396+ f,
397+ [ group( & format_args!(
398+ & if_group_breaks( & format_args!(
399+ token( "(" ) ,
400+ & soft_block_indent( & content) ,
401+ token( ")" ) ,
402+ ) ) ,
403+ & if_group_fits_on_line( & content)
404+ ) ) ]
405+ )
437406 } else {
438407 content. fmt ( f)
439408 }
440409 } ) ;
441410
442- let extends =
443- format_once ( |f| write ! ( f, [ space( ) , "extends" , space( ) , group ( & format_super) ] ) ) ;
411+ let format_extends =
412+ format_once ( |f| write ! ( f, [ space( ) , "extends" , space( ) , & format_super] ) ) ;
444413
445414 if group_mode {
446- write ! ( f, [ soft_line_break_or_space( ) , group( & extends ) ] ) ?;
415+ write ! ( f, [ soft_line_break_or_space( ) , group( & format_extends ) ] ) ?;
447416 } else {
448- write ! ( f, extends ) ?;
417+ write ! ( f, format_extends ) ?;
449418 }
450419 }
451420
452421 if !implements. is_empty ( ) {
453- if indent_only_heritage {
422+ let leading_comments =
423+ f. context ( ) . comments ( ) . comments_before ( implements[ 0 ] . span ( ) . start ) ;
424+
425+ if usize:: from ( super_class. is_some ( ) ) + implements. len ( ) > 1 {
454426 write ! (
455427 f,
456428 [
457- if_group_breaks( & space( ) ) . with_group_id( type_parameters_id) ,
458- if_group_fits_on_line( & soft_line_break_or_space( ) )
459- . with_group_id( type_parameters_id)
429+ soft_line_break_or_space( ) ,
430+ FormatLeadingComments :: Comments ( leading_comments) ,
431+ ( !leading_comments. is_empty( ) ) . then_some( hard_line_break( ) ) ,
432+ "implements" ,
433+ group( & soft_line_indent_or_space( implements) )
460434 ]
461435 ) ?;
462436 } else {
463- write ! ( f, [ soft_line_break_or_space( ) ] ) ?;
464- }
437+ let format_inner = format_once ( |f| {
438+ write ! (
439+ f,
440+ [
441+ FormatLeadingComments :: Comments ( leading_comments) ,
442+ "implements" ,
443+ space( ) ,
444+ implements,
445+ ]
446+ )
447+ } ) ;
465448
466- let comments = f. context ( ) . comments ( ) . comments_before ( implements[ 0 ] . span ( ) . start ) ;
467- write ! ( f, [ FormatLeadingComments :: Comments ( comments) , implements] ) ?;
449+ if group_mode {
450+ write ! ( f, [ soft_line_break_or_space( ) , group( & format_inner) ] ) ?;
451+ } else {
452+ write ! ( f, [ space( ) , format_inner] ) ?;
453+ }
454+ }
468455 }
469456
470457 Ok ( ( ) )
471458 } ) ;
472459
473460 if group_mode {
474- let indented = format_with ( |f| {
475- if indent_only_heritage {
476- write ! ( f, [ head, indent( & format_heritage_clauses) ] )
477- } else {
478- write ! ( f, indent( & format_args!( head, format_heritage_clauses) ) )
479- }
480- } ) ;
461+ let indented = format_with ( |f| write ! ( f, [ head, indent( & format_heritage_clauses) ] ) ) ;
481462
482463 let heritage_id = f. group_id ( "heritageGroup" ) ;
483464 write ! ( f, [ group( & indented) . with_group_id( Some ( heritage_id) ) , space( ) ] ) ?;
484465
485- if !body. body ( ) . is_empty ( ) {
466+ if !body. body . is_empty ( ) {
486467 write ! ( f, [ if_group_breaks( & hard_line_break( ) ) . with_group_id( Some ( heritage_id) ) ] ) ?;
487468 }
488469 } else {
489470 write ! ( f, [ head, format_heritage_clauses, space( ) ] ) ?;
490471 }
491472
492- if body. body ( ) . is_empty ( ) {
473+ if body. body . is_empty ( ) {
493474 write ! ( f, [ "{" , format_dangling_comments( self . span) . with_block_indent( ) , "}" ] )
494475 } else {
495476 body. fmt ( f)
@@ -503,16 +484,16 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
503484/// on the same line but break together if they don't fit.
504485///
505486/// Heritage clauses are grouped when:
506- /// 1. The class has an `implements` clause
487+ /// 1. Superclass and/or implements are more than one
507488/// 2. There are comments in the heritage clause area
508489/// 3. There are trailing line comments after type parameters
509490fn should_group < ' a > ( class : & Class < ' a > , f : & Formatter < ' _ , ' a > ) -> bool {
510- let comments = f. comments ( ) ;
511-
512- if !class. implements . is_empty ( ) {
491+ if usize:: from ( class. super_class . is_some ( ) ) + class. implements . len ( ) > 1 {
513492 return true ;
514493 }
515494
495+ let comments = f. comments ( ) ;
496+
516497 let id_span = class. id . as_ref ( ) . map ( GetSpan :: span) ;
517498 let type_parameters_span = class. type_parameters . as_ref ( ) . map ( |t| t. span ) ;
518499 let super_class_span = class. super_class . as_ref ( ) . map ( GetSpan :: span) ;
0 commit comments