class RuboCop::Cop::Style::IfWithSemicolon

Checks for uses of semicolon in if statements.

@example

# bad
result = if some_condition; something else another_thing end

# good
result = some_condition ? something : another_thing

Constants

MSG_IF_ELSE
MSG_NEWLINE
MSG_TERNARY

Public Instance Methods

on_normal_if_unless(node) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 24
def on_normal_if_unless(node)
  return if node.parent&.if_type?

  beginning = node.loc.begin
  return unless beginning&.is?(';')

  message = message(node)

  add_offense(node, message: message) do |corrector|
    autocorrect(corrector, node)
  end
end

Private Instance Methods

autocorrect(corrector, node) click to toggle source

rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

# File lib/rubocop/cop/style/if_with_semicolon.rb, line 54
def autocorrect(corrector, node)
  if node.branches.compact.any?(&:begin_type?) || use_block_in_branches?(node)
    corrector.replace(node.loc.begin, "\n")
  else
    corrector.replace(node, replacement(node))
  end
end
build_else_branch(second_condition) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 93
        def build_else_branch(second_condition)
          result = <<~RUBY
            elsif #{second_condition.condition.source}
              #{second_condition.if_branch&.source}
          RUBY

          if second_condition.else_branch
            result += if second_condition.else_branch.if_type?
                        build_else_branch(second_condition.else_branch)
                      else
                        <<~RUBY
                          else
                            #{second_condition.else_branch.source}
                        RUBY
                      end
          end

          result
        end
build_expression(expr) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 84
def build_expression(expr)
  return expr.source unless require_argument_parentheses?(expr)

  method = expr.source_range.begin.join(expr.loc.selector.end)
  arguments = expr.first_argument.source_range.begin.join(expr.source_range.end)

  "#{method.source}(#{arguments.source})"
end
correct_elsif(node) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 75
        def correct_elsif(node)
          <<~RUBY.chop
            if #{node.condition.source}
              #{node.if_branch&.source}
            #{build_else_branch(node.else_branch).chop}
            end
          RUBY
        end
message(node) click to toggle source

rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

# File lib/rubocop/cop/style/if_with_semicolon.rb, line 40
def message(node)
  template = if node.if_branch&.begin_type?
               MSG_NEWLINE
             elsif node.else_branch&.if_type? || node.else_branch&.begin_type? ||
                   use_block_in_branches?(node)
               MSG_IF_ELSE
             else
               MSG_TERNARY
             end

  format(template, expr: node.condition.source)
end
replacement(node) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 66
def replacement(node)
  return correct_elsif(node) if node.else_branch&.if_type?

  then_code = node.if_branch ? build_expression(node.if_branch) : 'nil'
  else_code = node.else_branch ? build_expression(node.else_branch) : 'nil'

  "#{node.condition.source} ? #{then_code} : #{else_code}"
end
require_argument_parentheses?(node) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 113
def require_argument_parentheses?(node)
  return false unless node.call_type?

  !node.parenthesized? && node.arguments.any? && !node.method?(:[]) && !node.method?(:[]=)
end
use_block_in_branches?(node) click to toggle source
# File lib/rubocop/cop/style/if_with_semicolon.rb, line 62
def use_block_in_branches?(node)
  node.branches.compact.any? { |branch| branch.block_type? || branch.numblock_type? }
end