@@ -1028,17 +1028,46 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
1028
1028
1029
1029
bool reportRelatedRef (ValueDecl *D, SourceLoc Loc, bool isImplicit, SymbolRoleSet Relations, Decl *Related);
1030
1030
1031
- // / Report references for dependent types
1031
+ // / Report a related type relation for a given TypeRepr.
1032
1032
// /
1033
- // / NOTE: If the dependent type is a typealias, report the underlying types as well.
1033
+ // / NOTE: If the dependent type is a typealias, report the underlying types as
1034
+ // / well.
1035
+ // /
1036
+ // / \param TR The type being referenced.
1037
+ // / \param Relations The relationship between the referenced type and the
1038
+ // / passed Decl.
1039
+ // / \param Related The Decl that is referencing the type.
1040
+ // / \param Implicit Whether the reference is implicit, such as for a
1041
+ // / typealias' underlying type.
1042
+ // / \param ParentLoc The parent location of the reference that should be used
1043
+ // / for implicit references.
1044
+ bool reportRelatedTypeRepr (const TypeRepr *TR, SymbolRoleSet Relations,
1045
+ Decl *Related, bool Implicit, SourceLoc ParentLoc);
1046
+
1047
+ // / Report a related type relation for a Type at a given location.
1034
1048
// /
1035
1049
// / \param Ty The type being referenced.
1036
- // / \param Relations The relationship between the referenced type and the passed Decl.
1050
+ // / \param Relations The relationship between the referenced type and the
1051
+ // / passed Decl.
1052
+ // / \param Related The Decl that is referencing the type.
1053
+ // / \param Implicit Whether the reference is implicit, such as for a
1054
+ // / typealias' underlying type.
1055
+ // / \param Loc The location of the reference.
1056
+ bool reportRelatedType (Type Ty, SymbolRoleSet Relations, Decl *Related,
1057
+ bool Implicit, SourceLoc Loc);
1058
+
1059
+ // / Report references for dependent types.
1060
+ // /
1061
+ // / NOTE: If the dependent type is a typealias, report the underlying types as
1062
+ // / well.
1063
+ // /
1064
+ // / \param TL The type being referenced.
1065
+ // / \param Relations The relationship between the referenced type and the
1066
+ // / passed Decl.
1037
1067
// / \param Related The Decl that is referencing the type.
1038
- // / \param isImplicit Whether the reference is implicit, such as for a typealias' underlying type.
1039
- // / \param Loc The location of the reference, otherwise the location of the TypeLoc is used.
1040
- bool reportRelatedTypeRef (const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related,
1041
- bool isImplicit=false , SourceLoc Loc={});
1068
+ bool reportRelatedTypeRef (const TypeLoc &TL, SymbolRoleSet Relations,
1069
+ Decl *Related);
1070
+
1042
1071
bool reportInheritedTypeRefs (InheritedTypes Inherited, Decl *Inheritee);
1043
1072
1044
1073
bool reportPseudoGetterDecl (VarDecl *D) {
@@ -1477,58 +1506,113 @@ bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isI
1477
1506
bool IndexSwiftASTWalker::reportInheritedTypeRefs (InheritedTypes Inherited,
1478
1507
Decl *Inheritee) {
1479
1508
for (auto Base : Inherited.getEntries ()) {
1509
+ // Suppressed conformances aren't considered base types.
1510
+ if (Base.isSuppressed ())
1511
+ continue ;
1480
1512
if (!reportRelatedTypeRef (Base, (SymbolRoleSet) SymbolRole::RelationBaseOf, Inheritee))
1481
1513
return false ;
1482
1514
}
1483
1515
return true ;
1484
1516
}
1485
1517
1486
- bool IndexSwiftASTWalker::reportRelatedTypeRef (const TypeLoc &Ty, SymbolRoleSet Relations,
1487
- Decl *Related, bool Implicit, SourceLoc Loc) {
1488
- if (auto *composite = llvm::dyn_cast_or_null<CompositionTypeRepr>(Ty.getTypeRepr ())) {
1489
- SourceLoc IdLoc = Loc.isValid () ? Loc : composite->getSourceLoc ();
1518
+ bool IndexSwiftASTWalker::reportRelatedTypeRepr (const TypeRepr *TR,
1519
+ SymbolRoleSet Relations,
1520
+ Decl *Related, bool Implicit,
1521
+ SourceLoc ParentLoc) {
1522
+ // Look through parens/specifiers/attributes.
1523
+ while (true ) {
1524
+ if (TR->isParenType ()) {
1525
+ TR = TR->getWithoutParens ();
1526
+ continue ;
1527
+ }
1528
+ if (auto *SPR = dyn_cast<SpecifierTypeRepr>(TR)) {
1529
+ TR = SPR->getBase ();
1530
+ continue ;
1531
+ }
1532
+ if (auto *ATR = dyn_cast<AttributedTypeRepr>(TR)) {
1533
+ TR = ATR->getTypeRepr ();
1534
+ continue ;
1535
+ }
1536
+ break ;
1537
+ }
1538
+ // NOTE: We don't yet handle InverseTypeRepr since we don't have an inverse
1539
+ // relation for inheritance.
1540
+
1541
+ if (auto *composite = dyn_cast<CompositionTypeRepr>(TR)) {
1490
1542
for (auto *Type : composite->getTypes ()) {
1491
- if (!reportRelatedTypeRef (Type, Relations, Related, /* isImplicit=*/ Implicit, IdLoc))
1543
+ if (!reportRelatedTypeRepr (Type, Relations, Related, Implicit,
1544
+ ParentLoc)) {
1492
1545
return false ;
1546
+ }
1493
1547
}
1548
+ }
1549
+ auto *declRefTR = dyn_cast<DeclRefTypeRepr>(TR);
1550
+ if (!declRefTR)
1551
+ return true ;
1494
1552
1553
+ auto *VD = declRefTR->getBoundDecl ();
1554
+ if (!VD)
1495
1555
return true ;
1496
- } else if (auto *declRefTR = dyn_cast_or_null<DeclRefTypeRepr>(Ty.getTypeRepr ())) {
1497
- SourceLoc IdLoc = Loc.isValid () ? Loc : declRefTR->getLoc ();
1498
- NominalTypeDecl *NTD = nullptr ;
1499
- bool isImplicit = Implicit;
1500
- if (auto *VD = declRefTR->getBoundDecl ()) {
1501
- if (auto *TAD = dyn_cast<TypeAliasDecl>(VD)) {
1502
- IndexSymbol Info;
1503
- if (isImplicit)
1504
- Info.roles |= (unsigned )SymbolRole::Implicit;
1505
- if (!reportRef (TAD, IdLoc, Info, std::nullopt))
1506
- return false ;
1507
- if (auto Ty = TAD->getUnderlyingType ()) {
1508
- NTD = Ty->getAnyNominal ();
1509
- isImplicit = true ;
1510
- }
1511
1556
1512
- if (isa_and_nonnull<CompositionTypeRepr>(TAD->getUnderlyingTypeRepr ())) {
1513
- TypeLoc TL (TAD->getUnderlyingTypeRepr (), TAD->getUnderlyingType ());
1514
- if (!reportRelatedTypeRef (TL, Relations, Related, /* isImplicit=*/ true , IdLoc))
1515
- return false ;
1516
- }
1517
- } else {
1518
- NTD = dyn_cast<NominalTypeDecl>(VD);
1519
- }
1557
+ SourceLoc IdLoc = ParentLoc.isValid () ? ParentLoc : declRefTR->getLoc ();
1558
+ if (auto *TAD = dyn_cast<TypeAliasDecl>(VD)) {
1559
+ IndexSymbol Info;
1560
+ if (Implicit)
1561
+ Info.roles |= (unsigned )SymbolRole::Implicit;
1562
+ if (!reportRef (TAD, IdLoc, Info, std::nullopt))
1563
+ return false ;
1564
+
1565
+ // Recurse into the underlying type and report any found references as
1566
+ // implicit references at the location of the typealias reference.
1567
+ if (auto *UTR = TAD->getUnderlyingTypeRepr ()) {
1568
+ return reportRelatedTypeRepr (UTR, Relations, Related,
1569
+ /* Implicit*/ true , /* ParentLoc*/ IdLoc);
1520
1570
}
1521
- if (NTD) {
1522
- if (!reportRelatedRef (NTD, IdLoc, isImplicit, Relations, Related))
1571
+ // If we don't have a TypeRepr available, this is a typealias in another
1572
+ // module, consult the computed underlying type.
1573
+ return reportRelatedType (TAD->getUnderlyingType (), Relations, Related,
1574
+ /* Implicit*/ true , /* ParentLoc*/ IdLoc);
1575
+ }
1576
+ if (auto *NTD = dyn_cast<NominalTypeDecl>(VD)) {
1577
+ if (!reportRelatedRef (NTD, IdLoc, Implicit, Relations, Related))
1578
+ return false ;
1579
+ }
1580
+ return true ;
1581
+ }
1582
+
1583
+ bool IndexSwiftASTWalker::reportRelatedType (Type Ty, SymbolRoleSet Relations,
1584
+ Decl *Related, bool Implicit,
1585
+ SourceLoc Loc) {
1586
+ // Try decompose a protocol composition.
1587
+ if (auto *PCT = Ty->getAs <ProtocolCompositionType>()) {
1588
+ for (auto member : PCT->getMembers ()) {
1589
+ if (!reportRelatedType (member, Relations, Related, Implicit, Loc))
1523
1590
return false ;
1524
1591
}
1525
1592
return true ;
1526
1593
}
1527
1594
1528
- if (Ty.getType ()) {
1529
- if (auto nominal = Ty.getType ()->getAnyNominal ())
1530
- if (!reportRelatedRef (nominal, Ty.getLoc (), /* isImplicit=*/ false , Relations, Related))
1531
- return false ;
1595
+ if (auto *nominal = Ty->getAnyNominal ()) {
1596
+ if (!reportRelatedRef (nominal, Loc, Implicit, Relations, Related))
1597
+ return false ;
1598
+ }
1599
+ return true ;
1600
+ }
1601
+
1602
+ bool IndexSwiftASTWalker::reportRelatedTypeRef (const TypeLoc &TL,
1603
+ SymbolRoleSet Relations,
1604
+ Decl *Related) {
1605
+ // If we have a TypeRepr, prefer that since it lets us match up source
1606
+ // locations with the code the user wrote.
1607
+ if (auto *TR = TL.getTypeRepr ()) {
1608
+ return reportRelatedTypeRepr (TR, Relations, Related, /* Implicit*/ false ,
1609
+ /* ParentLoc*/ SourceLoc ());
1610
+ }
1611
+ // Otherwise fall back to reporting the Type, this is necessary when indexing
1612
+ // swiftmodules.
1613
+ if (auto Ty = TL.getType ()) {
1614
+ return reportRelatedType (Ty, Relations, Related,
1615
+ /* Implicit*/ false , SourceLoc ());
1532
1616
}
1533
1617
return true ;
1534
1618
}
0 commit comments