Class: RuboCop::Cop::Lint::UnmodifiedReduceAccumulator
- Defined in:
- lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb
Overview
Looks for ‘reduce` or `inject` blocks where the value returned (implicitly or explicitly) does not include the accumulator. A block is considered valid as long as at least one return value includes the accumulator.
If the accumulator is not included in the return value, then the entire block will just return a transformation of the last element value, and could be rewritten as such without a loop.
Also catches instances where an index of the accumulator is returned, as this may change the type of object being retained.
NOTE: For the purpose of reducing false positives, this cop only flags returns in ‘reduce` blocks where the element is the only variable in the expression (since we will not be able to tell what other variables relate to via static analysis).
Constant Summary collapse
- MSG =
'Ensure the accumulator `%<accum>s` will be modified by `%<method>s`.'
- MSG_INDEX =
'Do not return an element of the accumulator in `%<method>s`.'
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #accumulator_index?(node, accumulator_name) ⇒ Object
- #element_modified?(node, element_name) ⇒ Object
- #expression_values(node) ⇒ Object
- #lvar_used?(node, name) ⇒ Object
- #on_block(node) ⇒ Object (also: #on_numblock)
- #reduce_with_block?(node) ⇒ Object
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_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
#accumulator_index?(node, accumulator_name) ⇒ Object
78 79 80 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 78 def_node_matcher :accumulator_index?, <<~PATTERN (send (lvar %1) {:[] :[]=} ...) PATTERN |
#element_modified?(node, element_name) ⇒ Object
83 84 85 86 87 88 89 90 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 83 def_node_search :element_modified?, <<~PATTERN { (send _receiver !{:[] :[]=} <`(lvar %1) `_ ...>) # method(el, ...) (send (lvar %1) _message <{ivar gvar cvar lvar send} ...>) # el.method(...) (lvasgn %1 _) # el = ... (%RuboCop::AST::Node::SHORTHAND_ASSIGNMENTS (lvasgn %1) ... _) # el += ... } PATTERN |
#expression_values(node) ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 104 def_node_search :expression_values, <<~PATTERN { (%RuboCop::AST::Node::VARIABLES $_) (%RuboCop::AST::Node::EQUALS_ASSIGNMENTS $_ ...) (send (%RuboCop::AST::Node::VARIABLES $_) :<< ...) $(send _ _) (dstr (begin {(%RuboCop::AST::Node::VARIABLES $_)})) (%RuboCop::AST::Node::SHORTHAND_ASSIGNMENTS (%RuboCop::AST::Node::EQUALS_ASSIGNMENTS $_) ...) } PATTERN |
#lvar_used?(node, name) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 93 def_node_matcher :lvar_used?, <<~PATTERN { (lvar %1) (lvasgn %1 ...) (send (lvar %1) :<< ...) (dstr (begin (lvar %1))) (%RuboCop::AST::Node::SHORTHAND_ASSIGNMENTS (lvasgn %1)) } PATTERN |
#on_block(node) ⇒ Object Also known as: on_numblock
115 116 117 118 119 120 121 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 115 def on_block(node) return unless node.body return unless reduce_with_block?(node) return unless node.argument_list.length >= 2 check_return_values(node) end |
#reduce_with_block?(node) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb', line 70 def_node_matcher :reduce_with_block?, <<~PATTERN { (block (call _recv {:reduce :inject} ...) args ...) (numblock (call _recv {:reduce :inject} ...) ...) } PATTERN |