Skip to content

Commit

Permalink
Handle implicit receivers in Style/InvertibleUnlessCondition
Browse files Browse the repository at this point in the history
Previously, we would attempt to call `node.receiver.source`, but
`node.receiver` could be `nil`.

This teaches the cop to handle implicit receivers.
  • Loading branch information
sambostock authored and bbatsov committed Feb 28, 2024
1 parent 18004e9 commit 5da1905
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog/fix_handle_implicit_receivers_in.md
@@ -0,0 +1 @@
* [#12711](https://github.com/rubocop/rubocop/pull/12711): Handle implicit receivers in `Style/InvertibleUnlessCondition`. ([@sambostock][])
14 changes: 7 additions & 7 deletions lib/rubocop/cop/style/invertible_unless_condition.rb
Expand Up @@ -99,23 +99,23 @@ def preferred_condition(node)
end
end

def preferred_send_condition(node)
receiver_source = node.receiver.source
def preferred_send_condition(node) # rubocop:disable Metrics/CyclomaticComplexity
receiver_source = node.receiver&.source
return receiver_source if node.method?(:!)

receive = receiver_source ? "#{receiver_source}." : '' # receiver may be implicit (self)

inverse_method_name = inverse_methods[node.method_name]
return "#{receiver_source}.#{inverse_method_name}" unless node.arguments?
return "#{receive}#{inverse_method_name}" unless node.arguments?

argument_list = node.arguments.map(&:source).join(', ')
if node.operator_method?
return "#{receiver_source} #{inverse_method_name} #{argument_list}"
end

if node.parenthesized?
return "#{receiver_source}.#{inverse_method_name}(#{argument_list})"
end
return "#{receive}#{inverse_method_name}(#{argument_list})" if node.parenthesized?

"#{receiver_source}.#{inverse_method_name} #{argument_list}"
"#{receive}#{inverse_method_name} #{argument_list}"
end

def preferred_logical_condition(node)
Expand Down
33 changes: 33 additions & 0 deletions spec/rubocop/cop/style/invertible_unless_condition_spec.rb
Expand Up @@ -91,6 +91,39 @@
end
end

it 'registers an offense and corrects methods without arguments called with implicit receivers' do
expect_offense(<<~RUBY)
foo unless odd?
^^^^^^^^^^^^^^^ Prefer `if even?` over `unless odd?`.
RUBY

expect_correction(<<~RUBY)
foo if even?
RUBY
end

it 'registers an offense and corrects parenthesized methods with arguments called with implicit receivers' do
expect_offense(<<~RUBY)
foo unless include?(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `if exclude?(value)` over `unless include?(value)`.
RUBY

expect_correction(<<~RUBY)
foo if exclude?(value)
RUBY
end

it 'registers an offense and corrects unparenthesized methods with arguments called with implicit receivers' do
expect_offense(<<~RUBY)
foo unless include? value
^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `if exclude? value` over `unless include? value`.
RUBY

expect_correction(<<~RUBY)
foo if exclude? value
RUBY
end

it 'does not register an offense when using explicit begin condition' do
expect_no_offenses(<<~RUBY)
foo unless begin x != y end
Expand Down

0 comments on commit 5da1905

Please sign in to comment.