module YARP

def self.dump(code, filepath = nil)

Mirror the YARP.dump API by using the serialization API.
def self.dump(code, filepath = nil)
  dump_internal(code, code.bytesize, filepath)
end

def self.dump_file(filepath)

Mirror the YARP.dump_file API by using the serialization API.
def self.dump_file(filepath)
  LibRubyParser.with_string(filepath) do |string|
    dump_internal(string.source, string.length, filepath)
  end
end

def self.dump_internal(source, source_size, filepath)

def self.dump_internal(source, source_size, filepath)
  LibRubyParser.with_buffer do |buffer|
    metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
    LibRubyParser.yp_parse_serialize(source, source_size, buffer, metadata)
    buffer.to_ruby_string
  end
end

def self.lex(code, filepath = nil)

Mirror the YARP.lex API by using the serialization API.
def self.lex(code, filepath = nil)
  LibRubyParser.with_buffer do |buffer|
    LibRubyParser.yp_lex_serialize(code, code.bytesize, filepath, buffer)
    source = Source.new(code)
    Serialize.load_tokens(source, buffer.to_ruby_string).with_source(source)
  end
end

def self.lex_compat(source, filepath = "")

same way, it's going to always return the NONE state.
The only difference is that since we don't keep track of lexer state in the
Returns an array of tokens that closely resembles that of the Ripper lexer.
def self.lex_compat(source, filepath = "")
  LexCompat.new(source, filepath).result
end

def self.lex_file(filepath)

Mirror the YARP.lex_file API by using the serialization API.
def self.lex_file(filepath)
  LibRubyParser.with_string(filepath) { |string| lex(string.read, filepath) }
end

def self.lex_ripper(source)

invalid.
returns the same tokens. Raises SyntaxError if the syntax in source is
This lexes with the Ripper lex. It drops any space events but otherwise
def self.lex_ripper(source)
  previous = []
  results = []
  Ripper.lex(source, raise_errors: true).each do |token|
    case token[1]
    when :on_sp
      # skip
    when :on_tstring_content
      if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
        previous[2] << token[2]
      else
        results << token
        previous = token
      end
    when :on_words_sep
      if previous[1] == :on_words_sep
        previous[2] << token[2]
      else
        results << token
        previous = token
      end
    else
      results << token
      previous = token
    end
  end
  results
end

def self.load(source, serialized)

Load the serialized AST using the source as a reference into a tree.
def self.load(source, serialized)
  Serialize.load(source, serialized)
end

def self.parse(code, filepath = nil)

Mirror the YARP.parse API by using the serialization API.
def self.parse(code, filepath = nil)
  YARP.load(code, dump(code, filepath)).with_source(Source.new(code))
end

def self.parse_file(filepath)

it is available.
native strings instead of Ruby strings because it allows us to use mmap when
Mirror the YARP.parse_file API by using the serialization API. This uses
def self.parse_file(filepath)
  LibRubyParser.with_string(filepath) { |string| parse(string.read, filepath) }
end