Skip to content

Commit

Permalink
Merge pull request #9800 from dvandersluis/issue/9799
Browse files Browse the repository at this point in the history
[Fix #9799] Fix invalid line splitting by `Layout/LineLength` for `send` nodes with heredoc arguments
  • Loading branch information
koic committed May 16, 2021
2 parents 563d907 + 1d81c00 commit fcde5d7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/fix_fix_invalid_line_splitting_by.md
@@ -0,0 +1 @@
* [#9799](https://github.com/rubocop/rubocop/issues/9799): Fix invalid line splitting by `Layout/LineLength` for `send` nodes with heredoc arguments. ([@dvandersluis][])
16 changes: 16 additions & 0 deletions lib/rubocop/cop/mixin/check_line_breakable.rb
Expand Up @@ -76,11 +76,27 @@ def extract_first_element_over_column_limit(node, elements, max)

i = 0
i += 1 while within_column_limit?(elements[i], max, line)
i = shift_elements_for_heredoc_arg(node, elements, i)

return if i.nil?
return elements.first if i.zero?

elements[i - 1]
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.
def shift_elements_for_heredoc_arg(node, elements, index)
return index unless node.send_type?

heredoc_index = elements.index { |arg| (arg.str_type? || arg.dstr_type?) && arg.heredoc? }
return index unless heredoc_index
return nil if heredoc_index.zero?

heredoc_index >= index ? index : heredoc_index + 1
end

# @api private
def within_column_limit?(element, max, line)
element && element.loc.column <= max && element.loc.line == line
Expand Down
47 changes: 47 additions & 0 deletions spec/rubocop/cop/layout/line_length_spec.rb
Expand Up @@ -727,6 +727,53 @@ def baz(bar)
RUBY
end
end

context 'with a heredoc argument' do
it 'does not break up the line' do
args = 'x' * 25
expect_offense(<<~RUBY, args: args)
foo(<<~STRING, #{args}xxx)
_{args}^^^^ Line is too long. [44/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
expect_offense(<<~RUBY, args: args)
foo(abc, <<~STRING, #{args}xxx)
_{args}^^^^ Line is too long. [44/40]
STRING
RUBY

expect_correction(<<~RUBY)
foo(abc,#{trailing_whitespace}
<<~STRING, #{args}xxx)
STRING
RUBY
end
end

context 'and the heredoc is after the line should split' do
it 'can break up the line before the heredoc argument' do
args = 'x' * 34
expect_offense(<<~RUBY, args: args)
foo(#{args}, <<~STRING)
_{args} ^^^^^^^^^^ Line is too long. [50/40]
STRING
RUBY

expect_correction(<<~RUBY)
foo(#{args},#{trailing_whitespace}
<<~STRING)
STRING
RUBY
end
end
end
end

context 'array' do
Expand Down

0 comments on commit fcde5d7

Please sign in to comment.