5
5
-export ([default_macros /0 , default_functions /0 , default_requires /0 ,
6
6
dispatch_require /6 , dispatch_import /5 ,
7
7
require_function /5 , import_function /4 ,
8
- expand_import /8 , expand_require /8 , find_import /4 ,
8
+ expand_import /9 , expand_require /8 , find_import /4 ,
9
9
format_error /1 , in_erlang_functions /0 , in_erlang_macros /0 ]).
10
10
-include (" elixir.hrl" ).
11
11
-compile ({parse_transform , elixir_transform }).
@@ -20,11 +20,11 @@ default_macros() ->
20
20
default_requires () ->
21
21
[ ? BUILTIN , 'Elixir.Kernel.Typespec' ].
22
22
23
- find_import (_Meta , Name , Arity , S ) ->
23
+ find_import (Meta , Name , Arity , S ) ->
24
24
Tuple = { Name , Arity },
25
- case find_dispatch (Tuple , S # elixir_scope .functions ) of
25
+ case find_dispatch (Meta , S # elixir_scope . file , Tuple , S # elixir_scope .functions , S # elixir_scope . macros ) of
26
26
false ->
27
- case find_dispatch (Tuple , S # elixir_scope .macros ) of
27
+ case find_dispatch (Meta , S # elixir_scope . file , Tuple , S # elixir_scope .macros , S # elixir_scope . functions ) of
28
28
false -> false ;
29
29
Receiver -> Receiver
30
30
end ;
@@ -35,9 +35,9 @@ find_import(_Meta, Name, Arity, S) ->
35
35
36
36
import_function (Meta , Name , Arity , S ) ->
37
37
Tuple = { Name , Arity },
38
- case find_dispatch (Tuple , S # elixir_scope .functions ) of
38
+ case find_dispatch (Meta , S # elixir_scope . file , Tuple , S # elixir_scope .functions , S # elixir_scope . macros ) of
39
39
false ->
40
- case find_dispatch (Tuple , S # elixir_scope .macros ) of
40
+ case find_dispatch (Meta , S # elixir_scope . file , Tuple , S # elixir_scope .macros , S # elixir_scope . functions ) of
41
41
false -> { { 'fun' , ? line (Meta ), { function , Name , Arity } }, S };
42
42
_ -> false
43
43
end ;
@@ -61,10 +61,10 @@ dispatch_import(Meta, Name, Args, S, Callback) ->
61
61
Arity = length (Args ),
62
62
Tuple = { Name , Arity },
63
63
64
- case find_dispatch (Tuple , S # elixir_scope .functions ) of
64
+ case find_dispatch (Meta , S # elixir_scope . file , Tuple , S # elixir_scope .functions , S # elixir_scope . macros ) of
65
65
false ->
66
66
case expand_import (Meta , Tuple , Args , Module , S # elixir_scope .function ,
67
- S # elixir_scope .requires , S # elixir_scope .macros , S ) of
67
+ S # elixir_scope .requires , S # elixir_scope .macros , S # elixir_scope . functions , S ) of
68
68
{ error , noexpansion } ->
69
69
Callback ();
70
70
{ error , internal } ->
@@ -104,8 +104,8 @@ dispatch_require(Meta, Receiver, Name, Args, S, Callback) ->
104
104
105
105
% % Macros expansion
106
106
107
- expand_import (Meta , { Name , Arity } = Tuple , Args , Module , Function , Requires , Macros , SEnv ) ->
108
- case find_dispatch (Tuple , Macros ) of
107
+ expand_import (Meta , { Name , Arity } = Tuple , Args , Module , Function , Requires , Macros , Functions , SEnv ) ->
108
+ case find_dispatch (Meta , elixir_scope : filename ( SEnv ), Tuple , Macros , Functions ) of
109
109
false ->
110
110
Fun = (Function /= Tuple ) andalso
111
111
elixir_def_local :macro_for (Tuple , true , Module ),
@@ -199,13 +199,25 @@ merge_aliases(A1, A2) ->
199
199
skip_requires (# elixir_scope {check_requires = false }) -> true ;
200
200
skip_requires (_ ) -> false .
201
201
202
- find_dispatch (Tuple , [{ Name , Values }|T ]) ->
203
- case is_element (Tuple , Values ) of
204
- true -> Name ;
205
- false -> find_dispatch (Tuple , T )
206
- end ;
202
+ find_dispatch (Meta , File , {Name , Arity } = Tuple , List1 , List2 ) ->
203
+ Matcher = fun (List ) -> lists :filter (fun ({_ , Vals }) -> is_element (Tuple , Vals ) end , List ) end ,
204
+ Matches1 = Matcher (List1 ),
205
+
206
+ case length (Matches1 ) of
207
+ 0 -> false ;
208
+ 1 ->
209
+ Matches2 = Matcher (List2 ),
207
210
208
- find_dispatch (_Tuple , []) -> false .
211
+ case length (Matches2 ) of
212
+ 0 -> element (1 , hd (Matches1 ));
213
+ _ ->
214
+ Err = {ambiguous_call , {element (1 , hd (Matches1 )), element (1 , hd (Matches2 )), Name , Arity }},
215
+ elixir_errors :form_error (Meta , File , ? MODULE , Err )
216
+ end ;
217
+ _ ->
218
+ Err = {ambiguous_call , {element (1 , hd (Matches1 )), element (1 , hd (tl (Matches1 ))), Name , Arity }},
219
+ elixir_errors :form_error (Meta , File , ? MODULE , Err )
220
+ end .
209
221
210
222
munge_stacktrace (Info , [{ _ , _ , [S |_ ], _ }|_ ], S ) ->
211
223
[Info ];
@@ -224,7 +236,11 @@ munge_stacktrace(_, [], _) ->
224
236
format_error ({ unrequired_module ,{Receiver , Name , Arity , Required }}) ->
225
237
String = string :join ([elixir_errors :inspect (R ) || R <- Required ], " , " ),
226
238
io_lib :format (" tried to invoke macro ~ts .~ts /~B but module was not required. Required: ~ts " ,
227
- [elixir_errors :inspect (Receiver ), Name , Arity , String ]).
239
+ [elixir_errors :inspect (Receiver ), Name , Arity , String ]);
240
+
241
+ format_error ({ ambiguous_call ,{Mod1 , Mod2 , Name , Arity }}) ->
242
+ io_lib :format (" function ~ts /~B imported from both ~ts and ~ts ; call is ambiguous" ,
243
+ [Name , Arity , elixir_errors :inspect (Mod1 ), elixir_errors :inspect (Mod2 )]).
228
244
229
245
% % INTROSPECTION
230
246
@@ -398,4 +414,4 @@ in_erlang_macros() ->
398
414
{'receive' ,1 },
399
415
{'try' ,1 },
400
416
{'xor' ,2 }
401
- ].
417
+ ].
0 commit comments