@ -1598,37 +1598,8 @@ function serialize_template_literal(values, visit, state) {
if ( node . type === 'ExpressionTag' && node . metadata . contains _call _expression ) {
if ( node . type === 'ExpressionTag' && node . metadata . contains _call _expression ) {
contains _call _expression = true ;
contains _call _expression = true ;
}
}
let expression = visit ( node . expression ) ;
if ( node . expression . type === 'Identifier' ) {
expressions . push ( b . call ( '$.stringify' , visit ( node . expression ) ) ) ;
const name = node . expression . name ;
const binding = scope . get ( name ) ;
// When we combine expressions as part of a single template element, we might
// be referencing variables that can be mutated, but are not actually state.
// In order to prevent this undesired behavior, we need ensure we cache the
// latest value we have of that variable before we process the template, enforcing
// the value remains static through the lifetime of the template.
if ( binding !== null && binding . kind === 'normal' && binding . mutated ) {
let has _already _cached = false ;
// Check if we already create a const of this expression
for ( let node of state . init ) {
if (
node . type === 'VariableDeclaration' &&
node . declarations [ 0 ] . id . type === 'Identifier' &&
node . declarations [ 0 ] . id . name === name + '_const'
) {
has _already _cached = true ;
expression = b . id ( name + '_const' ) ;
break ;
}
}
if ( ! has _already _cached ) {
const tmp _id = scope . generate ( name + '_const' ) ;
state . init . push ( b . const ( tmp _id , expression ) ) ;
expression = b . id ( tmp _id ) ;
}
}
}
expressions . push ( b . call ( '$.stringify' , expression ) ) ;
quasis . push ( b . quasi ( '' , i + 1 === values . length ) ) ;
quasis . push ( b . quasi ( '' , i + 1 === values . length ) ) ;
}
}
}
}