29
29
#include " swift/AST/PrintOptions.h"
30
30
#include " swift/AST/SourceFile.h"
31
31
#include " swift/AST/Stmt.h"
32
+ #include " swift/AST/TypeCheckRequests.h"
32
33
#include " swift/AST/TypeRepr.h"
33
34
#include " swift/Basic/Assertions.h"
34
35
#include " swift/Basic/SourceManager.h"
@@ -1306,20 +1307,6 @@ void DiagnosticEngine::forwardTentativeDiagnosticsTo(
1306
1307
clearTentativeDiagnostics ();
1307
1308
}
1308
1309
1309
- // / Returns the access level of the least accessible PrettyPrintedDeclarations
1310
- // / buffer that \p decl should appear in.
1311
- // /
1312
- // / This is always \c Public unless \p decl is a \c ValueDecl and its
1313
- // / access level is below \c Public. (That can happen with @testable and
1314
- // / @_private imports.)
1315
- static AccessLevel getBufferAccessLevel (const Decl *decl) {
1316
- AccessLevel level = AccessLevel::Public;
1317
- if (auto *VD = dyn_cast<ValueDecl>(decl))
1318
- level = VD->getFormalAccessScope ().accessLevelForDiagnostics ();
1319
- if (level > AccessLevel::Public) level = AccessLevel::Public;
1320
- return level;
1321
- }
1322
-
1323
1310
std::optional<DiagnosticInfo>
1324
1311
DiagnosticEngine::diagnosticInfoForDiagnostic (const Diagnostic &diagnostic) {
1325
1312
auto behavior = state.determineBehavior (diagnostic);
@@ -1334,154 +1321,12 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
1334
1321
// has a location we can point to, use that location.
1335
1322
loc = decl->getLoc ();
1336
1323
1324
+ // If the location of the decl is invalid still, try to pretty-print the
1325
+ // declaration into a buffer and capture the source location there.
1337
1326
if (loc.isInvalid ()) {
1338
- // There is no location we can point to. Pretty-print the declaration
1339
- // so we can point to it.
1340
- SourceLoc ppLoc = PrettyPrintedDeclarations[decl];
1341
- if (ppLoc.isInvalid ()) {
1342
- class TrackingPrinter : public StreamPrinter {
1343
- SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries;
1344
- AccessLevel bufferAccessLevel;
1345
-
1346
- public:
1347
- TrackingPrinter (
1348
- SmallVectorImpl<std::pair<const Decl *, uint64_t >> &Entries,
1349
- raw_ostream &OS, AccessLevel bufferAccessLevel) :
1350
- StreamPrinter (OS), Entries(Entries),
1351
- bufferAccessLevel (bufferAccessLevel) {}
1352
-
1353
- void printDeclLoc (const Decl *D) override {
1354
- if (getBufferAccessLevel (D) == bufferAccessLevel)
1355
- Entries.push_back ({ D, OS.tell () });
1356
- }
1357
- };
1358
- SmallVector<std::pair<const Decl *, uint64_t >, 8 > entries;
1359
- llvm::SmallString<128 > buffer;
1360
- llvm::SmallString<128 > bufferName;
1361
- const Decl *ppDecl = decl;
1362
- {
1363
- // The access level of the buffer we want to print. Declarations below
1364
- // this access level will be omitted from the buffer; declarations
1365
- // above it will be printed, but (except for Open declarations in the
1366
- // Public buffer) will not be recorded in PrettyPrintedDeclarations as
1367
- // the "true" SourceLoc for the declaration.
1368
- AccessLevel bufferAccessLevel = getBufferAccessLevel (decl);
1369
-
1370
- // Figure out which declaration to print. It's the top-most
1371
- // declaration (not a module).
1372
- auto dc = decl->getDeclContext ();
1373
-
1374
- // FIXME: Horrible, horrible hackaround. We're not getting a
1375
- // DeclContext everywhere we should.
1376
- if (!dc) {
1377
- return std::nullopt;
1378
- }
1379
-
1380
- while (!dc->isModuleContext ()) {
1381
- switch (dc->getContextKind ()) {
1382
- case DeclContextKind::Package:
1383
- llvm_unreachable (" Not in a package context!" );
1384
- break ;
1385
- case DeclContextKind::Module:
1386
- llvm_unreachable (" Not in a module context!" );
1387
- break ;
1388
-
1389
- case DeclContextKind::FileUnit:
1390
- case DeclContextKind::TopLevelCodeDecl:
1391
- case DeclContextKind::SerializedTopLevelCodeDecl:
1392
- break ;
1393
-
1394
- case DeclContextKind::ExtensionDecl:
1395
- ppDecl = cast<ExtensionDecl>(dc);
1396
- break ;
1397
-
1398
- case DeclContextKind::GenericTypeDecl:
1399
- ppDecl = cast<GenericTypeDecl>(dc);
1400
- break ;
1401
-
1402
- case DeclContextKind::Initializer:
1403
- case DeclContextKind::AbstractClosureExpr:
1404
- case DeclContextKind::SerializedAbstractClosure:
1405
- case DeclContextKind::AbstractFunctionDecl:
1406
- case DeclContextKind::SubscriptDecl:
1407
- case DeclContextKind::EnumElementDecl:
1408
- case DeclContextKind::MacroDecl:
1409
- break ;
1410
- }
1411
-
1412
- dc = dc->getParent ();
1413
- }
1414
-
1415
- // Build the module name path (in reverse), which we use to
1416
- // build the name of the buffer.
1417
- SmallVector<StringRef, 4 > nameComponents;
1418
- while (dc) {
1419
- auto publicName = cast<ModuleDecl>(dc)->
1420
- getPublicModuleName (/* onlyIfImported*/ true );
1421
- nameComponents.push_back (publicName.str ());
1422
- dc = dc->getParent ();
1423
- }
1424
-
1425
- for (unsigned i = nameComponents.size (); i; --i) {
1426
- bufferName += nameComponents[i-1 ];
1427
- bufferName += ' .' ;
1428
- }
1429
-
1430
- if (auto value = dyn_cast<ValueDecl>(ppDecl)) {
1431
- bufferName += value->getBaseName ().userFacingName ();
1432
- } else if (auto ext = dyn_cast<ExtensionDecl>(ppDecl)) {
1433
- bufferName += ext->getExtendedType ().getString ();
1434
- }
1435
-
1436
- // If we're using a lowered access level, give the buffer a distinct
1437
- // name.
1438
- if (bufferAccessLevel != AccessLevel::Public) {
1439
- assert (bufferAccessLevel < AccessLevel::Public
1440
- && " Above-public access levels should use public buffer" );
1441
- bufferName += " (" ;
1442
- bufferName += getAccessLevelSpelling (bufferAccessLevel);
1443
- bufferName += " )" ;
1444
- }
1445
-
1446
- // Pretty-print the declaration we've picked.
1447
- llvm::raw_svector_ostream out (buffer);
1448
- TrackingPrinter printer (entries, out, bufferAccessLevel);
1449
- llvm::SaveAndRestore<bool > isPrettyPrinting (
1450
- IsPrettyPrintingDecl, true );
1451
- ppDecl->print (
1452
- printer,
1453
- PrintOptions::printForDiagnostics (
1454
- bufferAccessLevel,
1455
- decl->getASTContext ().TypeCheckerOpts .PrintFullConvention ));
1456
- }
1457
-
1458
- // Build a buffer with the pretty-printed declaration.
1459
- auto bufferID = SourceMgr.addMemBufferCopy (buffer, bufferName);
1460
- auto memBufferStartLoc = SourceMgr.getLocForBufferStart (bufferID);
1461
-
1462
- SourceMgr.setGeneratedSourceInfo (
1463
- bufferID,
1464
- GeneratedSourceInfo{
1465
- GeneratedSourceInfo::PrettyPrinted,
1466
- CharSourceRange (),
1467
- CharSourceRange (memBufferStartLoc, buffer.size ()),
1468
- ASTNode (const_cast <Decl *>(ppDecl)).getOpaqueValue (),
1469
- nullptr
1470
- }
1471
- );
1472
-
1473
- // Go through all of the pretty-printed entries and record their
1474
- // locations.
1475
- for (auto entry : entries) {
1476
- PrettyPrintedDeclarations[entry.first ] =
1477
- memBufferStartLoc.getAdvancedLoc (entry.second );
1478
- }
1479
-
1480
- // Grab the pretty-printed location.
1481
- ppLoc = PrettyPrintedDeclarations[decl];
1482
- }
1483
-
1484
- loc = ppLoc;
1327
+ loc = evaluateOrDefault (
1328
+ decl->getASTContext ().evaluator , PrettyPrintDeclRequest{decl},
1329
+ SourceLoc ());
1485
1330
}
1486
1331
}
1487
1332
0 commit comments