module Prism
  BACKEND: :CEXT | :FFI
  VERSION: String

  class CurrentVersionError < ArgumentError
    def initialize: (String version) -> void
  end

  # Methods taking a Ruby source code string:
  <%-
    {
      parse: "ParseResult",
      profile: "nil",
      lex: "LexResult",
      lex_compat: "LexCompat::Result",
      parse_lex: "ParseLexResult",
      dump: "String",
      parse_comments: "Array[comment]",
      parse_success?: "bool",
      parse_failure?: "bool",
    }.each do |method, return_type|
  -%>

  def self.<%= method %>: (
    String source,
    ?encoding: Encoding | false,
    ?filepath: String,
    ?freeze: bool,
    ?frozen_string_literal: bool,
    ?line: Integer,
    ?main_script: bool,
    ?offset: Integer,
    ?scopes: Array[Array[Symbol]],
    ?verbose: bool
  ) -> <%= return_type %>
  <%- end -%>

  def self.load: (
    String source,
    String serialized,
    ?bool freeze
  ) -> ParseResult

  def self.lex_ripper: (
    String source
  ) -> Array[[[Integer, Integer], Symbol, String, untyped]]

  # Methods taking a path to a Ruby file:
  <%-
    {
      parse_file: "ParseResult",
      profile_file: "nil",
      lex_file: "LexResult",
      parse_lex_file: "ParseLexResult",
      dump_file: "String",
      parse_file_comments: "Array[comment]",
      parse_file_success?: "bool",
      parse_file_failure?: "bool",
    }.each do |method, return_type|
  -%>

  def self.<%= method %>: (
    String filepath,
    ?encoding: Encoding | false,
    ?freeze: bool,
    ?frozen_string_literal: bool,
    ?line: Integer,
    ?main_script: bool,
    ?offset: Integer,
    ?scopes: Array[Array[Symbol]],
    ?verbose: bool
  ) -> <%= return_type %>
  <%- end -%>

  interface _Stream
    def gets: (?Integer integer) -> (String | nil)
  end

  def self.parse_stream: (
    _Stream stream,
    ?encoding: Encoding | false,
    ?filepath: String,
    ?freeze: bool,
    ?frozen_string_literal: bool,
    ?line: Integer,
    ?main_script: bool,
    ?offset: Integer,
    ?scopes: Array[Array[Symbol]],
    ?verbose: bool
  ) -> ParseResult

  def self.scope: (?locals: Array[Symbol], ?forwarding: Array[Symbol]) -> Scope
end
