Class: Prism::Translation::Parser

Inherits:
Parser::Base
  • Object
show all
Defined in:
lib/prism/translation/parser.rb,
lib/prism/translation/parser/lexer.rb,
lib/prism/translation/parser/builder.rb,
lib/prism/translation/parser/compiler.rb

Overview

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.

Note that this version of the parser always parses using the latest version of Ruby syntax supported by Prism. If you want specific version support, use one of the version-specific subclasses, such as ‘Prism::Translation::Parser34`. If you want to parse using the same version of Ruby syntax as the currently running version of Ruby, use `Prism::Translation::ParserCurrent`.

Direct Known Subclasses

Parser33, Parser34, Parser40, Parser41

Defined Under Namespace

Classes: Builder, Compiler, PrismDiagnostic

Constant Summary collapse

Racc_debug_parser =

:nodoc:

false

Instance Method Summary collapse

Constructor Details

#initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism) ⇒ Parser

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.



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/prism/translation/parser.rb', line 74

def initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism)
  if !builder.is_a?(Prism::Translation::Parser::Builder)
    warn("      [deprecation]: The builder passed to `Prism::Translation::Parser.new` is not a \\\n      `Prism::Translation::Parser::Builder` subclass. This will raise in the next major version.\n    MSG\n  end\n  @parser = parser\n\n  super(builder)\nend\n", uplevel: 1, category: :deprecated)

Instance Method Details

#default_encodingObject

The default encoding for Ruby files is UTF-8.



91
92
93
# File 'lib/prism/translation/parser.rb', line 91

def default_encoding
  Encoding::UTF_8
end

#parse(source_buffer) ⇒ Object

Parses a source buffer and returns the AST.



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/prism/translation/parser.rb', line 99

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

#parse_with_comments(source_buffer) ⇒ Object

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



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/prism/translation/parser.rb', line 112

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

#tokenize(source_buffer, recover = false) ⇒ Object

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



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/prism/translation/parser.rb', line 129

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

#try_declare_numparam(node) ⇒ Object

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



155
156
157
# File 'lib/prism/translation/parser.rb', line 155

def try_declare_numparam(node)
  node.children[0].match?(/\A_[1-9]\z/)
end

#versionObject

:nodoc:



86
87
88
# File 'lib/prism/translation/parser.rb', line 86

def version # :nodoc:
  41
end

#yyerrorObject

:nodoc:



95
96
# File 'lib/prism/translation/parser.rb', line 95

def yyerror # :nodoc:
end