@@ -1396,7 +1396,7 @@ function process_children(nodes, expression, is_element, { visit, state }) {
1396
1396
1397
1397
state . template . push ( ' ' ) ;
1398
1398
1399
- const [ contains_call_expression , value ] = serialize_template_literal ( sequence , visit ) ;
1399
+ const [ contains_call_expression , value ] = serialize_template_literal ( sequence , visit , state ) ;
1400
1400
1401
1401
const update = b . stmt ( b . call ( '$.set_text' , text_id , value ) ) ;
1402
1402
@@ -1511,25 +1511,39 @@ function serialize_attribute_value(attribute_value, context) {
1511
1511
}
1512
1512
}
1513
1513
1514
- return serialize_template_literal ( attribute_value , context . visit ) ;
1514
+ return serialize_template_literal ( attribute_value , context . visit , context . state ) ;
1515
1515
}
1516
1516
1517
1517
/**
1518
1518
* @param {Array<import('#compiler').Text | import('#compiler').ExpressionTag> } values
1519
1519
* @param {(node: import('#compiler').SvelteNode) => any } visit
1520
+ * @param {import("../types.js").ComponentClientTransformState } state
1520
1521
* @returns {[boolean, import('estree').TemplateLiteral] }
1521
1522
*/
1522
- function serialize_template_literal ( values , visit ) {
1523
+ function serialize_template_literal ( values , visit , state ) {
1523
1524
/** @type {import('estree').TemplateElement[] } */
1524
1525
const quasis = [ ] ;
1525
1526
1526
1527
/** @type {import('estree').Expression[] } */
1527
1528
const expressions = [ ] ;
1528
1529
let contains_call_expression = false ;
1530
+ let contains_multiple_call_expression = false ;
1529
1531
quasis . push ( b . quasi ( '' ) ) ;
1530
1532
1531
1533
for ( let i = 0 ; i < values . length ; i ++ ) {
1532
1534
const node = values [ i ] ;
1535
+
1536
+ if ( node . type === 'ExpressionTag' && node . metadata . contains_call_expression ) {
1537
+ if ( contains_call_expression ) {
1538
+ contains_multiple_call_expression = true ;
1539
+ }
1540
+ contains_call_expression = true ;
1541
+ }
1542
+ }
1543
+
1544
+ for ( let i = 0 ; i < values . length ; i ++ ) {
1545
+ const node = values [ i ] ;
1546
+
1533
1547
if ( node . type === 'Text' ) {
1534
1548
const last = /** @type {import('estree').TemplateElement } */ ( quasis . at ( - 1 ) ) ;
1535
1549
last . value . raw += sanitize_template_string ( node . data ) ;
@@ -1539,11 +1553,23 @@ function serialize_template_literal(values, visit) {
1539
1553
last . value . raw += sanitize_template_string ( node . expression . value + '' ) ;
1540
1554
}
1541
1555
} else {
1542
- if ( node . type === 'ExpressionTag' && node . metadata . contains_call_expression ) {
1543
- contains_call_expression = true ;
1544
- }
1556
+ if ( contains_multiple_call_expression ) {
1557
+ const id = b . id ( state . scope . generate ( 'stringified_text' ) ) ;
1545
1558
1546
- expressions . push ( b . call ( '$.stringify' , visit ( node . expression ) ) ) ;
1559
+ state . init . push (
1560
+ b . const (
1561
+ id ,
1562
+ b . call (
1563
+ // In runes mode, we want things to be fine-grained - but not in legacy mode
1564
+ state . analysis . runes ? '$.derived' : '$.derived_safe_equal' ,
1565
+ b . thunk ( /** @type {import('estree').Expression } */ ( visit ( node . expression ) ) )
1566
+ )
1567
+ )
1568
+ ) ;
1569
+ expressions . push ( b . call ( '$.get' , id ) ) ;
1570
+ } else {
1571
+ expressions . push ( b . call ( '$.stringify' , visit ( node . expression ) ) ) ;
1572
+ }
1547
1573
quasis . push ( b . quasi ( '' , i + 1 === values . length ) ) ;
1548
1574
}
1549
1575
}
@@ -1586,7 +1612,7 @@ export const template_visitors = {
1586
1612
declaration . id ,
1587
1613
b . call (
1588
1614
// In runes mode, we want things to be fine-grained - but not in legacy mode
1589
- state . options . runes ? '$.derived' : '$.derived_safe_equal' ,
1615
+ state . analysis . runes ? '$.derived' : '$.derived_safe_equal' ,
1590
1616
b . thunk ( /** @type {import('estree').Expression } */ ( visit ( declaration . init ) ) )
1591
1617
)
1592
1618
)
@@ -1623,7 +1649,7 @@ export const template_visitors = {
1623
1649
1624
1650
state . init . push (
1625
1651
// In runes mode, we want things to be fine-grained - but not in legacy mode
1626
- b . const ( tmp , b . call ( state . options . runes ? '$.derived' : '$.derived_safe_equal' , fn ) )
1652
+ b . const ( tmp , b . call ( state . analysis . runes ? '$.derived' : '$.derived_safe_equal' , fn ) )
1627
1653
) ;
1628
1654
1629
1655
// we need to eagerly evaluate the expression in order to hit any
@@ -2972,7 +2998,7 @@ export const template_visitors = {
2972
2998
b . assignment (
2973
2999
'=' ,
2974
3000
b . member ( b . id ( '$.document' ) , b . id ( 'title' ) ) ,
2975
- serialize_template_literal ( /** @type {any } */ ( node . fragment . nodes ) , visit ) [ 1 ]
3001
+ serialize_template_literal ( /** @type {any } */ ( node . fragment . nodes ) , visit , state ) [ 1 ]
2976
3002
)
2977
3003
)
2978
3004
) ;
0 commit comments