2020
2121namespace swift {
2222
23+ // / Used to provide the kind of scope limitation in AccessScope::Value
24+ enum class AccessLimitKind : uint8_t { None = 0 , Private, Package };
25+
2326// / The wrapper around the outermost DeclContext from which
2427// / a particular declaration can be accessed.
2528class AccessScope {
26- // / The declaration context (if not public) along with a bit saying
27- // / whether this scope is private, SPI or not.
28- // / If the declaration context is set, the bit means that the scope is
29- // / private or not. If the declaration context is null, the bit means that
30- // / this scope is SPI or not.
31- llvm::PointerIntPair<const DeclContext *, 1 , bool > Value;
29+ // / The declaration context along with an enum indicating the level of
30+ // / scope limitation.
31+ // / If the declaration context is set, and the limit kind is Private, the
32+ // / access level is considered 'private'. Whether it's 'internal' or
33+ // / 'fileprivate' is determined by what the declaration context casts to. If
34+ // / the declaration context is null, and the limit kind is None, the access
35+ // / level is considered 'public'. If the limit kind is Private, the access
36+ // / level is considered SPI. If it's Package, the access level is considered
37+ // / 'package'. Below is a table showing the combinations.
38+ // /
39+ // / AccessLimitKind DC == nullptr DC != nullptr
40+ // / ---------------------------------------------------------------------------
41+ // / None public fileprivate or internal (check DC to tell which)
42+ // / Private `@_spi` public private
43+ // / Package package (unused)
44+
45+ llvm::PointerIntPair<const DeclContext *, 2 , AccessLimitKind> Value;
3246
3347public:
34- AccessScope (const DeclContext *DC, bool isPrivate = false );
48+ AccessScope (const DeclContext *DC,
49+ AccessLimitKind limitKind = AccessLimitKind::None);
3550
36- static AccessScope getPublic () { return AccessScope (nullptr , false ); }
51+ static AccessScope getPublic () {
52+ return AccessScope (nullptr , AccessLimitKind::None);
53+ }
54+ static AccessScope getPackage () {
55+ return AccessScope (nullptr , AccessLimitKind::Package);
56+ }
3757
3858 // / Check if private access is allowed. This is a lexical scope check in Swift
3959 // / 3 mode. In Swift 4 mode, declarations and extensions of the same type will
@@ -46,25 +66,46 @@ class AccessScope {
4666 bool operator ==(AccessScope RHS) const { return Value == RHS.Value ; }
4767 bool operator !=(AccessScope RHS) const { return !(*this == RHS); }
4868 bool hasEqualDeclContextWith (AccessScope RHS) const {
69+ if (isPublic ())
70+ return RHS.isPublic ();
71+ if (isPackage ())
72+ return RHS.isPackage ();
4973 return getDeclContext () == RHS.getDeclContext ();
5074 }
5175
52- bool isPublic () const { return !Value.getPointer (); }
53- bool isPrivate () const { return Value.getPointer () && Value.getInt (); }
76+ bool isPublic () const {
77+ return !Value.getPointer () && Value.getInt () == AccessLimitKind::None;
78+ }
79+ bool isPrivate () const {
80+ return Value.getPointer () && Value.getInt () == AccessLimitKind::Private;
81+ }
5482 bool isFileScope () const ;
5583 bool isInternal () const ;
84+ bool isPackage () const {
85+ return !Value.getPointer () && Value.getInt () == AccessLimitKind::Package;
86+ }
5687
57- // / Returns true if this is a child scope of the specified other access scope.
58- // /
88+ // / Returns true if this scope is more restrictive than the argument scope.
89+ // / It's often used to compute the min access scope. The order of restrictiveness
90+ // / is: private (most restrictive), fileprivate, internal, package, public (least restrictive).
5991 // / \see DeclContext::isChildContextOf
6092 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 ();
93+ if (isInternalOrLess ()) {
94+ if (AS.isInternalOrLess ())
95+ return allowsPrivateAccess (getDeclContext (), AS.getDeclContext ());
96+ else
97+ return AS.isPackage () || AS.isPublic ();
98+ }
99+ if (isPackage ())
100+ return AS.isPublic ();
101+
102+ // If this is public, it can't be less than access level of AS
103+ // so return false
104+ return false ;
66105 }
67106
107+ bool isInternalOrLess () const { return getDeclContext () != nullptr ; }
108+
68109 // / Returns the associated access level for diagnostic purposes.
69110 AccessLevel accessLevelForDiagnostics () const ;
70111
0 commit comments