123456789_123456789_123456789_123456789_123456789_

Module: Prism

Relationships & Source Files
Namespace Children
Modules:
Classes:
Exceptions:
Defined in: lib/prism.rb,
lib/prism/desugar_compiler.rb,
lib/prism/ffi.rb,
lib/prism/lex_compat.rb,
lib/prism/node_ext.rb,
lib/prism/node_find.rb,
lib/prism/parse_result.rb,
lib/prism/pattern.rb,
lib/prism/relocation.rb,
lib/prism/string_query.rb,
lib/prism/translation.rb,
lib/prism/parse_result/comments.rb,
lib/prism/parse_result/errors.rb,
lib/prism/parse_result/newlines.rb,
lib/prism/translation/parser.rb,
lib/prism/translation/parser_current.rb,
lib/prism/translation/parser_versions.rb,
lib/prism/translation/ripper.rb,
lib/prism/translation/ruby_parser.rb,
lib/prism/translation/parser/builder.rb,
lib/prism/translation/parser/compiler.rb,
lib/prism/translation/parser/lexer.rb,
lib/prism/translation/ripper/filter.rb,
lib/prism/translation/ripper/lexer.rb,
lib/prism/translation/ripper/sexp.rb,
prism/extension.c

Overview

Grab up references to all of the constants that we are going to need to reference throughout this extension.

Constant Summary

  • BACKEND =

    The FFI backend is used on other Ruby implementations.

    # File 'lib/prism.rb', line 137
    :FFI
  • DUMP_OPTIONS_KEYS = private

    The set of options that are understood by the parsing APIs. Note that raise_error is not listed here because it is deleted from the options hash by raise_error_format_type before the options are dumped.

    # File 'lib/prism/ffi.rb', line 602
    [:command_line, :encoding, :filepath, :freeze, :frozen_string_literal, :line, :main_script, :partial_script, :scopes, :version].freeze
  • VERSION =

    The version constant is set by reading the result of calling pm_version.

    # File 'lib/prism/ffi.rb', line 258
    LibRubyParser.pm_version.read_string.freeze

Class Method Summary

Class Method Details

.dump(source, **options) ⇒ String

Dump the AST corresponding to the given string to a string. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 529

static VALUE
dump(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    const uint8_t *source = (const uint8_t *) RSTRING_PTR(string);
    size_t length = RSTRING_LEN(string);

#ifdef PRISM_BUILD_DEBUG
    char* dup = xmalloc(length);
    memcpy(dup, source, length);
    source = (const uint8_t *) dup;
#endif

    result_t result = dump_input(source, length, options, NULL);

#ifdef PRISM_BUILD_DEBUG
#ifdef xfree_sized
    xfree_sized(dup, length);
#else
    xfree(dup);
#endif
#endif

    pm_options_free(options);
    return result_get(result);
}

.dump_common(string, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 420

def dump_common(string, options) # :nodoc:
  if (format_type = raise_error_format_type(options))
    raise_error(string, options, format_type)
  end

  LibRubyParser::PrismBuffer.with do |buffer|
    LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options))

    dumped = buffer.read
    dumped.freeze if options.fetch(:freeze, false)

    dumped
  end
end

.dump_file(filepath, **options) ⇒ String

Dump the AST corresponding to the given file to a string. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 565

