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

Calls with braces in interpolation for Style/MethodCallWithArgsParentheses #9629

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 @@
* [#9629](https://github.com/rubocop/rubocop/issues/9629): Add `AllowParenthesesInStringInterpolation` configuration to `Style/MethodCallWithArgsParentheses` to allow parenthesized calls in string interpolation. ([@gsamokovarov][])
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -3675,6 +3675,7 @@ Style/MethodCallWithArgsParentheses:
AllowParenthesesInMultilineCall: false
AllowParenthesesInChaining: false
AllowParenthesesInCamelCaseMethod: false
AllowParenthesesInStringInterpolation: false
EnforcedStyle: require_parentheses
SupportedStyles:
- require_parentheses
Expand Down
16 changes: 16 additions & 0 deletions lib/rubocop/cop/style/method_call_with_args_parentheses.rb
Expand Up @@ -146,6 +146,22 @@ module Style
#
# # good
# Array 1
#
# @example AllowParenthesesInStringInterpolation: false (default)
#
# # bad
# "#{t('this.is.bad')}"
#
# # good
# "#{t 'this.is.better'}"
#
# @example AllowParenthesesInStringInterpolation: true
#
# # good
# "#{t('this.is.good')}"
#
# # good
# "#{t 'this.is.also.good'}"
class MethodCallWithArgsParentheses < Base
require_relative 'method_call_with_args_parentheses/omit_parentheses'
require_relative 'method_call_with_args_parentheses/require_parentheses'
Expand Down
Expand Up @@ -5,25 +5,29 @@ module Cop
module Style
class MethodCallWithArgsParentheses
# Style omit_parentheses
# rubocop:disable Metrics/ModuleLength
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)
return if node.implicit_call?
return if super_call_without_arguments?(node)
return if allowed_camel_case_method_call?(node)
return if legitimate_call_with_parentheses?(node)
return if allowed_string_interpolation_method_call?(node)

add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
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 @@ -53,6 +57,11 @@ def allowed_camel_case_method_call?(node)
cop_config['AllowParenthesesInCamelCaseMethod'])
end

def allowed_string_interpolation_method_call?(node)
cop_config['AllowParenthesesInStringInterpolation'] &&
inside_string_interpolation?(node)
end

def parentheses_at_the_end_of_multiline_call?(node)
node.multiline? &&
node.loc.begin.source_line
Expand Down Expand Up @@ -172,7 +181,12 @@ def assigned_before?(node, target)
node.assignment? &&
node.loc.operator.begin < target.loc.begin
end

def inside_string_interpolation?(node)
node.ancestors.drop_while { |a| !a.begin_type? }.any?(&:dstr_type?)
end
end
# rubocop:enable Metrics/ModuleLength
end
end
end
Expand Down
27 changes: 27 additions & 0 deletions spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb
Expand Up @@ -467,6 +467,17 @@ def foo
RUBY
end

it 'register an offense for parens in string interpolation' do
expect_offense(<<~'RUBY')
"#{t('no.parens')}"
^^^^^^^^^^^^^ Omit parentheses for method calls with arguments.
RUBY

expect_correction(<<~'RUBY')
"#{t 'no.parens'}"
RUBY
end

it 'register an offense in complex conditionals' do
expect_offense(<<~RUBY)
def foo
Expand Down Expand Up @@ -831,6 +842,22 @@ def seatle_style arg: default(42)
end
end

context 'allowing parens in string interpolation' do
let(:cop_config) do
{
'EnforcedStyle' => 'omit_parentheses',
'AllowParenthesesInStringInterpolation' => true
}
end

it 'accepts parens for camel-case method names' do
expect_no_offenses(<<~'RUBY')
"#{t('this.is.good')}"
"#{t 'this.is.also.good'}"
RUBY
end
end

context 'when inspecting macro methods with IncludedMacros' do
let(:cop_config) do
{
Expand Down