zf

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

single_pipe.ex (2445B)


      1 defmodule Credo.Check.Readability.SinglePipe do
      2   use Credo.Check,
      3     base_priority: :high,
      4     tags: [:controversial],
      5     param_defaults: [allow_0_arity_functions: false],
      6     explanations: [
      7       check: """
      8       Pipes (`|>`) should only be used when piping data through multiple calls.
      9 
     10       So while this is fine:
     11 
     12           list
     13           |> Enum.take(5)
     14           |> Enum.shuffle
     15           |> evaluate()
     16 
     17       The code in this example ...
     18 
     19           list
     20           |> evaluate()
     21 
     22       ... should be refactored to look like this:
     23 
     24           evaluate(list)
     25 
     26       Using a single |> to invoke functions makes the code harder to read. Instead,
     27       write a function call when a pipeline is only one function long.
     28 
     29       Like all `Readability` issues, this one is not a technical concern.
     30       But you can improve the odds of others reading and liking your code by making
     31       it easier to follow.
     32       """,
     33       params: [
     34         allow_0_arity_functions: "Allow 0-arity functions"
     35       ]
     36     ]
     37 
     38   @doc false
     39   @impl true
     40   def run(%SourceFile{} = source_file, params) do
     41     issue_meta = IssueMeta.for(source_file, params)
     42 
     43     allow_0_arity_functions = Params.get(params, :allow_0_arity_functions, __MODULE__)
     44 
     45     {_continue, issues} =
     46       Credo.Code.prewalk(
     47         source_file,
     48         &traverse(&1, &2, issue_meta, allow_0_arity_functions),
     49         {true, []}
     50       )
     51 
     52     issues
     53   end
     54 
     55   defp traverse({:|>, _, [{:|>, _, _} | _]} = ast, {_, issues}, _, _) do
     56     {ast, {false, issues}}
     57   end
     58 
     59   defp traverse({:|>, meta, _} = ast, {true, issues}, issue_meta, false) do
     60     {
     61       ast,
     62       {false, issues ++ [issue_for(issue_meta, meta[:line], "|>")]}
     63     }
     64   end
     65 
     66   defp traverse({:|>, _, [{{:., _, _}, _, []}, _]} = ast, {true, issues}, _, true) do
     67     {ast, {false, issues}}
     68   end
     69 
     70   defp traverse({:|>, _, [{fun, _, []}, _]} = ast, {true, issues}, _, true) when is_atom(fun) do
     71     {ast, {false, issues}}
     72   end
     73 
     74   defp traverse({:|>, meta, _} = ast, {true, issues}, issue_meta, true) do
     75     {
     76       ast,
     77       {false, issues ++ [issue_for(issue_meta, meta[:line], "|>")]}
     78     }
     79   end
     80 
     81   defp traverse(ast, {_, issues}, _issue_meta, _allow_functions) do
     82     {ast, {true, issues}}
     83   end
     84 
     85   defp issue_for(issue_meta, line_no, trigger) do
     86     format_issue(
     87       issue_meta,
     88       message: "Use a function call when a pipeline is only one function long",
     89       trigger: trigger,
     90       line_no: line_no
     91     )
     92   end
     93 end