static VALUE
dump_file(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = dump_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.dump_options(options) (private)

Convert the given options into a serialized options string.

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 606

def dump_options(options)
  unknown_keys = options.keys - DUMP_OPTIONS_KEYS
  raise ArgumentError, "unknown keyword: #{unknown_keys.first}" unless unknown_keys.empty?

  template = +""
  values = []

  template << "L"
  if (filepath = options[:filepath])
    values.push(filepath.bytesize, filepath.b)
    template << "A*"
  else
    values << 0
  end

  template << "l"
  values << options.fetch(:line, 1)

  template << "L"
  if (encoding = options[:encoding])
    name = encoding.is_a?(Encoding) ? encoding.name : encoding
    values.push(name.bytesize, name.b)
    template << "A*"
  else
    values << 0
  end

  template << "C"
  values << (options.fetch(:frozen_string_literal, false) ? 1 : 0)

  template << "C"
  values << dump_options_command_line(options)

  template << "C"
  values << dump_options_version(options[:version])

  template << "C"
  values << (options[:encoding] == false ? 1 : 0)

  template << "C"
  values << (options.fetch(:main_script, false) ? 1 : 0)

  template << "C"
  values << (options.fetch(:partial_script, false) ? 1 : 0)

  template << "C"
  values << (options.fetch(:freeze, false) ? 1 : 0)

  template << "L"
  if (scopes = options[:scopes])
    values << scopes.length

    scopes.each do |scope|
      locals = nil
      forwarding = 0

      case scope
      when Array
        locals = scope
      when Scope
        locals = scope.locals

        scope.forwarding.each do |forward|
          case forward
          when :*     then forwarding |= 0x1
          when :**    then forwarding |= 0x2
          when :&     then forwarding |= 0x4
          when :"..." then forwarding |= 0x8
          else raise ArgumentError, "invalid forwarding value: #{forward}"
          end
        end
      else
        raise TypeError, "wrong argument type #{scope.class.inspect} (expected Array or Prism::Scope)"
      end

      template << "L"
      values << locals.length

      template << "C"
      values << forwarding

      locals.each do |local|
        name = local.name
        template << "L"
        values << name.bytesize

        template << "A*"
        values << name.b
      end
    end
  else
    values << 0
  end

  values.pack(template)
end

.dump_options_command_line(options) (private)

Return the value that should be dumped for the command_line option.

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 547

def dump_options_command_line(options)
  command_line = options.fetch(:command_line, "")
  raise ArgumentError, "command_line must be a string" unless command_line.is_a?(String)

  command_line.each_char.inject(0) do |value, char|
    case char
    when "a" then value | 0b000001
    when "e" then value | 0b000010
    when "l" then value | 0b000100
    when "n" then value | 0b001000
    when "p" then value | 0b010000
    when "x" then value | 0b100000
    else raise ArgumentError, "invalid command_line option: #{char}"
    end
  end
end

.dump_options_version(version) (private)

Return the value that should be dumped for the version option.

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 565

def dump_options_version(version)
  case version
  when "current"
    version_string_to_number(RUBY_VERSION) || raise(CurrentVersionError, RUBY_VERSION)
  when "latest", nil
    0 # Handled in pm_parser_init
  when "nearest"
    dump = version_string_to_number(RUBY_VERSION)
    return dump if dump
    if RUBY_VERSION < "3.3"
      version_string_to_number("3.3")
    else
      0 # Handled in pm_parser_init
    end
  else
    version_string_to_number(version) || raise(ArgumentError, "invalid version: #{version}")
  end
end

.find(callable, rubyvm: !!defined?(RubyVM)))

Given a Method, UnboundMethod, Proc, or Thread::Backtrace::Location, returns the Prism node representing it. On CRuby, this uses node_id for an exact match. On other implementations, it falls back to best-effort matching by source location line number.

[ GitHub ]

  
# File 'lib/prism.rb', line 94

def self.find(callable, rubyvm: !!defined?(RubyVM))
  NodeFind.find(callable, rubyvm)
end

.lex(source, **options) ⇒ LexResult

Return a ::Prism::LexResult instance that contains an array of ::Prism::Token instances corresponding to the given string. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 977

static VALUE
lex(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    result_t result = parse_lex_input((const uint8_t *) RSTRING_PTR(string), RSTRING_LEN(string), options, NULL, false);
    pm_options_free(options);

    return result_get(result);
}

.lex_common(string, code, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 435

def lex_common(string, code, options) # :nodoc:
  format_type = raise_error_format_type(options)

  LibRubyParser::PrismBuffer.with do |buffer|
    LibRubyParser.pm_serialize_lex(buffer.pointer, string.pointer, string.length, dump_options(options))
    result = Serialize.load_lex(code, buffer.read, options.fetch(:freeze, false))

    raise_error(string, options, format_type) if format_type && result.failure?
    result
  end
end

.lex_compat(source, **options) ⇒ LexCompat::Result

Returns a parse result whose value is an array of tokens that closely resembles the return value of Ripper.lex.

For supported options, see .parse.

[ GitHub ]

  
# File 'lib/prism.rb', line 74

def self.lex_compat(source, **options)
  LexCompat.new(source, **options).result # steep:ignore
end

.lex_file(filepath, **options) ⇒ LexResult

Return a ::Prism::LexResult instance that contains an array of ::Prism::Token instances corresponding to the given file. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 996

static VALUE
lex_file(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = parse_lex_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath), false);
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.load(source, serialized, freeze) ⇒ ParseResult

Load the serialized AST using the source as a reference into a tree.

[ GitHub ]

  
# File 'lib/prism.rb', line 84

def self.load(source, serialized, freeze = false)
  Serialize.load_parse(source, serialized, freeze)
