Class: RuboCop::Cop::Style::SelectByKind
Overview
Looks for places where a subset of an Enumerable (array, range, set, etc.; see note below) is calculated based on a class type check, and suggests grep or grep_v instead.
NOTE: Hashes do not behave as you may expect with grep, which means that hash.grep is not equivalent to hash.select. Although RuboCop is limited by static analysis, this cop attempts to avoid registering an offense when the receiver is a hash (hash literal, Hash.new, ‘Hash#[]`, or to_h/to_hash).
Constant Summary collapse
- MSG =
'Prefer `%<replacement>s` to `%<original_method>s` with a kind check.'- RESTRICT_ON_SEND =
%i[select filter find_all reject].freeze
- SELECT_METHODS =
%i[select filter find_all].freeze
- CLASS_CHECK_METHODS =
%i[is_a? kind_of?].to_set.freeze
Constants included from RangeHelp
RangeHelp::BYTE_ORDER_MARK, RangeHelp::NOT_GIVEN
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #calls_lvar?(node, name) ⇒ Object
- #class_check?(node) ⇒ Object
-
#creates_hash?(node) ⇒ Object
Returns true if a node appears to return a hash.
- #env_const?(node) ⇒ Object
- #negated_calls_lvar?(node, name) ⇒ Object
- #on_send(node) ⇒ Object (also: #on_csend)
Methods included from AutoCorrector
Methods inherited from Base
#active_support_extensions_enabled?, #add_global_offense, #add_offense, #always_autocorrect?, autocorrect_incompatible_with, badge, #begin_investigation, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #cop_config, #cop_name, cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #message, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #parser_engine, #ready, #relevant_file?, requires_gem, #string_literals_frozen_by_default?, support_autocorrect?, support_multiple_source?, #target_gem_version, #target_rails_version, #target_ruby_version
Methods included from ExcludeLimit
Methods included from AutocorrectLogic
#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?
Methods included from IgnoredNode
#ignore_node, #ignored_node?, #part_of_ignored_node?
Methods included from Util
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Method Details
#calls_lvar?(node, name) ⇒ Object
72 73 74 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 72 def_node_matcher :calls_lvar?, <<~PATTERN (send (lvar %1) %CLASS_CHECK_METHODS _) PATTERN |
#class_check?(node) ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 45 def_node_matcher :class_check?, <<~PATTERN { (block call (args (arg $_)) ${(send (lvar _) %CLASS_CHECK_METHODS _)}) (block call (args (arg $_)) ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)}) (numblock call $1 ${(send (lvar _) %CLASS_CHECK_METHODS _)}) (numblock call $1 ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)}) (itblock call $_ ${(send (lvar _) %CLASS_CHECK_METHODS _)}) (itblock call $_ ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)}) } PATTERN |
#creates_hash?(node) ⇒ Object
Returns true if a node appears to return a hash
58 59 60 61 62 63 64 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 58 def_node_matcher :creates_hash?, <<~PATTERN { (call (const _ :Hash) {:new :[]} ...) (block (call (const _ :Hash) :new ...) ...) (call _ { :to_h :to_hash } ...) } PATTERN |
#env_const?(node) ⇒ Object
67 68 69 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 67 def_node_matcher :env_const?, <<~PATTERN (const {nil? cbase} :ENV) PATTERN |
#negated_calls_lvar?(node, name) ⇒ Object
77 78 79 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 77 def_node_matcher :negated_calls_lvar?, <<~PATTERN (send (send (lvar %1) %CLASS_CHECK_METHODS _) :!) PATTERN |
#on_send(node) ⇒ Object Also known as: on_csend
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rubocop/cop/style/select_by_kind.rb', line 81 def on_send(node) return unless (block_node = node.block_node) return if block_node.body&.begin_type? return if receiver_allowed?(block_node.receiver) return unless (class_check_send_node = extract_send_node(block_node)) replacement = replacement(class_check_send_node, node) class_constant = find_class_constant(class_check_send_node) register_offense(node, block_node, class_constant, replacement) end |