Skip to content

Commit

Permalink
[Fix rubocop#12298] Fix a false positive for `Style/RedundantParenthe…
Browse files Browse the repository at this point in the history
…ses`

Fixes rubocop#12298.

This PR fixes a false positive for `Style/RedundantParentheses`
when using a parenthesized hash literal as the first argument
in a method call without parentheses.
  • Loading branch information
koic committed Oct 20, 2023
1 parent 79f8187 commit 9409b72
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#12298](https://github.com/rubocop/rubocop/issues/12298): Fix a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. ([@koic][])
26 changes: 17 additions & 9 deletions lib/rubocop/cop/style/redundant_parentheses.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,19 @@ def empty_parentheses?(node)

def first_arg_begins_with_hash_literal?(node)
# Don't flag `method ({key: value})` or `method ({key: value}.method)`
method_chain_begins_with_hash_literal?(node.children.first) &&
first_argument?(node) &&
!parentheses?(node.parent)
hash_literal = method_chain_begins_with_hash_literal(node.children.first)
if (root_method = node.each_ancestor(:send).to_a.last)
parenthesized = root_method.parenthesized_call?
end
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
end

def method_chain_begins_with_hash_literal?(node)
return false if node.nil?
return true if node.hash_type?
return false unless node.send_type?
def method_chain_begins_with_hash_literal(node)
return if node.nil?
return node if node.hash_type?
return unless node.send_type?

method_chain_begins_with_hash_literal?(node.children.first)
method_chain_begins_with_hash_literal(node.children.first)
end

def check(begin_node)
Expand Down Expand Up @@ -231,7 +233,13 @@ def only_begin_arg?(args)
end

def first_argument?(node)
first_send_argument?(node) || first_super_argument?(node) || first_yield_argument?(node)
if first_send_argument?(node) ||
first_super_argument?(node) ||
first_yield_argument?(node)
return true
end

node.each_ancestor.any? { |ancestor| first_argument?(ancestor) }
end

# @!method first_send_argument?(node)
Expand Down
1 change: 1 addition & 0 deletions spec/rubocop/cop/style/redundant_parentheses_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ def x
context 'when the first argument in a method call begins with a hash literal' do
it 'accepts parentheses if the argument list is not parenthesized' do
expect_no_offenses('x ({ y: 1 }), z')
expect_no_offenses('x ({ y: 1 }).merge({ y: 2 }), z')
expect_no_offenses('x ({ y: 1 }.merge({ y: 2 })), z')
expect_no_offenses('x ({ y: 1 }.merge({ y: 2 }).merge({ y: 3 })), z')
end
Expand Down

0 comments on commit 9409b72

Please sign in to comment.