Class: RuboCop::Cop::Sevencop::MapMethodChain

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
IgnoredNode
Defined in:
lib/rubocop/cop/sevencop/map_method_chain.rb

Overview

Checks if the map method is used in a chain.

This cop is another version of ‘Performance/MapMethodChain` cop which has the autocorrection support. They have decided not to add autocorrection, so we have this cop in case you want to use it. github.com/rubocop/rubocop-performance/issues/436

Examples:

# bad
array.map(&:foo).map(&:bar)

# good
array.map { |element| element.foo.bar }

Constant Summary collapse

RESTRICT_ON_SEND =
%i[map collect].freeze

Instance Method Summary collapse

Instance Method Details

#block_pass_with_symbol_arg?(node) ⇒ Object



26
27
28
# File 'lib/rubocop/cop/sevencop/map_method_chain.rb', line 26

def_node_matcher :block_pass_with_symbol_arg?, <<~PATTERN
  (:block_pass (:sym $_))
PATTERN

#on_send(node) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rubocop/cop/sevencop/map_method_chain.rb', line 30

def on_send(node)
  return if part_of_ignored_node?(node)
  return unless (map_arg = block_pass_with_symbol_arg?(node.first_argument))

  map_args = [map_arg]
  return unless (begin_of_chained_map_method = find_begin_of_chained_map_method(node, map_args))

  range = begin_of_chained_map_method.loc.selector.begin.join(node.source_range.end)
  replacement = "#{begin_of_chained_map_method.method_name} { |element| element.#{map_args.join('.')} }"
  add_offense(
    range,
    message: format(
      'Use `%<replacement>s` instead of `%<method_name>s` method chain.',
      method_name: begin_of_chained_map_method.method_name,
      replacement: replacement
    )
  ) do |corrector|
    corrector.replace(range, replacement)
  end

  ignore_node(node)
end