@@ -31,11 +31,11 @@ impl FormatJsxChildList {
3131 self
3232 }
3333
34- pub fn fmt_children < ' a > (
34+ pub fn fmt_children < ' a , ' b > (
3535 & self ,
36- children : & AstNode < ' a , ArenaVec < ' a , JSXChild < ' a > > > ,
36+ children : & ' b AstNode < ' a , ArenaVec < ' a , JSXChild < ' a > > > ,
3737 f : & mut Formatter < ' _ , ' a > ,
38- ) -> FormatChildrenResult < ' a > {
38+ ) -> FormatChildrenResult < ' a , ' b > {
3939 // Use Biome's exact approach - no need for jsx_split_children at this stage
4040 let children_meta = Self :: children_meta ( children, f. context ( ) . comments ( ) ) ;
4141 let layout = self . layout ( children_meta) ;
@@ -57,6 +57,13 @@ impl FormatJsxChildList {
5757 children. pop ( ) ;
5858 }
5959
60+ if children. len ( ) == 1 {
61+ return FormatChildrenResult :: SingleChild ( FormatSingleChild {
62+ child : children. pop ( ) . unwrap ( ) ,
63+ force_multiline,
64+ } ) ;
65+ }
66+
6067 let mut is_next_child_suppressed = false ;
6168 let mut last: Option < & JsxChild > = None ;
6269 let mut children_iter = JsxChildrenIterator :: new ( children. iter ( ) ) ;
@@ -390,7 +397,7 @@ impl FormatJsxChildList {
390397
391398/// The result of formatting the children of a JSX child list.
392399#[ derive( Debug ) ]
393- pub enum FormatChildrenResult < ' a > {
400+ pub enum FormatChildrenResult < ' a , ' b > {
394401 /// Force the children to be formatted over multiple lines.
395402 ///
396403 /// For example:
@@ -409,6 +416,8 @@ pub enum FormatChildrenResult<'a> {
409416 flat_children : FormatFlatChildren < ' a > ,
410417 expanded_children : FormatMultilineChildren < ' a > ,
411418 } ,
419+
420+ SingleChild ( FormatSingleChild < ' a , ' b > ) ,
412421}
413422
414423#[ derive( Debug , Default , Copy , Clone ) ]
@@ -720,3 +729,42 @@ impl<'a> Format<'a> for FormatFlatChildren<'a> {
720729 }
721730 }
722731}
732+
733+ /// Optimized formatting for a single JSX child.
734+ ///
735+ /// When there is only a single child, we do not need to write the child into a temporary buffer
736+ /// and then take it when formatting. Instead, we can directly write the child into the root buffer.
737+ ///
738+ /// Also, this can avoid calling costly `best_fitting!` formatting in some situations.
739+ #[ derive( Debug ) ]
740+ pub struct FormatSingleChild < ' a , ' b > {
741+ child : JsxChild < ' a , ' b > ,
742+ force_multiline : bool ,
743+ }
744+
745+ impl < ' a > Format < ' a > for FormatSingleChild < ' a , ' _ > {
746+ fn fmt ( & self , f : & mut Formatter < ' _ , ' a > ) {
747+ let format_inner = format_with ( |f| match & self . child {
748+ JsxChild :: Word ( word) => {
749+ word. fmt ( f) ;
750+ }
751+ JsxChild :: Whitespace => {
752+ JsxSpace . fmt ( f) ;
753+ }
754+ JsxChild :: NonText ( non_text) => {
755+ non_text. fmt ( f) ;
756+ }
757+ JsxChild :: Newline | JsxChild :: EmptyLine => {
758+ unreachable ! (
759+ "`Newline` or `EmptyLine` should have been trimmed for single child formatting"
760+ ) ;
761+ }
762+ } ) ;
763+
764+ if self . force_multiline {
765+ write ! ( f, [ block_indent( & format_inner) ] ) ;
766+ } else {
767+ write ! ( f, [ soft_block_indent( & format_inner) ] ) ;
768+ }
769+ }
770+ }
0 commit comments