diff --git a/changelog/fix_incorrect_autocorrect_for_style_single_line_methods.md b/changelog/fix_incorrect_autocorrect_for_style_single_line_methods.md new file mode 100644 index 00000000000..5e6e09297b9 --- /dev/null +++ b/changelog/fix_incorrect_autocorrect_for_style_single_line_methods.md @@ -0,0 +1 @@ +* [#9926](https://github.com/rubocop/rubocop/pull/9926): Fix an incorrect auto-correct for `Style/SingleLineMethods` when method body is enclosed in parentheses. ([@koic][]) diff --git a/lib/rubocop/cop/style/mutable_constant.rb b/lib/rubocop/cop/style/mutable_constant.rb index 1bb3bf3b886..e6e509a5d93 100644 --- a/lib/rubocop/cop/style/mutable_constant.rb +++ b/lib/rubocop/cop/style/mutable_constant.rb @@ -62,13 +62,12 @@ class MutableConstant < Base def on_casgn(node) _scope, _const_name, value = *node - on_assignment(value) - end + if value.nil? # This is only the case for `CONST += ...` or similarg66 + parent = node.parent + return unless parent.or_asgn_type? # We only care about `CONST ||= ...` - def on_or_asgn(node) - lhs, value = *node - - return unless lhs&.casgn_type? + value = parent.children.last + end on_assignment(value) end @@ -119,14 +118,13 @@ def autocorrect(corrector, node) end def mutable_literal?(value) - return false if value.nil? return false if frozen_regexp_or_range_literals?(value) value.mutable_literal? end def immutable_literal?(node) - node.nil? || frozen_regexp_or_range_literals?(node) || node.immutable_literal? + frozen_regexp_or_range_literals?(node) || node.immutable_literal? end def frozen_string_literal?(node) diff --git a/lib/rubocop/cop/style/single_line_methods.rb b/lib/rubocop/cop/style/single_line_methods.rb index 098dd7c4d7f..5e0f2a9bf68 100644 --- a/lib/rubocop/cop/style/single_line_methods.rb +++ b/lib/rubocop/cop/style/single_line_methods.rb @@ -72,17 +72,15 @@ def correct_to_endless?(body_node) end def correct_to_multiline(corrector, node) - each_part(node.body) do |part| - LineBreakCorrector.break_line_before( - range: part, node: node, corrector: corrector, - configured_width: configured_indentation_width - ) + if (body = node.body) && body.begin_type? && body.parenthesized_call? + break_line_before(corrector, node, body) + else + each_part(body) do |part| + break_line_before(corrector, node, part) + end end - LineBreakCorrector.break_line_before( - range: node.loc.end, node: node, corrector: corrector, - indent_steps: 0, configured_width: configured_indentation_width - ) + break_line_before(corrector, node, node.loc.end, indent_steps: 0) move_comment(node, corrector) end @@ -96,6 +94,13 @@ def correct_to_endless(corrector, node) corrector.replace(node, replacement) end + def break_line_before(corrector, node, range, indent_steps: 1) + LineBreakCorrector.break_line_before( + range: range, node: node, corrector: corrector, + configured_width: configured_indentation_width, indent_steps: indent_steps + ) + end + def each_part(body) return unless body diff --git a/spec/rubocop/cop/style/single_line_methods_spec.rb b/spec/rubocop/cop/style/single_line_methods_spec.rb index 96b4c57d7aa..de3899ef801 100644 --- a/spec/rubocop/cop/style/single_line_methods_spec.rb +++ b/spec/rubocop/cop/style/single_line_methods_spec.rb @@ -32,6 +32,19 @@ def @table.columns;#{trailing_whitespace} RUBY end + it 'registers an offense for a single-line method and method body is enclosed in parentheses' do + expect_offense(<<~RUBY) + def foo() (do_something) end + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid single-line method definitions. + RUBY + + expect_correction(<<~RUBY) + def foo()#{trailing_whitespace} + (do_something)#{trailing_whitespace} + end + RUBY + end + context 'when AllowIfMethodIsEmpty is disabled' do let(:cop_config) { { 'AllowIfMethodIsEmpty' => false } }