Skip to content

Commit 99f6341

Browse files
committed
[Index] Handle more cases in reportRelatedTypeRef
Look through attributed/specifier/paren TypeReprs, avoid reporting `RelBase` relations for suppressed conformances, and handle protocol compositions for the `Type` code path. rdar://146331982
1 parent 548374d commit 99f6341

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

lib/Index/Index.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,9 @@ bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isI
15061506
bool IndexSwiftASTWalker::reportInheritedTypeRefs(InheritedTypes Inherited,
15071507
Decl *Inheritee) {
15081508
for (auto Base : Inherited.getEntries()) {
1509+
// Suppressed conformances aren't considered base types.
1510+
if (Base.isSuppressed())
1511+
continue;
15091512
if (!reportRelatedTypeRef(Base, (SymbolRoleSet) SymbolRole::RelationBaseOf, Inheritee))
15101513
return false;
15111514
}
@@ -1516,6 +1519,25 @@ bool IndexSwiftASTWalker::reportRelatedTypeRepr(const TypeRepr *TR,
15161519
SymbolRoleSet Relations,
15171520
Decl *Related, bool Implicit,
15181521
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+
15191541
if (auto *composite = dyn_cast<CompositionTypeRepr>(TR)) {
15201542
for (auto *Type : composite->getTypes()) {
15211543
if (!reportRelatedTypeRepr(Type, Relations, Related, Implicit,
@@ -1561,6 +1583,15 @@ bool IndexSwiftASTWalker::reportRelatedTypeRepr(const TypeRepr *TR,
15611583
bool IndexSwiftASTWalker::reportRelatedType(Type Ty, SymbolRoleSet Relations,
15621584
Decl *Related, bool Implicit,
15631585
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))
1590+
return false;
1591+
}
1592+
return true;
1593+
}
1594+
15641595
if (auto *nominal = Ty->getAnyNominal()) {
15651596
if (!reportRelatedRef(nominal, Loc, Implicit, Relations, Related))
15661597
return false;

test/Index/conformances.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ struct DirectConf: P1 { // CHECK: [[@LINE]]:8 | struct/Swift | DirectConf | [[Di
1010
// CHECK-NEXT: RelChild | struct/Swift | DirectConf | [[DirectConf_USR]]
1111
}
1212

13+
struct LookThroughReprs: (@unchecked (Sendable)) {}
14+
// CHECK: [[@LINE-1]]:39 | protocol/Swift | Sendable | s:s8SendableP | Ref,RelBase | rel: 1
15+
// CHECK-NEXT: RelBase | struct/Swift | LookThroughReprs | s:14swift_ide_test16LookThroughReprsV
16+
17+
// No RelBase relation here since `Copyable` isn't a base type. Also make sure
18+
// we don't put a reference at the `~`.
19+
struct NonCopyable: ~Copyable {}
20+
// CHECK-NOT: [[@LINE-1]]:21
21+
// CHECK: [[@LINE-2]]:22 | protocol/Swift | Copyable | s:s8CopyableP | Ref | rel: 0
22+
// CHECK-NOT: [[@LINE-3]]:21
23+
24+
protocol NonCopyableProto: ~Copyable {}
25+
26+
struct AlsoNonCopyable: NonCopyableProto & ~Copyable {}
27+
// CHECK: [[@LINE-1]]:25 | protocol/Swift | NonCopyableProto | s:14swift_ide_test16NonCopyableProtoP | Ref,RelBase | rel: 1
28+
// CHECK-NEXT: RelBase | struct/Swift | AlsoNonCopyable | s:14swift_ide_test15AlsoNonCopyableV
29+
// CHECK-NEXT: [[@LINE-3]]:45 | protocol/Swift | Copyable | s:s8CopyableP | Ref | rel: 0
30+
1331
struct ConfFromExtension {}
1432
extension ConfFromExtension: P1 { // CHECK: [[@LINE]]:11 | extension/ext-struct/Swift | ConfFromExtension | [[ConfFromExtension_ext_USR:.*]] | Def
1533
func foo() {} // CHECK: [[@LINE]]:8 | instance-method/Swift | foo() | [[ConfFromExtension_ext_foo_USR:.*]] | Def,RelChild,RelOver | rel: 2

test/Index/index_imported.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file --leading-lines %s %t
3+
4+
// RUN: %target-swift-frontend -emit-module -o %t/Lib.swiftmodule %t/Lib.swift -module-name Lib
5+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/main.swift -module-to-print Lib -I %t | %FileCheck %s --check-prefix LIB
6+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/main.swift -I %t | %FileCheck %s
7+
8+
//--- Lib.swift
9+
10+
public protocol P {}
11+
public protocol Q {}
12+
public protocol R {}
13+
14+
public typealias X = Q & R
15+
16+
public struct S: X & P {}
17+
// LIB: 0:0 | protocol/Swift | Q | s:3Lib1QP | Ref,RelBase | rel: 1
18+
// LIB-NEXT: RelBase | struct/Swift | S | s:3Lib1SV
19+
// LIB-NEXT: 0:0 | protocol/Swift | R | s:3Lib1RP | Ref,RelBase | rel: 1
20+
// LIB-NEXT: RelBase | struct/Swift | S | s:3Lib1SV
21+
// LIB-NEXT: 0:0 | protocol/Swift | P | s:3Lib1PP | Ref,RelBase | rel: 1
22+
// LIB-NEXT: RelBase | struct/Swift | S | s:3Lib1SV
23+
24+
public protocol NonCopyableProto: ~Copyable {}
25+
public struct NonCopyable: NonCopyableProto & ~Copyable {}
26+
// LIB: 0:0 | protocol/Swift | NonCopyableProto | s:3Lib16NonCopyableProtoP | Ref,RelBase | rel: 1
27+
// LIB-NEXT: RelBase | struct/Swift | NonCopyable | s:3Lib11NonCopyableV
28+
29+
// We don't currently have a relation for Copyable.
30+
// LIB-NOT: s:s8CopyableP
31+
32+
//--- main.swift
33+
34+
import Lib
35+
36+
struct K: P & X {}
37+
// CHECK: [[@LINE-1]]:11 | protocol/Swift | P | s:3Lib1PP | Ref,RelBase | rel: 1
38+
// CHECK-NEXT: RelBase | struct/Swift | K | s:14swift_ide_test1KV
39+
// CHECK-NEXT: [[@LINE-3]]:15 | type-alias/Swift | X | s:3Lib1Xa | Ref | rel: 0
40+
// CHECK-NEXT: [[@LINE-4]]:15 | protocol/Swift | Q | s:3Lib1QP | Ref,Impl,RelBase | rel: 1
41+
// CHECK-NEXT: RelBase | struct/Swift | K | s:14swift_ide_test1KV
42+
// CHECK-NEXT: [[@LINE-6]]:15 | protocol/Swift | R | s:3Lib1RP | Ref,Impl,RelBase | rel: 1
43+
// CHECK-NEXT: RelBase | struct/Swift | K | s:14swift_ide_test1KV

0 commit comments

Comments
 (0)