class Prism::Translation::Parser

This class is the entry-point for converting a prism syntax tree into the whitequark/parser gem’s syntax tree. It inherits from the base parser for the parser gem, and overrides the parse* methods to parse with prism and then translate.

Public Class Methods

The ‘builder` argument is used to create the parser using our custom builder class by default.

By using the ‘:parser` keyword argument, you can translate in a way that is compatible with the Parser gem using any parser.

For example, in RuboCop for Ruby LSP, the following approach can be used to improve performance by reusing a pre-parsed ‘Prism::ParseLexResult`:

class PrismPreparsed
  def initialize(prism_result)
    @prism_result = prism_result
  end

  def parse_lex(source, **options)
    @prism_result
  end
end

prism_preparsed = PrismPreparsed.new(prism_result)

Prism::Translation::Ruby34.new(builder, parser: prism_preparsed)

In an object passed to the ‘:parser` keyword argument, the `parse` and `parse_lex` methods should be implemented as needed.

Calls superclass method
# File lib/prism/translation/parser.rb, line 66
      def initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism)
        if !builder.is_a?(Prism::Translation::Parser::Builder)
          warn(<<~MSG, uplevel: 1, category: :deprecated)
            [deprecation]: The builder passed to `Prism::Translation::Parser.new` is not a \
            `Prism::Translation::Parser::Builder` subclass. This will raise in the next major version.
          MSG
        end
        @parser = parser

        super(builder)
      end

Public Instance Methods

The default encoding for Ruby files is UTF-8.

# File lib/prism/translation/parser.rb, line 83
def default_encoding
  Encoding::UTF_8
end

Parses a source buffer and returns the AST.

# File lib/prism/translation/parser.rb, line 91
def parse(source_buffer)
  @source_buffer = source_buffer
  source = source_buffer.source

  offset_cache = build_offset_cache(source)
  result = unwrap(@parser.parse(source, **prism_options), offset_cache)

  build_ast(result.value, offset_cache)
ensure
  @source_buffer = nil
end

Parses a source buffer and returns the AST and the source code comments.

# File lib/prism/translation/parser.rb, line 104
def parse_with_comments(source_buffer)
  @source_buffer = source_buffer
  source = source_buffer.source

  offset_cache = build_offset_cache(source)
  result = unwrap(@parser.parse(source, **prism_options), offset_cache)

  [
    build_ast(result.value, offset_cache),
    build_comments(result.comments, offset_cache)
  ]
ensure
  @source_buffer = nil
end

Parses a source buffer and returns the AST, the source code comments, and the tokens emitted by the lexer.

# File lib/prism/translation/parser.rb, line 121
def tokenize(source_buffer, recover = false)
  @source_buffer = source_buffer
  source = source_buffer.source

  offset_cache = build_offset_cache(source)
  result =
    begin
      unwrap(@parser.parse_lex(source, **prism_options), offset_cache)
    rescue ::Parser::SyntaxError
      raise if !recover
    end

  program, tokens = result.value
  ast = build_ast(program, offset_cache) if result.success?

  [
    ast,
    build_comments(result.comments, offset_cache),
    build_tokens(tokens, offset_cache)
  ]
ensure
  @source_buffer = nil
end

Since prism resolves num params for us, we don’t need to support this kind of logic here.

# File lib/prism/translation/parser.rb, line 147
def try_declare_numparam(node)
  node.children[0].match?(/\A_[1-9]\z/)
end