1818
1919using namespace swift ;
2020
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+
2237 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));
2445
25- return false ;
46+ return isConstrained ;
2647}
2748
2849bool 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)
3352 return false ;
3453
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 ;
3858
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+ }
4369
4470 IsUnavailable = true ;
45- UnavailablePlatform = attr-> Platform ;
71+ UnavailablePlatform = *unavailablePlatform ;
4672 return true ;
4773}
4874
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)
5277 return false ;
5378
5479 IsDeprecated = true ;
@@ -116,6 +141,18 @@ bool AvailabilityContext::isDeprecated() const {
116141 return Info->Platform .IsDeprecated ;
117142}
118143
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+
119156void AvailabilityContext::constrainWithPlatformRange (
120157 const AvailabilityRange &platformRange, ASTContext &ctx) {
121158 PlatformInfo platformAvailability{Info->Platform };
@@ -126,13 +163,11 @@ void AvailabilityContext::constrainWithPlatformRange(
126163}
127164
128165void AvailabilityContext::constrainWithDeclAndPlatformRange (
129- Decl *decl, const AvailabilityRange &platformRange) {
166+ const Decl *decl, const AvailabilityRange &platformRange) {
130167 PlatformInfo platformAvailability{Info->Platform };
131168 bool isConstrained = false ;
132- isConstrained |= platformAvailability.constrainRange (decl);
169+ isConstrained |= platformAvailability.constrainWith (decl);
133170 isConstrained |= platformAvailability.constrainRange (platformRange);
134- isConstrained |= platformAvailability.constrainUnavailability (decl);
135- isConstrained |= platformAvailability.constrainDeprecated (decl);
136171
137172 if (!isConstrained)
138173 return ;
0 commit comments