class RubbyCop::Cop::Style::IdenticalConditionalBranches

This cop checks for identical lines at the beginning or end of each branch of a conditional statement.

@example

@bad
if condition
  do_x
  do_z
else
  do_y
  do_z
end

@good
if condition
  do_x
else
  do_y
end
do_z

@bad
if condition
  do_z
  do_x
else
  do_z
  do_y
end

@good
do_z
if condition
  do_x
else
  do_y
end

@bad
case foo
when 1
  do_x
when 2
  do_x
else
  do_x
end

@good
case foo
when 1
  do_x
  do_y
when 2
  # nothing
else
  do_x
  do_z
end

Constants

MSG

Public Instance Methods

on_case(node) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 80
def on_case(node)
  return unless node.else? && node.else_branch

  branches = node.when_branches.map(&:body).push(node.else_branch)

  return if branches.any?(&:nil?)

  check_branches(branches)
end
on_if(node) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 68
def on_if(node)
  return if node.elsif?

  branches = expand_elses(node.else_branch).unshift(node.if_branch)

  # return if any branch is empty. An empty branch can be an `if`
  # without an `else`, or a branch that contains only comments.
  return if branches.any?(&:nil?)

  check_branches(branches)
end

Private Instance Methods

check_branches(branches) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 92
def check_branches(branches)
  tails = branches.compact.map { |branch| tail(branch) }
  check_expressions(tails)
  heads = branches.compact.map { |branch| head(branch) }
  check_expressions(heads)
end
check_expressions(expressions) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 99
def check_expressions(expressions)
  return unless expressions.size > 1 && expressions.uniq.one?

  expressions.each do |expression|
    add_offense(expression, :expression, format(MSG, expression.source))
  end
end
expand_elses(branch) click to toggle source

`elsif` branches show up in the if node as nested `else` branches. We need to recursively iterate over all `else` branches.

# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 109
def expand_elses(branch)
  if branch.nil?
    [nil]
  elsif branch.if_type?
    _condition, elsif_branch, else_branch = *branch
    expand_elses(else_branch).unshift(elsif_branch)
  else
    [branch]
  end
end
head(node) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 124
def head(node)
  node.begin_type? ? node.children.first : node
end
tail(node) click to toggle source
# File lib/rubbycop/cop/style/identical_conditional_branches.rb, line 120
def tail(node)
  node.begin_type? ? node.children.last : node
end