class RuboCop::Cop::Rails::Delegate
This cop looks for delegations that could have been created automatically with the `delegate` method.
Safe navigation `&.` is ignored because Rails' `allow_nil` option checks not just for nil but also delegates if nil responds to the delegated method.
The `EnforceForPrefixed` option (defaulted to `true`) means that using the target object as a prefix of the method name without using the `delegate` method will be a violation. When set to `false`, this case is legal.
@example
# bad def bar foo.bar end # good delegate :bar, to: :foo # good def bar foo&.bar end # good private def bar foo.bar end
@example EnforceForPrefixed: true (default)
# bad def foo_bar foo.bar end # good delegate :bar, to: :foo, prefix: true
@example EnforceForPrefixed: false
# good def foo_bar foo.bar end # good delegate :bar, to: :foo, prefix: true
Constants
- MSG
Public Instance Methods
on_def(node)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 65 def on_def(node) return unless trivial_delegate?(node) return if private_or_protected_delegation(node) register_offense(node) end
Private Instance Methods
arguments_match?(arg_array, body)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 89 def arguments_match?(arg_array, body) argument_array = body.arguments return false if arg_array.size != argument_array.size arg_array.zip(argument_array).all? do |arg, argument| arg.arg_type? && argument.lvar_type? && arg.children == argument.children end end
include_prefix_case?()
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 106 def include_prefix_case? cop_config['EnforceForPrefixed'] end
method_name_matches?(method_name, body)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 101 def method_name_matches?(method_name, body) method_name == body.method_name || (include_prefix_case? && method_name == prefixed_method_name(body)) end
prefixed_method_name(body)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 110 def prefixed_method_name(body) [body.receiver.method_name, body.method_name].join('_').to_sym end
private_or_protected_before(line)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 120 def private_or_protected_before(line) (processed_source[0..line].map(&:strip) & %w[private protected]).any? end
private_or_protected_delegation(node)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 114 def private_or_protected_delegation(node) line = node.first_line private_or_protected_before(line) || private_or_protected_inline(line) end
private_or_protected_inline(line)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 124 def private_or_protected_inline(line) processed_source[line - 1].strip.match?(/\A(private )|(protected )/) end
register_offense(node)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 74 def register_offense(node) add_offense(node.loc.keyword) do |corrector| delegation = ["delegate :#{node.body.method_name}", "to: :#{node.body.receiver.method_name}"] delegation << ['prefix: true'] if node.method?(prefixed_method_name(node.body)) corrector.replace(node.source_range, delegation.join(', ')) end end
trivial_delegate?(def_node)
click to toggle source
# File lib/rubocop/cop/rails/delegate.rb, line 83 def trivial_delegate?(def_node) delegate?(def_node) && method_name_matches?(def_node.method_name, def_node.body) && arguments_match?(def_node.arguments, def_node.body) end