Module: SimpleCov::Formatter::AIFormatter::ASTResolver::ParserBackend

Extended by:
T::Sig
Defined in:
lib/simplecov-ai/ast_resolver/parser_backend.rb

Overview

Chooses the parsing backend once, at load time, and parses source buffers with it without ever writing to STDERR (the diagnostics engine is given no consumer, so warnings are dropped and only errors surface). Prism's parser-compatible translation layer is preferred whenever it offers a grammar for the running Ruby (Ruby >= 3.3 with Prism >= 1.2 and a parser gem recent enough for the translation to load); otherwise the parser gem's exact grammar for the running Ruby is loaded, falling back to parser/current with its version-deviation warning muted. Syntax errors surface as Parser::SyntaxError; warnings and non-fatal diagnostics are dropped.

Constant Summary collapse

PRISM_MINIMUM_VERSION =

Prism releases below this predate the version-specific translation grammars this backend selects (Ruby 3.4.0 bundles Prism 1.2.0).

T.let('1.2.0', String)
PARSER_MINIMUM_FOR_PRISM =

Prism's translation layer refuses to load alongside older parser gems, so it is only attempted when the installed gem satisfies that floor.

T.let('3.3.7.2', String)
PRISM_OLDEST_GRAMMAR =

The oldest Ruby grammar Prism implements; older Rubies are parsed by the parser gem, which ships an exact grammar for each of them.

T.let('3.3', String)
FALLBACK_GRAMMAR_FEATURE =

The parser gem grammar loaded when no exact grammar exists for the running Ruby.

T.let('parser/current', String)
PRISM_GRAMMARS =

Prism's version-specific translation grammars keyed by Ruby major/minor, resolved lazily because the newer classes only exist in newer Prism releases.

T.let(
  {
    '33' => -> { Prism::Translation::Parser33 },
    '34' => -> { Prism::Translation::Parser34 },
    '40' => -> { defined?(Prism::Translation::Parser40) ? Prism::Translation::Parser40 : nil },
    '41' => -> { defined?(Prism::Translation::Parser41) ? Prism::Translation::Parser41 : nil }
  }.freeze,
  T::Hash[String, T.proc.returns(T.nilable(T.class_of(Parser::Base)))]
)
PARSER_GEM_GRAMMARS =

The parser gem's exact grammars keyed by Ruby major/minor, resolved lazily so only the grammar for the running Ruby is ever loaded.

T.let(
  {
    '27' => -> { Parser::Ruby27 },
    '30' => -> { Parser::Ruby30 },
    '31' => -> { Parser::Ruby31 },
    '32' => -> { Parser::Ruby32 },
    '33' => -> { Parser::Ruby33 },
    '34' => -> { Parser::Ruby34 }
  }.freeze,
  T::Hash[String, T.proc.returns(T.class_of(Parser::Base))]
)
GRAMMAR =

The grammar class selected for this process.

T.let(select_grammar, T.class_of(Parser::Base))

Class Method Summary collapse

Class Method Details

.parse(buffer) ⇒ Object



78
79
80
81
82
83
# File 'lib/simplecov-ai/ast_resolver/parser_backend.rb', line 78

def self.parse(buffer)
  parser = GRAMMAR.new
  T.cast(parser.builder, Parser::Builders::Default).extend(LenientLiterals)
  T.cast(parser.diagnostics, Parser::Diagnostic::Engine).all_errors_are_fatal = true
  T.cast(parser.parse(buffer), T.nilable(Parser::AST::Node))
end

.select_grammar(ruby_version: RUBY_VERSION, parser_version: T.let(Parser::VERSION, String)) ⇒ Object



66
67
68
# File 'lib/simplecov-ai/ast_resolver/parser_backend.rb', line 66

def self.select_grammar(ruby_version: RUBY_VERSION, parser_version: T.let(Parser::VERSION, String))
  prism_grammar(ruby_version, parser_version) || parser_gem_grammar(ruby_version)
end