@@ -205,40 +205,98 @@ fn merge_string_expressions<'a>(
205205 return None ;
206206 }
207207 if expressions. len ( ) == 1 {
208- return Some ( expressions[ 0 ] . clone_in ( ast_builder. allocator ) ) ;
208+ return Some ( expressions. first ( ) . unwrap ( ) . clone_in ( ast_builder. allocator ) ) ;
209209 }
210210
211- let mut string_literals = vec ! [ ] ;
211+ let mut string_literals: std :: vec :: Vec < String > = vec ! [ ] ;
212212 let mut other_expressions = vec ! [ ] ;
213213 for ex in expressions {
214+ string_literals. push ( "" . to_string ( ) ) ;
214215 if let Expression :: StringLiteral ( literal) = ex {
215- string_literals. push ( literal. value . trim ( ) ) ;
216+ if !string_literals. is_empty ( ) {
217+ string_literals
218+ . last_mut ( )
219+ . unwrap ( )
220+ . push_str ( & format ! ( " {}" , literal. value. trim( ) ) ) ;
221+ } else {
222+ string_literals. push ( literal. value . trim ( ) . to_string ( ) ) ;
223+ }
224+ } else if let Expression :: TemplateLiteral ( template) = ex {
225+ if !string_literals. is_empty ( ) {
226+ string_literals. last_mut ( ) . unwrap ( ) . push_str ( & format ! (
227+ " {}" ,
228+ template
229+ . quasis
230+ . iter( )
231+ . map( |q| q. value. raw. trim( ) )
232+ . filter( |q| !q. is_empty( ) )
233+ . collect:: <Vec <_>>( )
234+ . join( " " )
235+ ) ) ;
236+ } else {
237+ string_literals. push (
238+ template
239+ . quasis
240+ . iter ( )
241+ . map ( |q| q. value . raw . as_str ( ) )
242+ . collect :: < Vec < _ > > ( )
243+ . join ( " " ) ,
244+ ) ;
245+ }
246+ other_expressions. extend ( template. expressions . clone_in ( ast_builder. allocator ) ) ;
216247 } else {
217- other_expressions. push ( ex) ;
248+ other_expressions. push ( ex. clone_in ( ast_builder . allocator ) ) ;
218249 }
219250 }
220251 if other_expressions. is_empty ( ) {
221- return Some ( Expression :: StringLiteral ( ast_builder. alloc_string_literal (
222- SPAN ,
223- ast_builder. atom ( & string_literals. join ( " " ) ) ,
224- None ,
225- ) ) ) ;
252+ return Some ( Expression :: StringLiteral (
253+ ast_builder. alloc_string_literal (
254+ SPAN ,
255+ ast_builder. atom (
256+ & string_literals
257+ . iter ( )
258+ . map ( |s| s. trim ( ) )
259+ . filter ( |s| !s. is_empty ( ) )
260+ . collect :: < Vec < _ > > ( )
261+ . join ( " " ) ,
262+ ) ,
263+ None ,
264+ ) ,
265+ ) ) ;
226266 }
267+ let literals = oxc_allocator:: Vec :: from_iter_in (
268+ string_literals. iter ( ) . enumerate ( ) . map ( |( idx, s) | {
269+ ast_builder. template_element (
270+ SPAN ,
271+ TemplateElementValue {
272+ raw : ast_builder. atom ( & {
273+ let trimmed = s. trim ( ) ;
274+ if trimmed. is_empty ( ) {
275+ "" . to_string ( )
276+ } else if idx > 0 && idx == string_literals. len ( ) - 1 {
277+ if string_literals. len ( ) == other_expressions. len ( ) {
278+ format ! ( " {} " , trimmed)
279+ } else {
280+ format ! ( " {}" , trimmed)
281+ }
282+ } else if idx == string_literals. len ( ) - 1 {
283+ trimmed. to_string ( )
284+ } else {
285+ format ! ( "{} " , trimmed)
286+ }
287+ } ) ,
288+ cooked : None ,
289+ } ,
290+ false ,
291+ )
292+ } ) ,
293+ ast_builder. allocator ,
294+ ) ;
227295
228296 Some ( Expression :: TemplateLiteral (
229297 ast_builder. alloc_template_literal (
230298 SPAN ,
231- oxc_allocator:: Vec :: from_iter_in (
232- [ ast_builder. template_element (
233- SPAN ,
234- TemplateElementValue {
235- raw : ast_builder. atom ( & format ! ( "{} " , string_literals. join( " " ) ) ) ,
236- cooked : None ,
237- } ,
238- false ,
239- ) ] ,
240- ast_builder. allocator ,
241- ) ,
299+ literals,
242300 oxc_allocator:: Vec :: from_iter_in (
243301 other_expressions
244302 . into_iter ( )
0 commit comments