Skip to content

Commit

Permalink
[Fix #10734] Handle ClobberingError in `Style/NestedTernaryOperator…
Browse files Browse the repository at this point in the history
…` when there are multiple nested ternaries.
  • Loading branch information
dvandersluis authored and bbatsov committed Jun 24, 2022
1 parent 1c25af3 commit 83d500f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
1 change: 1 addition & 0 deletions changelog/fix_handle_clobberingerror_in.md
@@ -0,0 +1 @@
* [#10734](https://github.com/rubocop/rubocop/issues/10734): Handle `ClobberingError` in `Style/NestedTernaryOperator` when there are multiple nested ternaries. ([@dvandersluis][])
26 changes: 19 additions & 7 deletions lib/rubocop/cop/style/nested_ternary_operator.rb
Expand Up @@ -17,6 +17,8 @@ module Style
# end
class NestedTernaryOperator < Base
extend AutoCorrector
include RangeHelp
include IgnoredNode

MSG = 'Ternary operators must not be nested. Prefer `if` or `else` constructs instead.'

Expand All @@ -26,14 +28,10 @@ def on_if(node)
node.each_descendant(:if).select(&:ternary?).each do |nested_ternary|
add_offense(nested_ternary) do |corrector|
if_node = if_node(nested_ternary)
next if part_of_ignored_node?(if_node)

corrector.replace(if_node, <<~RUBY.chop)
if #{if_node.condition.source}
#{remove_parentheses(if_node.if_branch.source)}
else
#{if_node.else_branch.source}
end
RUBY
autocorrect(corrector, if_node)
ignore_node(if_node)
end
end
end
Expand All @@ -47,11 +45,25 @@ def if_node(node)
if_node(node)
end

def autocorrect(corrector, if_node)
replace_loc_and_whitespace(corrector, if_node.loc.question, "\n")
replace_loc_and_whitespace(corrector, if_node.loc.colon, "\nelse\n")
corrector.replace(if_node.if_branch, remove_parentheses(if_node.if_branch.source))
corrector.wrap(if_node, 'if ', "\nend")
end

def remove_parentheses(source)
return source unless source.start_with?('(')

source.delete_prefix('(').delete_suffix(')')
end

def replace_loc_and_whitespace(corrector, range, replacement)
corrector.replace(
range_with_surrounding_space(range: range, whitespace: true),
replacement
)
end
end
end
end
Expand Down
32 changes: 26 additions & 6 deletions spec/rubocop/cop/style/nested_ternary_operator_spec.rb
Expand Up @@ -9,9 +9,9 @@

expect_correction(<<~RUBY)
if a
b ? b1 : b2
b ? b1 : b2
else
a2
a2
end
RUBY
end
Expand All @@ -25,9 +25,9 @@

expect_correction(<<~RUBY)
if cond
foo
foo
else
bar(foo.a ? foo.b : foo) { |e, k| e.nil? ? nil : e[k] }
bar(foo.a ? foo.b : foo) { |e, k| e.nil? ? nil : e[k] }
end
RUBY
end
Expand All @@ -40,9 +40,9 @@

expect_correction(<<~RUBY)
if x
y + (z ? 1 : 0)
y + (z ? 1 : 0)
else
nil
nil
end
RUBY
end
Expand All @@ -56,4 +56,24 @@
end
RUBY
end

it 'can handle multiple nested ternaries' do
expect_offense(<<~RUBY)
a ? b : c ? d : e ? f : g
^^^^^^^^^ Ternary operators must not be nested. Prefer `if` or `else` constructs instead.
^^^^^^^^^^^^^^^^^ Ternary operators must not be nested. Prefer `if` or `else` constructs instead.
RUBY

expect_correction(<<~RUBY)
if a
b
else
if c
d
else
e ? f : g
end
end
RUBY
end
end

0 comments on commit 83d500f

Please sign in to comment.