diff --git a/changelog/fix_false_positive_for_style_redundant_each.md b/changelog/fix_false_positive_for_style_redundant_each.md new file mode 100644 index 00000000000..02f1bc2bd11 --- /dev/null +++ b/changelog/fix_false_positive_for_style_redundant_each.md @@ -0,0 +1 @@ +* [#11165](https://github.com/rubocop/rubocop/issues/11165): Fix a false positive for `Style/RedundantEach` when any method is used between methods containing `each` in the method name. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_each.rb b/lib/rubocop/cop/style/redundant_each.rb index 0a85a948028..6a651a3d849 100644 --- a/lib/rubocop/cop/style/redundant_each.rb +++ b/lib/rubocop/cop/style/redundant_each.rb @@ -68,15 +68,17 @@ def redundant_each_method(node) ancestor.receiver == node && (RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each)) end + + return ancestor_node if ancestor_node end - ancestor_node || node.each_descendant(:send).detect do |descendant| - next if descendant.parent.block_type? || descendant.last_argument&.block_pass_type? + return unless (prev_method = node.children.first) + return if !prev_method.send_type? || + prev_method.parent.block_type? || prev_method.last_argument&.block_pass_type? - detected = descendant.method_name.to_s.start_with?('each_') unless node.method?(:each) + detected = prev_method.method_name.to_s.start_with?('each_') unless node.method?(:each) - detected || descendant.method?(:reverse_each) - end + prev_method if detected || prev_method.method?(:reverse_each) end # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity diff --git a/spec/rubocop/cop/style/redundant_each_spec.rb b/spec/rubocop/cop/style/redundant_each_spec.rb index f47e68ef38b..454d1a4c747 100644 --- a/spec/rubocop/cop/style/redundant_each_spec.rb +++ b/spec/rubocop/cop/style/redundant_each_spec.rb @@ -143,6 +143,12 @@ RUBY end + it 'does not register an offense when any method is used between methods with `each` in the method name' do + expect_no_offenses(<<~RUBY) + string.each_char.map(&:to_i).reverse.each_with_index.map { |v, i| do_something(v, i) } + RUBY + end + it 'does not register an offense when using `each.with_object`' do expect_no_offenses(<<~RUBY) array.each.with_object { |v, o| do_something(v, o) }