4747#include " rbs/AssertionsRewriter.h"
4848#include " rbs/CommentsAssociator.h"
4949#include " rbs/SigsRewriter.h"
50+ #include " rbs/prism/AssertionsRewriterPrism.h"
51+ #include " rbs/prism/CommentsAssociatorPrism.h"
52+ #include " rbs/prism/SigsRewriterPrism.h"
5053#include " resolver/resolver.h"
5154#include " rewriter/rewriter.h"
5255
@@ -203,6 +206,10 @@ core::StrictLevel decideStrictLevel(const core::GlobalState &gs, const core::Fil
203206
204207namespace {
205208
209+ pm_node_t *runPrismRBSRewrite (core::GlobalState &gs, core::FileRef file, pm_node_t *node,
210+ const vector<core::LocOffsets> &commentLocations, const options::Printers &print,
211+ core::MutableContext &ctx, const parser::Prism::Parser &parser);
212+
206213ast::ExpressionPtr fetchTreeFromCache (core::GlobalState &gs, core::FileRef fref, core::File &file,
207214 const unique_ptr<const OwnedKeyValueStore> &kvstore) {
208215 if (kvstore == nullptr ) {
@@ -252,6 +259,59 @@ parser::ParseResult runParser(core::GlobalState &gs, core::FileRef file, const o
252259 return result;
253260}
254261
262+ parser::ParseResult runPrismParser (core::GlobalState &gs, core::FileRef file, const options::Printers &print,
263+ const options::Options &opts, bool preserveConcreteSyntax = false ) {
264+ Timer timeit (gs.tracer (), " runParser" , {{" file" , string (file.data (gs).path ())}});
265+
266+ parser::ParseResult parseResult;
267+ {
268+ core::MutableContext ctx (gs, core::Symbols::root (), file);
269+ core::UnfreezeNameTable nameTableAccess (gs); // enters strings from source code as names
270+ // The RBS rewriter produces plain Whitequark nodes and not `NodeWithExpr` which causes errors in
271+ // `PrismDesugar.cc`. For now, disable all direct translation, and fallback to `Desugar.cc`.
272+ auto source = file.data (ctx).source ();
273+ parser::Prism::Parser parser{source};
274+ bool collectComments = gs.cacheSensitiveOptions .rbsEnabled ;
275+ parser::Prism::ParseResult prismResult = parser.parseWithoutTranslation (collectComments);
276+
277+ if (opts.stopAfterPhase == options::Phase::PARSER) {
278+ return parser::ParseResult{nullptr , prismResult.getCommentLocations ()};
279+ }
280+
281+ auto node = prismResult.getRawNodePointer ();
282+
283+ // TODO: Remove `&& false` once RBS rewriter with Prism AST migration is complete
284+ // https://github.com/sorbet/sorbet/issues/9065
285+ if (gs.cacheSensitiveOptions .rbsEnabled && false ) {
286+ node = runPrismRBSRewrite (gs, file, node, prismResult.getCommentLocations (), print, ctx, parser);
287+ }
288+
289+ bool directlyDesugar = !gs.cacheSensitiveOptions .rbsEnabled ;
290+ auto translatedTree = parser::Prism::Translator (parser, ctx, prismResult.getParseErrors (), directlyDesugar,
291+ preserveConcreteSyntax)
292+ .translate (node);
293+
294+ parseResult = parser::ParseResult{move (translatedTree), prismResult.getCommentLocations ()};
295+ }
296+
297+ if (parseResult.tree ) {
298+ if (print.ParseTree .enabled ) {
299+ print.ParseTree .fmt (" {}\n " , parseResult.tree ->toStringWithTabs (gs, 0 ));
300+ }
301+ if (print.ParseTreeJson .enabled ) {
302+ print.ParseTreeJson .fmt (" {}\n " , parseResult.tree ->toJSON (gs, 0 ));
303+ }
304+ if (print.ParseTreeJsonWithLocs .enabled ) {
305+ print.ParseTreeJson .fmt (" {}\n " , parseResult.tree ->toJSONWithLocs (gs, file, 0 ));
306+ }
307+ if (print.ParseTreeWhitequark .enabled ) {
308+ print.ParseTreeWhitequark .fmt (" {}\n " , parseResult.tree ->toWhitequark (gs, 0 ));
309+ }
310+ }
311+
312+ return parseResult;
313+ }
314+
255315unique_ptr<parser::Node> runRBSRewrite (core::GlobalState &gs, core::FileRef file, parser::ParseResult &&parseResult,
256316 const options::Printers &print) {
257317 auto node = move (parseResult.tree );
@@ -278,36 +338,6 @@ unique_ptr<parser::Node> runRBSRewrite(core::GlobalState &gs, core::FileRef file
278338 return node;
279339}
280340
281- parser::ParseResult runPrismParser (core::GlobalState &gs, core::FileRef file, const options::Printers &print,
282- bool preserveConcreteSyntax = false ) {
283- Timer timeit (gs.tracer (), " runParser" , {{" file" , string (file.data (gs).path ())}});
284-
285- parser::ParseResult parseResult;
286- {
287- core::MutableContext ctx (gs, core::Symbols::root (), file);
288- core::UnfreezeNameTable nameTableAccess (gs); // enters strings from source code as names
289- // The RBS rewriter produces plain Whitequark nodes and not `NodeWithExpr` which causes errors in
290- // `PrismDesugar.cc`. For now, disable all direct translation, and fallback to `Desugar.cc`.
291- auto directlyTranslate = !gs.cacheSensitiveOptions .rbsEnabled ;
292- parseResult = parser::Prism::Parser::run (ctx, directlyTranslate);
293- }
294-
295- if (print.ParseTree .enabled ) {
296- print.ParseTree .fmt (" {}\n " , parseResult.tree ->toStringWithTabs (gs, 0 ));
297- }
298- if (print.ParseTreeJson .enabled ) {
299- print.ParseTreeJson .fmt (" {}\n " , parseResult.tree ->toJSON (gs, 0 ));
300- }
301- if (print.ParseTreeJsonWithLocs .enabled ) {
302- print.ParseTreeJson .fmt (" {}\n " , parseResult.tree ->toJSONWithLocs (gs, file, 0 ));
303- }
304- if (print.ParseTreeWhitequark .enabled ) {
305- print.ParseTreeWhitequark .fmt (" {}\n " , parseResult.tree ->toWhitequark (gs, 0 ));
306- }
307-
308- return parseResult;
309- }
310-
311341ast::ExpressionPtr runDesugar (core::GlobalState &gs, core::FileRef file, unique_ptr<parser::Node> parseTree,
312342 const options::Printers &print, bool preserveConcreteSyntax = false ) {
313343 Timer timeit (gs.tracer (), " runDesugar" , {{" file" , string (file.data (gs).path ())}});
@@ -351,6 +381,27 @@ ast::ParsedFile emptyParsedFile(core::FileRef file) {
351381 return {ast::MK::EmptyTree (), file};
352382}
353383
384+ pm_node_t *runPrismRBSRewrite (core::GlobalState &gs, core::FileRef file, pm_node_t *node,
385+ const vector<core::LocOffsets> &commentLocations, const options::Printers &print,
386+ core::MutableContext &ctx, const parser::Prism::Parser &parser) {
387+ Timer timeit (gs.tracer (), " runPrismRBSRewrite" , {{" file" , string (file.data (gs).path ())}});
388+
389+ auto associator = rbs::CommentsAssociatorPrism (ctx, parser, commentLocations);
390+ auto commentMap = associator.run (node);
391+
392+ auto sigsRewriter = rbs::SigsRewriterPrism (ctx, parser, commentMap.signaturesForNode );
393+ node = sigsRewriter.run (node);
394+
395+ auto assertionsRewriter = rbs::AssertionsRewriterPrism (ctx, commentMap.assertionsForNode );
396+ node = assertionsRewriter.run (node);
397+
398+ if (print.RBSRewriteTree .enabled ) {
399+ print.RBSRewriteTree .fmt (" {}\n " , parser.prettyPrint (node));
400+ }
401+
402+ return node;
403+ }
404+
354405} // namespace
355406
356407ast::ExpressionPtr desugarOne (const options::Options &opts, core::GlobalState &gs, core::FileRef file,
@@ -401,20 +452,21 @@ ast::ParsedFile indexOne(const options::Options &opts, core::GlobalState &lgs, c
401452 }
402453
403454 parseTree = runRBSRewrite (lgs, file, move (parseResult), print);
404- if (opts.stopAfterPhase == options::Phase::RBS_REWRITER) {
405- return emptyParsedFile (file);
406- }
407455
408456 break ;
409457 }
410458 case options::Parser::PRISM: {
411- auto parseResult = runPrismParser (lgs, file, print);
412- parseTree = runRBSRewrite (lgs, file, move (parseResult), print);
459+ auto parseResult = runPrismParser (lgs, file, print, opts);
413460
414- if (opts.stopAfterPhase == options::Phase::PARSER) {
461+ // parseResult is null if runPrismParser stopped after an intermediate phase
462+ if (parseResult.tree == nullptr ) {
415463 return emptyParsedFile (file);
416464 }
417465
466+ // TODO: Remove this check once runPrismRBSRewrite is no longer no-oped inside of runPrismParser
467+ // https://github.com/sorbet/sorbet/issues/9065
468+ parseTree = runRBSRewrite (lgs, file, move (parseResult), print);
469+
418470 break ;
419471 }
420472 }
0 commit comments