Skip to content

Commit 893340d

Browse files
authored
Merge pull request #85175 from ahoppen/swift-access-level
[Index] Record the access level of declarations in the index
2 parents d9383e6 + aa9c295 commit 893340d

40 files changed

+492
-386
lines changed

lib/Index/Index.cpp

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,12 +1108,19 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
11081108
/// Whether the given decl should be marked implicit in the index data.
11091109
bool hasImplicitRole(Decl *D);
11101110

1111-
bool initIndexSymbol(ValueDecl *D, SourceLoc Loc, bool IsRef,
1112-
IndexSymbol &Info);
1111+
bool initIndexSymbol(
1112+
ValueDecl *D, SourceLoc Loc, bool IsRef, IndexSymbol &Info,
1113+
llvm::function_ref<bool(IndexSymbol &)> updateInfo = [](IndexSymbol &) {
1114+
return false;
1115+
});
11131116
bool initIndexSymbol(ExtensionDecl *D, ValueDecl *ExtendedD, SourceLoc Loc,
11141117
IndexSymbol &Info);
11151118
bool initFuncDeclIndexSymbol(FuncDecl *D, IndexSymbol &Info);
1116-
bool initFuncRefIndexSymbol(ValueDecl *D, SourceLoc Loc, IndexSymbol &Info);
1119+
bool initFuncRefIndexSymbol(
1120+
ValueDecl *D, SourceLoc Loc, IndexSymbol &Info,
1121+
llvm::function_ref<bool(IndexSymbol &)> updateInfo = [](IndexSymbol &) {
1122+
return false;
1123+
});
11171124
bool initVarRefIndexSymbols(Expr *CurrentE, ValueDecl *D, SourceLoc Loc,
11181125
IndexSymbol &Info,
11191126
std::optional<AccessKind> AccKind);
@@ -1663,22 +1670,18 @@ bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
16631670
// AbstractStorageDecl.
16641671
assert(getParentDecl() == D);
16651672
auto PreviousTop = EntitiesStack.pop_back_val();
1666-
bool initFailed = initFuncRefIndexSymbol(D, Loc, Info);
1673+
bool initFailed = initFuncRefIndexSymbol(D, Loc, Info, updateInfo);
16671674
EntitiesStack.push_back(PreviousTop);
16681675

16691676
if (initFailed)
16701677
return true; // continue walking.
1671-
if (updateInfo(Info))
1672-
return true;
16731678

