From c21dc46f0e81d5abe168e8c323a13bc962a5d2ea Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 10 Aug 2021 02:38:31 +0900 Subject: [PATCH] [Fix #255] Fix a false positive for `Performance/RedundantEqualityComparisonBlock` Fixes #255. This PR fixes a false positive for `Performance/RedundantEqualityComparisonBlock` when using block argument is used for an argument of operand. --- CHANGELOG.md | 4 ++++ .../redundant_equality_comparison_block.rb | 19 +++++++++++++-- ...edundant_equality_comparison_block_spec.rb | 24 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b8d8417fc..791be894be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### Bug fixes + +* [#255](https://github.com/rubocop/rubocop-performance/issues/255): Fix a false positive for `Performance/RedundantEqualityComparisonBlock` when using block argument is used for an argument of operand. ([@koic][]) + ## 1.11.4 (2021-07-07) ### Bug fixes diff --git a/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb b/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb index b905621de5..d1ef3db49a 100644 --- a/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +++ b/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb @@ -74,12 +74,27 @@ def same_block_argument_and_is_a_argument?(block_body, block_argument) def new_argument(block_argument, block_body) if block_argument.source == block_body.receiver.source - block_body.first_argument.source + rhs = block_body.first_argument + return if use_block_argument_in_method_argument_of_operand?(block_argument, rhs) + + rhs.source elsif block_argument.source == block_body.first_argument.source - block_body.receiver.source + lhs = block_body.receiver + return if use_block_argument_in_method_argument_of_operand?(block_argument, lhs) + + lhs.source end end + def use_block_argument_in_method_argument_of_operand?(block_argument, operand) + return false unless operand.send_type? + + arguments = operand.arguments + arguments.inject(arguments.map(&:source)) do |operand_sources, argument| + operand_sources + argument.each_descendant(:lvar).map(&:source) + end.any?(block_argument.source) + end + def offense_range(node) node.send_node.loc.selector.join(node.source_range.end) end diff --git a/spec/rubocop/cop/performance/redundant_equality_comparison_block_spec.rb b/spec/rubocop/cop/performance/redundant_equality_comparison_block_spec.rb index 2065a4165e..df2abdbaac 100644 --- a/spec/rubocop/cop/performance/redundant_equality_comparison_block_spec.rb +++ b/spec/rubocop/cop/performance/redundant_equality_comparison_block_spec.rb @@ -106,4 +106,28 @@ items.do_something { |item| item == other } RUBY end + + it 'does not register an offense when using block argument is used for an argument of RHS operand' do + expect_no_offenses(<<~RUBY) + items.any? { |item| item == do_something(item) } + RUBY + end + + it 'does not register an offense when using block argument is used for a argument of LHS operand' do + expect_no_offenses(<<~RUBY) + items.any? { |item| do_something(item) == item } + RUBY + end + + it 'does not register an offense when using block argument is used for a nested argument of RHS operand' do + expect_no_offenses(<<~RUBY) + items.any? { |item| item == do_something[0..item] } + RUBY + end + + it 'does not register an offense when using block argument is used for a nested argument of LHS operand' do + expect_no_offenses(<<~RUBY) + items.any? { |item| do_something[0..item] == item } + RUBY + end end