@@ -209,9 +209,7 @@ extern "C" void swift_ASTGen_buildTopLevelASTNodes(void *sourceFile,
209209void Parser::parseTopLevelItems (SmallVectorImpl<ASTNode> &items) {
210210#if SWIFT_SWIFT_PARSER
211211 Optional<DiagnosticTransaction> existingParsingTransaction;
212- if (!SF.getParsingOptions ()
213- .contains (SourceFile::ParsingFlags::DisableSwiftParserASTGen))
214- parseSourceFileViaASTGen (items, existingParsingTransaction);
212+ parseSourceFileViaASTGen (items, existingParsingTransaction);
215213#endif
216214
217215 // Prime the lexer.
@@ -261,92 +259,135 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
261259 }
262260
263261#if SWIFT_SWIFT_PARSER
264- if (!SF.getParsingOptions ().contains (
265- SourceFile::ParsingFlags::DisableSwiftParserASTGen)) {
266- if (existingParsingTransaction)
267- existingParsingTransaction->abort ();
268-
269- // Perform round-trip and/or validation checking.
270- if ((Context.LangOpts .hasFeature (Feature::ParserRoundTrip) ||
271- Context.LangOpts .hasFeature (Feature::ParserValidation)) &&
272- SF.exportedSourceFile &&
273- !SourceMgr.hasIDEInspectionTargetBuffer ()) {
274- if (Context.LangOpts .hasFeature (Feature::ParserRoundTrip) &&
275- swift_ASTGen_roundTripCheck (SF.exportedSourceFile )) {
276- SourceLoc loc;
277- if (auto bufferID = SF.getBufferID ()) {
278- loc = Context.SourceMgr .getLocForBufferStart (*bufferID);
279- }
280- diagnose (loc, diag::parser_round_trip_error);
281- } else if (Context.LangOpts .hasFeature (Feature::ParserValidation) &&
282- !Context.Diags .hadAnyError () &&
283- swift_ASTGen_emitParserDiagnostics (
284- &Context.Diags , SF.exportedSourceFile ,
285- /* emitOnlyErrors=*/ true ,
286- /* downgradePlaceholderErrorsToWarnings=*/
287- Context.LangOpts .Playground ||
288- Context.LangOpts .WarnOnEditorPlaceholder )) {
289- // We might have emitted warnings in the C++ parser but no errors, in
290- // which case we still have `hadAnyError() == false`. To avoid emitting
291- // the same warnings from SwiftParser, only emit errors from SwiftParser
292- SourceLoc loc;
293- if (auto bufferID = SF.getBufferID ()) {
262+ if (existingParsingTransaction)
263+ existingParsingTransaction->abort ();
264+
265+ using ParsingFlags = SourceFile::ParsingFlags;
266+ const auto parsingOpts = SF.getParsingOptions ();
267+
268+ // If we don't need to validate anything, we're done.
269+ if (!parsingOpts.contains (ParsingFlags::RoundTrip) &&
270+ !parsingOpts.contains (ParsingFlags::ValidateNewParserDiagnostics)) {
271+ return ;
272+ }
273+
274+ auto *exportedSourceFile = SF.getExportedSourceFile ();
275+ if (!exportedSourceFile)
276+ return ;
277+
278+ // Perform round-trip and/or validation checking.
279+ if (parsingOpts.contains (ParsingFlags::RoundTrip) &&
280+ swift_ASTGen_roundTripCheck (exportedSourceFile)) {
281+ SourceLoc loc;
282+ if (auto bufferID = SF.getBufferID ()) {
283+ loc = Context.SourceMgr .getLocForBufferStart (*bufferID);
284+ }
285+ diagnose (loc, diag::parser_round_trip_error);
286+ return ;
287+ }
288+ if (parsingOpts.contains (ParsingFlags::ValidateNewParserDiagnostics) &&
289+ !Context.Diags .hadAnyError ()) {
290+ auto hadSyntaxError = swift_ASTGen_emitParserDiagnostics (
291+ &Context.Diags , exportedSourceFile,
292+ /* emitOnlyErrors=*/ true ,
293+ /* downgradePlaceholderErrorsToWarnings=*/
294+ Context.LangOpts .Playground ||
295+ Context.LangOpts .WarnOnEditorPlaceholder );
296+ if (hadSyntaxError) {
297+ // We might have emitted warnings in the C++ parser but no errors, in
298+ // which case we still have `hadAnyError() == false`. To avoid
299+ // emitting the same warnings from SwiftParser, only emit errors from
300+ // SwiftParser
301+ SourceLoc loc;
302+ if (auto bufferID = SF.getBufferID ()) {
294303 loc = Context.SourceMgr .getLocForBufferStart (*bufferID);
295- }
296- diagnose (loc, diag::parser_new_parser_errors);
297304 }
305+ diagnose (loc, diag::parser_new_parser_errors);
298306 }
299307 }
300308#endif
301309}
302310
311+ void *ExportedSourceFileRequest::evaluate (Evaluator &evaluator,
312+ const SourceFile *SF) const {
313+ #if SWIFT_SWIFT_PARSER
314+ // The SwiftSyntax parser doesn't (yet?) handle SIL.
315+ if (SF->Kind == SourceFileKind::SIL)
316+ return nullptr ;
317+
318+ auto &ctx = SF->getASTContext ();
319+ auto &SM = ctx.SourceMgr ;
320+
321+ auto bufferID = SF->getBufferID ();
322+ if (!bufferID)
323+ return nullptr ;
324+
325+ StringRef contents = SM.extractText (SM.getRangeForBuffer (*bufferID));
326+
327+ // Parse the source file.
328+ auto exportedSourceFile = swift_ASTGen_parseSourceFile (
329+ contents.begin (), contents.size (),
330+ SF->getParentModule ()->getName ().str ().str ().c_str (),
331+ SF->getFilename ().str ().c_str ());
332+
333+ ctx.addCleanup ([exportedSourceFile] {
334+ swift_ASTGen_destroySourceFile (exportedSourceFile);
335+ });
336+ return exportedSourceFile;
337+ #else
338+ return nullptr ;
339+ #endif
340+ }
341+
303342void
304343Parser::parseSourceFileViaASTGen (SmallVectorImpl<ASTNode> &items,
305344 Optional<DiagnosticTransaction> &transaction,
306345 bool suppressDiagnostics) {
307346#if SWIFT_SWIFT_PARSER
308- Optional<DiagnosticTransaction> existingParsingTransaction;
309- if (SF.Kind != SourceFileKind::SIL) {
310- StringRef contents =
311- SourceMgr.extractText (SourceMgr.getRangeForBuffer (L->getBufferID ()));
312-
313- // Parse the source file.
314- auto exportedSourceFile = swift_ASTGen_parseSourceFile (
315- contents.begin (), contents.size (),
316- SF.getParentModule ()->getName ().str ().str ().c_str (),
317- SF.getFilename ().str ().c_str ());
318- SF.exportedSourceFile = exportedSourceFile;
319- Context.addCleanup ([exportedSourceFile] {
320- swift_ASTGen_destroySourceFile (exportedSourceFile);
321- });
347+ using ParsingFlags = SourceFile::ParsingFlags;
348+ const auto parsingOpts = SF.getParsingOptions ();
349+ const auto &langOpts = Context.LangOpts ;
350+
351+ // We only need to do parsing if we either have ASTGen enabled, or want the
352+ // new parser diagnostics.
353+ auto needToParse = [&]() {
354+ if (langOpts.hasFeature (Feature::ParserASTGen))
355+ return true ;
356+ if (!suppressDiagnostics &&
357+ langOpts.hasFeature (Feature::ParserDiagnostics)) {
358+ return true ;
359+ }
360+ return false ;
361+ }();
362+ if (!needToParse)
363+ return ;
322364
323- // If we're supposed to emit diagnostics from the parser, do so now.
324- if ((Context.LangOpts .hasFeature (Feature::ParserDiagnostics) ||
325- Context.LangOpts .hasFeature (Feature::ParserASTGen)) &&
326- !suppressDiagnostics &&
327- swift_ASTGen_emitParserDiagnostics (
328- &Context.Diags , SF.exportedSourceFile , /* emitOnlyErrors=*/ false ,
329- /* downgradePlaceholderErrorsToWarnings=*/
330- Context.LangOpts .Playground ||
331- Context.LangOpts .WarnOnEditorPlaceholder ) &&
332- Context.Diags .hadAnyError () &&
333- !Context.LangOpts .hasFeature (Feature::ParserASTGen)) {
365+ auto *exportedSourceFile = SF.getExportedSourceFile ();
366+ if (!exportedSourceFile)
367+ return ;
368+
369+ // If we're supposed to emit diagnostics from the parser, do so now.
370+ if (!suppressDiagnostics) {
371+ auto hadSyntaxError = swift_ASTGen_emitParserDiagnostics (
372+ &Context.Diags , exportedSourceFile, /* emitOnlyErrors=*/ false ,
373+ /* downgradePlaceholderErrorsToWarnings=*/ langOpts.Playground ||
374+ langOpts.WarnOnEditorPlaceholder );
375+ if (hadSyntaxError && Context.Diags .hadAnyError () &&
376+ !langOpts.hasFeature (Feature::ParserASTGen)) {
334377 // Errors were emitted, and we're still using the C++ parser, so
335378 // disable diagnostics from the C++ parser.
336379 transaction.emplace (Context.Diags );
337380 }
381+ }
338382
339- // If we want to do ASTGen, do so now.
340- if (Context.LangOpts .hasFeature (Feature::ParserASTGen)) {
341- swift_ASTGen_buildTopLevelASTNodes (
342- exportedSourceFile, CurDeclContext, &Context, &items, appendToVector);
343-
344- // Spin the C++ parser to the end; we won't be using it.
345- while (!Tok.is (tok::eof)) {
346- consumeToken ();
347- }
383+ // If we want to do ASTGen, do so now.
384+ if (langOpts.hasFeature (Feature::ParserASTGen)) {
385+ swift_ASTGen_buildTopLevelASTNodes (exportedSourceFile, CurDeclContext,
386+ &Context, &items, appendToVector);
348387
349- return ;
388+ // Spin the C++ parser to the end; we won't be using it.
389+ while (!Tok.is (tok::eof)) {
390+ consumeToken ();
350391 }
351392 }
352393#endif
0 commit comments