Skip to content

Commit

Permalink
Fix Layout/TrailingWhitespace auto-correction in heredoc
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre authored and mergify[bot] committed Oct 16, 2020
1 parent 83dffcf commit 5f3bbea
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
* [#8661](https://github.com/rubocop-hq/rubocop/pull/8661): Fix an incorrect auto-correct for `Style/MultilineTernaryOperator` when returning a multiline ternary operator expression. ([@koic][])
* [#8526](https://github.com/rubocop-hq/rubocop/pull/8526): Fix a false positive for `Style/CaseEquality` cop when the receiver is not a camel cased constant. ([@koic][])
* [#8673](https://github.com/rubocop-hq/rubocop/issues/8673): Fix the JSON parse error when specifying `--format=json` and `--stdin` options. ([@koic][])
* [#8692](https://github.com/rubocop-hq/rubocop/pull/8692): Fix `Layout/TrailingWhitespace` auto-correction in heredoc. ([@marcandre][])

### Changes

Expand Down
11 changes: 11 additions & 0 deletions docs/modules/ROOT/pages/cops_layout.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6369,6 +6369,17 @@ x = 0
code = <<~RUBY
x = 0
RUBY
# ok
code = <<~RUBY
x = 0 #{}
RUBY
# good
trailing_whitespace = ' '
code = <<~RUBY
x = 0#{trailing_whitespace}
RUBY
----

==== AllowInHeredoc: true (default)
Expand Down
39 changes: 29 additions & 10 deletions lib/rubocop/cop/layout/trailing_whitespace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ module Layout
# x = 0
# RUBY
#
# # ok
# code = <<~RUBY
# x = 0 #{}
# RUBY
#
# # good
# trailing_whitespace = ' '
# code = <<~RUBY
# x = 0#{trailing_whitespace}
# RUBY
#
# @example AllowInHeredoc: true (default)
# # The line in this example contains spaces after the 0.
# # good
Expand All @@ -35,28 +46,36 @@ class TrailingWhitespace < Base
MSG = 'Trailing whitespace detected.'

def on_new_investigation
heredoc_ranges = extract_heredoc_ranges(processed_source.ast)
@heredoc_ranges = extract_heredoc_ranges(processed_source.ast)
processed_source.lines.each_with_index do |line, index|
lineno = index + 1

next unless line.end_with?(' ', "\t")
next if skip_heredoc? && inside_heredoc?(heredoc_ranges, lineno)

range = offense_range(lineno, line)
add_offense(range) do |corrector|
corrector.remove(range)
end
process_line(line, index + 1)
end
end

private

def process_line(line, lineno)
in_heredoc = inside_heredoc?(lineno)
return if skip_heredoc? && in_heredoc

range = offense_range(lineno, line)
add_offense(range) do |corrector|
if in_heredoc
corrector.insert_after(range, '#{}') # rubocop:disable Lint/InterpolationCheck
else
corrector.remove(range)
end
end
end

def skip_heredoc?
cop_config.fetch('AllowInHeredoc', false)
end

def inside_heredoc?(heredoc_ranges, line_number)
heredoc_ranges.any? { |r| r.include?(line_number) }
def inside_heredoc?(line_number)
@heredoc_ranges.any? { |r| r.include?(line_number) }
end

def extract_heredoc_ranges(ast)
Expand Down
21 changes: 21 additions & 0 deletions spec/rubocop/cop/layout/trailing_whitespace_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,25 @@
expect(offenses.size).to eq(1)
end
end

context 'when `AllowInHeredoc` is set to false' do
let(:cop_config) { { 'AllowInHeredoc' => false } }

it 'corrects safely trailing whitespace in a heredoc string' do
expect_offense(<<~RUBY)
x = <<~EXAMPLE
has trailing#{trailing_whitespace}
^ Trailing whitespace detected.
no trailing
EXAMPLE
RUBY

expect_correction(<<~RUBY)
x = <<~EXAMPLE
has trailing \#{}
no trailing
EXAMPLE
RUBY
end
end
end

0 comments on commit 5f3bbea

Please sign in to comment.