Skip to content

Commit

Permalink
Merge pull request rubocop#13245 from masato-bkn/support-filter-style…
Browse files Browse the repository at this point in the history
…-collection-compact

Support `filter/filter!` in `Style/CollectionCompact`
  • Loading branch information
koic authored Sep 18, 2024
2 parents eb56d39 + dbe332a commit befebe2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#13245](https://github.com/rubocop/rubocop/pull/13245): Support `filter/filter!` in `Style/CollectionCompact`. ([@masato-bkn][])
8 changes: 6 additions & 2 deletions lib/rubocop/cop/style/collection_compact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module Style
# array.reject(&:nil?)
# array.reject { |e| e.nil? }
# array.select { |e| !e.nil? }
# array.filter { |e| !e.nil? }
# array.grep_v(nil)
# array.grep_v(NilClass)
#
Expand All @@ -31,6 +32,7 @@ module Style
# hash.reject!(&:nil?)
# hash.reject! { |k, v| v.nil? }
# hash.select! { |k, v| !v.nil? }
# hash.filter! { |k, v| !v.nil? }
#
# # good
# hash.compact!
Expand All @@ -46,8 +48,9 @@ class CollectionCompact < Base
extend TargetRubyVersion

MSG = 'Use `%<good>s` instead of `%<bad>s`.'
RESTRICT_ON_SEND = %i[reject reject! select select! grep_v].freeze
RESTRICT_ON_SEND = %i[reject reject! select select! filter filter! grep_v].freeze
TO_ENUM_METHODS = %i[to_enum lazy].freeze
FILTER_METHODS = %i[filter filter!].freeze

minimum_target_ruby_version 2.4

Expand All @@ -72,7 +75,7 @@ class CollectionCompact < Base
def_node_matcher :select_method?, <<~PATTERN
(block
(call
!nil? {:select :select!})
!nil? {:select :select! :filter :filter!})
$(args ...)
(call
(call
Expand All @@ -85,6 +88,7 @@ class CollectionCompact < Base
PATTERN

def on_send(node)
return if target_ruby_version < 2.6 && FILTER_METHODS.include?(node.method_name)
return unless (range = offense_range(node))
return if allowed_receiver?(node.receiver)
return if target_ruby_version <= 3.0 && to_enum_method?(node)
Expand Down
46 changes: 46 additions & 0 deletions spec/rubocop/cop/style/collection_compact_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,52 @@ def foo(params)
end
end

context 'Ruby >= 2.6', :ruby26, unsupported_on: :prism do
it 'registers an offense and corrects when using `filter/filter!` to reject nils' do
expect_offense(<<~RUBY)
array.filter { |e| !e.nil? }
^^^^^^^^^^^^^^^^^^^^^^ Use `compact` instead of `filter { |e| !e.nil? }`.
hash.filter! { |k, v| !v.nil? }
^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact!` instead of `filter! { |k, v| !v.nil? }`.
RUBY

expect_correction(<<~RUBY)
array.compact
hash.compact!
RUBY
end

it 'registers an offense and corrects when using safe navigation `filter/filter!` call to reject nils' do
expect_offense(<<~RUBY)
array&.filter { |e| e&.nil?&.! }
^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact` instead of `filter { |e| e&.nil?&.! }`.
hash&.filter! { |k, v| v&.nil?&.! }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact!` instead of `filter! { |k, v| v&.nil?&.! }`.
RUBY

expect_correction(<<~RUBY)
array&.compact
hash&.compact!
RUBY
end

it 'does not register an offense when using `filter/filter!` to reject nils without a receiver' do
expect_no_offenses(<<~RUBY)
filter { |e| !e.nil? }
filter! { |k, v| !v.nil? }
RUBY
end
end

context 'Ruby <= 2.5', :ruby25, unsupported_on: :prism do
it 'does not register an offense when using `filter/filter!`' do
expect_no_offenses(<<~RUBY)
array.filter { |e| !e.nil? }
hash.filter! { |k, v| !v.nil? }
RUBY
end
end

context 'when Ruby <= 2.3', :ruby23, unsupported_on: :prism do
it 'does not register an offense when using `reject` on hash to reject nils' do
expect_no_offenses(<<~RUBY)
Expand Down

0 comments on commit befebe2

Please sign in to comment.