16741679
if (!IdxConsumer.startSourceEntity(Info) || !IdxConsumer.finishSourceEntity(Info.symInfo, Info.roles))
16751680
Cancelled = true;
16761681
} else {
16771682
IndexSymbol Info;
1678-
if (initIndexSymbol(D, Loc, IsRef, Info))
1683+
if (initIndexSymbol(D, Loc, IsRef, Info, updateInfo))
16791684
return true; // continue walking.
1680-
if (updateInfo(Info))
1681-
return true;
16821685
if (addRelation(Info, (SymbolRoleSet)SymbolRole::RelationAccessorOf |
16831686
(SymbolRoleSet)SymbolRole::RelationChildOf , D))
16841687
return true;
@@ -1898,16 +1901,20 @@ bool IndexSwiftASTWalker::reportImplicitConformance(ValueDecl *witness, ValueDec
18981901
loc = container->getLoc(/*SerializedOK*/false);
18991902

19001903
IndexSymbol info;
1901-
if (initIndexSymbol(witness, loc, /*IsRef=*/true, info))
1904+
bool initFailed = initIndexSymbol(
1905+
witness, loc, /*IsRef=*/true, info, [](IndexSymbol &info) {
1906+
// Remove the 'ref' role that \c initIndexSymbol introduces. This isn't
1907+
// actually a 'reference', but an 'implicit' override.
1908+
info.roles &= ~(SymbolRoleSet)SymbolRole::Reference;
1909+
info.roles |= (SymbolRoleSet)SymbolRole::Implicit;
1910+
return false;
1911+
});
1912+
if (initFailed)
19021913
return true;
19031914
if (addRelation(info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, requirement))
19041915
return true;
19051916
if (addRelation(info, (SymbolRoleSet) SymbolRole::RelationContainedBy, container))
19061917
return true;
1907-
// Remove the 'ref' role that \c initIndexSymbol introduces. This isn't
1908-
// actually a 'reference', but an 'implicit' override.
1909-
info.roles &= ~(SymbolRoleSet)SymbolRole::Reference;
1910-
info.roles |= (SymbolRoleSet)SymbolRole::Implicit;
19111918

19121919
if (!startEntity(witness, info, /*IsRef=*/true))
19131920
return true;
@@ -1929,8 +1936,47 @@ bool IndexSwiftASTWalker::hasImplicitRole(Decl *D) {
19291936
return false;
19301937
}
19311938

1932-
bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
1933-
bool IsRef, IndexSymbol &Info) {
1939+
bool shouldOutputEffectiveAccessOfValueSymbol(SymbolInfo Info) {
1940+
SymbolKind Kind = Info.Kind;
1941+
SymbolSubKind SubKind = Info.SubKind;
1942+
switch (SubKind) {
1943+
case SymbolSubKind::AccessorGetter:
1944+
case SymbolSubKind::AccessorSetter:
1945+
case SymbolSubKind::SwiftAccessorWillSet:
1946+
case SymbolSubKind::SwiftAccessorDidSet:
1947+
case SymbolSubKind::SwiftAccessorAddressor:
1948+
case SymbolSubKind::SwiftAccessorMutableAddressor:
1949+
case SymbolSubKind::SwiftGenericTypeParam:
1950+
return false;
1951+
default:
1952+
break;
1953+
}
1954+
switch (Kind) {
1955+
case SymbolKind::Enum:
1956+
case SymbolKind::Struct:
1957+
case SymbolKind::Class:
1958+
case SymbolKind::Protocol:
1959+
case SymbolKind::Constructor:
1960+
case SymbolKind::EnumConstant:
1961+
case SymbolKind::Function:
1962+
case SymbolKind::StaticMethod:
1963+
case SymbolKind::Variable:
1964+
case SymbolKind::InstanceMethod:
1965+
case SymbolKind::ClassMethod:
1966+
case SymbolKind::InstanceProperty:
1967+
case SymbolKind::ClassProperty:
1968+
case SymbolKind::StaticProperty:
1969+
case SymbolKind::TypeAlias:
1970+
case SymbolKind::Macro:
1971+
return true;
1972+
default:
1973+
return false;
1974+
}
1975+
}
1976+
1977+
bool IndexSwiftASTWalker::initIndexSymbol(
1978+
ValueDecl *D, SourceLoc Loc, bool IsRef, IndexSymbol &Info,
1979+
llvm::function_ref<bool(IndexSymbol &)> updateInfo) {
19341980
assert(D);
19351981

19361982
auto MappedLoc = getMappedLocation(Loc);
@@ -1970,6 +2016,34 @@ bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
19702016
Info.roles |= (unsigned)SymbolRole::Implicit;
19712017
}
19722018

2019+
if (updateInfo(Info)) {
2020+
return true;
2021+
}
2022+
2023+
if (shouldOutputEffectiveAccessOfValueSymbol(Info.symInfo) &&
2024+
(Info.roles & (SymbolRoleSet)SymbolRole::Reference) == 0 &&
2025+
!isLocalSymbol(D)) {
2026+
AccessScope Scope = D->getFormalAccessScope();
2027+
if (Scope.isPublic()) {
2028+
if (D->isSPI()) {
2029+
Info.symInfo.Properties |= SymbolProperty::SwiftAccessControlSPI;
2030+
} else {
2031+
Info.symInfo.Properties |= SymbolProperty::SwiftAccessControlPublic;
2032+
}
2033+
} else if (Scope.isPackage()) {
2034+
Info.symInfo.Properties |= SymbolProperty::SwiftAccessControlPackage;
2035+
} else if (Scope.isInternal()) {
2036+
Info.symInfo.Properties |= SymbolProperty::SwiftAccessControlInternal;
2037+
} else if (Scope.isFileScope()) {
2038+
Info.symInfo.Properties |= SymbolProperty::SwiftAccessControlFilePrivate;
2039+
} else if (Scope.isPrivate()) {
2040+
Info.symInfo.Properties |=
2041+
SymbolProperty::SwiftAccessControlLessThanFilePrivate;
2042+
} else {
2043+
llvm_unreachable("Unsupported access scope");
2044+
}
2045+
}
2046+
19732047
return false;
19742048
}
19752049

@@ -2036,10 +2110,11 @@ bool IndexSwiftASTWalker::initFuncDeclIndexSymbol(FuncDecl *D,
20362110
return false;
20372111
}
20382112

2039-
bool IndexSwiftASTWalker::initFuncRefIndexSymbol(ValueDecl *D, SourceLoc Loc,
2040-
IndexSymbol &Info) {
2113+
bool IndexSwiftASTWalker::initFuncRefIndexSymbol(
2114+
ValueDecl *D, SourceLoc Loc, IndexSymbol &Info,
2115+
llvm::function_ref<bool(IndexSymbol &)> updateInfo) {
20412116

2042-
if (initIndexSymbol(D, Loc, /*IsRef=*/true, Info))
2117+
if (initIndexSymbol(D, Loc, /*IsRef=*/true, Info, updateInfo))
20432118
return true;
20442119

20452120
if (!isa<AbstractStorageDecl>(D) && !ide::isBeingCalled(ExprStack))

test/Index/access_level.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s -package-name MyModule | %FileCheck %s
2+
3+
private func myPrivateFunc() {}
4+
// CHECK: [[@LINE-1]]:14 | function(fileprivate)/Swift | myPrivateFunc() | {{.*}} | Def | rel: 0
5+
6+
fileprivate func myFileprivateFunc() {}
7+
// CHECK: [[@LINE-1]]:18 | function(fileprivate)/Swift | myFileprivateFunc() | {{.*}} | Def | rel: 0
8+
9+
func myInternalFunc() {}
10+
// CHECK: [[@LINE-1]]:6 | function(internal)/Swift | myInternalFunc() | {{.*}} | Def | rel: 0
11+
12+
package func myPackageFunc() {}
13+
// CHECK: [[@LINE-1]]:14 | function(package)/Swift | myPackageFunc() | {{.*}} | Def | rel: 0
14+
15+
public func myPublicFunc() {}
16+
// CHECK: [[@LINE-1]]:13 | function(public)/Swift | myPublicFunc() | {{.*}} | Def | rel: 0
17+
18+
open class MyOpenClass {}
19+
// CHECK: [[@LINE-1]]:12 | class(public)/Swift | MyOpenClass | {{.*}} | Def | rel: 0
20+
21+
@_spi(MySPI)
22+
public class MyPublicSPIClass {
23+
// CHECK: [[@LINE-1]]:14 | class(SPI)/Swift | MyPublicSPIClass | {{.*}} | Def | rel: 0
24+
25+
public func publicInSPI() {}
26+
// CHECK: [[@LINE-1]]:15 | instance-method(SPI)/Swift | publicInSPI() | {{.*}} | Def,Dyn,RelChild | rel: 1
27+
}
28+
29+
@_spi(MySPI)
30+
open class MyOpenSPIClass {}
31+
// CHECK: [[@LINE-1]]:12 | class(SPI)/Swift | MyOpenSPIClass | {{.*}} | Def | rel: 0
32+
33+
private class Foo {
34+
public func publicInPrivate() {}
35+
// CHECK: [[@LINE-1]]:15 | instance-method(fileprivate)/Swift | publicInPrivate() | {{.*}} | Def,Dyn,RelChild | rel: 1
36+
}
37+
38+
private enum PrivateEnum {
39+
// CHECK: [[@LINE-1]]:14 | enum(fileprivate)/Swift | PrivateEnum | {{.*}} | Def | rel: 0
40+
case myCase
41+
// CHECK: [[@LINE-1]]:8 | enumerator(fileprivate)/Swift | myCase | {{.*}} | Def,RelChild | rel: 1
42+
}
43+
extension PrivateEnum {
44+
private func f() { print("Hello") }
45+
// CHECK: [[@LINE-1]]:16 | instance-method(less_than_private)/Swift | f() | {{.*}} | Def,RelChild | rel: 1
46+
}
47+
48+
enum InternalEnum {
49+
// CHECK: [[@LINE-1]]:6 | enum(internal)/Swift | InternalEnum | {{.*}} | Def | rel: 0
50+
case myCase
51+
// CHECK: [[@LINE-1]]:8 | enumerator(internal)/Swift | myCase | {{.*}} | Def,RelChild | rel: 1
52+
}

test/Index/async.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
44

55
func globalAsyncFunc() async {}
6-
// CHECK: [[@LINE-1]]:6 | function(swift_async)/Swift | globalAsyncFunc() | {{.*}} | Def | rel: 0
6+
// CHECK: [[@LINE-1]]:6 | function(swift_async,internal)/Swift | globalAsyncFunc() | {{.*}} | Def | rel: 0
77

88
struct MyStruct {
99
func asyncMethod() async {}
10-
// CHECK: [[@LINE-1]]:8 | instance-method(swift_async)/Swift | asyncMethod() |
10+
// CHECK: [[@LINE-1]]:8 | instance-method(swift_async,internal)/Swift | asyncMethod() |
1111
}
1212

1313
class XCTestCase {}
1414
class MyTestCase : XCTestCase {
1515
func testSomeAsync() async {}
16-
// CHECK: [[@LINE-1]]:8 | instance-method(test,swift_async)/Swift | testSomeAsync() |
16+
// CHECK: [[@LINE-1]]:8 | instance-method(test,swift_async,internal)/Swift | testSomeAsync() |
1717
}

test/Index/circular.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,66 @@
11
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
22

33
class SelfCycle : SelfCycle {}
4-
// CHECK: [[@LINE-1]]:7 | class/Swift | SelfCycle | {{[^ ]*}} | Def | rel: 0
4+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | SelfCycle | {{[^ ]*}} | Def | rel: 0
55
// CHECK: [[@LINE-2]]:19 | class/Swift | SelfCycle | {{[^ ]*}} | Ref,RelBase | rel: 1
66
// CHECK: RelBase | class/Swift | SelfCycle | {{\W*}}
77

88
class Cycle1_A: Cycle1_B {}
9-
// CHECK: [[@LINE-1]]:7 | class/Swift | Cycle1_A | {{[^ ]*}} | Def | rel: 0
9+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | Cycle1_A | {{[^ ]*}} | Def | rel: 0
1010
// CHECK: [[@LINE-2]]:17 | class/Swift | Cycle1_B | {{[^ ]*}} | Ref,RelBase | rel: 1
1111
// CHECK: RelBase | class/Swift | Cycle1_A | {{[^ ]*}}
1212
class Cycle1_B: Cycle1_A {}
13-
// CHECK: [[@LINE-1]]:7 | class/Swift | Cycle1_B | {{[^ ]*}} | Def | rel: 0
13+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | Cycle1_B | {{[^ ]*}} | Def | rel: 0
1414
// CHECK: [[@LINE-2]]:17 | class/Swift | Cycle1_A | {{[^ ]*}} | Ref,RelBase | rel: 1
1515
// CHECK: RelBase | class/Swift | Cycle1_B | {{[^ ]*}}
1616

1717
class Cycle2_A: Cycle2_C {}
18-
// CHECK: [[@LINE-1]]:7 | class/Swift | Cycle2_A | {{[^ ]*}} | Def | rel: 0
18+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | Cycle2_A | {{[^ ]*}} | Def | rel: 0
1919
// CHECK: [[@LINE-2]]:17 | class/Swift | Cycle2_C | {{[^ ]*}} | Ref,RelBase | rel: 1
2020
// CHECK: RelBase | class/Swift | Cycle2_A | {{[^ ]*}}
2121
class Cycle2_B: Cycle2_A {}
22-
// CHECK: [[@LINE-1]]:7 | class/Swift | Cycle2_B | {{[^ ]*}} | Def | rel: 0
22+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | Cycle2_B | {{[^ ]*}} | Def | rel: 0
2323
// CHECK: [[@LINE-2]]:17 | class/Swift | Cycle2_A | {{[^ ]*}} | Ref,RelBase | rel: 1
2424
// CHECK: RelBase | class/Swift | Cycle2_B | {{[^ ]*}}
2525
class Cycle2_C: Cycle2_B {}
26-
// CHECK: [[@LINE-1]]:7 | class/Swift | Cycle2_C | {{[^ ]*}} | Def | rel: 0
26+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | Cycle2_C | {{[^ ]*}} | Def | rel: 0
2727
// CHECK: [[@LINE-2]]:17 | class/Swift | Cycle2_B | {{[^ ]*}} | Ref,RelBase | rel: 1
2828
// CHECK: RelBase | class/Swift | Cycle2_C | {{[^ ]*}}
2929

3030
class TestCase1: XCTestCase {}
31-
// CHECK: [[@LINE-1]]:7 | class/Swift | TestCase1 | {{[^ ]*}} | Def | rel: 0
31+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | TestCase1 | {{[^ ]*}} | Def | rel: 0
3232
// CHECK: [[@LINE-2]]:18 | class/Swift | XCTestCase | {{[^ ]*}} | Ref,RelBase | rel: 1
3333
// CHECK: RelBase | class/Swift | TestCase1 | {{[^ ]*}}
3434
class XCTestCase: TestCase1 {}
35-
// CHECK: [[@LINE-1]]:7 | class/Swift | XCTestCase | {{[^ ]*}} | Def | rel: 0
35+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | XCTestCase | {{[^ ]*}} | Def | rel: 0
3636
// CHECK: [[@LINE-2]]:19 | class/Swift | TestCase1 | {{[^ ]*}} | Ref,RelBase | rel: 1
3737
// CHECK: RelBase | class/Swift | XCTestCase | {{[^ ]*}}
3838
class TestCase2: TestCase1 {}
39-
// CHECK: [[@LINE-1]]:7 | class/Swift | TestCase2 | {{[^ ]*}} | Def | rel: 0
39+
// CHECK: [[@LINE-1]]:7 | class(internal)/Swift | TestCase2 | {{[^ ]*}} | Def | rel: 0
4040
// CHECK: [[@LINE-2]]:18 | class/Swift | TestCase1 | {{[^ ]*}} | Ref,RelBase | rel: 1
4141
// CHECK: RelBase | class/Swift | TestCase2 | {{[^ ]*}}
4242

4343
protocol SelfCycleP: SelfCycleP {}
44-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | SelfCycleP | {{[^ ]*}} | Def | rel: 0
44+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | SelfCycleP | {{[^ ]*}} | Def | rel: 0
4545
// CHECK: [[@LINE-2]]:22 | protocol/Swift | SelfCycleP | {{[^ ]*}} | Ref,RelBase | rel: 1
4646
// CHECK: RelBase | protocol/Swift | SelfCycleP | {{[^ ]*}}
4747
protocol Cycle1P_A: Cycle1P_B {}
48-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | Cycle1P_A | {{[^ ]*}} | Def | rel: 0
48+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | Cycle1P_A | {{[^ ]*}} | Def | rel: 0
4949
// CHECK: [[@LINE-2]]:21 | protocol/Swift | Cycle1P_B | {{[^ ]*}} | Ref,RelBase | rel: 1
5050
// CHECK: RelBase | protocol/Swift | Cycle1P_A | {{[^ ]*}}
5151
protocol Cycle1P_B: Cycle1P_A {}
52-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | Cycle1P_B | {{[^ ]*}} | Def | rel: 0
52+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | Cycle1P_B | {{[^ ]*}} | Def | rel: 0
5353
// CHECK: [[@LINE-2]]:21 | protocol/Swift | Cycle1P_A | {{[^ ]*}} | Ref,RelBase | rel: 1
5454
// CHECK: RelBase | protocol/Swift | Cycle1P_B | {{[^ ]*}}
5555
protocol Cycle2P_A: Cycle2P_C {}
56-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | Cycle2P_A | {{[^ ]*}} | Def | rel: 0
56+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | Cycle2P_A | {{[^ ]*}} | Def | rel: 0
5757
// CHECK: [[@LINE-2]]:21 | protocol/Swift | Cycle2P_C | {{[^ ]*}} | Ref,RelBase | rel: 1
5858
// CHECK: RelBase | protocol/Swift | Cycle2P_A | {{[^ ]*}}
5959
protocol Cycle2P_B: Cycle2P_A {}
60-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | Cycle2P_B | {{[^ ]*}} | Def | rel: 0
60+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | Cycle2P_B | {{[^ ]*}} | Def | rel: 0
6161
// CHECK: [[@LINE-2]]:21 | protocol/Swift | Cycle2P_A | {{[^ ]*}} | Ref,RelBase | rel: 1
6262
// CHECK: RelBase | protocol/Swift | Cycle2P_B | {{[^ ]*}}
6363
protocol Cycle2P_C: Cycle2P_B {}
64-
// CHECK: [[@LINE-1]]:10 | protocol/Swift | Cycle2P_C | {{[^ ]*}} | Def | rel: 0
64+
// CHECK: [[@LINE-1]]:10 | protocol(internal)/Swift | Cycle2P_C | {{[^ ]*}} | Def | rel: 0
6565
// CHECK: [[@LINE-2]]:21 | protocol/Swift | Cycle2P_B | {{[^ ]*}} | Ref,RelBase | rel: 1
6666
// CHECK: RelBase | protocol/Swift | Cycle2P_C | {{[^ ]*}}

0 commit comments

Comments
 (0)