class RuboCop::Cop::Layout::LineContinuationLeadingSpace

Checks that strings broken over multiple lines (by a backslash) contain trailing spaces instead of leading spaces (default) or leading spaces instead of trailing spaces.

@example EnforcedStyle: trailing (default)

# bad
'this text contains a lot of' \
'               spaces'

# good
'this text contains a lot of               ' \
'spaces'

# bad
'this text is too' \
' long'

# good
'this text is too ' \
'long'

@example EnforcedStyle: leading

# bad
'this text contains a lot of               ' \
'spaces'

# good
'this text contains a lot of' \
'               spaces'

# bad
'this text is too ' \
'long'

# good
'this text is too' \
' long'

Public Instance Methods

on_dstr(node) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 46
def on_dstr(node)
  end_of_first_line = node.loc.expression.begin_pos - node.loc.expression.column

  raw_lines(node).each_cons(2) do |raw_line_one, raw_line_two|
    end_of_first_line += raw_line_one.length

    next unless continuation?(raw_line_one)

    if enforced_style_leading?
      investigate_leading_style(raw_line_one, end_of_first_line)
    else
      investigate_trailing_style(raw_line_two, end_of_first_line)
    end
  end
end

Private Instance Methods

continuation?(line) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 82
def continuation?(line)
  line.end_with?("\\\n")
end
enforced_style_leading?() click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 106
def enforced_style_leading?
  cop_config['EnforcedStyle'] == 'leading'
end
investigate_leading_style(first_line, end_of_first_line) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 68
def investigate_leading_style(first_line, end_of_first_line)
  matches = first_line.match(/(?<trailing_spaces>\s+)(?<ending>['"]\s*\\\n)/)
  return if matches.nil?

  add_offense(leading_offense_range(end_of_first_line, matches))
end
investigate_trailing_style(second_line, end_of_first_line) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 75
def investigate_trailing_style(second_line, end_of_first_line)
  matches = second_line.match(/\A(?<beginning>\s*['"])(?<leading_spaces>\s+)/)
  return if matches.nil?

  add_offense(trailing_offense_range(end_of_first_line, matches))
end
leading_offense_range(end_of_first_line, matches) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 86
def leading_offense_range(end_of_first_line, matches)
  end_pos = end_of_first_line - matches[:ending].length
  begin_pos = end_pos - matches[:trailing_spaces].length
  range_between(begin_pos, end_pos)
end
message(_range) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 98
def message(_range)
  if enforced_style_leading?
    'Move trailing spaces to the start of next line.'
  else
    'Move leading spaces to the end of previous line.'
  end
end
raw_lines(node) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 64
def raw_lines(node)
  processed_source.raw_source.lines[node.first_line - 1, line_range(node).size]
end
trailing_offense_range(end_of_first_line, matches) click to toggle source
# File lib/rubocop/cop/layout/line_continuation_leading_space.rb, line 92
def trailing_offense_range(end_of_first_line, matches)
  begin_pos = end_of_first_line + matches[:beginning].length
  end_pos = begin_pos + matches[:leading_spaces].length
  range_between(begin_pos, end_pos)
end