Skip to content

Commit

Permalink
[Fix #9366] Fix an incorrect auto-correct for `Style/SoleNestedCondit…
Browse files Browse the repository at this point in the history
…ional`

Fixes #9366.

This PR fixes an incorrect auto-correct for `Style/SoleNestedConditional`
when using method arguments without parentheses for outer condition.
  • Loading branch information
koic authored and bbatsov committed Jan 12, 2021
1 parent 0bf1e53 commit 860e681
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#9366](https://github.com/rubocop-hq/rubocop/issues/9366): Fix an incorrect auto-correct for `Style/SoleNestedConditional` when using method arguments without parentheses for outer condition. ([@koic][])
26 changes: 25 additions & 1 deletion lib/rubocop/cop/style/sole_nested_conditional.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ def autocorrect(corrector, node, if_branch)
end

def correct_for_guard_condition_style(corrector, node, if_branch, and_operator)
outer_condition = node.condition
correct_outer_condition(corrector, outer_condition)

condition = if_branch.condition
corrector.insert_after(node.condition, replacement_condition(and_operator, condition))
corrector.insert_after(outer_condition, replacement_condition(and_operator, condition))

range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
corrector.remove(range_with_surrounding_space(range: range, newlines: false))
Expand All @@ -106,6 +109,27 @@ def correct_for_comment(corrector, node, if_branch)
corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
end

def correct_outer_condition(corrector, condition)
return unless requrie_parentheses?(condition)

range = range_between(
condition.loc.selector.end_pos, condition.first_argument.source_range.begin_pos
)

corrector.replace(range, '(')
corrector.insert_after(condition.last_argument.source_range, ')')
end

def requrie_parentheses?(condition)
condition.send_type? && !condition.arguments.empty? && !condition.parenthesized?
end

def arguments_range(node)
range_between(
node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
)
end

def wrap_condition?(node)
node.or_type? ||
(node.send_type? && node.arguments.any? && !node.parenthesized?)
Expand Down
48 changes: 48 additions & 0 deletions spec/rubocop/cop/style/sole_nested_conditional_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,54 @@
RUBY
end

it 'registers an offense and corrects when using `unless` and method arguments without parentheses ' \
'in the outer condition and nested modifier condition' do
expect_offense(<<~RUBY)
unless foo.is_a? Foo
do_something if bar
^^ Consider merging nested conditions into outer `unless` conditions.
end
RUBY

expect_correction(<<~RUBY)
if !foo.is_a?(Foo) && bar
do_something
end
RUBY
end

it 'registers an offense and corrects when using `unless` and method arguments with parentheses ' \
'in the outer condition and nested modifier condition' do
expect_offense(<<~RUBY)
unless foo.is_a?(Foo)
do_something if bar
^^ Consider merging nested conditions into outer `unless` conditions.
end
RUBY

expect_correction(<<~RUBY)
if !foo.is_a?(Foo) && bar
do_something
end
RUBY
end

it 'registers an offense and corrects when using `unless` and multiple method arguments with parentheses' \
'in the outer condition and nested modifier condition' do
expect_offense(<<~RUBY)
unless foo.bar arg1, arg2
do_something if baz
^^ Consider merging nested conditions into outer `unless` conditions.
end
RUBY

expect_correction(<<~RUBY)
if !foo.bar(arg1, arg2) && baz
do_something
end
RUBY
end

it 'registers an offense and corrects for multiple nested conditionals' do
expect_offense(<<~RUBY)
if foo
Expand Down

0 comments on commit 860e681

Please sign in to comment.