@@ -4,7 +4,11 @@ use oxc_span::GetSpan;
44
55use crate :: {
66 Format , FormatResult , format_args,
7- formatter:: { Formatter , prelude:: * } ,
7+ formatter:: {
8+ Formatter ,
9+ prelude:: * ,
10+ trivia:: { FormatLeadingComments , FormatTrailingComments } ,
11+ } ,
812 generated:: ast_nodes:: { AstNode , AstNodes } ,
913 write,
1014} ;
@@ -13,40 +17,46 @@ use super::FormatWrite;
1317
1418impl < ' a > Format < ' a > for AstNode < ' a , Vec < ' a , Decorator < ' a > > > {
1519 fn fmt ( & self , f : & mut Formatter < ' _ , ' a > ) -> FormatResult < ( ) > {
16- if self . is_empty ( ) {
20+ let Some ( last ) = self . last ( ) else {
1721 return Ok ( ( ) ) ;
18- }
22+ } ;
1923
20- // Check parent to determine formatting context
21- match self . parent {
22- AstNodes :: PropertyDefinition ( _)
23- | AstNodes :: MethodDefinition ( _)
24- | AstNodes :: AccessorProperty ( _) => {
25- return write ! (
26- f,
27- [ group( & format_args!(
28- format_once( |f| {
29- f. join_nodes_with_soft_line( ) . entries( self . iter( ) ) . finish( )
30- } ) ,
31- soft_line_break_or_space( )
32- ) )
33- . should_expand( should_expand_decorators( self , f) ) ]
34- ) ;
35- }
36- // Parameter decorators
37- AstNodes :: FormalParameter ( _) => {
38- write ! ( f, should_expand_decorators( self , f) . then_some( expand_parent( ) ) ) ?;
39- }
40- AstNodes :: ExportNamedDeclaration ( _) | AstNodes :: ExportDefaultDeclaration ( _) => {
41- write ! ( f, [ hard_line_break( ) ] ) ?;
42- }
43- _ => {
44- write ! ( f, [ expand_parent( ) ] ) ?;
24+ let format_decorators = format_once ( |f| {
25+ // Check parent to determine formatting context
26+ match self . parent {
27+ AstNodes :: PropertyDefinition ( _)
28+ | AstNodes :: MethodDefinition ( _)
29+ | AstNodes :: AccessorProperty ( _) => {
30+ return write ! (
31+ f,
32+ [ group( & format_args!(
33+ format_once( |f| {
34+ f. join_nodes_with_soft_line( ) . entries( self . iter( ) ) . finish( )
35+ } ) ,
36+ soft_line_break_or_space( )
37+ ) )
38+ . should_expand( should_expand_decorators( self , f) ) ]
39+ ) ;
40+ }
41+ // Parameter decorators
42+ AstNodes :: FormalParameter ( _) => {
43+ write ! ( f, should_expand_decorators( self , f) . then_some( expand_parent( ) ) ) ?;
44+ }
45+ AstNodes :: ExportNamedDeclaration ( _) | AstNodes :: ExportDefaultDeclaration ( _) => {
46+ write ! ( f, [ hard_line_break( ) ] ) ?;
47+ }
48+ _ => {
49+ write ! ( f, [ expand_parent( ) ] ) ?;
50+ }
4551 }
46- }
4752
48- f. join_with ( & soft_line_break_or_space ( ) ) . entries ( self . iter ( ) ) . finish ( ) ?;
49- write ! ( f, [ soft_line_break_or_space( ) ] )
53+ f. join_with ( & soft_line_break_or_space ( ) ) . entries ( self . iter ( ) ) . finish ( ) ?;
54+
55+ write ! ( f, [ soft_line_break_or_space( ) ] )
56+ } ) ;
57+
58+ format_decorators. fmt ( f) ?;
59+ format_trailing_comments_for_last_decorator ( last. span . end , f)
5060 }
5161}
5262
@@ -103,3 +113,32 @@ fn should_expand_decorators<'a>(
103113) -> bool {
104114 decorators. iter ( ) . any ( |decorator| f. source_text ( ) . lines_after ( decorator. span ( ) . end ) > 0 )
105115}
116+
117+ pub fn format_trailing_comments_for_last_decorator (
118+ mut start : u32 ,
119+ f : & mut Formatter < ' _ , ' _ > ,
120+ ) -> FormatResult < ( ) > {
121+ let mut comments = f. context ( ) . comments ( ) . unprinted_comments ( ) ;
122+
123+ for ( i, comment) in comments. iter ( ) . enumerate ( ) {
124+ if !f. source_text ( ) . all_bytes_match ( start, comment. span . start , |b| b. is_ascii_whitespace ( ) )
125+ {
126+ comments = & comments[ ..i] ;
127+ break ;
128+ }
129+
130+ start = comment. span . end ;
131+ }
132+
133+ if !comments. is_empty ( ) {
134+ write ! (
135+ f,
136+ [ group( & format_args!(
137+ FormatTrailingComments :: Comments ( comments) ,
138+ soft_line_break_or_space( )
139+ ) ) ]
140+ ) ?;
141+ }
142+
143+ Ok ( ( ) )
144+ }
0 commit comments