class RuboCop::Cop::Lint::UselessRuby2Keywords


define_method(:foo) { |arg| }
# good
ruby2_keywords :foo
define_method(:foo) { |arg| }
# bad (ruby2_keywords with dynamic method)
def foo; end
# good
ruby2_keywords :foo
def foo; end
# bad (ruby2_keywords given a symbol)
def foo(*args, **kwargs); end
# good
ruby2_keywords def foo(*args, **kwargs); end
# bad (splat argument with double splat)
def foo(*args, i:, j:); end
# good
ruby2_keywords def foo(*args, i:, j:); end
# bad (splat argument with keyword arguments)
def foo(i:, j:); end
# good
ruby2_keywords def foo(i:, j:); end
# bad (keyword arguments)
def foo(**args); end
# good
ruby2_keywords def foo(**args); end
# bad (double splatted argument)
def foo(arg); end
# good
ruby2_keywords def foo(arg); end
# bad (positional argument)
def foo; end
# good
ruby2_keywords def foo; end
# bad (no arguments)
ruby2_keywords def foo(*args); end
# good (splat argument without keyword arguments)
@example
a keyword splat (‘**kwargs`).
(`*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
`ruby2_keywords` should only be called on methods that accept an argument splat
This cop looks for `ruby2_keywords` calls for methods that do not need it.

def allowed_arguments(arguments)

`ruby2_keywords` is only allowed if there's a `restarg` and no keyword arguments
def allowed_arguments(arguments)
  return false if arguments.empty?
  arguments.each_child_node(:restarg).any? &&
    arguments.each_child_node(:kwarg, :kwoptarg, :kwrestarg).none?
end

def inspect_def(node, def_node)

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

def inspect_sym(node, sym_node)

def inspect_sym(node, sym_node)
  return unless node.parent
  method_name = sym_node.value
  definition = node.parent.each_child_node.detect { |n| method_definition(n, method_name) }
  return unless definition
  return if allowed_arguments(definition.arguments)
  add_offense(node, message: format(MSG, method_name: method_name))
end

def on_send(node)

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