Skip to content

Commit f76aeba

Browse files
author
José Valim
committed
Check for imports conflicts in batches
1 parent fbb06f2 commit f76aeba

File tree

3 files changed

+24
-19
lines changed

3 files changed

+24
-19
lines changed

lib/elixir/lib/module/dispatch_tracker.ex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,18 @@ defmodule Module.DispatchTracker do
153153
Enum.any?(:digraph.in_neighbours(d, mod), match?({ :import, _, _ }, &1))
154154
end
155155

156+
# Collecting all conflicting imports with the given functions
157+
@doc false
158+
def collect_imports_conflicts(pid, all_defined) do
159+
d = :gen_server.call(to_pid(pid), :digraph, @timeout)
160+
161+
lc { name, arity } inlist all_defined,
162+
n = :digraph.out_neighbours(d, { :import, name, arity }),
163+
n != [] do
164+
{ n, name, arity }
165+
end
166+
end
167+
156168
# Collect all unused definitions based on the private
157169
# given also accounting the expected amount of default
158170
# clauses a private function have.

lib/elixir/src/elixir_tracker.erl

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,14 @@ if_tracker(Module, Callback) ->
6969

7070
%% ERROR HANDLING
7171

72-
%% Ensure no import conflicts with any of the local definitions.
73-
7472
ensure_no_import_conflict(Meta, File, Module, AllDefined) ->
7573
if_tracker(Module, fun(Pid) ->
76-
[do_ensure_no_import_conflict(Meta, File, Pid, X) || X <- AllDefined]
74+
[ begin
75+
elixir_errors:form_error(Meta, File, ?MODULE, { import_conflict, Error })
76+
end || Error <- ?tracker:collect_imports_conflicts(Pid, AllDefined) ]
7777
end),
7878
ok.
7979

80-
do_ensure_no_import_conflict(Meta, File, Pid, { Name, Arity } = Tuple) ->
81-
Matches = ?tracker:imports_with_dispatch(Pid, Tuple),
82-
83-
case Matches of
84-
[] -> ok;
85-
Key ->
86-
Error = { import_conflict, { hd(Key), Name, Arity } },
87-
elixir_errors:form_error(Meta, File, ?MODULE, Error)
88-
end.
89-
90-
%% Ensure all imports are used.
91-
9280
ensure_all_imports_used(_Line, File, Module) ->
9381
if_tracker(Module, fun(Pid) ->
9482
[ begin
@@ -97,8 +85,6 @@ ensure_all_imports_used(_Line, File, Module) ->
9785
end),
9886
ok.
9987

100-
%% Warn for unused/unreachable locals and default arguments.
101-
10288
warn_unused_local(File, Module, Private) ->
10389
if_tracker(Module, fun(Pid) ->
10490
Args = [ { Fun, Kind, Defaults } ||
@@ -112,9 +98,9 @@ warn_unused_local(File, Module, Private) ->
11298
end || Error <- Unused ]
11399
end).
114100

115-
format_error({import_conflict,{Receiver, Name, Arity}}) ->
101+
format_error({import_conflict,{Receivers, Name, Arity}}) ->
116102
io_lib:format("imported ~ts.~ts/~B conflicts with local function",
117-
[elixir_errors:inspect(Receiver), Name, Arity]);
103+
[elixir_errors:inspect(hd(Receivers)), Name, Arity]);
118104

119105
format_error({ unused_import, Module }) ->
120106
io_lib:format("unused import ~ts", [elixir_errors:inspect(Module)]);

lib/elixir/test/elixir/module/dispatch_tracker_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,11 @@ defmodule Module.DispatchTrackerTest do
132132
D.add_warnable(config[:pid], Module, false, 15)
133133
refute { Module, 15 } in D.collect_unused_imports(config[:pid])
134134
end
135+
136+
test "find import conflicts", config do
137+
refute { [Module], :conflict, 1 } in D.collect_imports_conflicts(config[:pid], [conflict: 1])
138+
139+
D.add_import(config[:pid], Module, { :conflict, 1 })
140+
assert { [Module], :conflict, 1 } in D.collect_imports_conflicts(config[:pid], [conflict: 1])
141+
end
135142
end

0 commit comments

Comments
 (0)