From 60834d408504c106b250a89ccf657cacec8a3148 Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Sat, 15 May 2021 14:05:35 -0400 Subject: [PATCH] [Fix #9749] Fix autocorrection for `Layout/LineLength` to not move the first argument of an unparenthesized `send` node to the next line, which changes behaviour. Previously in #9382, `Layout/LineLength` was fixed for unparenthesized `send` nodes with a hash, but now it is applied to all argument types. --- ...fix_autocorrection_for_layoutlinelength.md | 1 + lib/rubocop/cop/mixin/check_line_breakable.rb | 6 ++-- spec/rubocop/cop/layout/line_length_spec.rb | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_fix_autocorrection_for_layoutlinelength.md diff --git a/changelog/fix_fix_autocorrection_for_layoutlinelength.md b/changelog/fix_fix_autocorrection_for_layoutlinelength.md new file mode 100644 index 00000000000..2f03b3fbb81 --- /dev/null +++ b/changelog/fix_fix_autocorrection_for_layoutlinelength.md @@ -0,0 +1 @@ +* [#9749](https://github.com/rubocop/rubocop/issues/9749): Fix autocorrection for `Layout/LineLength` to not move the first argument of an unparenthesized `send` node to the next line, which changes behaviour. ([@dvandersluis][]) diff --git a/lib/rubocop/cop/mixin/check_line_breakable.rb b/lib/rubocop/cop/mixin/check_line_breakable.rb index 0e6bad0a106..b0822b18911 100644 --- a/lib/rubocop/cop/mixin/check_line_breakable.rb +++ b/lib/rubocop/cop/mixin/check_line_breakable.rb @@ -70,9 +70,9 @@ def extract_breakable_node_from_elements(node, elements, max) def extract_first_element_over_column_limit(node, elements, max) line = node.first_line - # If the first argument is a hash pair but the method is not parenthesized, - # the argument cannot be moved to another line because it cause a syntax error. - elements.shift if node.send_type? && !node.parenthesized? && elements.first.pair_type? + # 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? i = 0 i += 1 while within_column_limit?(elements[i], max, line) diff --git a/spec/rubocop/cop/layout/line_length_spec.rb b/spec/rubocop/cop/layout/line_length_spec.rb index cc2d919cc24..99fc31a3a04 100644 --- a/spec/rubocop/cop/layout/line_length_spec.rb +++ b/spec/rubocop/cop/layout/line_length_spec.rb @@ -605,6 +605,34 @@ def baz(bar) end end + context 'when unparenthesized' do + context 'when there is one argument' do + it 'does not autocorrect' do + expect_offense(<<~RUBY) + method_call xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ^^ Line is too long. [42/40] + RUBY + + expect_no_corrections + end + end + + context 'when there are multiple arguments' do + it 'splits the line after the first element' do + args = 'x' * 28 + expect_offense(<<~RUBY, args: args) + method_call #{args}, abc + _{args}^^^^^ Line is too long. [45/40] + RUBY + + expect_correction(<<~RUBY, loop: false) + method_call #{args},#{trailing_whitespace} + abc + RUBY + end + end + end + context 'when call with hash on same line' do it 'adds an offense only to outer and autocorrects it' do expect_offense(<<~RUBY)