Skip to content

Commit

Permalink
Merge pull request #1085 from erlang-ls/1047-mark-headers-with-compil…
Browse files Browse the repository at this point in the history
…er-attribute-as-used

[#1047] Mark headers with compiler attributes as used
  • Loading branch information
robertoaloi committed Sep 20, 2021
2 parents a456c61 + eae6df9 commit 0982456
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%% Issue 1047
-module(diagnostics_unused_includes_compiler_attribute).

-include_lib("kernel/include/file.hrl").
-include_lib("eunit/include/eunit.hrl").

the_test() ->
ok.
7 changes: 6 additions & 1 deletion apps/els_lsp/src/els_parser.erl
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,12 @@ attribute(Tree) ->
[]
end;
{compile, [Arg]} ->
find_compile_options_pois(Arg);
%% When we encounter a compiler attribute, we include a POI
%% indicating the fact. This is useful, for example, to avoid
%% marking header files including parse transforms or other
%% compiler attributes as unused. See #1047
Marker = poi(erl_syntax:get_pos(Arg), compile, unused),
[Marker|find_compile_options_pois(Arg)];
{AttrName, [Arg]} when AttrName =:= export;
AttrName =:= export_type ->
find_export_pois(Tree, AttrName, Arg);
Expand Down
31 changes: 30 additions & 1 deletion apps/els_lsp/src/els_unused_includes_diagnostics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ find_unused_includes(#{uri := Uri} = Document) ->
, export_type_entry
]),
IncludedUris0 = els_diagnostics_utils:included_uris(Document),
IncludedUris1 = filter_includes_with_compiler_attributes(IncludedUris0),
ExcludeUnusedIncludes =
lists:filtermap(
fun(Include) ->
Expand All @@ -74,7 +75,7 @@ find_unused_includes(#{uri := Uri} = Document) ->
false
end
end, els_config:get(exclude_unused_includes)),
IncludedUris = IncludedUris0 -- ExcludeUnusedIncludes,
IncludedUris = IncludedUris1 -- ExcludeUnusedIncludes,
Fun = fun(POI, Acc) ->
update_unused(Graph, Uri, POI, Acc)
end,
Expand Down Expand Up @@ -120,3 +121,31 @@ inclusion_range(Uri, Document) ->
_ ->
#{from => {1, 1}, to => {2, 1}}
end.

%% @doc Given a list of included uris, filter out the ones containing
%% compiler attributes. If the Uri cannot be found, keep it in the list.
-spec filter_includes_with_compiler_attributes([uri()]) -> [uri()].
filter_includes_with_compiler_attributes(Uris) ->
Filter = fun(Uri) ->
case els_utils:lookup_document(Uri) of
{error, _Error} ->
{true, Uri};
{ok, Document} ->
case contains_compiler_attributes(Document) of
true ->
false;
false ->
{true, Uri}
end
end
end,
lists:filtermap(Filter, Uris).

%% @doc Return true if the Document contains a compiler attribute.
-spec contains_compiler_attributes(els_dt_document:item()) -> boolean().
contains_compiler_attributes(Document) ->
compiler_attributes(Document) =/= [].

-spec compiler_attributes(els_dt_document:item()) -> [poi()].
compiler_attributes(Document) ->
els_dt_document:pois(Document, [compile]).
30 changes: 25 additions & 5 deletions apps/els_lsp/test/els_diagnostics_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
, crossref_autoimport_disabled/1
, crossref_pseudo_functions/1
, unused_includes/1
, unused_includes_compiler_attribute/1
, exclude_unused_includes/1
, unused_macros/1
]).
Expand Down Expand Up @@ -369,14 +370,11 @@ compiler_with_parse_transform_included(Config) ->
els_mock_diagnostics:subscribe(),
ok = els_client:did_save(Uri),
Diagnostics = els_mock_diagnostics:wait_until_complete(),
?assertEqual(2, length(Diagnostics)),
?assertEqual(1, length(Diagnostics)),
Warnings = [D || #{severity := ?DIAGNOSTIC_WARNING} = D <- Diagnostics],
?assertEqual(2, length(Warnings)),
?assertEqual(1, length(Warnings)),
WarningRanges = [ Range || #{range := Range} <- Warnings],
ExpectedWarningsRanges =
[#{ 'end' => #{character => 32, line => 4}
, start => #{character => 0, line => 4}}
] ++
fixcolumns(
[ #{ 'end' => #{character => 9, line => 6}
, start => #{character => 5, line => 6}}], Config),
Expand Down Expand Up @@ -709,6 +707,28 @@ unused_includes(Config) ->
?assertEqual(Expected, lists:sort(F, Diagnostics)),
ok.

-spec unused_includes_compiler_attribute(config()) -> ok.
unused_includes_compiler_attribute(Config) ->
Uri = ?config(diagnostics_unused_includes_compiler_attribute_uri, Config),
els_mock_diagnostics:subscribe(),
ok = els_client:did_save(Uri),
Diagnostics = els_mock_diagnostics:wait_until_complete(),
Expected = [ #{ message => <<"Unused file: file.hrl">>
, range =>
#{ 'end' => #{ character => 40
, line => 3
}
, start => #{ character => 0
, line => 3
}
}
, severity => 2
, source => <<"UnusedIncludes">>
}
],
?assertEqual(Expected, Diagnostics),
ok.

-spec exclude_unused_includes(config()) -> ok.
exclude_unused_includes(Config) ->
Uri = ?config(diagnostics_unused_includes_uri, Config),
Expand Down
1 change: 1 addition & 0 deletions apps/els_lsp/test/els_test_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ sources() ->
, diagnostics_xref
, diagnostics_xref_pseudo
, diagnostics_unused_includes
, diagnostics_unused_includes_compiler_attribute
, diagnostics_unused_macros
, elvis_diagnostics
, execute_command_suggest_spec
Expand Down

0 comments on commit 0982456

Please sign in to comment.