@@ -1028,17 +1028,46 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
10281028
10291029 bool reportRelatedRef (ValueDecl *D, SourceLoc Loc, bool isImplicit, SymbolRoleSet Relations, Decl *Related);
10301030
1031- // / Report references for dependent types
1031+ // / Report a related type relation for a given TypeRepr.
10321032 // /
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.
10341048 // /
10351049 // / \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.
10371067 // / \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+
10421071 bool reportInheritedTypeRefs (InheritedTypes Inherited, Decl *Inheritee);
10431072
10441073 bool reportPseudoGetterDecl (VarDecl *D) {
@@ -1477,58 +1506,113 @@ bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isI
14771506bool IndexSwiftASTWalker::reportInheritedTypeRefs (InheritedTypes Inherited,
14781507 Decl *Inheritee) {
14791508 for (auto Base : Inherited.getEntries ()) {
1509+ // Suppressed conformances aren't considered base types.
1510+ if (Base.isSuppressed ())
1511+ continue ;
14801512 if (!reportRelatedTypeRef (Base, (SymbolRoleSet) SymbolRole::RelationBaseOf, Inheritee))
14811513 return false ;
14821514 }
14831515 return true ;
14841516}
14851517
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)) {
14901542 for (auto *Type : composite->getTypes ()) {
1491- if (!reportRelatedTypeRef (Type, Relations, Related, /* isImplicit=*/ Implicit, IdLoc))
1543+ if (!reportRelatedTypeRepr (Type, Relations, Related, Implicit,
1544+ ParentLoc)) {
14921545 return false ;
1546+ }
14931547 }
1548+ }
1549+ auto *declRefTR = dyn_cast<DeclRefTypeRepr>(TR);
1550+ if (!declRefTR)
1551+ return true ;
14941552
1553+ auto *VD = declRefTR->getBoundDecl ();
1554+ if (!VD)
14951555 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- }
15111556
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);
15201570 }
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))
15231590 return false ;
15241591 }
15251592 return true ;
15261593 }
15271594
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 ());
15321616 }
15331617 return true ;
15341618}
0 commit comments