class RuboCop::Cop::Lint::DuplicateBranch
Checks that there are no repeated bodies within ‘if/unless`, `case-when`, `case-in` and `rescue` constructs.
With ‘IgnoreLiteralBranches: true`, branches are not registered as offenses if they return a basic literal value (string, symbol, integer, float, rational, complex, `true`, `false`, or `nil`), or return an array, hash, regexp or range that only contains one of the above basic literal values.
With ‘IgnoreConstantBranches: true`, branches are not registered as offenses if they return a constant value.
@example
# bad if foo do_foo do_something_else elsif bar do_foo do_something_else end # good if foo || bar do_foo do_something_else end # bad case x when foo do_foo when bar do_foo else do_something_else end # good case x when foo, bar do_foo else do_something_else end # bad begin do_something rescue FooError handle_error rescue BarError handle_error end # good begin do_something rescue FooError, BarError handle_error end
@example IgnoreLiteralBranches: true
# good case size when "small" then 100 when "medium" then 250 when "large" then 1000 else 250 end
@example IgnoreConstantBranches: true
# good case size when "small" then SMALL_SIZE when "medium" then MEDIUM_SIZE when "large" then LARGE_SIZE else MEDIUM_SIZE end
Constants
- MSG
Public Instance Methods
on_branching_statement(node)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 91 def on_branching_statement(node) branches(node).each_with_object(Set.new) do |branch, previous| next unless consider_branch?(branch) add_offense(offense_range(branch)) unless previous.add?(branch) end end
Private Instance Methods
branches(node)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 119 def branches(node) node.branches.compact end
consider_branch?(branch)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 123 def consider_branch?(branch) return false if ignore_literal_branches? && literal_branch?(branch) return false if ignore_constant_branches? && const_branch?(branch) true end
const_branch?(branch)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 149 def const_branch?(branch) branch.const_type? end
ignore_constant_branches?()
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 134 def ignore_constant_branches? cop_config.fetch('IgnoreConstantBranches', false) end
ignore_literal_branches?()
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 130 def ignore_literal_branches? cop_config.fetch('IgnoreLiteralBranches', false) end
literal_branch?(branch)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 138 def literal_branch?(branch) # rubocop:disable Metrics/CyclomaticComplexity return false if !branch.literal? || branch.xstr_type? return true if branch.basic_literal? branch.each_descendant.all? do |node| node.basic_literal? || node.pair_type? || # hash keys and values are contained within a `pair` node (node.const_type? && ignore_constant_branches?) end end
offense_range(duplicate_branch)
click to toggle source
# File lib/rubocop/cop/lint/duplicate_branch.rb, line 105 def offense_range(duplicate_branch) parent = duplicate_branch.parent if parent.respond_to?(:else_branch) && parent.else_branch.equal?(duplicate_branch) if parent.if_type? && parent.ternary? duplicate_branch.source_range else parent.loc.else end else parent.source_range end end