Skip to content

Commit

Permalink
Add wildcard support in no_call_functions
Browse files Browse the repository at this point in the history
  • Loading branch information
attah committed Nov 3, 2023
1 parent 361e26f commit 09498c5
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
4 changes: 3 additions & 1 deletion doc_rules/elvis_style/no_call.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ functions).
## Options

- `no_call_functions :: [{module(), function(), arity()} | {module(), function()}]`.
- `no_call_functions :: [{module() | '_', function() | '_', arity() | '_'} | {module() | '_', function() | '_'}]`.
- default: `[]`.

`'_'` wildcards supported since [3.2.0](https://github.com/inaka/elvis_core/releases/tag/3.2.0)

## Example

```erlang
Expand Down
22 changes: 14 additions & 8 deletions src/elvis_style.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1935,20 +1935,20 @@ no_call_common(Config, Target, NoCallFuns, Msg, RuleConfig) ->
-spec check_no_call([ktn_code:tree_node()], string(), [function_spec()]) ->
[elvis_result:item()].
check_no_call(Calls, Msg, NoCallFuns) ->
DebugCalls = [Call || Call <- Calls, is_in_call_list(Call, NoCallFuns)],
BadCalls = [Call || Call <- Calls, is_in_call_list(Call, NoCallFuns)],
ResultFun =
fun(Call) ->
{M, F, A} = call_mfa(Call),
{Line, _} = ktn_code:attr(location, Call),
elvis_result:new(item, Msg, [M, F, A, Line], Line)
end,
lists:map(ResultFun, DebugCalls).
lists:map(ResultFun, BadCalls).

%% @private
is_in_call_list(Call, DebugFuns) ->
is_in_call_list(Call, DisallowedFuns) ->
MFA = call_mfa(Call),
MatchFun = fun(Spec) -> fun_spec_match(Spec, MFA) end,
lists:any(MatchFun, DebugFuns).
lists:any(MatchFun, DisallowedFuns).

%% @private
call_mfa(Call) ->
Expand All @@ -1971,13 +1971,19 @@ is_call(Node) ->
ktn_code:type(Node) =:= call.

%% @private
fun_spec_match({M, F}, {M, F, _}) ->
true;
fun_spec_match({M, F, A}, {M, F, A}) ->
true;
fun_spec_match({M, F}, MFA) ->
fun_spec_match({M, F, '_'}, MFA);
fun_spec_match({M1, F1, A1}, {M2, F2, A2}) ->
wildcard_match(M1, M2) andalso wildcard_match(F1, F2) andalso wildcard_match(A1, A2);
fun_spec_match(_, _) ->
false.

%% @private
wildcard_match('_', _) ->
true;
wildcard_match(X, Y) ->
X =:= Y.

%% @private
%% @doc No nested try...catch blocks
check_nested_try_catchs(ResultFun, TryExp) ->
Expand Down
4 changes: 3 additions & 1 deletion test/style_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,9 @@ verify_no_call_flavours(Config,
{{timer, send_interval, 2}, 1},
{{timer, send_interval, 3}, 1},
{{erlang, size, 1}, 2},
{{timer, send_after}, 2}],
{{timer, send_after}, 2},
{{timer, '_', '_'}, 4},
{{'_', tuple_size, 1}, 1}],

lists:foreach(fun({FunSpec, ExpectedCount}) ->
ThisRuleConfig = maps:from_list([{RuleConfigMapKey, [FunSpec]}]),
Expand Down

0 comments on commit 09498c5

Please sign in to comment.