@@ -209,9 +209,7 @@ extern "C" void swift_ASTGen_buildTopLevelASTNodes(void *sourceFile,
209
209
void Parser::parseTopLevelItems (SmallVectorImpl<ASTNode> &items) {
210
210
#if SWIFT_SWIFT_PARSER
211
211
Optional<DiagnosticTransaction> existingParsingTransaction;
212
- if (!SF.getParsingOptions ()
213
- .contains (SourceFile::ParsingFlags::DisableSwiftParserASTGen))
214
- parseSourceFileViaASTGen (items, existingParsingTransaction);
212
+ parseSourceFileViaASTGen (items, existingParsingTransaction);
215
213
#endif
216
214
217
215
// Prime the lexer.
@@ -261,92 +259,135 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
261
259
}
262
260
263
261
#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 ()) {
294
303
loc = Context.SourceMgr .getLocForBufferStart (*bufferID);
295
- }
296
- diagnose (loc, diag::parser_new_parser_errors);
297
304
}
305
+ diagnose (loc, diag::parser_new_parser_errors);
298
306
}
299
307
}
300
308
#endif
301
309
}
302
310
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
+
303
342
void
304
343
Parser::parseSourceFileViaASTGen (SmallVectorImpl<ASTNode> &items,
305
344
Optional<DiagnosticTransaction> &transaction,
306
345
bool suppressDiagnostics) {
307
346
#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 ;
322
364
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)) {
334
377
// Errors were emitted, and we're still using the C++ parser, so
335
378
// disable diagnostics from the C++ parser.
336
379
transaction.emplace (Context.Diags );
337
380
}
381
+ }
338
382
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);
348
387
349
- return ;
388
+ // Spin the C++ parser to the end; we won't be using it.
389
+ while (!Tok.is (tok::eof)) {
390
+ consumeToken ();
350
391
}
351
392
}
352
393
#endif
0 commit comments