end

.parse(source, **options) ⇒ ParseResult

Parse the given string and return a ::Prism::ParseResult instance. The options that are supported are:

  • command_line - either nil or a string of the various options that were set on the command line. Valid values are combinations of "a", "l", "n", "p", and "x".
  • encoding - the encoding of the source being parsed. This should be an encoding or nil.
  • filepath - the filepath of the source being parsed. This should be a string or nil.
  • freeze - whether or not to deeply freeze the AST. This should be a boolean or nil.
  • frozen_string_literal - whether or not the frozen string literal pragma has been set. This should be a boolean or nil.
  • line - the line number that the parse starts on. This should be an integer or nil. Note that this is 1-indexed.
  • main_script - a boolean indicating whether or not the source being parsed is the main script being run by the interpreter. This controls whether or not shebangs are parsed for additional flags and whether or not the parser will attempt to find a matching shebang if the first one does not contain the word "ruby".
  • partial_script - when the file being parsed is considered a "partial" script, jumps will not be marked as errors if they are not contained within loops/blocks. This is used in the case that you're parsing a script that you know will be embedded inside another script later, but you do not have that context yet. For example, when parsing an ERB template that will be evaluated inside another script.
  • .raise_error - either nil, true, or a symbol indicating that an error should be raised if the source contains any errors. The message of the error will include the source of the lines that contain errors when possible, and the value of this option controls how those lines are formatted. Valid values are :plain (no formatting), :style (bold formatting), and :color (bold and color formatting). When true is given, the formatting is determined by whether or not $stderr is a terminal and whether or not the NO_COLOR environment variable is set, mirroring the behavior of CRuby itself. Syntax-level errors raise SyntaxError, argument-level errors raise ArgumentError, and load-level errors raise LoadError. Note that this option is honored by every API that accepts these options, including predicates like Prism.parse_success?, which will raise instead of returning a boolean when the source contains errors.
  • scopes - the locals that are in scope surrounding the code that is being parsed. This should be an array of arrays of symbols or nil. Scopes are ordered from the outermost scope to the innermost one.
  • version - the version of Ruby syntax that prism should used to parse Ruby code. By default prism assumes you want to parse with the latest version of Ruby syntax (which you can trigger with nil or "latest"). You may also restrict the syntax to a specific version of Ruby, e.g., with "3.3.0". To parse with the same syntax version that the current Ruby is running use version: "current". To parse with the nearest version to the current Ruby that is running, use version: "nearest". Raises ArgumentError if the version is not currently supported by Prism.
[ GitHub ]

  
# File 'prism/extension.c', line 1103

static VALUE
parse(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    const uint8_t *source = (const uint8_t *) RSTRING_PTR(string);
    size_t length = RSTRING_LEN(string);

#ifdef PRISM_BUILD_DEBUG
    char* dup = xmalloc(length);
    memcpy(dup, source, length);
    source = (const uint8_t *) dup;
#endif

    result_t result = parse_input(source, length, options, NULL);

#ifdef PRISM_BUILD_DEBUG
#ifdef xfree_sized
    xfree_sized(dup, length);
#else
    xfree(dup);
#endif
#endif

    pm_options_free(options);
    return result_get(result);
}

.parse_comments(source, **options) ⇒ Array

Parse the given string and return an array of ::Prism::Comment objects. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1354

static VALUE
parse_comments(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    result_t result = parse_input_comments((const uint8_t *) RSTRING_PTR(string), RSTRING_LEN(string), options, NULL);
    pm_options_free(options);

    return result_get(result);
}

