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(code, **options) click to toggle source

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

# File lib/prism/ffi.rb, line 203
def dump(code, **options)
  LibRubyParser::PrismString.with_string(code) { |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 lib/prism/ffi.rb, line 208
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 lib/prism/ffi.rb, line 214
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 lib/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 lib/prism/ffi.rb, line 219
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 lib/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 lib/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 lib/prism/ffi.rb, line 225
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 lib/prism/ffi.rb, line 261
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 lib/prism/ffi.rb, line 290
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 lib/prism/ffi.rb, line 232
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 lib/prism/ffi.rb, line 268
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 lib/prism/ffi.rb, line 301
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 lib/prism/ffi.rb, line 295
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 lib/prism/ffi.rb, line 274
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 lib/prism/ffi.rb, line 279
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 lib/prism/ffi.rb, line 238
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 lib/prism/ffi.rb, line 285
def parse_success?(code, **options)
  LibRubyParser::PrismString.with_string(code) { |string| parse_file_success_common(string, options) }
end

Private Class Methods

dump_options(options) click to toggle source

Convert the given options into a serialized options string.

# File lib/prism/ffi.rb, line 380
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.name
    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 << { nil => 0, "3.3.0" => 1, "3.4.0" => 0, "latest" => 0 }.fetch(options[:version])

  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 lib/prism/ffi.rb, line 362
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