module Prism - prism: Ruby Standard Library Documentation

# module Prism

The `Prism` Ruby parser.

“Parsing Ruby is suddenly manageable!”

    - You, hopefully

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/compiler.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/dispatcher.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/dsl.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/inspect_visitor.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/mutation_compiler.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/node.rb.erb if you are looking to modify the template

Here we are reopening the prism module to provide methods on nodes that aren’t templated and are meant as convenience methods.

typed: ignore

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/reflection.rb.erb if you are looking to modify the template

This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/visitor.rb.erb if you are looking to modify the template

### Constants

BACKEND

  The C extension is the default backend on CRuby.

VERSION

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

### Public Class Methods

dump(source, **options) click to toggle source

Mirror the `Prism.dump` API by using the serialization API.

    # File prism/ffi.rb, line 229
    def dump(source, **options)
      LibRubyParser::PrismString.with_string(source) { |string| dump_common(string, options) }
    end

dump_file(filepath, **options) click to toggle source

Mirror the `Prism.dump_file` API by using the serialization API.

    # File prism/ffi.rb, line 234
    def dump_file(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| dump_common(string, options) }
    end

lex(code, **options) click to toggle source

Mirror the `Prism.lex` API by using the serialization API.

    # File prism/ffi.rb, line 240
    def lex(code, **options)
      LibRubyParser::PrismString.with_string(code) { |string| lex_common(string, code, options) }
    end

Prism::lex_compat(source, **options) → LexCompat::Result click to toggle source

Returns a parse result whose value is an array of tokens that closely resembles the return value of `Ripper::lex`. The main difference is that the ‘:on_sp` token is not emitted.

For supported options, see `Prism::parse`.

    # File prism.rb, line 47
    def self.lex_compat(source, **options)
      LexCompat.new(source, **options).result # steep:ignore
    end

lex_file(filepath, **options) click to toggle source

Mirror the `Prism.lex_file` API by using the serialization API.

    # File prism/ffi.rb, line 245
    def lex_file(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| lex_common(string, string.read, options) }
    end

Prism::lex_ripper(source) → Array click to toggle source

This lexes with the `Ripper` lex. It drops any space events but otherwise returns the same tokens. Raises SyntaxError if the syntax in source is invalid.

    # File prism.rb, line 57
    def self.lex_ripper(source)
      LexRipper.new(source).result # steep:ignore
    end

Prism::load(source, serialized) → ParseResult click to toggle source

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

    # File prism.rb, line 65
    def self.load(source, serialized)
      Serialize.load(source, serialized)
    end

parse(code, **options) click to toggle source

Mirror the `Prism.parse` API by using the serialization API.

    # File prism/ffi.rb, line 251
    def parse(code, **options)
      LibRubyParser::PrismString.with_string(code) { |string| parse_common(string, code, options) }
    end

parse_comments(code, **options) click to toggle source

Mirror the `Prism.parse_comments` API by using the serialization API.

    # File prism/ffi.rb, line 287
    def parse_comments(code, **options)
      LibRubyParser::PrismString.with_string(code) { |string| parse_comments_common(string, code, options) }
    end

parse_failure?(code, **options) click to toggle source

Mirror the `Prism.parse_failure?` API by using the serialization API.

    # File prism/ffi.rb, line 316
    def parse_failure?(code, **options)
      !parse_success?(code, **options)
    end

parse_file(filepath, **options) click to toggle source

Mirror the `Prism.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.

    # File prism/ffi.rb, line 258
    def parse_file(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| parse_common(string, string.read, options) }
    end

parse_file_comments(filepath, **options) click to toggle source

Mirror the `Prism.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.

    # File prism/ffi.rb, line 294
    def parse_file_comments(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| parse_comments_common(string, string.read, options) }
    end

parse_file_failure?(filepath, **options) click to toggle source

Mirror the `Prism.parse_file_failure?` API by using the serialization API.

    # File prism/ffi.rb, line 327
    def parse_file_failure?(filepath, **options)
      !parse_file_success?(filepath, **options)
    end

parse_file_success?(filepath, **options) click to toggle source

Mirror the `Prism.parse_file_success?` API by using the serialization API.

    # File prism/ffi.rb, line 321
    def parse_file_success?(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| parse_file_success_common(string, options) }
    end

parse_lex(code, **options) click to toggle source

Mirror the `Prism.parse_lex` API by using the serialization API.

    # File prism/ffi.rb, line 300
    def parse_lex(code, **options)
      LibRubyParser::PrismString.with_string(code) { |string| parse_lex_common(string, code, options) }
    end

parse_lex_file(filepath, **options) click to toggle source

Mirror the `Prism.parse_lex_file` API by using the serialization API.

    # File prism/ffi.rb, line 305
    def parse_lex_file(filepath, **options)
      options[:filepath] = filepath
      LibRubyParser::PrismString.with_file(filepath) { |string| parse_lex_common(string, string.read, options) }
    end

parse_stream(stream, **options) click to toggle source

Mirror the `Prism.parse_stream` API by using the serialization API.

    # File prism/ffi.rb, line 264
    def parse_stream(stream, **options)
      LibRubyParser::PrismBuffer.with do |buffer|
        source = +""
        callback = -> (string, size, _) {
          raise "Expected size to be >= 0, got: #{size}" if size <= 0

          if !(line = stream.gets(size - 1)).nil?
            source << line
            string.write_string("#{line}\x00", line.bytesize + 1)
          end
        }

        # In the pm_serialize_parse_stream function it accepts a pointer to the
        # IO object as a void* and then passes it through to the callback as the
        # third argument, but it never touches it itself. As such, since we have
        # access to the IO object already through the closure of the lambda, we
        # can pass a null pointer here and not worry.
        LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, dump_options(options))
        Prism.load(source, buffer.read)
      end
    end

parse_success?(code, **options) click to toggle source

Mirror the `Prism.parse_success?` API by using the serialization API.

    # File prism/ffi.rb, line 311
    def parse_success?(code, **options)
      LibRubyParser::PrismString.with_string(code) { |string| parse_file_success_common(string, options) }
    end

profile(source, **options) click to toggle source

Mirror the `Prism.profile` API by using the serialization API.

    # File prism/ffi.rb, line 332
    def profile(source, **options)
      LibRubyParser::PrismString.with_string(source) do |string|
        LibRubyParser::PrismBuffer.with do |buffer|
          LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options))
          nil
        end
      end
    end

profile_file(filepath, **options) click to toggle source

Mirror the `Prism.profile_file` API by using the serialization API.

    # File prism/ffi.rb, line 342
    def profile_file(filepath, **options)
      LibRubyParser::PrismString.with_file(filepath) do |string|
        LibRubyParser::PrismBuffer.with do |buffer|
          options[:filepath] = filepath
          LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options))
          nil
        end
      end
    end

### Private Class Methods

dump_options(options) click to toggle source

Convert the given options into a serialized options string.

    # File prism/ffi.rb, line 441
    def dump_options(options)
      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 << "L"
      if (scopes = options[:scopes])
        values << scopes.length

        scopes.each do |scope|
          template << "L"
          values << scope.length

          scope.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) click to toggle source

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

    # File prism/ffi.rb, line 409
    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) click to toggle source

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

    # File prism/ffi.rb, line 427
    def dump_options_version(version)
      case version
      when nil, "latest"
        0
      when /\A3\.3(\.\d+)?\z/
        1
      when /\A3\.4(\.\d+)?\z/
        0
      else
        raise ArgumentError, "invalid version: #{version}"
      end
    end