zf

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

unless_with_else.ex (1934B)


      1 defmodule Credo.Check.Refactor.UnlessWithElse do
      2   use Credo.Check,
      3     base_priority: :high,
      4     explanations: [
      5       check: """
      6       An `unless` block should not contain an else block.
      7 
      8       So while this is fine:
      9 
     10           unless allowed? do
     11             raise "Not allowed!"
     12           end
     13 
     14       This should be refactored:
     15 
     16           unless allowed? do
     17             raise "Not allowed!"
     18           else
     19             proceed_as_planned()
     20           end
     21 
     22       to look like this:
     23 
     24           if allowed? do
     25             proceed_as_planned()
     26           else
     27             raise "Not allowed!"
     28           end
     29 
     30       The reason for this is not a technical but a human one. The `else` in this
     31       case will be executed when the condition is met, which is the opposite of
     32       what the wording seems to imply.
     33       """
     34     ]
     35 
     36   @doc false
     37   @impl true
     38   def run(%SourceFile{} = source_file, params) do
     39     issue_meta = IssueMeta.for(source_file, params)
     40 
     41     Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
     42   end
     43 
     44   defp traverse({:@, _, [{:unless, _, _}]}, issues, _issue_meta) do
     45     {nil, issues}
     46   end
     47 
     48   # TODO: consider for experimental check front-loader (ast)
     49   # NOTE: we have to exclude the cases matching the above clause!
     50   defp traverse({:unless, meta, _arguments} = ast, issues, issue_meta) do
     51     new_issue = issue_for_else_block(Credo.Code.Block.else_block_for!(ast), meta, issue_meta)
     52 
     53     {ast, issues ++ List.wrap(new_issue)}
     54   end
     55 
     56   defp traverse(ast, issues, _issue_meta) do
     57     {ast, issues}
     58   end
     59 
     60   defp issue_for_else_block(nil, _meta, _issue_meta), do: nil
     61 
     62   defp issue_for_else_block(_else_block, meta, issue_meta) do
     63     issue_for(issue_meta, meta[:line], "unless")
     64   end
     65 
     66   defp issue_for(issue_meta, line_no, trigger) do
     67     format_issue(
     68       issue_meta,
     69       message: "Unless conditions should avoid having an `else` block.",
     70       trigger: trigger,
     71       line_no: line_no
     72     )
     73   end
     74 end