class RuboCop::Cop::Lint::UselessRuby2Keywords

Looks for ‘ruby2_keywords` calls for methods that do not need it.

‘ruby2_keywords` should only be called on methods that accept an argument splat (`*args`) but do not explicit keyword arguments (`k:` or `k: true`) or a keyword splat (`**kwargs`).

@example

# good (splat argument without keyword arguments)
ruby2_keywords def foo(*args); end

# bad (no arguments)
ruby2_keywords def foo; end

# good
def foo; end

# bad (positional argument)
ruby2_keywords def foo(arg); end

# good
def foo(arg); end

# bad (double splatted argument)
ruby2_keywords def foo(**args); end

# good
def foo(**args); end

# bad (keyword arguments)
ruby2_keywords def foo(i:, j:); end

# good
def foo(i:, j:); end

# bad (splat argument with keyword arguments)
ruby2_keywords def foo(*args, i:, j:); end

# good
def foo(*args, i:, j:); end

# bad (splat argument with double splat)
ruby2_keywords def foo(*args, **kwargs); end

# good
def foo(*args, **kwargs); end

# bad (ruby2_keywords given a symbol)
def foo; end
ruby2_keywords :foo

# good
def foo; end

# bad (ruby2_keywords with dynamic method)
define_method(:foo) { |arg| }
ruby2_keywords :foo

# good
define_method(:foo) { |arg| }

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/lint/useless_ruby2_keywords.rb, line 79
def on_send(node)
  return unless (first_argument = node.first_argument)

  if first_argument.def_type?
    inspect_def(node, first_argument)
  elsif node.first_argument.sym_type?
    inspect_sym(node, first_argument)
  end
end

Private Instance Methods

allowed_arguments(arguments) click to toggle source

‘ruby2_keywords` is only allowed if there’s a ‘restarg` and no keyword arguments

# File lib/rubocop/cop/lint/useless_ruby2_keywords.rb, line 118
def allowed_arguments(arguments)
  return false if arguments.empty?

  arguments.each_child_node(:restarg).any? &&
    arguments.each_child_node(:kwarg, :kwoptarg, :kwrestarg).none?
end
find_method_definition(node, method_name) click to toggle source
# File lib/rubocop/cop/lint/useless_ruby2_keywords.rb, line 109
def find_method_definition(node, method_name)
  node.each_ancestor.lazy.map do |ancestor|
    ancestor.each_child_node(:def, :block, :numblock).find do |child|
      method_definition(child, method_name)
    end
  end.find(&:itself)
end
inspect_def(node, def_node) click to toggle source
# File lib/rubocop/cop/lint/useless_ruby2_keywords.rb, line 91
def inspect_def(node, def_node)
  return if allowed_arguments(def_node.arguments)

  add_offense(node.loc.selector, message: format(MSG, method_name: def_node.method_name))
end
inspect_sym(node, sym_node) click to toggle source
# File lib/rubocop/cop/lint/useless_ruby2_keywords.rb, line 97
def inspect_sym(node, sym_node)
  return unless node.parent

  method_name = sym_node.value
  definition = find_method_definition(node, method_name)

  return unless definition
  return if allowed_arguments(definition.arguments)

  add_offense(node, message: format(MSG, method_name: method_name))
end