diff --git a/changelog/fix_an_incorrect_autocorrect_for_layout_line_length.md b/changelog/fix_an_incorrect_autocorrect_for_layout_line_length.md new file mode 100644 index 00000000000..248e9ff3e5c --- /dev/null +++ b/changelog/fix_an_incorrect_autocorrect_for_layout_line_length.md @@ -0,0 +1 @@ +* [#9882](https://github.com/rubocop/rubocop/pull/9882): Fix an incorrect auto-correct for `Layout/LineLength` when using heredoc as the first method argument and omitting parentheses. ([@koic][]) diff --git a/lib/rubocop/cop/mixin/check_line_breakable.rb b/lib/rubocop/cop/mixin/check_line_breakable.rb index e921502ef78..7329fe6402a 100644 --- a/lib/rubocop/cop/mixin/check_line_breakable.rb +++ b/lib/rubocop/cop/mixin/check_line_breakable.rb @@ -72,7 +72,9 @@ def extract_first_element_over_column_limit(node, elements, max) # If a `send` node is not parenthesized, don't move the first element, because it # can result in changed behavior or a syntax error. - elements = elements.drop(1) if node.send_type? && !node.parenthesized? + if node.send_type? && !node.parenthesized? && !first_argument_is_heredoc?(node) + elements = elements.drop(1) + end i = 0 i += 1 while within_column_limit?(elements[i], max, line) @@ -84,6 +86,13 @@ def extract_first_element_over_column_limit(node, elements, max) elements[i - 1] end + # @api private + def first_argument_is_heredoc?(node) + first_argument = node.first_argument + + first_argument.respond_to?(:heredoc?) && first_argument.heredoc? + end + # @api private # If a send node contains a heredoc argument, splitting cannot happen # after the heredoc or else it will cause a syntax error. diff --git a/spec/rubocop/cop/layout/line_length_spec.rb b/spec/rubocop/cop/layout/line_length_spec.rb index a0a3bcee67e..5ad3d910af6 100644 --- a/spec/rubocop/cop/layout/line_length_spec.rb +++ b/spec/rubocop/cop/layout/line_length_spec.rb @@ -768,6 +768,17 @@ def baz(bar) expect_no_corrections end + it 'does not break up the line when parentheses are omitted' do + args = 'x' * 25 + expect_offense(<<~RUBY, args: args) + foo <<~STRING, #{args}xxx + _{args}^^^ Line is too long. [43/40] + STRING + RUBY + + expect_no_corrections + end + context 'and other arguments before the heredoc' do it 'can break up the line before the heredoc argument' do args = 'x' * 20