zf

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

negated_conditions_in_unless.ex (1765B)


      1 defmodule Credo.Check.Refactor.NegatedConditionsInUnless do
      2   use Credo.Check,
      3     base_priority: :high,
      4     explanations: [
      5       check: """
      6       Unless blocks should avoid having a negated condition.
      7 
      8       The code in this example ...
      9 
     10           unless !allowed? do
     11             proceed_as_planned()
     12           end
     13 
     14       ... should be refactored to look like this:
     15 
     16           if allowed? do
     17             proceed_as_planned()
     18           end
     19 
     20       The reason for this is not a technical but a human one. It is pretty difficult
     21       to wrap your head around a block of code that is executed if a negated
     22       condition is NOT met. See what I mean?
     23       """
     24     ]
     25 
     26   @doc false
     27   @impl true
     28   def run(%SourceFile{} = source_file, params) do
     29     issue_meta = IssueMeta.for(source_file, params)
     30 
     31     Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
     32   end
     33 
     34   defp traverse({:@, _, [{:unless, _, _}]}, issues, _issue_meta) do
     35     {nil, issues}
     36   end
     37 
     38   # TODO: consider for experimental check front-loader (ast)
     39   # NOTE: we have to exclude the cases matching the above clause!
     40   defp traverse({:unless, _meta, arguments} = ast, issues, issue_meta)
     41        when is_list(arguments) do
     42     issue = issue_for_first_condition(List.first(arguments), issue_meta)
     43 
     44     {ast, issues ++ List.wrap(issue)}
     45   end
     46 
     47   defp traverse(ast, issues, _issue_meta) do
     48     {ast, issues}
     49   end
     50 
     51   defp issue_for_first_condition({:!, meta, _arguments}, issue_meta) do
     52     issue_for(issue_meta, meta[:line], "!")
     53   end
     54 
     55   defp issue_for_first_condition(_, _), do: nil
     56 
     57   defp issue_for(issue_meta, line_no, trigger) do
     58     format_issue(
     59       issue_meta,
     60       message: "Avoid negated conditions in unless blocks.",
     61       trigger: trigger,
     62       line_no: line_no
     63     )
     64   end
     65 end