zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

function_arity.ex (2201B)


      1 defmodule Credo.Check.Refactor.FunctionArity do
      2   use Credo.Check,
      3     param_defaults: [max_arity: 8, ignore_defp: false],
      4     explanations: [
      5       check: """
      6       A function can take as many parameters as needed, but even in a functional
      7       language there can be too many parameters.
      8 
      9       Can optionally ignore private functions (check configuration options).
     10       """,
     11       params: [
     12         max_arity: "The maximum number of parameters which a function should take.",
     13         ignore_defp: "Set to `true` to ignore private functions."
     14       ]
     15     ]
     16 
     17   alias Credo.Code.Parameters
     18 
     19   @def_ops [:def, :defp, :defmacro]
     20 
     21   @doc false
     22   @impl true
     23   def run(%SourceFile{} = source_file, params) do
     24     issue_meta = IssueMeta.for(source_file, params)
     25     max_arity = Params.get(params, :max_arity, __MODULE__)
     26     ignore_defp = Params.get(params, :ignore_defp, __MODULE__)
     27 
     28     Credo.Code.prewalk(
     29       source_file,
     30       &traverse(&1, &2, issue_meta, max_arity, ignore_defp)
     31     )
     32   end
     33 
     34   # TODO: consider for experimental check front-loader (ast)
     35   for op <- @def_ops do
     36     defp traverse(
     37            {unquote(op) = op, meta, arguments} = ast,
     38            issues,
     39            issue_meta,
     40            max_arity,
     41            ignore_defp
     42          )
     43          when is_list(arguments) do
     44       arity = Parameters.count(ast)
     45 
     46       if issue?(op, ignore_defp, arity, max_arity) do
     47         fun_name = Credo.Code.Module.def_name(ast)
     48 
     49         {
     50           ast,
     51           issues ++ [issue_for(issue_meta, meta[:line], fun_name, max_arity, arity)]
     52         }
     53       else
     54         {ast, issues}
     55       end
     56     end
     57   end
     58 
     59   defp traverse(ast, issues, _issue_meta, _max_arity, _ignore_defp) do
     60     {ast, issues}
     61   end
     62 
     63   defp issue?(:defp, true, _, _), do: false
     64   defp issue?(_, _, arity, max_arity) when arity > max_arity, do: true
     65   defp issue?(_, _, _, _), do: false
     66 
     67   defp issue_for(issue_meta, line_no, trigger, max_value, actual_value) do
     68     format_issue(
     69       issue_meta,
     70       message:
     71         "Function takes too many parameters (arity is #{actual_value}, max is #{max_value}).",
     72       trigger: trigger,
     73       line_no: line_no,
     74       severity: Severity.compute(actual_value, max_value)
     75     )
     76   end
     77 end