66 require_function /5 , import_function /4 ,
77 expand_import /7 , expand_require /6 ,
88 default_functions /0 , default_macros /0 , default_requires /0 ,
9- find_import /4 , find_imports /4 , format_error /1 ]).
9+ find_import /4 , find_imports /3 , format_error /1 ]).
1010-include (" elixir.hrl" ).
1111-import (ordsets , [is_element /2 ]).
1212-define (kernel , 'Elixir.Kernel' ).
@@ -25,7 +25,7 @@ default_requires() ->
2525find_import (Meta , Name , Arity , E ) ->
2626 Tuple = {Name , Arity },
2727
28- case find_dispatch (Meta , Tuple , [], E ) of
28+ case find_import_by_name_arity (Meta , Tuple , [], E ) of
2929 {function , Receiver } ->
3030 elixir_env :trace ({imported_function , Meta , Receiver , Name , Arity }, E ),
3131 Receiver ;
@@ -36,25 +36,37 @@ find_import(Meta, Name, Arity, E) ->
3636 false
3737 end .
3838
39- find_imports (Meta , Name , Arity , E ) ->
40- Tuple = {Name , Arity },
39+ find_imports (Meta , Name , E ) ->
40+ Funs = ? key (E , functions ),
41+ Macs = ? key (E , macros ),
4142
42- case find_dispatch (Meta , Tuple , [], E ) of
43- {function , Receiver } ->
44- elixir_env :trace ({imported_function , Meta , Receiver , Name , Arity }, E ),
45- [{Receiver , Arity }];
46- {macro , Receiver } ->
47- elixir_env :trace ({imported_macro , Meta , Receiver , Name , Arity }, E ),
48- [{Receiver , Arity }];
49- _ ->
50- []
51- end .
43+ Acc0 = #{},
44+ Acc1 = find_imports_by_name (Funs , Acc0 , Name , Meta , E ),
45+ Acc2 = find_imports_by_name (Macs , Acc1 , Name , Meta , E ),
46+
47+ Imports = lists :sort (maps :to_list (Acc2 )),
48+ trace_import_quoted (Imports , Meta , Name , E ),
49+ Imports .
50+
51+ trace_import_quoted ([{Arity , Mod } | Imports ], Meta , Name , E ) ->
52+ {Rest , Arities } = collect_trace_import_quoted (Imports , Mod , [], [Arity ]),
53+ elixir_env :trace ({imported_quoted , Meta , Mod , Name , Arities }, E ),
54+ trace_import_quoted (Rest , Meta , Name , E );
55+ trace_import_quoted ([], _Meta , _Name , _E ) ->
56+ ok .
57+
58+ collect_trace_import_quoted ([{Arity , Mod } | Imports ], Mod , Acc , Arities ) ->
59+ collect_trace_import_quoted (Imports , Mod , Acc , [Arity | Arities ]);
60+ collect_trace_import_quoted ([Import | Imports ], Mod , Acc , Arities ) ->
61+ collect_trace_import_quoted (Imports , Mod , [Import | Acc ], Arities );
62+ collect_trace_import_quoted ([], _Mod , Acc , Arities ) ->
63+ {lists :reverse (Acc ), lists :reverse (Arities )}.
5264
5365% % Function retrieval
5466
5567import_function (Meta , Name , Arity , E ) ->
5668 Tuple = {Name , Arity },
57- case find_dispatch (Meta , Tuple , [], E ) of
69+ case find_import_by_name_arity (Meta , Tuple , [], E ) of
5870 {function , Receiver } ->
5971 elixir_env :trace ({imported_function , Meta , Receiver , Name , Arity }, E ),
6072 elixir_locals :record_import (Tuple , Receiver , ? key (E , module ), ? key (E , function )),
@@ -134,15 +146,14 @@ dispatch_require(_Meta, Receiver, Name, Args, _S, _E, Callback) ->
134146expand_import (Meta , {Name , Arity } = Tuple , Args , S , E , Extra , External ) ->
135147 Module = ? key (E , module ),
136148 Function = ? key (E , function ),
137- Dispatch = find_dispatch (Meta , Tuple , Extra , E ),
149+ Dispatch = find_import_by_name_arity (Meta , Tuple , Extra , E ),
138150
139151 case Dispatch of
140152 {import , _ } ->
141153 do_expand_import (Meta , Tuple , Args , Module , S , E , Dispatch );
142154 _ ->
143155 AllowLocals = External orelse ((Function /= nil ) andalso (Function /= Tuple )),
144- Local = AllowLocals andalso
145- elixir_def :local_for (Meta , Name , Arity , [defmacro , defmacrop ], E ),
156+ Local = AllowLocals andalso elixir_def :local_for (Meta , Name , Arity , [defmacro , defmacrop ], E ),
146157
147158 case Dispatch of
148159 % % There is a local and an import. This is a conflict unless
@@ -246,15 +257,35 @@ caller(Line, E) ->
246257required (Meta ) ->
247258 lists :keyfind (required , 1 , Meta ) == {required , true }.
248259
249- find_dispatch (Meta , {_Name , Arity } = Tuple , Extra , E ) ->
260+ find_imports_by_name ([{Mod , Imports } | ModImports ], Acc , Name , Meta , E ) ->
261+ NewAcc = find_imports_by_name (Name , Imports , Acc , Mod , Meta , E ),
262+ find_imports_by_name (ModImports , NewAcc , Name , Meta , E );
263+ find_imports_by_name ([], Acc , _Name , _Meta , _E ) ->
264+ Acc .
265+
266+ find_imports_by_name (Name , [{Name , Arity } | Imports ], Acc , Mod , Meta , E ) ->
267+ case Acc of
268+ #{Arity := OtherMod } ->
269+ Error = {ambiguous_call , {Mod , OtherMod , Name , Arity }},
270+ elixir_errors :form_error (Meta , E , ? MODULE , Error );
271+
272+ #{} ->
273+ find_imports_by_name (Name , Imports , Acc #{Arity => Mod }, Mod , Meta , E )
274+ end ;
275+ find_imports_by_name (Name , [{ImportName , _ } | Imports ], Acc , Mod , Meta , E ) when Name > ImportName ->
276+ find_imports_by_name (Name , Imports , Acc , Mod , Meta , E );
277+ find_imports_by_name (_Name , _Imports , Acc , _Mod , _Meta , _E ) ->
278+ Acc .
279+
280+ find_import_by_name_arity (Meta , {_Name , Arity } = Tuple , Extra , E ) ->
250281 case is_import (Meta , Arity ) of
251282 {import , _ } = Import ->
252283 Import ;
253284 false ->
254285 Funs = ? key (E , functions ),
255286 Macs = Extra ++ ? key (E , macros ),
256- FunMatch = find_dispatch (Tuple , Funs ),
257- MacMatch = find_dispatch (Tuple , Macs ),
287+ FunMatch = find_import_by_name_arity (Tuple , Funs ),
288+ MacMatch = find_import_by_name_arity (Tuple , Macs ),
258289
259290 case {FunMatch , MacMatch } of
260291 {[], [Receiver ]} -> {macro , Receiver };
@@ -268,16 +299,16 @@ find_dispatch(Meta, {_Name, Arity} = Tuple, Extra, E) ->
268299 end
269300 end .
270301
271- find_dispatch (Tuple , List ) ->
302+ find_import_by_name_arity (Tuple , List ) ->
272303 [Receiver || {Receiver , Set } <- List , is_element (Tuple , Set )].
273304
274305is_import (Meta , Arity ) ->
275306 case lists :keyfind (imports , 1 , Meta ) of
276307 {imports , Imports } ->
277308 case lists :keyfind (context , 1 , Meta ) of
278309 {context , _ } ->
279- case lists :keyfind (Arity , 2 , Imports ) of
280- {Receiver , Arity } -> {import , Receiver };
310+ case lists :keyfind (Arity , 1 , Imports ) of
311+ {Arity , Receiver } -> {import , Receiver };
281312 false -> false
282313 end ;
283314 false -> false
0 commit comments