From 03204227e3b7e68f8414fb0a5e84c856afd5daed Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 5 May 2021 01:26:26 +0900 Subject: [PATCH] [Fix #238] Fix an incorrect auto-correct for `Performance/MapCompact` Fixes #238. This PR fixes an incorrect auto-correct for `Performance/MapCompact` when invoking a method after `map { ... }.compact` on the same line. --- CHANGELOG.md | 4 +++ lib/rubocop/cop/performance/map_compact.rb | 8 +++++- .../cop/performance/map_compact_spec.rb | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af3e03eece..374d9258a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### Bug fixes + +* [#238](https://github.com/rubocop/rubocop-performance/issues/238): Fix an incorrect auto-correct for `Performance/MapCompact` when invoking a method after `map { ... }.compact` on the same line. ([@koic][]) + ## 1.11.1 (2021-05-02) ### Bug fixes diff --git a/lib/rubocop/cop/performance/map_compact.rb b/lib/rubocop/cop/performance/map_compact.rb index 75c715a356..3e80f176a2 100644 --- a/lib/rubocop/cop/performance/map_compact.rb +++ b/lib/rubocop/cop/performance/map_compact.rb @@ -63,14 +63,20 @@ def on_send(node) private def compact_method_range(compact_node) + chained_method = compact_node.parent compact_method_range = compact_node.loc.selector - if compact_node.multiline? + if compact_node.multiline? && + chained_method && !invoke_method_after_map_compact_on_same_line?(compact_node, chained_method) range_by_whole_lines(compact_method_range, include_final_newline: true) else compact_method_range end end + + def invoke_method_after_map_compact_on_same_line?(compact_node, chained_method) + compact_node.loc.selector.line == chained_method.loc.selector.line + end end end end diff --git a/spec/rubocop/cop/performance/map_compact_spec.rb b/spec/rubocop/cop/performance/map_compact_spec.rb index 7d1c454d30..09d5c97c91 100644 --- a/spec/rubocop/cop/performance/map_compact_spec.rb +++ b/spec/rubocop/cop/performance/map_compact_spec.rb @@ -86,6 +86,32 @@ RUBY end + it 'registers an offense when using `map { ... }.compact`' do + expect_offense(<<~RUBY) + collection.map { |item| + ^^^^^^^^^^^^ Use `filter_map` instead. + }.compact + RUBY + + expect_correction(<<~RUBY) + collection.filter_map { |item| + } + RUBY + end + + it 'registers an offense when invoking a method after `map { ... }.compact`' do + expect_offense(<<~RUBY) + collection.map { |item| + ^^^^^^^^^^^^ Use `filter_map` instead. + }.compact.do_something + RUBY + + expect_correction(<<~RUBY) + collection.filter_map { |item| + }.do_something + RUBY + end + it 'does not register an offense when using `collection.map(&:do_something).compact!`' do expect_no_offenses(<<~RUBY) collection.map(&:do_something).compact!