class RuboCop::Cop::Lint::AssignmentInCondition

This cop checks for assignments in the conditions of if/while/until.

Constants

ASGN_TYPES
MSG

Public Instance Methods

on_if(node) click to toggle source
# File lib/rubocop/cop/lint/assignment_in_condition.rb, line 14
def on_if(node)
  check(node)
end
on_until(node) click to toggle source
# File lib/rubocop/cop/lint/assignment_in_condition.rb, line 22
def on_until(node)
  check(node)
end
on_while(node) click to toggle source
# File lib/rubocop/cop/lint/assignment_in_condition.rb, line 18
def on_while(node)
  check(node)
end

Private Instance Methods

check(node) click to toggle source
# File lib/rubocop/cop/lint/assignment_in_condition.rb, line 28
def check(node)
  condition, = *node

  # assignments inside blocks are not what we're looking for
  return if condition.type == :block
  traverse_node(condition, ASGN_TYPES) do |asgn_node|
    if asgn_node.type == :send
      _receiver, method_name, *_args = *asgn_node
      next :skip_children if method_name !~ /=\z/
    end

    # skip safe assignment nodes if safe assignment is allowed
    if safe_assignment_allowed? && safe_assignment?(asgn_node)
      next :skip_children
    end

    # assignment nodes from shorthand ops like ||= don't have operator
    if asgn_node.type != :begin && asgn_node.loc.operator
      add_offense(asgn_node, :operator)
    end
  end
end
traverse_node(node, types) { |node| ... } click to toggle source

each_node/visit_descendants_with_types with :skip_children

# File lib/rubocop/cop/lint/assignment_in_condition.rb, line 52
def traverse_node(node, types, &block)
  result = yield node if types.include?(node.type)
  # return to skip all descendant nodes
  return if result == :skip_children
  node.children.each do |child|
    traverse_node(child, types, &block) if child.is_a?(Node)
  end
end