@@ -974,24 +974,38 @@ defmodule ElixirSense.Core.CompilerTest do
974974 { { { :. , dot_meta , target } , call_meta , args } , state }
975975
976976 { :fn , meta , args } = _node , state ->
977- meta =
978- if Version . match? ( System . version ( ) , "< 1.19.0" ) do
979- Keyword . delete ( meta , :capture )
980- else
981- meta
982- end
983-
977+ # Always remove {:capture, true} metadata for normalization
978+ # Both ElixirSense and Elixir >= 1.19 produce it, so normalize it away
979+ meta = Keyword . delete ( meta , :capture )
984980 { { :fn , meta , args } , state }
985981
986982 { atom , meta , nil } = node , state when is_atom ( atom ) ->
987- # elixir changes the name to capture and does different counter tracking
983+ # ElixirSense intentionally uses :"&#{pos}" instead of :capture
984+ # Convert to :capture to match Elixir 1.17+ behavior
988985 node =
989- with "&" <> int <- to_string ( atom ) , { _ , "" } <- Integer . parse ( int ) do
986+ with "&" <> int <- to_string ( atom ) , { pos , "" } <- Integer . parse ( int ) do
987+ # Normalize metadata
990988 meta =
991- Keyword . delete ( meta , :counter )
992- |> Keyword . delete ( :capture )
993-
994- { :capture , meta , nil }
989+ if Version . match? ( System . version ( ) , "< 1.17.0" ) do
990+ # Elixir < 1.17 used :"&#{pos}" with no special metadata
991+ Keyword . delete ( meta , :counter ) |> Keyword . delete ( :capture )
992+ else
993+ # Elixir >= 1.17 uses :capture atom
994+ if Version . match? ( System . version ( ) , "< 1.19.0" ) do
995+ # Elixir 1.17-1.18: no {:capture, pos} metadata
996+ Keyword . delete ( meta , :counter ) |> Keyword . delete ( :capture )
997+ else
998+ # Elixir >= 1.19: has {:capture, pos} metadata, remove :counter only
999+ Keyword . delete ( meta , :counter )
1000+ end
1001+ end
1002+
1003+ # Convert to :capture for Elixir 1.17+
1004+ if Version . match? ( System . version ( ) , "< 1.17.0" ) do
1005+ { atom , meta , nil }
1006+ else
1007+ { :capture , meta , nil }
1008+ end
9951009 else
9961010 _ -> node
9971011 end
@@ -1019,28 +1033,37 @@ defmodule ElixirSense.Core.CompilerTest do
10191033 { { :-> , meta , args } , state }
10201034
10211035 { :fn , meta , args } = _node , state ->
1022- meta =
1023- if Version . match? ( System . version ( ) , ">= 1.19.0-rc.0" ) do
1024- Keyword . delete ( meta , :capture )
1025- else
1026- meta
1027- end
1028-
1036+ # Normalize :capture metadata - always remove for comparison
1037+ # (ElixirSense normalizes this too)
1038+ meta = Keyword . delete ( meta , :capture )
10291039 { { :fn , meta , args } , state }
10301040
10311041 { :capture , meta , nil } = _node , state ->
1032- # elixir changes the name to capture and does different counter tracking
1033- meta = Keyword . delete ( meta , :counter )
1034-
1042+ # Normalize capture variable metadata
1043+ # Always remove :counter and optionally :capture depending on version
10351044 meta =
1036- if Version . match? ( System . version ( ) , ">= 1.19.0-rc.0" ) do
1037- Keyword . delete ( meta , :capture )
1045+ if Version . match? ( System . version ( ) , "< 1.19.0" ) do
1046+ # Elixir < 1.19: remove both counter and capture metadata
1047+ Keyword . delete ( meta , :counter ) |> Keyword . delete ( :capture )
10381048 else
1039- meta
1049+ # Elixir >= 1.19: keep :capture but remove :counter
1050+ Keyword . delete ( meta , :counter )
10401051 end
10411052
10421053 { { :capture , meta , nil } , state }
10431054
1055+ { atom , meta , nil } = node , state when is_atom ( atom ) ->
1056+ # Handle old :"&#{pos}" format from Elixir < 1.18
1057+ node =
1058+ with "&" <> int <- to_string ( atom ) , { _ , "" } <- Integer . parse ( int ) do
1059+ meta = Keyword . delete ( meta , :counter ) |> Keyword . delete ( :capture )
1060+ { atom , meta , nil }
1061+ else
1062+ _ -> node
1063+ end
1064+
1065+ { node , state }
1066+
10441067 node , state ->
10451068 { node , state }
10461069 end )
0 commit comments