Skip to content

Commit 03b6c07

Browse files
author
José Valim
committed
Include proper line numbers on unused module attribute warning, closes #5490
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
1 parent d10b9d5 commit 03b6c07

File tree

4 files changed

+40
-37
lines changed

4 files changed

+40
-37
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2399,7 +2399,11 @@ defmodule Kernel do
23992399

24002400
# @attribute(value)
24012401
defp do_at([arg], meta, name, function?, env) do
2402-
read? = :lists.keymember(:context, 1, meta)
2402+
line =
2403+
case :lists.keymember(:context, 1, meta) do
2404+
true -> nil
2405+
false -> env.line
2406+
end
24032407

24042408
cond do
24052409
function? ->
@@ -2413,11 +2417,11 @@ defmodule Kernel do
24132417
{stack, _} = :elixir_quote.escape(env_stacktrace(env), false)
24142418
arg = {env.line, arg}
24152419
quote do: Module.put_attribute(__MODULE__, unquote(name), unquote(arg),
2416-
unquote(stack), unquote(read?))
2420+
unquote(stack), unquote(line))
24172421

24182422
true ->
24192423
quote do: Module.put_attribute(__MODULE__, unquote(name), unquote(arg),
2420-
nil, unquote(read?))
2424+
nil, unquote(line))
24212425
end
24222426
end
24232427

lib/elixir/lib/module.ex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ defmodule Module do
854854
"""
855855
@spec put_attribute(module, key :: atom, value :: term) :: term
856856
def put_attribute(module, key, value) do
857-
put_attribute(module, key, value, nil, false)
857+
put_attribute(module, key, value, nil, nil)
858858
end
859859

860860
@doc """
@@ -910,7 +910,7 @@ defmodule Module do
910910
table = data_table_for(module)
911911
case :ets.take(table, key) do
912912
[{_, value, _accumulated? = true, _}] ->
913-
:ets.insert(table, {key, [], true, true})
913+
:ets.insert(table, {key, [], true, nil})
914914
value
915915
[{_, value, _, _}] ->
916916
value
@@ -960,7 +960,7 @@ defmodule Module do
960960
end
961961

962962
if Keyword.get(opts, :accumulate) do
963-
:ets.insert_new(table, {new, [], _accumulated? = true, _read? = true}) ||
963+
:ets.insert_new(table, {new, [], _accumulated? = true, _unread_line = nil}) ||
964964
:ets.update_element(table, new, {3, true})
965965
end
966966

@@ -1031,7 +1031,7 @@ defmodule Module do
10311031
[] -> [value]
10321032
end
10331033

1034-
:ets.insert(table, {key, new, true, true})
1034+
:ets.insert(table, {key, new, true, nil})
10351035
end
10361036

10371037
@doc false
@@ -1043,7 +1043,7 @@ defmodule Module do
10431043

10441044
case :ets.lookup(table, key) do
10451045
[{^key, val, _, _}] ->
1046-
:ets.update_element(table, key, {4, true})
1046+
:ets.update_element(table, key, {4, nil})
10471047
val
10481048
[] when is_list(stack) ->
10491049
# TODO: Consider raising instead of warning on v2.0 as it usually cascades
@@ -1058,22 +1058,22 @@ defmodule Module do
10581058
@doc false
10591059
# Used internally by Kernel's @.
10601060
# This function is private and must be used only internally.
1061-
def put_attribute(module, key, value, stack, read?) when is_atom(key) do
1061+
def put_attribute(module, key, value, stack, unread_line) when is_atom(key) do
10621062
assert_not_compiled!(:put_attribute, module)
10631063
table = data_table_for(module)
10641064
value = preprocess_attribute(key, value)
10651065

10661066
case :ets.lookup(table, key) do
1067-
[{^key, {line, <<_::binary>>}, accumulated?, _read?}]
1067+
[{^key, {line, <<_::binary>>}, accumulated?, _unread_line}]
10681068
when key in [:doc, :typedoc, :moduledoc] and is_list(stack) ->
10691069
IO.warn "redefining @#{key} attribute previously set at line #{line}", stack
1070-
:ets.insert(table, {key, value, accumulated?, read?})
1070+
:ets.insert(table, {key, value, accumulated?, unread_line})
10711071

