Class: RuboCop::Cop::Sorbet::SelectByIsA

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Defined in:
lib/rubocop/cop/sorbet/select_by_is_a.rb

Overview

Suggests using ‘grep` over `select` when using it only for type narrowing.

Examples:


# bad
strings_or_integers.select { |e| e.is_a?(String) }
strings_or_integers.filter { |e| e.is_a?(String) }
strings_or_integers.select { |e| e.kind_of?(String) }

# good
strings_or_integers.grep(String)

Constant Summary collapse

MSG =
"Use `grep` instead of `select` when using it only for type narrowing."
RESTRICT_ON_SEND =
[:select, :filter].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object Also known as: on_csend



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubocop/cop/sorbet/select_by_is_a.rb', line 43

def on_send(node)
  block_node = node.block_node

  return unless block_node
  return unless type_narrowing_select?(block_node)

  add_offense(block_node) do |corrector|
    receiver = node.receiver
    type_class = block_node.body.children[2]
    navigation = node.csend_type? ? "&." : "."
    replacement = "#{receiver.source}#{navigation}grep(#{type_class.source})"

    corrector.replace(block_node, replacement)
  end
end

#type_narrowing_select?(node) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rubocop/cop/sorbet/select_by_is_a.rb', line 26

def_node_matcher :type_narrowing_select?, "{\n  (block\n    (call _ {:select :filter})\n    (args (arg _))\n    (send (lvar _) { :is_a? :kind_of? } (const nil? _)))\n  (numblock\n    (call _ {:select :filter})\n    _\n    (send (lvar _) { :is_a? :kind_of? } (const nil? _)))\n  (itblock\n    (call _ {:select :filter})\n    _\n    (send (lvar _) { :is_a? :kind_of? } (const nil? _)))\n}\n"