summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlauber Campinho <ggcampinho@gmail.com>2018-09-16 10:44:26 +0200
committerJosé Valim <jose.valim@gmail.com>2018-09-16 10:44:26 +0200
commitf3322732287ff733b02cd79debbf1b53de676251 (patch)
tree9a93d573d38afceefac9d2225145f48484f5906e
parent57c291280924dcbb7e9d5c771e2d3c23f422491d (diff)
downloadelixir-f3322732287ff733b02cd79debbf1b53de676251.tar.gz
Use head definition meta to warn about unused args (#8198)
Fixes #8184
-rw-r--r--lib/elixir/src/elixir_def.erl24
-rw-r--r--lib/elixir/test/elixir/kernel/warning_test.exs68
2 files changed, 68 insertions, 24 deletions
diff --git a/lib/elixir/src/elixir_def.erl b/lib/elixir/src/elixir_def.erl
index 24fca3410..e5b36f28e 100644
--- a/lib/elixir/src/elixir_def.erl
+++ b/lib/elixir/src/elixir_def.erl
@@ -65,17 +65,17 @@ fetch_definitions(File, Module) ->
{All, Unreachable}.
fetch_definition([Tuple | T], File, Module, Set, Bag, All, Private) ->
- [{_, Kind, Meta, _, Check, {Defaults, _, _}}] = ets:lookup(Set, {def, Tuple}),
+ [{_, Kind, Meta, _, Check, {MaxDefaults, _, Defaults}}] = ets:lookup(Set, {def, Tuple}),
try ets:lookup_element(Bag, {clauses, Tuple}, 2) of
Clauses ->
NewAll =
- [{Tuple, Kind, add_defaults_to_meta(Defaults, Meta), Clauses} | All],
+ [{Tuple, Kind, add_defaults_to_meta(MaxDefaults, Meta), Clauses} | All],
NewPrivate =
case (Kind == defp) orelse (Kind == defmacrop) of
true ->
- WarnMeta = case Check of true -> Meta; false -> false end,
- [{Tuple, Kind, WarnMeta, Defaults} | Private];
+ Metas = head_and_definition_meta(Check, Meta, MaxDefaults - Defaults, All),
+ [{Tuple, Kind, Metas, MaxDefaults} | Private];
false ->
Private
end,
@@ -92,6 +92,13 @@ fetch_definition([], _File, _Module, _Set, _Bag, All, Private) ->
add_defaults_to_meta(0, Meta) -> Meta;
add_defaults_to_meta(Defaults, Meta) -> [{defaults, Defaults} | Meta].
+head_and_definition_meta(true, Meta, 0, _All) ->
+ Meta;
+head_and_definition_meta(true, _Meta, _HeadDefaults, [{_, _, HeadMeta, _} | _]) ->
+ HeadMeta;
+head_and_definition_meta(false, _Meta, _HeadDefaults, _All) ->
+ false.
+
%% Section for storing definitions
store_definition(Kind, CheckClauses, Call, Body, Pos) ->
@@ -242,22 +249,23 @@ store_definition(Check, Kind, Meta, Name, Arity, File, Module, Defaults, Clauses
ok
end,
- MaxDefaults =
+ {MaxDefaults, FirstMeta} =
case ets:lookup(Set, {def, Tuple}) of
[{_, StoredKind, StoredMeta, StoredFile, StoredCheck, {StoredDefaults, LastHasBody, LastDefaults}}] ->
check_valid_kind(Meta, File, Name, Arity, Kind, StoredKind),
(Check and StoredCheck) andalso
check_valid_clause(Meta, File, Name, Arity, Kind, Set, StoredMeta, StoredFile),
check_valid_defaults(Meta, File, Name, Arity, Kind, Defaults, StoredDefaults, LastDefaults, HasBody, LastHasBody),
- max(Defaults, StoredDefaults);
+
+ {max(Defaults, StoredDefaults), StoredMeta};
[] ->
ets:insert(Bag, {defs, Tuple}),
- Defaults
+ {Defaults, Meta}
end,
Check andalso ets:insert(Set, {?last_def, Tuple}),
ets:insert(Bag, [{{clauses, Tuple}, Clause} || Clause <- Clauses]),
- ets:insert(Set, {{def, Tuple}, Kind, Meta, File, Check, {MaxDefaults, HasBody, Defaults}}).
+ ets:insert(Set, {{def, Tuple}, Kind, FirstMeta, File, Check, {MaxDefaults, HasBody, Defaults}}).
%% Handling of defaults
diff --git a/lib/elixir/test/elixir/kernel/warning_test.exs b/lib/elixir/test/elixir/kernel/warning_test.exs
index 76c986eb6..95f257718 100644
--- a/lib/elixir/test/elixir/kernel/warning_test.exs
+++ b/lib/elixir/test/elixir/kernel/warning_test.exs
@@ -343,7 +343,7 @@ defmodule Kernel.WarningTest do
defp hello, do: nil
end
""")
- end) =~ "function hello/0 is unused"
+ end) =~ "function hello/0 is unused\n nofile:2"
assert capture_err(fn ->
Code.eval_string("""
@@ -352,7 +352,7 @@ defmodule Kernel.WarningTest do
defp hello(1), do: :ok
end
""")
- end) =~ "function hello/1 is unused"
+ end) =~ "function hello/1 is unused\n nofile:2"
assert capture_err(fn ->
Code.eval_string(~S"""
@@ -363,20 +363,34 @@ defmodule Kernel.WarningTest do
defp d(x), do: x
end
""")
- end) =~ "function c/2 is unused"
- after
- purge([Sample1, Sample2, Sample3])
- end
+ end) =~ "function c/2 is unused\n nofile:4"
- test "unused cyclic functions" do
assert capture_err(fn ->
- Code.eval_string("""
- defmodule Sample do
- defp a, do: b()
- defp b, do: a()
+ Code.eval_string(~S"""
+ defmodule Sample4 do
+ def a, do: nil
+ defp b(x \\ 1, y \\ 1)
+ defp b(x, y), do: [x, y]
end
""")
- end) =~ "function a/0 is unused"
+ end) =~ "function b/2 is unused\n nofile:3"
+ after
+ purge([Sample1, Sample2, Sample3, Sample4])
+ end
+
+ test "unused cyclic functions" do
+ message =
+ capture_err(fn ->
+ Code.eval_string("""
+ defmodule Sample do
+ defp a, do: b()
+ defp b, do: a()
+ end
+ """)
+ end)
+
+ assert message =~ "function a/0 is unused\n nofile:2"
+ assert message =~ "function b/0 is unused\n nofile:3"
after
purge(Sample)
end
@@ -418,7 +432,7 @@ defmodule Kernel.WarningTest do
defp b(arg1 \\ 1, arg2 \\ 2, arg3 \\ 3), do: [arg1, arg2, arg3]
end
""")
- end) =~ "default arguments in b/3 are never used"
+ end) =~ "default arguments in b/3 are never used\n nofile:3"
assert capture_err(fn ->
Code.eval_string(~S"""
@@ -427,7 +441,7 @@ defmodule Kernel.WarningTest do
defp b(arg1 \\ 1, arg2 \\ 2, arg3 \\ 3), do: [arg1, arg2, arg3]
end
""")
- end) =~ "the first 2 default arguments in b/3 are never used"
+ end) =~ "the first 2 default arguments in b/3 are never used\n nofile:3"
assert capture_err(fn ->
Code.eval_string(~S"""
@@ -436,7 +450,7 @@ defmodule Kernel.WarningTest do
defp b(arg1 \\ 1, arg2 \\ 2, arg3 \\ 3), do: [arg1, arg2, arg3]
end
""")
- end) =~ "the first default argument in b/3 is never used"
+ end) =~ "the first default argument in b/3 is never used\n nofile:3"
assert capture_err(fn ->
Code.eval_string(~S"""
@@ -446,8 +460,30 @@ defmodule Kernel.WarningTest do
end
""")
end) == ""
+
+ assert capture_err(fn ->
+ Code.eval_string(~S"""
+ defmodule Sample5 do
+ def a, do: b(1, 2, 3)
+ defp b(arg1 \\ 1, arg2 \\ 2, arg3 \\ 3)
+
+ defp b(arg1, arg2, arg3), do: [arg1, arg2, arg3]
+ end
+ """)
+ end) =~ "default arguments in b/3 are never used\n nofile:3"
+
+ assert capture_err(fn ->
+ Code.eval_string(~S"""
+ defmodule Sample6 do
+ def a, do: b(1, 2)
+ defp b(arg1 \\ 1, arg2 \\ 2, arg3 \\ 3)
+
+ defp b(arg1, arg2, arg3), do: [arg1, arg2, arg3]
+ end
+ """)
+ end) =~ "the first 2 default arguments in b/3 are never used\n nofile:3"
after
- purge([Sample1, Sample2, Sample3, Sample4])
+ purge([Sample1, Sample2, Sample3, Sample4, Sample5, Sample6])
end
test "unused import" do