18
18
19
19
using namespace swift ;
20
20
21
- bool AvailabilityContext::PlatformInfo::constrainRange (const Decl *decl) {
21
+ bool AvailabilityContext::PlatformInfo::constrainWith (
22
+ const PlatformInfo &other) {
23
+ bool isConstrained = false ;
24
+ isConstrained |= constrainRange (other.Range );
25
+ if (other.IsUnavailable ) {
26
+ isConstrained |= constrainUnavailability (other.UnavailablePlatform );
27
+ }
28
+ isConstrained |= constrainDeprecated (other.IsDeprecated );
29
+
30
+ return isConstrained;
31
+ }
32
+
33
+ bool AvailabilityContext::PlatformInfo::constrainWith (const Decl *decl) {
34
+ bool isConstrained = false ;
35
+ auto &ctx = decl->getASTContext ();
36
+
22
37
if (auto range = AvailabilityInference::annotatedAvailableRange (decl))
23
- return constrainRange (*range);
38
+ isConstrained |= constrainRange (*range);
39
+
40
+ if (auto *attr = decl->getAttrs ().getUnavailable (ctx))
41
+ isConstrained |= constrainUnavailability (attr->Platform );
42
+
43
+ if (!IsDeprecated)
44
+ isConstrained |= constrainDeprecated (decl->getAttrs ().isDeprecated (ctx));
24
45
25
- return false ;
46
+ return isConstrained ;
26
47
}
27
48
28
49
bool AvailabilityContext::PlatformInfo::constrainUnavailability (
29
- const Decl *decl) {
30
- auto &ctx = decl->getASTContext ();
31
- auto *attr = decl->getAttrs ().getUnavailable (ctx);
32
- if (!attr)
50
+ std::optional<PlatformKind> unavailablePlatform) {
51
+ if (!unavailablePlatform)
33
52
return false ;
34
53
35
- // Check whether the decl's unavailability reason is the same.
36
- if (IsUnavailable && UnavailablePlatform == attr->Platform )
37
- return false ;
54
+ if (IsUnavailable) {
55
+ // Universal unavailability cannot be refined.
56
+ if (UnavailablePlatform == PlatformKind::none)
57
+ return false ;
38
58
39
- // Check whether the decl's unavailability reason is more specific.
40
- if (attr->Platform != PlatformKind::none &&
41
- inheritsAvailabilityFromPlatform (attr->Platform , UnavailablePlatform))
42
- return false ;
59
+ // There's nothing to do if the platforms already match.
60
+ if (UnavailablePlatform == *unavailablePlatform)
61
+ return false ;
62
+
63
+ // The new platform must be more restrictive.
64
+ if (*unavailablePlatform != PlatformKind::none &&
65
+ inheritsAvailabilityFromPlatform (*unavailablePlatform,
66
+ UnavailablePlatform))
67
+ return false ;
68
+ }
43
69
44
70
IsUnavailable = true ;
45
- UnavailablePlatform = attr-> Platform ;
71
+ UnavailablePlatform = *unavailablePlatform ;
46
72
return true ;
47
73
}
48
74
49
- bool AvailabilityContext::PlatformInfo::constrainDeprecated (const Decl *decl) {
50
- auto &ctx = decl->getASTContext ();
51
- if (IsDeprecated || !decl->getAttrs ().isDeprecated (ctx))
75
+ bool AvailabilityContext::PlatformInfo::constrainDeprecated (bool deprecated) {
76
+ if (IsDeprecated || !deprecated)
52
77
return false ;
53
78
54
79
IsDeprecated = true ;
@@ -116,6 +141,18 @@ bool AvailabilityContext::isDeprecated() const {
116
141
return Info->Platform .IsDeprecated ;
117
142
}
118
143
144
+ void AvailabilityContext::constrainWithContext (const AvailabilityContext &other,
145
+ ASTContext &ctx) {
146
+ PlatformInfo platformAvailability{Info->Platform };
147
+ if (platformAvailability.constrainWith (other.Info ->Platform )) {
148
+ Info = Storage::get (platformAvailability, ctx);
149
+ }
150
+ }
151
+
152
+ void AvailabilityContext::constrainWithDecl (const Decl *decl) {
153
+ constrainWithDeclAndPlatformRange (decl, AvailabilityRange::alwaysAvailable ());
154
+ }
155
+
119
156
void AvailabilityContext::constrainWithPlatformRange (
120
157
const AvailabilityRange &platformRange, ASTContext &ctx) {
121
158
PlatformInfo platformAvailability{Info->Platform };
@@ -126,13 +163,11 @@ void AvailabilityContext::constrainWithPlatformRange(
126
163
}
127
164
128
165
void AvailabilityContext::constrainWithDeclAndPlatformRange (
129
- Decl *decl, const AvailabilityRange &platformRange) {
166
+ const Decl *decl, const AvailabilityRange &platformRange) {
130
167
PlatformInfo platformAvailability{Info->Platform };
131
168
bool isConstrained = false ;
132
- isConstrained |= platformAvailability.constrainRange (decl);
169
+ isConstrained |= platformAvailability.constrainWith (decl);
133
170
isConstrained |= platformAvailability.constrainRange (platformRange);
134
- isConstrained |= platformAvailability.constrainUnavailability (decl);
135
- isConstrained |= platformAvailability.constrainDeprecated (decl);
136
171
137
172
if (!isConstrained)
138
173
return ;
0 commit comments