class RuboCop::Cop::Layout::LineContinuationLeadingSpace

‘ long’
‘this text is too’ <br># good
’long’
‘this text is too ’ <br># bad
’ spaces’
‘this text contains a lot of’ <br># good
’spaces’
‘this text contains a lot of ’ <br># bad
@example EnforcedStyle: leading
’long’
‘this text is too ’ <br># good
’ long’
‘this text is too’ <br># bad
’spaces’
‘this text contains a lot of ’ <br># good
’ spaces’
‘this text contains a lot of’ <br># bad
@example EnforcedStyle: trailing (default)
instead of trailing spaces.
trailing spaces instead of leading spaces (default) or leading spaces
Checks that strings broken over multiple lines (by a backslash) contain

def self.autocorrect_incompatible_with

delimiters, in order to handle escaping for quotes within the string.
takes the original string content and transforms it, rather than just modifying the
`Layout/LineContinuationLeadingSpace` performs. This is because `Style/StringLiterals`
`Style/StringLiterals` undoes the moving of spaces that
When both cops are activated and run in the same iteration of the correction loop,
def self.autocorrect_incompatible_with
  [Style::StringLiterals]
end

def autocorrect(corrector, offense_range, insert_pos, spaces)

def autocorrect(corrector, offense_range, insert_pos, spaces)
  corrector.remove(offense_range)
  corrector.replace(range_between(insert_pos, insert_pos), spaces)
end

def continuation?(line, line_num, node)

def continuation?(line, line_num, node)
  return false unless line.end_with?("\\\n")
  # Ensure backslash isn't part of a token spanning to the next line.
  node.children.none? { |c| (c.first_line...c.last_line).cover?(line_num) && c.multiline? }
end

def enforced_style_leading?

def enforced_style_leading?
  cop_config['EnforcedStyle'] == 'leading'
end

def investigate(first_line, second_line, end_of_first_line)

def investigate(first_line, second_line, end_of_first_line)
  if enforced_style_leading?
    investigate_leading_style(first_line, second_line, end_of_first_line)
  else
    investigate_trailing_style(first_line, second_line, end_of_first_line)
  end
end

def investigate_leading_style(first_line, second_line, end_of_first_line)

def investigate_leading_style(first_line, second_line, end_of_first_line)
  matches = first_line.match(LEADING_STYLE_OFFENSE)
  return if matches.nil?
  offense_range = leading_offense_range(end_of_first_line, matches)
  add_offense(offense_range) do |corrector|
    insert_pos = end_of_first_line + second_line[LINE_2_BEGINNING].length
    autocorrect(corrector, offense_range, insert_pos, matches[:trailing_spaces])
  end
end

def investigate_trailing_style(first_line, second_line, end_of_first_line)

def investigate_trailing_style(first_line, second_line, end_of_first_line)
  matches = second_line.match(TRAILING_STYLE_OFFENSE)
  return if matches.nil?
  offense_range = trailing_offense_range(end_of_first_line, matches)
  add_offense(offense_range) do |corrector|
    insert_pos = end_of_first_line - first_line[LINE_1_ENDING].length
    autocorrect(corrector, offense_range, insert_pos, matches[:leading_spaces])
  end
end

def leading_offense_range(end_of_first_line, matches)

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

def message(_range)

def message(_range)
  if enforced_style_leading?
    'Move trailing spaces to the start of the next line.'
  else
    'Move leading spaces to the end of the previous line.'
  end
end

def on_dstr(node)

def on_dstr(node)
  # Quick check if we possibly have line continuations.
  return unless node.source.include?('\\')
  end_of_first_line = node.source_range.begin_pos - node.source_range.column
  lines = raw_lines(node)
  lines.each_cons(2).with_index(node.first_line) do |(raw_line_one, raw_line_two), line_num|
    end_of_first_line += raw_line_one.length
    next unless continuation?(raw_line_one, line_num, node)
    investigate(raw_line_one, raw_line_two, end_of_first_line)
  end
end

def raw_lines(node)

def raw_lines(node)
  processed_source.raw_source.lines[node.first_line - 1, line_range(node).size]
end

def trailing_offense_range(end_of_first_line, matches)

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