@@ -33,20 +33,35 @@ defmodule ElixirSense.Core.Compiler do
33
33
{ :alias_reference , meta , alias } ->
34
34
# emitted by Macro.expand/2 and Macro.expand_once/2
35
35
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 )
38
37
39
38
{ :alias , meta , module , _as , _opts } ->
40
39
# emitted by Macro.Env.define_alias/3 and Macro.Env.define_require/3
41
40
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 )
44
42
45
43
{ kind , meta , module , _opts } when kind in [ :import , :require ] ->
46
44
# emitted by Macro.Env.define_import/3 and Macro.Env.define_require/3
47
45
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 )
50
65
51
66
_ ->
52
67
Logger . warning ( "Unhandled trace event: #{ inspect ( event ) } " )
@@ -204,7 +219,6 @@ defmodule ElixirSense.Core.Compiler do
204
219
if is_atom ( arg ) do
205
220
case NormalizedMacroEnv . define_alias ( env , meta , arg , [ trace: true ] ++ opts ) do
206
221
{ :ok , env } ->
207
- state = collect_traces ( state )
208
222
{ arg , state , env }
209
223
210
224
{ :error , _ } ->
@@ -235,7 +249,6 @@ defmodule ElixirSense.Core.Compiler do
235
249
# and optionally waits until required module is compiled
236
250
case NormalizedMacroEnv . define_require ( env , meta , arg , [ trace: true ] ++ opts ) do
237
251
{ :ok , env } ->
238
- state = collect_traces ( state )
239
252
{ arg , state , env }
240
253
241
254
{ :error , _ } ->
@@ -267,7 +280,6 @@ defmodule ElixirSense.Core.Compiler do
267
280
268
281
case NormalizedMacroEnv . define_import ( env , meta , arg , opts ) do
269
282
{ :ok , env } ->
270
- state = collect_traces ( state )
271
283
{ arg , state , env }
272
284
273
285
_ ->
@@ -456,12 +468,7 @@ defmodule ElixirSense.Core.Compiler do
456
468
when is_atom ( context ) and is_integer ( arity ) do
457
469
case resolve_super ( meta , arity , s , e ) do
458
470
{ 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 )
465
472
466
473
_ ->
467
474
expand_fn_capture ( meta , expr , s , e )
@@ -535,7 +542,7 @@ defmodule ElixirSense.Core.Compiler do
535
542
536
543
sa =
537
544
sa
538
- |> State . add_call_to_line ( { nil , name , arity } , meta )
545
+ |> State . add_call_to_line ( { e . module , name , arity } , meta , :local_function )
539
546
|> State . add_current_env_to_line ( meta , ea )
540
547
541
548
{ { :super , [ { :super , { kind , name } } | meta ] , e_args } , sa , ea }
@@ -705,17 +712,38 @@ defmodule ElixirSense.Core.Compiler do
705
712
allow_locals = match? ( { n , a } when fun != n or arity != a , env . function )
706
713
707
714
case NormalizedMacroEnv . expand_import ( env , meta , fun , arity ,
708
- trace: false ,
715
+ trace: true ,
709
716
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
711
743
) do
712
744
{ :macro , module , callback } ->
713
745
# NOTE there is a subtle difference - callback will call expander with state derived from env via
714
746
# :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 )
719
747
720
748
expand_macro ( meta , module , fun , args , callback , state , env )
721
749
@@ -751,35 +779,55 @@ defmodule ElixirSense.Core.Compiler do
751
779
defp do_expand ( { { :. , dot_meta , [ module , fun ] } , meta , args } , state , env )
752
780
when ( is_tuple ( module ) or is_atom ( module ) ) and is_atom ( fun ) and is_list ( meta ) and
753
781
is_list ( args ) do
754
- # dbg({module, fun, args})
755
782
{ module , state_l , env } = expand ( module , State . prepare_write ( state , env ) , env )
756
783
arity = length ( args )
757
784
758
785
if is_atom ( module ) do
759
786
case __MODULE__ . Rewrite . inline ( module , fun , arity ) do
760
787
{ 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
+
761
793
expand_remote ( ar , dot_meta , an , meta , args , state , state_l , env )
762
794
763
795
false ->
764
796
case NormalizedMacroEnv . expand_require ( env , meta , module , fun , arity ,
765
- trace: false ,
797
+ trace: true ,
766
798
check_deprecations: false
767
799
) do
768
800
{ :macro , module , callback } ->
769
801
# NOTE there is a subtle difference - callback will call expander with state derived from env via
770
802
# :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 = % {
772
805
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
+ }
775
813
776
814
expand_macro ( meta , module , fun , args , callback , state_l , env )
777
815
778
816
: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
+
779
822
expand_remote ( module , dot_meta , fun , meta , args , state , state_l , env )
780
823
end
781
824
end
782
825
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
+
783
831
expand_remote ( module , dot_meta , fun , meta , args , state , state_l , env )
784
832
end
785
833
end
@@ -797,7 +845,7 @@ defmodule ElixirSense.Core.Compiler do
797
845
798
846
sa =
799
847
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 )
801
849
|> State . add_current_env_to_line ( meta , e )
802
850
803
851
{ { { :. , dot_meta , [ e_expr ] } , meta , e_args } , sa , ea }
@@ -1502,6 +1550,8 @@ defmodule ElixirSense.Core.Compiler do
1502
1550
{ ast , state , env } =
1503
1551
expand_macro_callback! ( meta , Kernel , :defprotocol , args , callback , state , env )
1504
1552
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: []
1505
1555
[ module ] = env . context_modules -- original_env . context_modules
1506
1556
# add behaviour_info builtin
1507
1557
# generate callbacks as macro expansion currently fails
@@ -1564,8 +1614,6 @@ defmodule ElixirSense.Core.Compiler do
1564
1614
function: { :__impl__ , 1 }
1565
1615
} )
1566
1616
1567
- state = collect_traces ( state )
1568
-
1569
1617
{ for , state } =
1570
1618
if is_atom ( for ) or ( is_list ( for ) and Enum . all? ( for , & is_atom / 1 ) ) do
1571
1619
{ for , state }
@@ -1641,8 +1689,6 @@ defmodule ElixirSense.Core.Compiler do
1641
1689
{ :"Elixir.__Unknown__" , env }
1642
1690
end
1643
1691
1644
- state = collect_traces ( state )
1645
-
1646
1692
# elixir emits a special require directive with :defined key set in meta
1647
1693
# require expand does alias, updates context_modules and runtime_modules
1648
1694
# we do it here instead
@@ -2167,11 +2213,6 @@ defmodule ElixirSense.Core.Compiler do
2167
2213
# look for cursor in discarded args
2168
2214
{ _ast , sl , _env } = expand ( args , sl , e )
2169
2215
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
-
2175
2216
{ { { :. , dot_meta , [ receiver , right ] } , meta , [ ] } , sl , e }
2176
2217
2177
2218
context == nil ->
@@ -2190,7 +2231,6 @@ defmodule ElixirSense.Core.Compiler do
2190
2231
{ :ok , rewritten } ->
2191
2232
s =
2192
2233
State . close_write ( sa , s )
2193
- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
2194
2234
|> State . add_current_env_to_line ( meta , e )
2195
2235
2196
2236
{ rewritten , s , ea }
@@ -2199,7 +2239,6 @@ defmodule ElixirSense.Core.Compiler do
2199
2239
# elixir raises here elixir_rewrite
2200
2240
s =
2201
2241
State . close_write ( sa , s )
2202
- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
2203
2242
|> State . add_current_env_to_line ( meta , e )
2204
2243
2205
2244
{ { { :. , dot_meta , [ receiver , right ] } , attached_meta , e_args } , s , ea }
@@ -2224,7 +2263,6 @@ defmodule ElixirSense.Core.Compiler do
2224
2263
# elixir raises here elixir_rewrite
2225
2264
s =
2226
2265
sa
2227
- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
2228
2266
|> State . add_current_env_to_line ( meta , e )
2229
2267
2230
2268
{ { { :. , dot_meta , [ receiver , right ] } , meta , e_args } , s , ea }
@@ -2239,7 +2277,6 @@ defmodule ElixirSense.Core.Compiler do
2239
2277
2240
2278
s =
2241
2279
State . close_write ( sa , s )
2242
- |> State . add_call_to_line ( { receiver , right , length ( e_args ) } , meta )
2243
2280
|> State . add_current_env_to_line ( meta , e )
2244
2281
2245
2282
{ { { :. , dot_meta , [ receiver , right ] } , meta , e_args } , s , ea }
@@ -2282,7 +2319,7 @@ defmodule ElixirSense.Core.Compiler do
2282
2319
2283
2320
state =
2284
2321
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 )
2286
2323
|> State . add_current_env_to_line ( meta , env )
2287
2324
2288
2325
{ args , state , env } = expand_args ( args , state , env )
@@ -2410,13 +2447,7 @@ defmodule ElixirSense.Core.Compiler do
2410
2447
2411
2448
case state . mods_funs_to_positions [ { module , name , arity } ] do
2412
2449
% 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 )
2420
2451
2421
2452
hidden = Map . get ( info . meta , :hidden , false )
2422
2453
# def meta is not used anyway so let's pass empty
@@ -2451,22 +2482,12 @@ defmodule ElixirSense.Core.Compiler do
2451
2482
{ { :remote , remote , fun , arity } , require_meta , dot_meta , se , ee } ->
2452
2483
attached_meta = attach_runtime_module ( remote , require_meta , s , e )
2453
2484
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
-
2459
2485
{ { :& , meta , [ { :/ , [ ] , [ { { :. , dot_meta , [ remote , fun ] } , attached_meta , [ ] } , arity ] } ] } , se ,
2460
2486
ee }
2461
2487
2462
2488
{ { :local , fun , arity } , local_meta , _ , se , ee } ->
2463
2489
# elixir raises undefined_local_capture if ee.function is nil
2464
2490
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
-
2470
2491
{ { :& , meta , [ { :/ , [ ] , [ { fun , local_meta , nil } , arity ] } ] } , se , ee }
2471
2492
2472
2493
{ :expand , expr , se , ee } ->
@@ -2780,13 +2801,13 @@ defmodule ElixirSense.Core.Compiler do
2780
2801
end
2781
2802
2782
2803
defp expand_aliases ( { :__aliases__ , meta , [ head | tail ] = list } , state , env , report ) do
2804
+ # TODO pass true to track alias_expansion?
2783
2805
case NormalizedMacroEnv . expand_alias ( env , meta , list , trace: false ) do
2784
2806
{ :alias , alias } ->
2785
2807
state =
2786
2808
if report do
2787
2809
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 )
2790
2811
else
2791
2812
state
2792
2813
end
@@ -2802,8 +2823,7 @@ defmodule ElixirSense.Core.Compiler do
2802
2823
state =
2803
2824
if report do
2804
2825
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 )
2807
2827
else
2808
2828
state
2809
2829
end
0 commit comments