zf

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

collector.ex (2411B)


      1 defmodule Credo.Check.Consistency.UnusedVariableNames.Collector do
      2   @moduledoc false
      3 
      4   use Credo.Check.Consistency.Collector
      5 
      6   def collect_matches(source_file, _params) do
      7     unused_variable_recorder = &record_unused_variable/2
      8 
      9     Credo.Code.prewalk(source_file, &traverse(unused_variable_recorder, &1, &2), %{})
     10   end
     11 
     12   def find_locations_not_matching(expected, source_file) do
     13     location_recorder = &record_not_matching(expected, &1, &2)
     14 
     15     source_file
     16     |> Credo.Code.prewalk(&traverse(location_recorder, &1, &2), [])
     17     |> Enum.reverse()
     18   end
     19 
     20   defp traverse(callback, {:=, _, params} = ast, acc) do
     21     {ast, reduce_unused_variables(params, callback, acc)}
     22   end
     23 
     24   defp traverse(callback, {def, _, [{_, _, params} | _]} = ast, acc)
     25        when def in [:def, :defp] do
     26     {ast, reduce_unused_variables(params, callback, acc)}
     27   end
     28 
     29   defp traverse(callback, {:->, _, [params | _]} = ast, acc) do
     30     {ast, reduce_unused_variables(params, callback, acc)}
     31   end
     32 
     33   defp traverse(_callback, ast, acc), do: {ast, acc}
     34 
     35   defp reduce_unused_variables(nil, _callback, acc), do: acc
     36 
     37   defp reduce_unused_variables(ast, callback, acc) do
     38     Enum.reduce(ast, acc, fn
     39       {_, _, params}, param_acc when is_list(params) ->
     40         reduce_unused_variables(params, callback, param_acc)
     41 
     42       param_ast, param_acc ->
     43         if unused_variable_ast?(param_ast) do
     44           callback.(param_ast, param_acc)
     45         else
     46           param_acc
     47         end
     48     end)
     49   end
     50 
     51   defp unused_variable_ast?({:_, _, _}), do: true
     52 
     53   defp unused_variable_ast?({name, _, _}) when is_atom(name) do
     54     name
     55     |> Atom.to_string()
     56     |> unused_variable_name?()
     57   end
     58 
     59   defp unused_variable_ast?(_), do: false
     60 
     61   defp unused_variable_name?("__" <> _rest), do: false
     62 
     63   defp unused_variable_name?("_" <> _rest), do: true
     64 
     65   defp unused_variable_name?(_rest), do: false
     66 
     67   defp record_unused_variable({:_, _, _}, acc), do: Map.update(acc, :anonymous, 1, &(&1 + 1))
     68   defp record_unused_variable(_, acc), do: Map.update(acc, :meaningful, 1, &(&1 + 1))
     69 
     70   defp record_not_matching(expected, {name, meta, _}, acc) do
     71     case {expected, Atom.to_string(name)} do
     72       {:anonymous, "_" <> rest = trigger} when rest != "" ->
     73         [[line_no: meta[:line], trigger: trigger] | acc]
     74 
     75       {:meaningful, "_" = trigger} ->
     76         [[line_no: meta[:line], trigger: trigger] | acc]
     77 
     78       _ ->
     79         acc
     80     end
     81   end
     82 end