class RuboCop::Cop::Performance::BindCall


umethod.bind_call(obj, foo, bar)
# good
umethod.bind(obj).(foo, bar)
umethod.bind(obj).call(foo, bar)
# bad
@example
`bind(obj).call(args, …)‘.
The `bind_call(obj, args, …)` method is faster than
can be replaced by `bind_call(obj, args, …)`.
This cop identifies places where `bind(obj).call(args, …)`
In Ruby 2.7, `UnboundMethod#bind_call` has been added.

def build_call_args(call_args_node)

def build_call_args(call_args_node)
  call_args_node.map(&:source).join(', ')
end

def correction_range(receiver, node)

def correction_range(receiver, node)
  location_of_bind = receiver.loc.selector.begin_pos
  location_of_call = node.source_range.end.end_pos
  range_between(location_of_bind, location_of_call)
end

def message(bind_arg, call_args)

def message(bind_arg, call_args)
  comma = call_args.empty? ? '' : ', '
  format(MSG, bind_arg: bind_arg, comma: comma, call_args: call_args)
end

def on_send(node)

def on_send(node)
  return unless (receiver, bind_arg, call_args_node = bind_with_call_method?(node))
  range = correction_range(receiver, node)
  call_args = build_call_args(call_args_node)
  message = message(bind_arg.source, call_args)
  add_offense(range, message: message) do |corrector|
    call_args = ", #{call_args}" unless call_args.empty?
    replacement_method = "bind_call(#{bind_arg.source}#{call_args})"
    corrector.replace(range, replacement_method)
  end
end