@@ -33,20 +33,35 @@ defmodule ElixirSense.Core.Compiler do
3333 { :alias_reference , meta , alias } ->
3434 # emitted by Macro.expand/2 and Macro.expand_once/2
3535 acc
36- |> State . add_call_to_line ( { alias , nil , nil } , meta )
37- |> State . add_current_env_to_line ( meta , env )
36+ |> State . add_call_to_line ( { alias , nil , nil } , meta , :alias_reference )
3837
3938 { :alias , meta , module , _as , _opts } ->
4039 # emitted by Macro.Env.define_alias/3 and Macro.Env.define_require/3
4140 acc
42- |> State . add_call_to_line ( { module , nil , nil } , meta )
43- |> State . add_current_env_to_line ( meta , env )
41+ |> State . add_call_to_line ( { module , nil , nil } , meta , :alias )
4442
4543 { kind , meta , module , _opts } when kind in [ :import , :require ] ->
4644 # emitted by Macro.Env.define_import/3 and Macro.Env.define_require/3
4745 acc
48- |> State . add_call_to_line ( { module , nil , nil } , meta )
49- |> State . add_current_env_to_line ( meta , env )
46+ |> State . add_call_to_line ( { module , nil , nil } , meta , kind )
47+
48+ { kind , meta , receiver , name , arity }
49+ when kind in [ :remote_function , :remote_macro , :imported_function , :imported_macro ] ->
50+ # emitted by MacroEnv.expand_require/6, MacroEnv.expand_import/5
51+ acc
52+ |> State . add_call_to_line ( { receiver , name , arity } , meta , kind )
53+
54+ { :imported_quoted , meta , module , name , arities } ->
55+ for arity <- arities , reduce: acc do
56+ acc ->
57+ acc
58+ |> State . add_call_to_line ( { module , name , arity } , meta , :imported_quoted )
59+ end
60+
61+ { kind , meta , name , arity } when kind in [ :local_function , :local_macro ] ->
62+ # emitted by MacroEnv.expand_require/6, MacroEnv.expand_import/5
63+ acc
64+ |> State . add_call_to_line ( { env . module , name , arity } , meta , kind )
5065
5166 _ ->
5267 Logger . warning ( "Unhandled trace event: #{ inspect ( event ) } " )
@@ -204,7 +219,6 @@ defmodule ElixirSense.Core.Compiler do
204219 if is_atom ( arg ) do
205220 case NormalizedMacroEnv . define_alias ( env , meta , arg , [ trace: true ] ++ opts ) do
206221 { :ok , env } ->
207- state = collect_traces ( state )
208222 { arg , state , env }
209223
210224 { :error , _ } ->
@@ -235,7 +249,6 @@ defmodule ElixirSense.Core.Compiler do
235249 # and optionally waits until required module is compiled
236250 case NormalizedMacroEnv . define_require ( env , meta , arg , [ trace: true ] ++ opts ) do
237251 { :ok , env } ->
238- state = collect_traces ( state )
239252 { arg , state , env }
240253
241254 { :error , _ } ->
@@ -267,7 +280,6 @@ defmodule ElixirSense.Core.Compiler do
267280
268281 case NormalizedMacroEnv . define_import ( env , meta , arg , opts ) do
269282 { :ok , env } ->
270- state = collect_traces ( state )
271283 { arg , state , env }
272284
273285 _ ->
@@ -456,12 +468,7 @@ defmodule ElixirSense.Core.Compiler do
456468 when is_atom ( context ) and is_integer ( arity ) do
457469 case resolve_super ( meta , arity , s , e ) do
458470 { kind , name , _ } when kind in [ :def , :defp ] ->
459- s =
460- s
461- |> State . add_call_to_line ( { nil , name , arity } , super_meta )
462- |> State . add_current_env_to_line ( super_meta , e )
463-
464- { { :& , meta , [ { :/ , arity_meta , [ { name , super_meta , context } , arity ] } ] } , s , e }
471+ expand ( { :& , meta , [ { :/ , arity_meta , [ { name , super_meta , context } , arity ] } ] } , s , e )
465472
466473 _ ->
467474 expand_fn_capture ( meta , expr , s , e )
@@ -535,7 +542,7 @@ defmodule ElixirSense.Core.Compiler do
535542
536543 sa =
537544 sa
538- |> State . add_call_to_line ( { nil , name , arity } , meta )
545+ |> State . add_call_to_line ( { e . module , name , arity } , meta , :local_function )
539546 |> State . add_current_env_to_line ( meta , ea )
540547
541548 { { :super , [ { :super , { kind , name } } | meta ] , e_args } , sa , ea }
@@ -705,17 +712,38 @@ defmodule ElixirSense.Core.Compiler do
705712 allow_locals = match? ( { n , a } when fun != n or arity != a , env . function )
706713
707714 case NormalizedMacroEnv . expand_import ( env , meta , fun , arity ,
708- trace: false ,
715+ trace: true ,
709716 allow_locals: allow_locals ,
710- check_deprecations: false
717+ check_deprecations: false ,
718+ local_for_callback: fn meta , name , arity , kinds , e ->
719+ case state . mods_funs_to_positions [ { e . module , name , arity } ] do
720+ nil ->
721+ false
722+
723+ % ModFunInfo { } = info ->
724+ category = ModFunInfo . get_category ( info )
725+ definition_line = info . positions |> List . first ( ) |> elem ( 0 )
726+ usage_line = meta |> Keyword . get ( :line )
727+
728+ if ModFunInfo . get_def_kind ( info ) in kinds and
729+ ( category != :macro or usage_line >= definition_line ) do
730+ if macro_exported? ( e . module , name , arity ) do
731+ proper_name = :"MACRO-#{ name } "
732+ proper_arity = arity + 1
733+ Function . capture ( e . module , proper_name , proper_arity )
734+ else
735+ # return a fake macro
736+ true
737+ end
738+ else
739+ false
740+ end
741+ end
742+ end
711743 ) do
712744 { :macro , module , callback } ->
713745 # NOTE there is a subtle difference - callback will call expander with state derived from env via
714746 # :elixir_env.env_to_ex(env) possibly losing some details. Jose Valim is convinced this is not a problem
715- state =
716- state
717- |> State . add_call_to_line ( { module , fun , length ( args ) } , meta )
718- |> State . add_current_env_to_line ( meta , env )
719747
720748 expand_macro ( meta , module , fun , args , callback , state , env )
721749
@@ -751,35 +779,55 @@ defmodule ElixirSense.Core.Compiler do
751779 defp do_expand ( { { :. , dot_meta , [ module , fun ] } , meta , args } , state , env )
752780 when ( is_tuple ( module ) or is_atom ( module ) ) and is_atom ( fun ) and is_list ( meta ) and
753781 is_list ( args ) do
754- # dbg({module, fun, args})
755782 { module , state_l , env } = expand ( module , State . prepare_write ( state , env ) , env )
756783 arity = length ( args )
757784
758785 if is_atom ( module ) do
759786 case __MODULE__ . Rewrite . inline ( module , fun , arity ) do
760787 { ar , an } ->
788+ state_l =
789+ state_l
790+ |> State . add_call_to_line ( { module , fun , arity } , meta , :remote_function )
791+ |> State . add_current_env_to_line ( meta , env )
792+
761793 expand_remote ( ar , dot_meta , an , meta , args , state , state_l , env )
762794
763795 false ->
764796 case NormalizedMacroEnv . expand_require ( env , meta , module , fun , arity ,
765- trace: false ,
797+ trace: true ,
766798 check_deprecations: false
767799 ) do
768800 { :macro , module , callback } ->
769801 # NOTE there is a subtle difference - callback will call expander with state derived from env via
770802 # :elixir_env.env_to_ex(env) possibly losing some details. Jose Valim is convinced this is not a problem
771- state_l =
803+ # elixir expands the macro with original state, we pass state after left expand and need to revert some props
804+ state_l = % {
772805 state_l
773- |> State . add_call_to_line ( { module , fun , length ( args ) } , meta )
774- |> State . add_current_env_to_line ( meta , env )
806+ | vars: state . vars ,
807+ prematch: state . prematch ,
808+ unused: state . unused ,
809+ stacktrace: state . stacktrace ,
810+ caller: state . caller ,
811+ runtime_modules: state . runtime_modules
812+ }
775813
776814 expand_macro ( meta , module , fun , args , callback , state_l , env )
777815
778816 :error ->
817+ state_l =
818+ state_l
819+ |> State . add_call_to_line ( { module , fun , arity } , meta , :remote_function )
820+ |> State . add_current_env_to_line ( meta , env )
821+
779822 expand_remote ( module , dot_meta , fun , meta , args , state , state_l , env )
780823 end
781824 end
782825 else
826+ state_l =
827+ state_l
828+ |> State . add_call_to_line ( { module , fun , arity } , meta , :remote_function )
829+ |> State . add_current_env_to_line ( meta , env )
830+
783831 expand_remote ( module , dot_meta , fun , meta , args , state , state_l , env )
784832 end
785833 end
@@ -797,7 +845,7 @@ defmodule ElixirSense.Core.Compiler do
797845
798846 sa =
799847 sa
800- |> State . add_call_to_line ( { nil , e_expr , length ( e_args ) } , dot_meta )
848+ |> State . add_call_to_line ( { nil , e_expr , length ( e_args ) } , dot_meta , :anonymous_function )
801849 |> State . add_current_env_to_line ( meta , e )
802850
803851 { { { :. , dot_meta , [ e_expr ] } , meta , e_args } , sa , ea }
@@ -1502,6 +1550,8 @@ defmodule ElixirSense.Core.Compiler do
15021550 { ast , state , env } =
15031551 expand_macro_callback! ( meta , Kernel , :defprotocol , args , callback , state , env )
15041552
1553+ # TODO
1554+ # [warning] Unable to expand ast node {:defprotocol, [end_of_expression: [newlines: 1, line: 3, column: 4], do: [line: 1, column: 19], end: [line: 3, column: 1], line: 1, column: 1], [{:__aliases__, [last: [line: 1, column: 13], line: 1, column: 13], [:Proto]}, [do: {:def, [end_of_expression: [newlines: 1, line: 2, column: 20], line: 2, column: 3], [{:reverse, [closing: [line: 2, column: 19], line: 2, column: 7], [{:term, [line: 2, column: 15], nil}]}]}]]}: ** (MatchError) no match of right hand side value: []
15051555 [ module ] = env . context_modules -- original_env . context_modules
15061556 # add behaviour_info builtin
15071557 # generate callbacks as macro expansion currently fails
@@ -1564,8 +1614,6 @@ defmodule ElixirSense.Core.Compiler do
15641614 function: { :__impl__ , 1 }
15651615 } )
15661616
1567- state = collect_traces ( state )
1568-
15691617 { for , state } =
15701618 if is_atom ( for ) or ( is_list ( for ) and Enum . all? ( for , & is_atom / 1 ) ) do
15711619 { for , state }
@@ -1641,8 +1689,6 @@ defmodule ElixirSense.Core.Compiler do
16411689 { :"Elixir.__Unknown__" , env }
16421690 end
16431691
1644- state = collect_traces ( state )
1645-
16461692 # elixir emits a special require directive with :defined key set in meta
16471693 # require expand does alias, updates context_modules and runtime_modules
16481694 # we do it here instead
@@ -2167,11 +2213,6 @@ defmodule ElixirSense.Core.Compiler do
21672213 # look for cursor in discarded args
21682214 { _ast , sl , _env } = expand ( args , sl , e )
21692215
2170- sl =
2171- sl
2172- |> State . add_call_to_line ( { receiver , right , length ( args ) } , meta )
2173- |> State . add_current_env_to_line ( meta , e )
2174-
21752216 { { { :. , dot_meta , [ receiver , right ] } , meta , [ ] } , sl , e }
21762217
21772218 context == nil ->
@@ -2190,7 +2231,6 @@ defmodule ElixirSense.Core.Compiler do
21902231 { :ok , rewritten } ->
21912232 s =
21922233 State . close_write ( sa , s )
2193- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
21942234 |> State . add_current_env_to_line ( meta , e )
21952235
21962236 { rewritten , s , ea }
@@ -2199,7 +2239,6 @@ defmodule ElixirSense.Core.Compiler do
21992239 # elixir raises here elixir_rewrite
22002240 s =
22012241 State . close_write ( sa , s )
2202- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
22032242 |> State . add_current_env_to_line ( meta , e )
22042243
22052244 { { { :. , dot_meta , [ receiver , right ] } , attached_meta , e_args } , s , ea }
@@ -2224,7 +2263,6 @@ defmodule ElixirSense.Core.Compiler do
22242263 # elixir raises here elixir_rewrite
22252264 s =
22262265 sa
2227- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
22282266 |> State . add_current_env_to_line ( meta , e )
22292267
22302268 { { { :. , dot_meta , [ receiver , right ] } , meta , e_args } , s , ea }
@@ -2239,7 +2277,6 @@ defmodule ElixirSense.Core.Compiler do
22392277
22402278 s =
22412279 State . close_write ( sa , s )
2242- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
22432280 |> State . add_current_env_to_line ( meta , e )
22442281
22452282 { { { :. , dot_meta , [ receiver , right ] } , meta , e_args } , s , ea }
@@ -2282,7 +2319,7 @@ defmodule ElixirSense.Core.Compiler do
22822319
22832320 state =
22842321 state
2285- |> State . add_call_to_line ( { nil , fun , length ( args ) } , meta )
2322+ |> State . add_call_to_line ( { env . module , fun , length ( args ) } , meta , :local_function )
22862323 |> State . add_current_env_to_line ( meta , env )
22872324
22882325 { args , state , env } = expand_args ( args , state , env )
@@ -2410,13 +2447,7 @@ defmodule ElixirSense.Core.Compiler do
24102447
24112448 case state . mods_funs_to_positions [ { module , name , arity } ] do
24122449 % ModFunInfo { overridable: { true , _ } } = info ->
2413- kind =
2414- case info . type do
2415- :defdelegate -> :def
2416- :defguard -> :defmacro
2417- :defguardp -> :defmacrop
2418- other -> other
2419- end
2450+ kind = ModFunInfo . get_def_kind ( info )
24202451
24212452 hidden = Map . get ( info . meta , :hidden , false )
24222453 # def meta is not used anyway so let's pass empty
@@ -2451,22 +2482,12 @@ defmodule ElixirSense.Core.Compiler do
24512482 { { :remote , remote , fun , arity } , require_meta , dot_meta , se , ee } ->
24522483 attached_meta = attach_runtime_module ( remote , require_meta , s , e )
24532484
2454- se =
2455- se
2456- |> State . add_call_to_line ( { remote , fun , arity } , attached_meta )
2457- |> State . add_current_env_to_line ( attached_meta , ee )
2458-
24592485 { { :& , meta , [ { :/ , [ ] , [ { { :. , dot_meta , [ remote , fun ] } , attached_meta , [ ] } , arity ] } ] } , se ,
24602486 ee }
24612487
24622488 { { :local , fun , arity } , local_meta , _ , se , ee } ->
24632489 # elixir raises undefined_local_capture if ee.function is nil
24642490
2465- se =
2466- se
2467- |> State . add_call_to_line ( { nil , fun , arity } , local_meta )
2468- |> State . add_current_env_to_line ( local_meta , ee )
2469-
24702491 { { :& , meta , [ { :/ , [ ] , [ { fun , local_meta , nil } , arity ] } ] } , se , ee }
24712492
24722493 { :expand , expr , se , ee } ->
@@ -2780,13 +2801,13 @@ defmodule ElixirSense.Core.Compiler do
27802801 end
27812802
27822803 defp expand_aliases ( { :__aliases__ , meta , [ head | tail ] = list } , state , env , report ) do
2804+ # TODO pass true to track alias_expansion?
27832805 case NormalizedMacroEnv . expand_alias ( env , meta , list , trace: false ) do
27842806 { :alias , alias } ->
27852807 state =
27862808 if report do
27872809 state
2788- |> State . add_call_to_line ( { alias , nil , nil } , meta )
2789- |> State . add_current_env_to_line ( meta , env )
2810+ |> State . add_call_to_line ( { alias , nil , nil } , meta , :alias_reference )
27902811 else
27912812 state
27922813 end
@@ -2802,8 +2823,7 @@ defmodule ElixirSense.Core.Compiler do
28022823 state =
28032824 if report do
28042825 state
2805- |> State . add_call_to_line ( { alias , nil , nil } , meta )
2806- |> State . add_current_env_to_line ( meta , env )
2826+ |> State . add_call_to_line ( { alias , nil , nil } , meta , :alias_reference )
28072827 else
28082828 state
28092829 end
0 commit comments