@@ -51,6 +51,7 @@ import { javascript_visitors_runes } from './javascript-runes.js';
5151import { sanitize_template_string } from '../../../../utils/sanitize_template_string.js' ;
5252import { walk } from 'zimmerframe' ;
5353import { locator } from '../../../../state.js' ;
54+ import is_reference from 'is-reference' ;
5455
5556/**
5657 * @param {import('#compiler').RegularElement | import('#compiler').SvelteElement } element
@@ -1021,51 +1022,48 @@ function serialize_bind_this(bind_this, context, node) {
10211022 // some scenarios where the value is a member expression with changing computed parts or using a combination of multiple
10221023 // variables, but that was the same case in Svelte 4, too. Once legacy mode is gone completely, we can revisit this.
10231024 walk ( bind_this , null , {
1024- Identifier ( node ) {
1025+ Identifier ( node , { path } ) {
1026+ const parent = /** @type {Expression } */ ( path . at ( - 1 ) ) ;
1027+ if ( ! is_reference ( node , parent ) ) return ;
1028+
10251029 const binding = child_state . scope . get ( node . name ) ;
10261030 if ( ! binding || seen . includes ( node . name ) ) return ;
10271031
1028- const associated_node = Array . from ( child_state . scopes . entries ( ) ) . find (
1029- ( [ _ , scope ] ) => scope === binding ?. scope
1030- ) ?. [ 0 ] ;
1031-
1032- if ( associated_node ?. type === 'EachBlock' ) {
1033- seen . push ( node . name ) ;
1032+ for ( const [ owner , scope ] of child_state . scopes ) {
1033+ if ( owner . type === 'EachBlock' && scope === binding . scope ) {
1034+ seen . push ( node . name ) ;
10341035
1035- ids . push ( node ) ;
1036- values . push ( /** @type {Expression } */ ( context . visit ( node ) ) ) ;
1037- child_state . getters [ node . name ] = node ;
1036+ ids . push ( node ) ;
1037+ values . push ( /** @type {Expression } */ ( context . visit ( node ) ) ) ;
1038+ child_state . getters [ node . name ] = node ;
1039+ break ;
1040+ }
10381041 }
10391042 }
10401043 } ) ;
10411044
1042- const bind_this_id = /** @type {Expression } */ ( context . visit ( bind_this , child_state ) ) ;
1045+ const expression = /** @type {Expression } */ ( context . visit ( bind_this , child_state ) ) ;
10431046 const assignment = /** @type {Expression } */ (
10441047 context . visit ( b . assignment ( '=' , bind_this , b . id ( '$$value' ) ) , child_state )
10451048 ) ;
10461049
1047- /** @type {Expression[] } */
1048- const args = [
1049- node ,
1050- b . arrow ( [ b . id ( '$$value' ) , ...ids ] , assignment ) ,
1051- b . arrow ( [ ...ids ] , bind_this_id )
1052- ] ;
1053-
10541050 // If we're mutating a property, then it might already be non-existent.
10551051 // If we make all the object nodes optional, then it avoids any runtime exceptions.
10561052 /** @type {Expression | Super } */
1057- let bind_node = bind_this_id ;
1053+ let bind_node = expression ;
10581054
1059- while ( bind_node ? .type === 'MemberExpression' ) {
1055+ while ( bind_node . type === 'MemberExpression' ) {
10601056 bind_node . optional = true ;
10611057 bind_node = bind_node . object ;
10621058 }
10631059
1064- if ( values . length > 0 ) {
1065- args . push ( b . thunk ( b . array ( values ) ) ) ;
1066- }
1067-
1068- return b . call ( '$.bind_this' , ...args ) ;
1060+ return b . call (
1061+ '$.bind_this' ,
1062+ node ,
1063+ b . arrow ( [ b . id ( '$$value' ) , ...ids ] , assignment ) ,
1064+ b . arrow ( [ ...ids ] , expression ) ,
1065+ values . length > 0 && b . thunk ( b . array ( values ) )
1066+ ) ;
10691067}
10701068
10711069/**
0 commit comments