class RuboCop::Cop::Style::ArgumentsForwarding
In Ruby 2.7, arguments forwarding has been added.
This cop identifies places where ‘do_something(*args, &block)` can be replaced by `do_something(…)`.
@example
# bad def foo(*args, &block) bar(*args, &block) end # bad def foo(*args, **kwargs, &block) bar(*args, **kwargs, &block) end # good def foo(...) bar(...) end
@example AllowOnlyRestArgument: true (default)
# good def foo(*args) bar(*args) end def foo(**kwargs) bar(**kwargs) end
@example AllowOnlyRestArgument: false
# bad # The following code can replace the arguments with `...`, # but it will change the behavior. Because `...` forwards block also. def foo(*args) bar(*args) end def foo(**kwargs) bar(**kwargs) end
Constants
- MSG
Public Instance Methods
on_def(node)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 84 def on_def(node) return unless node.body return unless (rest_args_name, args = use_rest_arguments?(node.arguments)) node.each_descendant(:send) do |send_node| kwargs_name, block_name = extract_argument_names_from(args) next unless forwarding_method?(send_node, rest_args_name, kwargs_name, block_name) && all_lvars_as_forwarding_method_arguments?(node, send_node) register_offense_to_forwarding_method_arguments(send_node) register_offense_to_method_definition_arguments(node) end end
Also aliased as: on_defs
Private Instance Methods
all_lvars_as_forwarding_method_arguments?(def_node, forwarding_method)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 115 def all_lvars_as_forwarding_method_arguments?(def_node, forwarding_method) lvars = def_node.body.each_descendant(:lvar, :lvasgn) begin_pos = forwarding_method.source_range.begin_pos end_pos = forwarding_method.source_range.end_pos lvars.all? { |lvar| lvar.source_range.begin_pos.between?(begin_pos, end_pos) } end
allow_only_rest_arguments?()
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 148 def allow_only_rest_arguments? cop_config.fetch('AllowOnlyRestArgument', true) end
arguments_range(node)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 142 def arguments_range(node) arguments = node.arguments range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos) end
extract_argument_names_from(args)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 102 def extract_argument_names_from(args) kwargs_name = args.first.source.delete('**') if args.first&.kwrestarg_type? block_arg_name = args.last.source.delete('&') if args.last&.blockarg_type? [kwargs_name, block_arg_name].map { |name| name&.to_sym } end
forwarding_method?(node, rest_arg, kwargs, block_arg)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 109 def forwarding_method?(node, rest_arg, kwargs, block_arg) return only_rest_arguments?(node, rest_arg) unless allow_only_rest_arguments? forwarding_method_arguments?(node, rest_arg, block_arg, kwargs) end
register_offense_to_forwarding_method_arguments(forwarding_method)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 124 def register_offense_to_forwarding_method_arguments(forwarding_method) add_offense(arguments_range(forwarding_method)) do |corrector| range = range_between( forwarding_method.loc.selector.end_pos, forwarding_method.source_range.end_pos ) corrector.replace(range, '(...)') end end
register_offense_to_method_definition_arguments(method_definition)
click to toggle source
# File lib/rubocop/cop/style/arguments_forwarding.rb, line 133 def register_offense_to_method_definition_arguments(method_definition) add_offense(arguments_range(method_definition)) do |corrector| arguments_range = range_with_surrounding_space( method_definition.arguments.source_range, side: :left ) corrector.replace(arguments_range, '(...)') end end