class RBI::Parser

def parse(source, file:)

: (String source, file: String) -> Tree
def parse(source, file:)
  result = Prism.parse(source)
  unless result.success?
    message = result.errors.map { |e| "#{e.message}." }.join(" ")
    error = result.errors.first
    location = Loc.new(file: file, begin_line: error.location.start_line, begin_column: error.location.start_column)
    raise ParseError.new(message, location)
  end
  visitor = TreeBuilder.new(source, comments: result.comments, file: file)
  visitor.visit(result.value)
  visitor.tree
rescue ParseError => e
  raise e
rescue => e
  last_node = visitor&.last_node
  last_location = if last_node
    Loc.from_prism(file, last_node.location)
  else
    Loc.new(file: file)
  end
  exception = UnexpectedParserError.new(e, last_location)
  exception.print_debug
  raise exception
end

def parse_file(path)

: (String path) -> Tree
def parse_file(path)
  Parser.new.parse_file(path)
end

def parse_file(path)

: (String path) -> Tree
def parse_file(path)
  parse(::File.read(path), file: path)
end

def parse_files(paths)

: (Array[String] paths) -> Array[Tree]
def parse_files(paths)
  parser = Parser.new
  paths.map { |path| parser.parse_file(path) }
end

def parse_string(string)

: (String string) -> Tree
def parse_string(string)
  Parser.new.parse_string(string)
end

def parse_string(string)

: (String string) -> Tree
def parse_string(string)
  parse(string, file: "-")
end

def parse_strings(strings)

: (Array[String] strings) -> Array[Tree]
def parse_strings(strings)
  parser = Parser.new
  strings.map { |string| parser.parse_string(string) }
end