Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parenthesized forwarded args in Style/MethodCallWithArgsParentheses omit_parentheses #9637

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1 @@
* [#9637](https://github.com/rubocop/rubocop/issues/9637): Allow parentheses for forwarded args in `Style/MethodCallWithArgsParentheses`'s `omit_parentheses` style to avoid endless range ambiguity. ([@gsamokovarov][])
8 changes: 6 additions & 2 deletions lib/rubocop/cop/style/method_call_with_args_parentheses.rb
Expand Up @@ -40,8 +40,12 @@ module Style
# to `true` allows the presence of parentheses in such a method call
# even with arguments.
#
# NOTE: Parens are required around a method with arguments when inside an
# endless method definition (>= Ruby 3.0).
# NOTE: Parentheses are still allowed in cases where omitting them
# results in ambiguous or syntactically incorrect code. For example,
# parentheses are required around a method with arguments when inside an
# endless method definition introduced in Ruby 3.0. Parentheses are also
# allowed when forwarding arguments with the triple-dot syntax introduced
# in Ruby 2.7 as omitting them starts an endless range.
#
# @example EnforcedStyle: require_parentheses (default)
#
Expand Down
Expand Up @@ -5,15 +5,14 @@ module Cop
module Style
class MethodCallWithArgsParentheses
# Style omit_parentheses
# rubocop:disable Metrics/ModuleLength
# rubocop:disable Metrics/ModuleLength, Metrics/CyclomaticComplexity
module OmitParentheses
TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
OMIT_MSG = 'Omit parentheses for method calls with arguments.'
private_constant :OMIT_MSG

private

# rubocop:disable Metrics/CyclomaticComplexity
def omit_parentheses(node)
return unless node.parenthesized?
return if inside_endless_method_def?(node)
Expand All @@ -27,7 +26,6 @@ def omit_parentheses(node)
auto_correct(corrector, node)
end
end
# rubocop:enable Metrics/CyclomaticComplexity

def auto_correct(corrector, node)
if parentheses_at_the_end_of_multiline_call?(node)
Expand Down Expand Up @@ -114,7 +112,7 @@ def call_with_ambiguous_arguments?(node)
call_as_argument_or_chain?(node) ||
hash_literal_in_arguments?(node) ||
node.descendants.any? do |n|
ambigious_literal?(n) || logical_operator?(n) ||
n.forwarded_args_type? || ambigious_literal?(n) || logical_operator?(n) ||
call_with_braced_block?(n)
end
end
Expand Down Expand Up @@ -190,7 +188,7 @@ def inside_string_interpolation?(node)
node.ancestors.drop_while { |a| !a.begin_type? }.any?(&:dstr_type?)
end
end
# rubocop:enable Metrics/ModuleLength
# rubocop:enable Metrics/ModuleLength, Metrics/CyclomaticComplexity
end
end
end
Expand Down
20 changes: 20 additions & 0 deletions spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb
Expand Up @@ -361,6 +361,26 @@ module Foo

it_behaves_like 'endless methods', omit: true

context 'forwarded arguments in 2.7', :ruby27 do
it 'accepts parens for forwarded arguments' do
expect_no_offenses(<<~RUBY)
def delegated_call(...)
@proxy.call(...)
end
RUBY
end
end

context 'forwarded arguments in 3.0', :ruby30 do
it 'accepts parens for forwarded arguments' do
expect_no_offenses(<<~RUBY)
def method_missing(name, ...)
@proxy.call(name, ...)
end
RUBY
end
end

it 'register an offense for parens in method call without args' do
trailing_whitespace = ' '

Expand Down