.parse_comments_common(string, code, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 456

def parse_comments_common(string, code, options) # :nodoc:
  if (format_type = raise_error_format_type(options))
    raise_error(string, options, format_type)
  end

  LibRubyParser::PrismBuffer.with do |buffer|
    LibRubyParser.pm_serialize_parse_comments(buffer.pointer, string.pointer, string.length, dump_options(options))
    Serialize.load_parse_comments(code, buffer.read, options.fetch(:freeze, false))
  end
end

.parse_common(string, code, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 447

def parse_common(string, code, options) # :nodoc:
  format_type = raise_error_format_type(options)
  serialized = dump_common(string, options)
  result = Serialize.load_parse(code, serialized, options.fetch(:freeze, false))

  raise_error(string, options, format_type) if format_type && result.failure?
  result
end

.parse_failure?(source, **options) ⇒ Boolean

Parse the given string and return true if it parses with errors. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1489

static VALUE
parse_failure_p(int argc, VALUE *argv, VALUE self) {
    return RTEST(parse_success_p(argc, argv, self)) ? Qfalse : Qtrue;
}

.parse_file(filepath, **options)

Mirror the parse_file API by using the serialization API. This uses native strings instead of Ruby strings because it allows us to use mmap when it is available.

[ GitHub ]

  
# File 'prism/extension.c', line 1139

static VALUE
parse_file(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = parse_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.parse_file_comments(filepath, **options)

Mirror the parse_file_comments API by using the serialization API. This uses native strings instead of Ruby strings because it allows us to use mmap when it is available.

[ GitHub ]

  
# File 'prism/extension.c', line 1373

static VALUE
parse_file_comments(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = parse_input_comments(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.parse_file_failure?(filepath, **options) ⇒ Boolean

Parse the given file and return true if it parses with errors. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1524

static VALUE
parse_file_failure_p(int argc, VALUE *argv, VALUE self) {
    return RTEST(parse_file_success_p(argc, argv, self)) ? Qfalse : Qtrue;
}

.parse_file_success?(filepath, **options) ⇒ Boolean

Parse the given file and return true if it parses without errors. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1502

static VALUE
parse_file_success_p(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = parse_input_success_p(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.parse_file_success_common(string, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 479

def parse_file_success_common(string, options) # :nodoc:
  format_type = raise_error_format_type(options)
  success = LibRubyParser.pm_serialize_parse_success_p(string.pointer, string.length, dump_options(options))

  raise_error(string, options, format_type) if format_type && !success
  success
end

.parse_lex(source, **options) ⇒ ParseLexResult

Parse the given string and return a ::Prism::ParseLexResult instance that contains a 2-element array, where the first element is the AST and the second element is an array of ::Prism::Token instances.

This API is only meant to be used in the case where you need both the AST and the tokens. If you only need one or the other, use either .parse or .lex.

For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1402

static VALUE
parse_lex(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    result_t result = parse_lex_input((const uint8_t *) RSTRING_PTR(string), RSTRING_LEN(string), options, NULL, true);
    pm_options_free(options);

    return result_get(result);
}

.parse_lex_common(string, code, options) (private)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 467

def parse_lex_common(string, code, options) # :nodoc:
  format_type = raise_error_format_type(options)

  LibRubyParser::PrismBuffer.with do |buffer|
    LibRubyParser.pm_serialize_parse_lex(buffer.pointer, string.pointer, string.length, dump_options(options))
    result = Serialize.load_parse_lex(code, buffer.read, options.fetch(:freeze, false))

    raise_error(string, options, format_type) if format_type && result.failure?
    result
  end
end

.parse_lex_file(filepath, **options) ⇒ ParseLexResult

Parse the given file and return a ::Prism::ParseLexResult instance that contains a 2-element array, where the first element is the AST and the second element is an array of ::Prism::Token instances.

This API is only meant to be used in the case where you need both the AST and the tokens. If you only need one or the other, use either .parse_file or .lex_file.

For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1428

static VALUE
parse_lex_file(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = parse_lex_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath), true);
    pm_source_free(src);
    pm_options_free(options);

    return result_get(result);
}

.parse_stream(stream, **options) ⇒ ParseResult

Parse the given object that responds to gets and return a ::Prism::ParseResult instance. The options that are supported are the same as .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1290

static VALUE
parse_stream(int argc, VALUE *argv, VALUE self) {
    VALUE stream;
    VALUE keywords;
    rb_scan_args(argc, argv, "1:", &stream, &keywords);

    pm_options_t *options = pm_options_new();
    extract_options(options, Qnil, keywords);

    pm_source_t *src = pm_source_stream_new((void *) stream, parse_stream_fgets, parse_stream_eof);
    pm_arena_t *arena = pm_arena_new();
    pm_parser_t *parser;

    pm_node_t *node = pm_parse_stream(&parser, arena, src, options);

    result_t result = check_raise_error_option(parser, options, NULL);
    if (result.type == RESULT_OK) {
        rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));

        VALUE source = pm_source_new(parser, encoding, pm_options_freeze(options));
        VALUE value = pm_ast_new(parser, node, encoding, source, pm_options_freeze(options));
        result = result_ok(parse_result_create(rb_cPrismParseResult, parser, value, encoding, source, pm_options_freeze(options)));
    }

    pm_source_free(src);
    pm_parser_free(parser);
    pm_arena_free(arena);
    pm_options_free(options);

    return result_get(result);
}

.parse_success?(source, **options) ⇒ Boolean

Parse the given string and return true if it parses without errors. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1470

static VALUE
parse_success_p(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    result_t result = parse_input_success_p((const uint8_t *) RSTRING_PTR(string), RSTRING_LEN(string), options, NULL);
    pm_options_free(options);

    return result_get(result);
}

.profile(source, **options) ⇒ nil

Parse the given string and return nothing. This method is meant to allow profilers to avoid the overhead of reifying the AST to Ruby. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1179

static VALUE
profile(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();
    VALUE string = string_options(argc, argv, options);

    result_t result = profile_input((const uint8_t *) RSTRING_PTR(string), RSTRING_LEN(string), options, NULL);
    pm_options_free(options);
    result_get(result);

    return Qnil;
}

.profile_file(filepath, **options) ⇒ nil

Parse the given file and return nothing. This method is meant to allow profilers to avoid the overhead of reifying the AST to Ruby. For supported options, see .parse.

[ GitHub ]

  
# File 'prism/extension.c', line 1200

static VALUE
profile_file(int argc, VALUE *argv, VALUE self) {
    pm_options_t *options = pm_options_new();

    VALUE encoded_filepath;
    pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);

    result_t result = profile_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
    pm_source_free(src);
    pm_options_free(options);
    result_get(result);

    return Qnil;
}

.raise_error(string, options, format_type) (private)

This method is for internal use only.

Parse the given source and format any errors that are encountered into an appropriate exception, then raise it. If the source parses without any errors, then return nil.

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 522

def raise_error(string, options, format_type) # :nodoc:
  LibRubyParser::PrismBuffer.with do |buffer|
    level = LibRubyParser.pm_serialize_parse_errors_format(buffer.pointer, string.pointer, string.length, dump_options(options), format_type)
    return if level == -1

    encoding_name, _, message = buffer.read.partition("\0")

    case level
    when 0 # syntax
      error = SyntaxError.new(message.force_encoding(encoding_name))
      error.instance_variable_set(:@path, options.fetch(:filepath, ""))
      raise error
    when 1 # argument
      raise ArgumentError, message.force_encoding(encoding_name)
    when 2 # load
      error = LoadError.new(message.force_encoding(Encoding.find("locale")))
      error.instance_variable_set(:@path, nil)
      raise error
    else
      raise "Unknown error level: #{level}"
    end
  end
end

.raise_error_format_type(options) (private)

This method is for internal use only.

Extract the raise_error option from the given options hash and convert it into the format type that should be used when formatting errors, or nil if raising is disabled.

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 490

def raise_error_format_type(options) # :nodoc:
  case (value = options.delete(:raise_error))
  when nil, false
    nil
  when true
    # When given true, mirror the behavior of CRuby itself: color when
    # $stderr is a terminal (unless NO_COLOR is set), bold styling when
    # NO_COLOR is set, plain otherwise. This policy is duplicated in
    # ext/prism/extension.c (build_options_i) and the two must stay in
    # sync.
    if $stderr.respond_to?(:tty?) && $stderr.tty?
      no_color = ENV["NO_COLOR"]
      (no_color.nil? || no_color.empty?) ? :PM_ERRORS_FORMAT_COLOR : :PM_ERRORS_FORMAT_STYLE
    else
      :PM_ERRORS_FORMAT_PLAIN
    end
  when :plain
    :PM_ERRORS_FORMAT_PLAIN
  when :style
    :PM_ERRORS_FORMAT_STYLE
  when :color
    :PM_ERRORS_FORMAT_COLOR
  when Symbol
    raise ArgumentError, "invalid raise_error value: #{value}"
  else
    raise TypeError, "wrong argument type #{value.class} (expected Symbol)"
  end
end

.scope(locals: [], forwarding: [])

Create a new scope with the given locals and forwarding options that is suitable for passing into one of the Prism.* methods that accepts the scopes option.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 1208

def self.scope(locals: [], forwarding: [])
  Scope.new(locals, forwarding)
end

.version_string_to_number(version) (private)

Converts a version string like "4.0.0" or "4.0" into a number. Returns nil if the version is unknown.

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 586

def version_string_to_number(version)
  case version
  when /\A3\.3(\.\d+)?\z/
    1
  when /\A3\.4(\.\d+)?\z/
    2
  when /\A3\.5(\.\d+)?\z/, /\A4\.0(\.\d+)?\z/
    3
  when /\A4\.1(\.\d+)?\z/
    4
  end
end