class RuboCop::Cop::Lint::SafeNavigationConsistency

This cop check to make sure that if safe navigation is used for a method call in an `&&` or `||` condition that safe navigation is used for all method calls on that same object.

@example

# bad
foo&.bar && foo.baz

# bad
foo.bar || foo&.baz

# bad
foo&.bar && (foobar.baz || foo.baz)

# good
foo.bar && foo.baz

# good
foo&.bar || foo&.baz

# good
foo&.bar && (foobar.baz || foo&.baz)

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/lint/safe_navigation_consistency.rb, line 61
def autocorrect(node)
  return unless node.dot?

  lambda do |corrector|
    corrector.insert_before(node.loc.dot, '&')
  end
end
check(node) click to toggle source
# File lib/rubocop/cop/lint/safe_navigation_consistency.rb, line 42
def check(node)
  ancestor = top_conditional_ancestor(node)
  conditions = ancestor.conditions
  safe_nav_receiver = node.receiver

  method_calls = conditions.select(&:send_type?)
  unsafe_method_calls =
    unsafe_method_calls(method_calls, safe_nav_receiver)

  unsafe_method_calls.each do |unsafe_method_call|
    location =
      node.loc.expression.join(unsafe_method_call.loc.expression)
    add_offense(unsafe_method_call,
                location: location)

    ignore_node(unsafe_method_call)
  end
end
on_csend(node) click to toggle source
# File lib/rubocop/cop/lint/safe_navigation_consistency.rb, line 36
def on_csend(node)
  return unless node.parent&.operator_keyword?

  check(node)
end

Private Instance Methods

top_conditional_ancestor(node) click to toggle source
# File lib/rubocop/cop/lint/safe_navigation_consistency.rb, line 71
def top_conditional_ancestor(node)
  parent = node.parent
  unless parent &&
         (parent.operator_keyword? ||
          (parent.begin_type? &&
           parent.parent &&
           parent.parent.operator_keyword?))
    return node
  end

  top_conditional_ancestor(parent)
end
unsafe_method_calls(method_calls, safe_nav_receiver) click to toggle source
# File lib/rubocop/cop/lint/safe_navigation_consistency.rb, line 84
def unsafe_method_calls(method_calls, safe_nav_receiver)
  method_calls.select do |method_call|
    safe_nav_receiver == method_call.receiver &&
      !nil_methods.include?(method_call.method_name) &&
      !ignored_node?(method_call)
  end
end