zf

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

apply.ex (1895B)


      1 defmodule Credo.Check.Refactor.Apply do
      2   use Credo.Check,
      3     base_priority: :low,
      4     explanations: [
      5       check: """
      6       Prefer calling functions directly if the number of arguments is known
      7       at compile time instead of using `apply/2` and `apply/3`.
      8 
      9       Example:
     10 
     11           # preferred
     12 
     13           fun.(arg_1, arg_2, ..., arg_n)
     14 
     15           module.function(arg_1, arg_2, ..., arg_n)
     16 
     17           # NOT preferred
     18 
     19           apply(fun, [arg_1, arg_2, ..., arg_n])
     20 
     21           apply(module, :function, [arg_1, arg_2, ..., arg_n])
     22       """
     23     ]
     24 
     25   @doc false
     26   @impl true
     27   def run(%SourceFile{} = source_file, params) do
     28     Credo.Code.prewalk(source_file, &traverse(&1, &2, IssueMeta.for(source_file, params)))
     29   end
     30 
     31   defp traverse(ast, issues, issue_meta) do
     32     case issue(ast, issue_meta) do
     33       nil -> {ast, issues}
     34       issue -> {ast, [issue | issues]}
     35     end
     36   end
     37 
     38   defp issue({:apply, _meta, [{:__MODULE__, _, _}, _fun, _args]}, _issue_meta), do: nil
     39 
     40   defp issue({:apply, meta, [fun, args]}, issue_meta) do
     41     do_issue(:apply2, fun, args, meta, issue_meta)
     42   end
     43 
     44   defp issue({:apply, meta, [_module, fun, args]}, issue_meta) do
     45     do_issue(:apply3, fun, args, meta, issue_meta)
     46   end
     47 
     48   defp issue(_ast, _issue_meta), do: nil
     49 
     50   defp do_issue(_apply, _fun, [{:|, _, _}], _meta, _issue_meta), do: nil
     51 
     52   defp do_issue(:apply2, {name, _meta, nil}, args, meta, issue_meta)
     53        when is_atom(name) and is_list(args) do
     54     issue_for(meta, issue_meta)
     55   end
     56 
     57   defp do_issue(:apply3, fun, args, meta, issue_meta)
     58        when is_atom(fun) and is_list(args) do
     59     issue_for(meta, issue_meta)
     60   end
     61 
     62   defp do_issue(_apply, _fun, _args, _meta, _issue_meta), do: nil
     63 
     64   defp issue_for(meta, issue_meta) do
     65     format_issue(
     66       issue_meta,
     67       message: "Avoid `apply/2` and `apply/3` when the number of arguments is known",
     68       line_no: meta[:line]
     69     )
     70   end
     71 end