class RuboCop::Cop::Lint::AmbiguousOperator

Checks for ambiguous operators in the first argument of a method invocation without parentheses.

@example

# bad

# The `*` is interpreted as a splat operator but it could possibly be
# a `*` method invocation (i.e. `do_something.*(some_array)`).
do_something *some_array

@example

# good

# With parentheses, there's no ambiguity.
do_something(*some_array)

Constants

AMBIGUITIES
MSG_FORMAT

Public Instance Methods

on_new_investigation() click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 41
def on_new_investigation
  processed_source.diagnostics.each do |diagnostic|
    next unless diagnostic.reason == :ambiguous_prefix

    offense_node = find_offense_node_by(diagnostic)
    next unless offense_node

    message = message(diagnostic)

    add_offense(
      diagnostic.location, message: message, severity: diagnostic.level
    ) do |corrector|
      add_parentheses(offense_node, corrector)
    end
  end
end

Private Instance Methods

find_offense_node_by(diagnostic) click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 60
def find_offense_node_by(diagnostic)
  ast = processed_source.ast
  ast.each_node(:splat, :block_pass, :kwsplat) do |node|
    next unless offense_position?(node, diagnostic)

    offense_node = offense_node(node)
    return offense_node if offense_node
  end

  ast.each_node(:send).find do |send_node|
    first_argument = send_node.first_argument

    first_argument &&
      offense_position?(first_argument, diagnostic) &&
      unary_operator?(first_argument, diagnostic)
  end
end
message(diagnostic) click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 78
def message(diagnostic)
  operator = diagnostic.location.source
  hash = AMBIGUITIES[operator]
  format(MSG_FORMAT, hash)
end
offense_node(node) click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 88
def offense_node(node)
  case node.type
  when :splat, :block_pass
    node.parent
  when :kwsplat
    node.parent.parent
  end
end
offense_position?(node, diagnostic) click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 84
def offense_position?(node, diagnostic)
  node.source_range.begin_pos == diagnostic.location.begin_pos
end
unary_operator?(node, diagnostic) click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator.rb, line 97
def unary_operator?(node, diagnostic)
  node.source.start_with?(diagnostic.arguments[:prefix])
end