class Parser::Lexer::Dedenter

def dedent(string)


Of course, lexer could do it but once again: it's all because of dedenting.
It has no effect for non-squiggly heredocs, i.e. it simply removes "\\\n"

but it has to be concatenated __after__ dedenting.
This is important because technically it's a single line,

calls this method only once with a string " a\\\n b\n"
HERE
b
a\
<<-HERE

However, the following heredoc:

this method gets called with " a\n" and " b\n"
HERE
b
a
<<-HERE
For a heredoc like
def dedent(string)
  original_encoding = string.encoding
  # Prevent the following error when processing binary encoded source.
  # "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
  lines = string.force_encoding(Encoding::BINARY).split("\\\n")
  if lines.length == 1
    # If the line continuation sequence was found but there is no second
    # line, it was not really a line continuation and must be ignored.
    lines = [string.force_encoding(original_encoding)]
  else
    lines.map! {|s| s.force_encoding(original_encoding) }
  end
  if @at_line_begin
    lines_to_dedent = lines
  else
    _first, *lines_to_dedent = lines
  end
  lines_to_dedent.each do |line|
    left_to_remove = @dedent_level
    remove = 0
    line.each_char do |char|
      break if left_to_remove <= 0
      case char
      when ?\s
        remove += 1
        left_to_remove -= 1
      when ?\t
        break if TAB_WIDTH * (remove / TAB_WIDTH + 1) > @dedent_level
        remove += 1
        left_to_remove -= TAB_WIDTH
      else
        # no more spaces or tabs
        break
      end
    end
    line.slice!(0, remove)
  end
  string.replace(lines.join)
  @at_line_begin = string.end_with?("\n")
end

def initialize(dedent_level)

def initialize(dedent_level)
  @dedent_level = dedent_level
  @at_line_begin = true
  @indent_level  = 0
end

def interrupt

def interrupt
  @at_line_begin = false
end