-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Bug Description
Record fields that appear "obviously in use" in the code are detected as unused.
To Reproduce
Well, this is the tricky bit as we don't use rebar3 in KAZOO. Hooked into hank:analze/5 directly.
Here's the basic escript:
#!/usr/bin/env escript
%%! +A0 -sname kazoo_hank
%% -*- coding: utf-8 -*-
-mode('compile').
-export([main/1]).
%% API
main([]) ->
AppFiles = lists:foldl(fun add_app_path/2, [], kz_ast_util:project_apps()),
main(AppFiles);
main(Files) ->
#{results := Results
,stats := Stats
} = hank:analyze(Files
,hank_ignores()
,hank_rules()
,parsing_style()
,hank_context()
),
print_stats(Stats),
io:format("results(~p):~n", [length(Results)]),
{_LastRule, Counts} = lists:foldl(fun print_result/2, {'undefined', #{}}, Results),
io:format("rule violations: ~p~n", [Counts]).
add_app_path(App, Acc) ->
filelib:wildcard(
filename:join([code:lib_dir(App), "**/*.[e|h]rl"])
) ++ Acc.
print_stats(#{ignored := Ignored
,parsing := ParsingMs
,analyzing := AnalysisMs
,total := TotalMs
}) ->
io:format("analysis took ~pms parsing, ~pms analyzing, ~pms total, ignore ~p files~n"
,[ParsingMs, AnalysisMs, TotalMs, Ignored]
).
print_result(#{file := File
,line := Line
,pattern := Pattern
,rule := Rule
,text := Text
}
,{Rule, RuleCounts}
) ->
io:format("~s:~p: ~s~n~n"
,[File, Line, rule_text(Rule, Text, Pattern)]
),
{Rule, maps:update_with(Rule, fun(V) -> V+1 end, 1, RuleCounts)};
print_result(#{rule := NewRule}=Result
,{_OldRule, RuleCounts}
) ->
io:format("rule violations for ~s:~n", [NewRule]),
print_result(Result, {NewRule, RuleCounts}).
rule_text(_Rule, Text, _Pattern) ->
Text.
-spec hank_ignores() -> [hank_rule:ignore_spec()].
hank_ignores() -> [].
hank_rules() ->
hank_rule:default_rules().
parsing_style() ->
'sequential'. % or parallel
hank_context() ->
Apps = [{App, code:lib_dir(App)}
|| App <- kz_ast_util:project_apps()
],
hank_context:new(maps:from_list(Apps), []).Here's an example of the output:
src/omnip_subscriptions.erl:52: Field ready in record state is unused
src/omnip_subscriptions.erl:54: Field other_nodes_count in record state is unused
The record in question: https://github.com/2600hz/kazoo/blob/master/applications/omnipresence/src/omnip_subscriptions.erl#L51
The record fields being used: https://github.com/2600hz/kazoo/blob/master/applications/omnipresence/src/omnip_subscriptions.erl#L164
This is all very much first pass, quick hack to correct low-hanging fruit; fully expect there are better ways to call into hank or provide it more context.
Expected Behavior
Not detect record fields as unused
Additional Context
- OS: Debian
- Erlang version 23.1
- rebar3 NA
I will say this: just on unused_record_fields, the first pass of hank detected 133 instances, of which it appears 7 are false positives. The above represents 2 of the 7. So I think that is phenomenal and really fun to dig through KAZOO's cobwebs and oxtail code (love that btw!).
@elbrujohalcon great preso on hank and thanks for poking at KAZOO. Hope we can get hank integrated into CI after this initial pass.