From a18932c148a075d1e43fad1027745271f1d8a5f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mil=C3=A1n=20B=C3=B3r?= Date: Tue, 5 Nov 2024 20:35:37 +0100 Subject: [PATCH 1/5] change(export_used_types): don't warn on behaviour callbacks --- src/elvis_style.erl | 13 ++++++++++++- test/examples/pass_export_used_types2.erl | 17 +++++++++++++++++ test/style_SUITE.erl | 6 ++++-- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/examples/pass_export_used_types2.erl diff --git a/src/elvis_style.erl b/src/elvis_style.erl index efa6e197..bc73ffb7 100644 --- a/src/elvis_style.erl +++ b/src/elvis_style.erl @@ -1460,13 +1460,15 @@ always_shortcircuit(Config, Target, RuleConfig) -> [elvis_result:item()]. export_used_types(Config, Target, RuleConfig) -> TreeRootNode = get_root(Config, Target, RuleConfig), + IgnoredFunctions = get_behaviour_callbacks(TreeRootNode), ExportedFunctions = elvis_code:exported_functions(TreeRootNode), + FilteredExportedFunctions = lists:subtract(ExportedFunctions, IgnoredFunctions), ExportedTypes = elvis_code:exported_types(TreeRootNode), SpecNodes = elvis_code:find(fun is_spec_attribute/1, TreeRootNode, #{traverse => all, mode => node}), ExportedSpecs = lists:filter(fun(#{attrs := #{arity := Arity, name := Name}}) -> - lists:member({Name, Arity}, ExportedFunctions) + lists:member({Name, Arity}, FilteredExportedFunctions) end, SpecNodes), UsedTypes = @@ -1492,6 +1494,15 @@ export_used_types(Config, Target, RuleConfig) -> end, UnexportedUsedTypes). +get_behaviour_callbacks(Root) -> + IsBehaviour = fun(Node) -> ktn_code:type(Node) == behaviour end, + Behaviours = elvis_code:find(IsBehaviour, Root), + BehaviourNames = lists:map(fun(#{attrs := #{value := Behaviour}}) -> Behaviour end, Behaviours), + + lists:append( + lists:map(fun(B) -> B:behaviour_info(callbacks) end, BehaviourNames + )). + get_type_of_type(#{type := type_attr, node_attrs := #{type := #{attrs := #{name := TypeOfType}}}}) -> TypeOfType; diff --git a/test/examples/pass_export_used_types2.erl b/test/examples/pass_export_used_types2.erl new file mode 100644 index 00000000..cf7afe72 --- /dev/null +++ b/test/examples/pass_export_used_types2.erl @@ -0,0 +1,17 @@ +-module(pass_export_used_types2). + +-behaviour(gen_server). + +-record(state, {a = field}). + +-type state() :: #state{}. + +-export([init/1, handle_cast/2, handle_call/3]). + +-spec init(_) -> {ok, state()}. +init(_) -> {ok, #state{}}. + +handle_call(_, _, State) -> {State, ok, State}. + +-spec handle_cast(_, state()) -> {noreply, state()}. +handle_cast(_, State) -> {noreply, State}. diff --git a/test/style_SUITE.erl b/test/style_SUITE.erl index d6aa6126..1a0ab141 100644 --- a/test/style_SUITE.erl +++ b/test/style_SUITE.erl @@ -753,8 +753,7 @@ verify_state_record_and_type_plus_export_used_types(Config) -> elvis_core_apply_rule(Config, elvis_style, export_used_types, #{}, PathPassGenStateM), PathFail = "fail_state_record_and_type_plus_export_used_types." ++ Ext, - [] = elvis_core_apply_rule(Config, elvis_style, state_record_and_type, #{}, PathFail), - [_] = elvis_core_apply_rule(Config, elvis_style, export_used_types, #{}, PathFail). + [] = elvis_core_apply_rule(Config, elvis_style, state_record_and_type, #{}, PathFail). -spec verify_behaviour_spelling(config()) -> any(). verify_behaviour_spelling(Config) -> @@ -1754,6 +1753,9 @@ verify_export_used_types(Config) -> PathPass = "pass_export_used_types." ++ Ext, [] = elvis_core_apply_rule(Config, elvis_style, export_used_types, #{}, PathPass), + PathPass2 = "pass_export_used_types2." ++ Ext, + [] = elvis_core_apply_rule(Config, elvis_style, export_used_types, #{}, PathPass2), + PathFail = "fail_export_used_types." ++ Ext, [#{line_num := 3}] = elvis_core_apply_rule(Config, elvis_style, export_used_types, #{}, PathFail). From 2b4498253fc3d7c7fd71b1cf973874dfeebf1c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mil=C3=A1n=20B=C3=B3r?= Date: Tue, 5 Nov 2024 20:46:53 +0100 Subject: [PATCH 2/5] fix format --- src/elvis_style.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/elvis_style.erl b/src/elvis_style.erl index bc73ffb7..c7140471 100644 --- a/src/elvis_style.erl +++ b/src/elvis_style.erl @@ -1497,11 +1497,11 @@ export_used_types(Config, Target, RuleConfig) -> get_behaviour_callbacks(Root) -> IsBehaviour = fun(Node) -> ktn_code:type(Node) == behaviour end, Behaviours = elvis_code:find(IsBehaviour, Root), - BehaviourNames = lists:map(fun(#{attrs := #{value := Behaviour}}) -> Behaviour end, Behaviours), + BehaviourNames = + lists:map(fun(#{attrs := #{value := Behaviour}}) -> Behaviour end, Behaviours), lists:append( - lists:map(fun(B) -> B:behaviour_info(callbacks) end, BehaviourNames - )). + lists:map(fun(B) -> B:behaviour_info(callbacks) end, BehaviourNames)). get_type_of_type(#{type := type_attr, node_attrs := #{type := #{attrs := #{name := TypeOfType}}}}) -> From b27b8a52fc1aec61e104cecdf6f0e99eecbdf5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mil=C3=A1n=20B=C3=B3r?= Date: Tue, 5 Nov 2024 20:50:55 +0100 Subject: [PATCH 3/5] fix dynamic call --- src/elvis_style.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elvis_style.erl b/src/elvis_style.erl index c7140471..6d97b4e8 100644 --- a/src/elvis_style.erl +++ b/src/elvis_style.erl @@ -1501,7 +1501,7 @@ get_behaviour_callbacks(Root) -> lists:map(fun(#{attrs := #{value := Behaviour}}) -> Behaviour end, Behaviours), lists:append( - lists:map(fun(B) -> B:behaviour_info(callbacks) end, BehaviourNames)). + lists:map(fun(B) -> apply(B, behaviour_info, [callbacks]) end, BehaviourNames)). get_type_of_type(#{type := type_attr, node_attrs := #{type := #{attrs := #{name := TypeOfType}}}}) -> From 6b1a1c8b23cb0d997958713cd68d6c4576830f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mil=C3=A1n=20B=C3=B3r?= Date: Sun, 10 Nov 2024 12:52:47 +0100 Subject: [PATCH 4/5] fix behaviour_info call in try-catch --- src/elvis_style.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/elvis_style.erl b/src/elvis_style.erl index 6d97b4e8..9774e455 100644 --- a/src/elvis_style.erl +++ b/src/elvis_style.erl @@ -1500,8 +1500,13 @@ get_behaviour_callbacks(Root) -> BehaviourNames = lists:map(fun(#{attrs := #{value := Behaviour}}) -> Behaviour end, Behaviours), - lists:append( - lists:map(fun(B) -> apply(B, behaviour_info, [callbacks]) end, BehaviourNames)). + try lists:map(fun(B) -> apply(B, behaviour_info, [callbacks]) end, BehaviourNames) of + DeepList -> + lists:append(DeepList) + catch + _ -> + [] + end. get_type_of_type(#{type := type_attr, node_attrs := #{type := #{attrs := #{name := TypeOfType}}}}) -> From 90075d9278fcca17d3f4e40df762c9ff16733ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=B3r=20Mil=C3=A1n?= <71042542+bormilan@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:39:50 +0100 Subject: [PATCH 5/5] Update src/elvis_style.erl Co-authored-by: Brujo Benavides --- src/elvis_style.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elvis_style.erl b/src/elvis_style.erl index 9774e455..b83e1586 100644 --- a/src/elvis_style.erl +++ b/src/elvis_style.erl @@ -1504,7 +1504,7 @@ get_behaviour_callbacks(Root) -> DeepList -> lists:append(DeepList) catch - _ -> + _:_ -> [] end.