20
20
21
21
namespace swift {
22
22
23
+ // / Used to provide the kind of scope limitation in AccessScope::Value
24
+ enum class AccessLimitKind : uint8_t { None = 0 , Private, Package };
25
+
23
26
// / The wrapper around the outermost DeclContext from which
24
27
// / a particular declaration can be accessed.
25
28
class 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;
32
46
33
47
public:
34
- AccessScope (const DeclContext *DC, bool isPrivate = false );
48
+ AccessScope (const DeclContext *DC,
49
+ AccessLimitKind limitKind = AccessLimitKind::None);
35
50
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
+ }
37
57
38
58
// / Check if private access is allowed. This is a lexical scope check in Swift
39
59
// / 3 mode. In Swift 4 mode, declarations and extensions of the same type will
@@ -46,25 +66,46 @@ class AccessScope {
46
66
bool operator ==(AccessScope RHS) const { return Value == RHS.Value ; }
47
67
bool operator !=(AccessScope RHS) const { return !(*this == RHS); }
48
68
bool hasEqualDeclContextWith (AccessScope RHS) const {
69
+ if (isPublic ())
70
+ return RHS.isPublic ();
71
+ if (isPackage ())
72
+ return RHS.isPackage ();
49
73
return getDeclContext () == RHS.getDeclContext ();
50
74
}
51
75
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
+ }
54
82
bool isFileScope () const ;
55
83
bool isInternal () const ;
84
+ bool isPackage () const {
85
+ return !Value.getPointer () && Value.getInt () == AccessLimitKind::Package;
86
+ }
56
87
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).
59
91
// / \see DeclContext::isChildContextOf
60
92
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 ;
66
105
}
67
106
107
+ bool isInternalOrLess () const { return getDeclContext () != nullptr ; }
108
+
68
109
// / Returns the associated access level for diagnostic purposes.
69
110
AccessLevel accessLevelForDiagnostics () const ;
70
111
0 commit comments