@@ -1197,7 +1197,7 @@ defmodule Phoenix.LiveView.TagEngine do
11971197 # validate_quoted_special_attr
11981198 { :<- , for_meta , [ lhs , rhs ] } = for_expr
11991199 # now we mark all eligible variables in the left-hand side as `:change_track`able
1200- { lhs , variables } = mark_variables_as_change_tracked ( lhs )
1200+ { lhs , variables } = mark_variables_as_change_tracked ( lhs , % { } )
12011201 for_expr = { :<- , for_meta , [ lhs , rhs ] }
12021202
12031203 # now we build the new ast that we pass to the engine
@@ -1206,7 +1206,7 @@ defmodule Phoenix.LiveView.TagEngine do
12061206 Phoenix.LiveView.TagEngine . keyed_comprehension (
12071207 { unquote ( state . caller . module ) , unquote ( tag_meta . line ) , unquote ( tag_meta . column ) ,
12081208 unquote ( key_expr ) } ,
1209- % { unquote_splicing ( variables ) } ,
1209+ % { unquote_splicing ( Map . to_list ( variables ) ) } ,
12101210 do: unquote ( invoke_subengine ( state , :handle_end , [ [ meta: [ root: true ] ] ] ) )
12111211 )
12121212 end
@@ -1228,57 +1228,39 @@ defmodule Phoenix.LiveView.TagEngine do
12281228 end
12291229
12301230 @ doc false
1231- def mark_variables_as_change_tracked ( ast ) do
1232- # we traverse the AST and mark elements that should not considered
1233- # to be variables as "skip";
1234- # we need to handle both the pre and post phases to properly unmark
1235- # the skip after we handled an expression
1236- { ast , { _ , vars } } =
1237- Macro . traverse (
1238- ast ,
1239- # we start in collect mode (true) and an empty list of vars
1240- { true , [ ] } ,
1241- fn
1242- # skip pinned expressions, marking the pin expression and setting
1243- # collect to false
1244- { :^ , meta , [ expr ] } , { true , vars } ->
1245- { { :^ , Keyword . put ( meta , :skip_mark , true ) , [ expr ] } , { false , vars } }
1246-
1247- # skip the right hand side in something like <<foo::binary>>
1248- { :"::" , meta , [ left , right ] } , { true , vars } ->
1249- # we need to return a list for prewalk to walk the left hand side
1250- { new_left , inner_vars } = mark_variables_as_change_tracked ( left )
1251-
1252- { { :"::" , Keyword . put ( meta , :skip_mark , true ) , [ new_left , right ] } ,
1253- { false , vars ++ inner_vars } }
1254-
1255- # collect mode -> mark the variable as change_track and collect
1256- # it for passing it to the KeyedComprehension component
1257- { name , meta , context } , { true , vars }
1258- when is_atom ( name ) and is_list ( meta ) and is_atom ( context ) ->
1259- var = { name , Keyword . put ( meta , :change_track , true ) , context }
1260- { var , { true , [ { name , var } | vars ] } }
1261-
1262- other , acc ->
1263- { other , acc }
1264- end ,
1265- fn
1266- { op , meta , args } , { false , vars } when is_atom ( op ) and is_list ( meta ) and is_list ( args ) ->
1267- case Keyword . pop ( meta , :skip_mark ) do
1268- { nil , meta } ->
1269- { { op , meta , args } , { false , vars } }
1270-
1271- { true , meta } ->
1272- # reset the collect mode
1273- { { op , meta , args } , { true , vars } }
1274- end
1231+ def mark_variables_as_change_tracked ( { :^ , _ , [ _ ] } = ast , vars ) do
1232+ { ast , vars }
1233+ end
12751234
1276- other , acc ->
1277- { other , acc }
1278- end
1279- )
1235+ def mark_variables_as_change_tracked ( { :"::" , meta , [ left , right ] } , vars ) do
1236+ { left , vars } = mark_variables_as_change_tracked ( left , vars )
1237+ { { :"::" , meta , [ left , right ] } , vars }
1238+ end
12801239
1281- { ast , vars }
1240+ def mark_variables_as_change_tracked ( { name , meta , context } , vars )
1241+ when is_atom ( name ) and is_list ( meta ) and is_atom ( context ) do
1242+ var = { name , [ change_track: true ] ++ meta , context }
1243+ { var , Map . put ( vars , name , var ) }
1244+ end
1245+
1246+ def mark_variables_as_change_tracked ( { left , meta , right } , vars ) do
1247+ { left , vars } = mark_variables_as_change_tracked ( left , vars )
1248+ { right , vars } = mark_variables_as_change_tracked ( right , vars )
1249+ { { left , meta , right } , vars }
1250+ end
1251+
1252+ def mark_variables_as_change_tracked ( { left , right } , vars ) do
1253+ { left , vars } = mark_variables_as_change_tracked ( left , vars )
1254+ { right , vars } = mark_variables_as_change_tracked ( right , vars )
1255+ { { left , right } , vars }
1256+ end
1257+
1258+ def mark_variables_as_change_tracked ( [ _ | _ ] = list , vars ) do
1259+ Enum . map_reduce ( list , vars , & mark_variables_as_change_tracked / 2 )
1260+ end
1261+
1262+ def mark_variables_as_change_tracked ( other , vars ) do
1263+ { other , vars }
12821264 end
12831265
12841266 ## build_self_close_component_assigns/build_component_assigns
0 commit comments