10721072
[{^key, current, _accumulated? = true, _read?}] ->
1073-
:ets.insert(table, {key, [value | current], true, read?})
1073+
:ets.insert(table, {key, [value | current], true, unread_line})
10741074

10751075
_ ->
1076-
:ets.insert(table, {key, value, false, read?})
1076+
:ets.insert(table, {key, value, false, unread_line})
10771077
end
10781078

10791079
value

lib/elixir/src/elixir_module.erl

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ do_compile(Line, Module, Block, Vars, E) ->
8585
Forms3 = attributes_form(Line, File, Data, PersistedAttrs, Forms2),
8686

8787
elixir_locals:ensure_no_import_conflict(Line, File, Module, All),
88-
warn_unused_attributes(Line, File, Data, PersistedAttrs),
88+
warn_unused_attributes(File, Data, PersistedAttrs),
8989

9090
Location = {elixir_utils:characters_to_list(elixir_utils:relative_to_cwd(File)), Line},
9191

@@ -152,26 +152,26 @@ build(Line, File, Module, Docs, Lexical) ->
152152
end,
153153

154154
ets:insert(Data, [
155-
% {Key, Value, Accumulate?, Read?}
156-
{after_compile, [], true, true},
157-
{before_compile, [], true, true},
158-
{behaviour, [], true, true},
159-
{compile, [], true, true},
160-
{derive, [], true, true},
161-
{dialyzer, [], true, true},
162-
{external_resource, [], true, true},
163-
{moduledoc, nil, false, true},
164-
{on_definition, OnDefinition, true, true},
165-
{on_load, [], true, true},
155+
% {Key, Value, Accumulate?, UnreadLine}
156+
{after_compile, [], true, nil},
157+
{before_compile, [], true, nil},
158+
{behaviour, [], true, nil},
159+
{compile, [], true, nil},
160+
{derive, [], true, nil},
161+
{dialyzer, [], true, nil},
162+
{external_resource, [], true, nil},
163+
{moduledoc, nil, false, nil},
164+
{on_definition, OnDefinition, true, nil},
165+
{on_load, [], true, nil},
166166

167167
% Types
168-
{callback, [], true, true},
169-
{opaque, [], true, true},
170-
{optional_callbacks, [], true, true},
171-
{macrocallback, [], true, true},
172-
{spec, [], true, true},
173-
{type, [], true, true},
174-
{typep, [], true, true}
168+
{callback, [], true, nil},
169+
{opaque, [], true, nil},
170+
{optional_callbacks, [], true, nil},
171+
{macrocallback, [], true, nil},
172+
{spec, [], true, nil},
173+
{type, [], true, nil},
174+
{typep, [], true, nil}
175175
]),
176176

177177
Persisted = [behaviour, on_load, compile, external_resource, dialyzer, vsn],
@@ -425,11 +425,11 @@ check_module_availability(Line, File, Module) ->
425425
ok
426426
end.
427427

428-
warn_unused_attributes(Line, File, Data, PersistedAttrs) ->
428+
warn_unused_attributes(File, Data, PersistedAttrs) ->
429429
ReservedAttrs = [after_compile, before_compile, moduledoc, on_definition | PersistedAttrs],
430-
Keys = ets:select(Data, [{{'$1', '_', '_', false}, [{is_atom, '$1'}], ['$1']}]),
430+
Keys = ets:select(Data, [{{'$1', '_', '_', '$2'}, [{is_atom, '$1'}, {is_integer, '$2'}], [['$1', '$2']]}]),
431431
[elixir_errors:form_warn([{line, Line}], File, ?MODULE, {unused_attribute, Key}) ||
432-
Key <- Keys, not lists:member(Key, ReservedAttrs)].
432+
[Key, Line] <- Keys, not lists:member(Key, ReservedAttrs)].
433433

434434
% __INFO__
435435

lib/elixir/test/elixir/kernel/warning_test.exs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,11 @@ defmodule Kernel.WarningTest do
685685
Code.eval_string """
686686
defmodule Sample do
687687
@at "Something"
688-
Module.put_attribute(__MODULE__, :put_attribute, "Something")
689688
end
690689
"""
691690
end)
692691
assert content =~ "module attribute @at was set but never used"
693-
assert content =~ "module attribute @put_attribute was set but never used"
692+
assert content =~ "nofile:2"
694693
after
695694
purge Sample
696695
end

0 commit comments

Comments
 (0)