Skip to content

Commit 169cb0f

Browse files
committed
Add package access level to enum AccessLevel
Resolves rdar://104198440
1 parent 3d36113 commit 169cb0f

32 files changed

+108
-22
lines changed

include/swift/AST/AccessScope.h

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace swift {
2222

23+
enum class AccessLimitKind : uint8_t { None = 0, Private, Package };
2324
/// The wrapper around the outermost DeclContext from which
2425
/// a particular declaration can be accessed.
2526
class AccessScope {
@@ -28,12 +29,17 @@ class AccessScope {
2829
/// If the declaration context is set, the bit means that the scope is
2930
/// private or not. If the declaration context is null, the bit means that
3031
/// this scope is SPI or not.
31-
llvm::PointerIntPair<const DeclContext *, 1, bool> Value;
32+
llvm::PointerIntPair<const DeclContext *, 1, AccessLimitKind> Value;
3233

3334
public:
34-
AccessScope(const DeclContext *DC, bool isPrivate = false);
35-
36-
static AccessScope getPublic() { return AccessScope(nullptr, false); }
35+
AccessScope(const DeclContext *DC,
36+
AccessLimitKind limitKind = AccessLimitKind::None);
37+
static AccessScope getPublic() {
38+
return AccessScope(nullptr, AccessLimitKind::None);
39+
}
40+
static AccessScope getPackage() {
41+
return AccessScope(nullptr, AccessLimitKind::Package);
42+
}
3743

3844
/// Check if private access is allowed. This is a lexical scope check in Swift
3945
/// 3 mode. In Swift 4 mode, declarations and extensions of the same type will
@@ -46,25 +52,45 @@ class AccessScope {
4652
bool operator==(AccessScope RHS) const { return Value == RHS.Value; }
4753
bool operator!=(AccessScope RHS) const { return !(*this == RHS); }
4854
bool hasEqualDeclContextWith(AccessScope RHS) const {
55+
if (isPublic())
56+
return RHS.isPublic();
57+
if (isPackage())
58+
return RHS.isPackage();
4959
return getDeclContext() == RHS.getDeclContext();
5060
}
5161

52-
bool isPublic() const { return !Value.getPointer(); }
53-
bool isPrivate() const { return Value.getPointer() && Value.getInt(); }
62+
bool isPublic() const {
63+
return !Value.getPointer() && Value.getInt() == AccessLimitKind::None;
64+
}
65+
bool isPackage() const {
66+
return !Value.getPointer() && Value.getInt() == AccessLimitKind::Package;
67+
}
68+
bool isPrivate() const {
69+
return Value.getPointer() && Value.getInt() == AccessLimitKind::Private;
70+
}
5471
bool isFileScope() const;
5572
bool isInternal() const;
5673

5774
/// Returns true if this is a child scope of the specified other access scope.
5875
///
5976
/// \see DeclContext::isChildContextOf
6077
bool isChildOf(AccessScope AS) const {
61-
if (!isPublic() && !AS.isPublic())
62-
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext());
63-
if (isPublic() && AS.isPublic())
64-
return false;
65-
return AS.isPublic();
78+
if (isInternalOrLess()) {
79+
if (AS.isInternalOrLess())
80+
return allowsPrivateAccess(getDeclContext(), AS.getDeclContext());
81+
else
82+
return AS.isPackage() || AS.isPublic();
83+
}
84+
if (isPackage())
85+
return AS.isPublic();
86+
87+
// If this is public, it can't be less than access level of AS, so return
88+
// false
89+
return false;
6690
}
6791

92+
bool isInternalOrLess() const { return getDeclContext() != nullptr; }
93+
6894
/// Returns the associated access level for diagnostic purposes.
6995
AccessLevel accessLevelForDiagnostics() const;
7096

include/swift/AST/AttrKind.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ enum class AccessLevel : uint8_t {
6060
FilePrivate,
6161
/// Internal access is limited to the current module.
6262
Internal,
63+
/// Package access is not limited, but some capabilities may be
64+
/// restricted outside of the current package containing modules.
65+
/// It's similar to Public in that it's accessible from other modules
66+
/// and subclassable only within the definng module as long as
67+
/// the modules are in the same package.
68+
Package,
6369
/// Public access is not limited, but some capabilities may be
6470
/// restricted outside of the current module.
6571
Public,

include/swift/AST/Decl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,13 +687,14 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
687687
NumPathElements : 8
688688
);
689689

690-
SWIFT_INLINE_BITFIELD(ExtensionDecl, Decl, 3+1,
690+
SWIFT_INLINE_BITFIELD(ExtensionDecl, Decl, 4+1,
691691
/// An encoding of the default and maximum access level for this extension.
692+
/// The value 4 corresponds to AccessLevel::Public
692693
///
693694
/// This is encoded as (1 << (maxAccess-1)) | (1 << (defaultAccess-1)),
694695
/// which works because the maximum is always greater than or equal to the
695696
/// default, and 'private' is never used. 0 represents an uncomputed value.
696-
DefaultAndMaxAccessLevel : 3,
697+
DefaultAndMaxAccessLevel : 4,
697698

698699
/// Whether there is are lazily-loaded conformances for this extension.
699700
HasLazyConformances : 1

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,7 @@ SDKContext::shouldIgnore(Decl *D, const Decl* Parent) const {
17331733
case AccessLevel::Private:
17341734
case AccessLevel::FilePrivate:
17351735
return true;
1736+
case AccessLevel::Package:
17361737
case AccessLevel::Public:
17371738
case AccessLevel::Open:
17381739
break;

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
728728
case AccessLevel::Public:
729729
Printer << tok::kw_public;
730730
break;
731+
case AccessLevel::Package:
732+
Printer.printKeyword("package", Options);
733+
break;
731734
case AccessLevel::Open:
732735
Printer.printKeyword("open", Options);
733736
break;

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ class Verifier : public ASTWalker {
944944
PrettyStackTraceDecl debugStack("verifying access", D);
945945
if (!D->getASTContext().isAccessControlDisabled() &&
946946
D->getFormalAccessScope().isPublic() &&
947-
D->getFormalAccess() < AccessLevel::Public) {
947+
D->getFormalAccess() <= AccessLevel::Internal) {
948948
Out << "non-public decl has no formal access scope\n";
949949
D->dump(Out);
950950
abort();

lib/AST/AccessRequests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ DefaultAndMaxAccessLevelRequest::evaluate(Evaluator &evaluator,
251251
maxAccess = AccessLevel::Public;
252252
} else if (maxScope->isPublic()) {
253253
maxAccess = AccessLevel::Public;
254+
} else if (maxScope->isPackage()) {
255+
maxAccess = AccessLevel::Package;
254256
} else if (isa<ModuleDecl>(maxScope->getDeclContext())) {
255257
maxAccess = AccessLevel::Internal;
256258
} else {

lib/AST/Attr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ StringRef swift::getAccessLevelSpelling(AccessLevel value) {
7474
case AccessLevel::Private: return "private";
7575
case AccessLevel::FilePrivate: return "fileprivate";
7676
case AccessLevel::Internal: return "internal";
77+
case AccessLevel::Package: return "package";
7778
case AccessLevel::Public: return "public";
7879
case AccessLevel::Open: return "open";
7980
}

lib/AST/Decl.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,6 +3598,7 @@ AccessLevel ValueDecl::getEffectiveAccess() const {
35983598
switch (effectiveAccess) {
35993599
case AccessLevel::Open:
36003600
break;
3601+
case AccessLevel::Package:
36013602
case AccessLevel::Public:
36023603
case AccessLevel::Internal:
36033604
if (getModuleContext()->isTestingEnabled() ||
@@ -3678,11 +3679,13 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
36783679
while (!resultDC->isModuleScopeContext()) {
36793680
if (isa<TopLevelCodeDecl>(resultDC)) {
36803681
return AccessScope(resultDC->getModuleScopeContext(),
3681-
access == AccessLevel::Private);
3682+
access == AccessLevel::Private
3683+
? AccessLimitKind::Private
3684+
: AccessLimitKind::None);
36823685
}
36833686

36843687
if (resultDC->isLocalContext() || access == AccessLevel::Private)
3685-
return AccessScope(resultDC, /*private*/true);
3688+
return AccessScope(resultDC, AccessLimitKind::Private);
36863689

36873690
if (auto enclosingNominal = dyn_cast<GenericTypeDecl>(resultDC)) {
36883691
auto enclosingAccess =
@@ -3713,9 +3716,12 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
37133716
case AccessLevel::Private:
37143717
case AccessLevel::FilePrivate:
37153718
assert(resultDC->isModuleScopeContext());
3716-
return AccessScope(resultDC, access == AccessLevel::Private);
3719+
return AccessScope(resultDC, access == AccessLevel::Private
3720+
? AccessLimitKind::Private
3721+
: AccessLimitKind::None);
37173722
case AccessLevel::Internal:
37183723
return AccessScope(resultDC->getParentModule());
3724+
case AccessLevel::Package:
37193725
case AccessLevel::Public:
37203726
case AccessLevel::Open:
37213727
return AccessScope::getPublic();
@@ -3865,6 +3871,7 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,
38653871
auto *useSF = dyn_cast<SourceFile>(useFile);
38663872
return useSF && useSF->hasTestableOrPrivateImport(access, sourceModule);
38673873
}
3874+
case AccessLevel::Package:
38683875
case AccessLevel::Public:
38693876
case AccessLevel::Open:
38703877
return true;

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,12 +1136,15 @@ getPrivateDeclContext(const DeclContext *DC, const SourceFile *useSF) {
11361136
return lastExtension ? lastExtension : DC;
11371137
}
11381138

1139-
AccessScope::AccessScope(const DeclContext *DC, bool isPrivate)
1140-
: Value(DC, isPrivate) {
1141-
if (isPrivate) {
1139+
AccessScope::AccessScope(const DeclContext *DC, AccessLimitKind limitKind)
1140+
: Value(DC, limitKind) {
1141+
auto isPrivate = false;
1142+
if (limitKind == AccessLimitKind::Private) {
11421143
DC = getPrivateDeclContext(DC, DC->getParentSourceFile());
11431144
Value.setPointer(DC);
1145+
isPrivate = true;
11441146
}
1147+
11451148
if (!DC || isa<ModuleDecl>(DC))
11461149
assert(!isPrivate && "public or internal scope can't be private");
11471150
}

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2752,6 +2752,7 @@ bool SourceFile::hasTestableOrPrivateImport(
27522752
auto *module = ofDecl->getModuleContext();
27532753
switch (accessLevel) {
27542754
case AccessLevel::Internal:
2755+
case AccessLevel::Package:
27552756
case AccessLevel::Public:
27562757
// internal/public access only needs an import marked as @_private. The
27572758
// filename does not need to match (and we don't serialize it for such

lib/IDE/CodeCompletionResultBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ class CodeCompletionResultBuilder {
179179
case AccessLevel::Internal:
180180
// 'internal' is the default, don't add it.
181181
break;
182+
case AccessLevel::Package:
183+
addChunkWithTextNoCopy(
184+
CodeCompletionString::Chunk::ChunkKind::AccessControlKeyword,
185+
"package ");
186+
break;
182187
case AccessLevel::Public:
183188
addChunkWithTextNoCopy(
184189
CodeCompletionString::Chunk::ChunkKind::AccessControlKeyword,

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,7 @@ bool IRGenerator::hasLazyMetadata(TypeDecl *type) {
15291529
switch (type->getEffectiveAccess()) {
15301530
case AccessLevel::Open:
15311531
case AccessLevel::Public:
1532+
case AccessLevel::Package:
15321533
// We can't remove metadata for externally visible types.
15331534
return false;
15341535
case AccessLevel::Internal:

lib/SIL/IR/SIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
4040
return FormalLinkage::PublicNonUnique;
4141

4242
switch (D->getEffectiveAccess()) {
43+
case AccessLevel::Package:
4344
case AccessLevel::Public:
4445
case AccessLevel::Open:
4546
return FormalLinkage::PublicUnique;

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,7 @@ SILLinkage SILDeclRef::getDefinitionLinkage() const {
600600
return SILLinkage::Shared;
601601
return SILLinkage::Hidden;
602602

603+
case AccessLevel::Package:
603604
case AccessLevel::Public:
604605
case AccessLevel::Open:
605606
switch (limit) {
@@ -1490,6 +1491,7 @@ SubclassScope SILDeclRef::getSubclassScope() const {
14901491
// SILModule, so we don't need to do anything.
14911492
return SubclassScope::NotApplicable;
14921493
case AccessLevel::Internal:
1494+
case AccessLevel::Package:
14931495
case AccessLevel::Public:
14941496
// If the class is internal or public, it can only be subclassed from
14951497
// the same AST Module, but possibly a different SILModule.

lib/SIL/IR/SILModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,7 @@ SILLinkage swift::getDeclSILLinkage(const ValueDecl *decl) {
926926
case AccessLevel::Internal:
927927
linkage = SILLinkage::Hidden;
928928
break;
929+
case AccessLevel::Package:
929930
case AccessLevel::Public:
930931
case AccessLevel::Open:
931932
linkage = SILLinkage::Public;

lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ void CalleeCache::computeWitnessMethodCalleesForWitnessTable(
177177
switch (Conf->getProtocol()->getEffectiveAccess()) {
178178
case AccessLevel::Open:
179179
llvm_unreachable("protocols cannot have open access level");
180+
case AccessLevel::Package:
180181
case AccessLevel::Public:
181182
canCallUnknown = true;
182183
break;

lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ class DeadFunctionAndGlobalElimination {
394394
case AccessLevel::Internal:
395395
linkage = SILLinkage::Hidden;
396396
break;
397+
case AccessLevel::Package:
397398
case AccessLevel::Public:
398399
case AccessLevel::Open:
399400
linkage = SILLinkage::Public;

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ static bool canBeChangedExternally(SILGlobalVariable *SILG) {
490490
return false;
491491
case AccessLevel::Internal:
492492
return !SILG->getModule().isWholeModule();
493+
case AccessLevel::Package:
493494
case AccessLevel::Public:
494495
case AccessLevel::Open:
495496
return true;

lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static bool isDefaultCaseKnown(ClassHierarchyAnalysis *CHA,
305305
case AccessLevel::Open:
306306
return false;
307307
case AccessLevel::Public:
308+
case AccessLevel::Package:
308309
case AccessLevel::Internal:
309310
if (!AI.getModule().isWholeModule())
310311
return false;

lib/SILOptimizer/Utils/Devirtualize.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ static bool isKnownFinalClass(ClassDecl *cd, SILModule &module,
156156
case AccessLevel::Open:
157157
return false;
158158
case AccessLevel::Public:
159+
case AccessLevel::Package:
159160
case AccessLevel::Internal:
160161
if (!module.isWholeModule())
161162
return false;
@@ -177,6 +178,7 @@ static bool isKnownFinalClass(ClassDecl *cd, SILModule &module,
177178
case AccessLevel::Open:
178179
return false;
179180
case AccessLevel::Public:
181+
case AccessLevel::Package:
180182
case AccessLevel::Internal:
181183
if (!module.isWholeModule())
182184
return false;

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,7 @@ bool swift::calleesAreStaticallyKnowable(SILModule &module, ValueDecl *vd) {
13441344
case AccessLevel::Open:
13451345
return false;
13461346
case AccessLevel::Public:
1347+
case AccessLevel::Package:
13471348
if (isa<ConstructorDecl>(vd)) {
13481349
// Constructors are special: a derived class in another module can
13491350
// "override" a constructor if its class is "open", although the

lib/Sema/MiscDiagnostics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5554,6 +5554,7 @@ void swift::fixItAccess(InFlightDiagnostic &diag, ValueDecl *VD,
55545554
case AccessLevel::Private: fixItString = "private "; break;
55555555
case AccessLevel::FilePrivate: fixItString = "fileprivate "; break;
55565556
case AccessLevel::Internal: fixItString = "internal "; break;
5557+
case AccessLevel::Package: fixItString = "package "; break;
55575558
case AccessLevel::Public: fixItString = "public "; break;
55585559
case AccessLevel::Open: fixItString = "open "; break;
55595560
}

lib/Sema/TypeCheckAccess.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2095,12 +2095,14 @@ static void checkExtensionGenericParamAccess(const ExtensionDecl *ED) {
20952095
case AccessLevel::FilePrivate: {
20962096
const DeclContext *DC = ED->getModuleScopeContext();
20972097
bool isPrivate = (userSpecifiedAccess == AccessLevel::Private);
2098-
desiredAccessScope = AccessScope(DC, isPrivate);
2098+
desiredAccessScope = AccessScope(DC, isPrivate ? AccessLimitKind::Private
2099+
: AccessLimitKind::None);
20992100
break;
21002101
}
21012102
case AccessLevel::Internal:
21022103
desiredAccessScope = AccessScope(ED->getModuleContext());
21032104
break;
2105+
case AccessLevel::Package:
21042106
case AccessLevel::Public:
21052107
case AccessLevel::Open:
21062108
break;

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3420,6 +3420,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
34203420
case AccessLevel::Open:
34213421
requiredAccess = AccessLevel::Public;
34223422
break;
3423+
case AccessLevel::Package:
34233424
case AccessLevel::Public:
34243425
case AccessLevel::Internal:
34253426
requiredAccess = AccessLevel::Internal;

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6180,6 +6180,7 @@ static void diagnoseUnstableName(ProtocolConformance *conformance,
61806180
case AccessLevel::Internal:
61816181
case AccessLevel::Open:
61826182
case AccessLevel::Public:
6183+
case AccessLevel::Package:
61836184
break;
61846185
}
61856186
}

lib/Serialization/Deserialization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,7 @@ static Optional<swift::AccessLevel> getActualAccessLevel(uint8_t raw) {
24812481
CASE(Private)
24822482
CASE(FilePrivate)
24832483
CASE(Internal)
2484+
CASE(Package)
24842485
CASE(Public)
24852486
CASE(Open)
24862487
#undef CASE

0 commit comments

Comments
 (0)