Skip to content

Commit

Permalink
[Fix rubocop#7063] Fix unsafe autocorrect for 'Style/TernaryParentheses'
Browse files Browse the repository at this point in the history
This takes the precedence of operators used into account when deciding
to autocorrect. The issue is that if an operator of precedence below
that of the ternary operator (e.g. "or") is used, then the existing
autocorrect can change the semantics by removing parentheses. With
this change, the autocorrect will no longer attempt to make this
correction.
  • Loading branch information
parkerfinch committed Jun 2, 2019
1 parent 64f6ca7 commit 4d01b52
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bug fixes

* [#7063](https://github.com/rubocop-hq/rubocop/issues/7063): Fix autocorrect in `Style/TernaryParentheses` cop. ([@parkerfinch][])

### Changes

* [#5976](https://github.com/rubocop-hq/rubocop/issues/5976): Remove Rails cops. ([@koic][])
Expand Down
12 changes: 11 additions & 1 deletion lib/rubocop/cop/style/ternary_parentheses.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,24 @@ def infinite_loop?

def unsafe_autocorrect?(condition)
condition.children.any? do |child|
unparenthesized_method_call?(child)
unparenthesized_method_call?(child) ||
below_ternary_precedence?(child)
end
end

def unparenthesized_method_call?(child)
method_name(child) =~ /^[a-z]/i && !child.parenthesized?
end

def below_ternary_precedence?(child)
# Handle English "or", e.g. 'foo or bar ? a : b'
(child.or_type? && child.semantic_operator?) ||
# Handle English "and", e.g. 'foo and bar ? a : b'
(child.and_type? && child.semantic_operator?) ||
# Handle English "not", e.g. 'not foo ? a : b'
(child.send_type? && child.prefix_not?)
end

def_node_matcher :method_name, <<-PATTERN
{($:defined? (send nil? _) ...)
(send {_ nil?} $_ _ ...)}
Expand Down
21 changes: 21 additions & 0 deletions spec/rubocop/cop/style/ternary_parentheses_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@
it_behaves_like 'code with offense',
'foo = bar && (baz || bar) ? a : b',
'foo = (bar && (baz || bar)) ? a : b'

it_behaves_like 'code with offense',
'foo = bar or baz ? a : b',
'foo = bar or (baz) ? a : b'

it_behaves_like 'code with offense',
'not bar ? a : b',
'not (bar) ? a : b'
end

context 'with an assignment condition' do
Expand Down Expand Up @@ -168,6 +176,12 @@

it_behaves_like 'code without offense',
'foo = bar && (baz || bar) ? a : b'

it_behaves_like 'code with offense',
'foo = (foo or bar) ? a : b'

it_behaves_like 'code with offense',
'foo = (not bar) ? a : b'
end

context 'with an assignment condition' do
Expand Down Expand Up @@ -248,13 +262,20 @@
it_behaves_like 'code with offense',
'foo = (bar[:baz]) ? a : b',
'foo = bar[:baz] ? a : b'

it_behaves_like 'code with offense',
'foo = bar or (baz) ? a : b',
'foo = bar or baz ? a : b'
end

context 'with a complex condition' do
it_behaves_like 'code with offense',
'foo = (bar.baz?) ? a : b',
'foo = bar.baz? ? a : b'

it_behaves_like 'code without offense',
'foo = (baz or bar) ? a : b'

it_behaves_like 'code without offense',
'foo = (bar && (baz || bar)) ? a : b'
end
Expand Down

0 comments on commit 4d01b52

Please sign in to comment.