Skip to content

Commit ddb5f23

Browse files
committed
AST: Add AvailabilityContext::containsUnavailableDomain().
Replaces AvailabilityContext::getUnavailableDomain().
1 parent 889bc31 commit ddb5f23

File tree

5 files changed

+54
-40
lines changed

5 files changed

+54
-40
lines changed

include/swift/AST/AvailabilityContext.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,11 @@ class AvailabilityContext {
7474
/// availability context, starting at its introduction version.
7575
AvailabilityRange getPlatformRange() const;
7676

77-
/// Returns the broadest AvailabilityDomain that is unavailable in this
78-
/// context.
79-
std::optional<AvailabilityDomain> getUnavailableDomain() const;
77+
/// Returns true if this context contains any unavailable domains.
78+
bool isUnavailable() const;
8079

81-
/// Returns true if this context is unavailable.
82-
bool isUnavailable() const { return getUnavailableDomain().has_value(); }
80+
/// Returns true if \p domain is unavailable in this context.
81+
bool containsUnavailableDomain(AvailabilityDomain domain) const;
8382

8483
/// Returns true if this context is deprecated on the current platform.
8584
bool isDeprecated() const;

lib/AST/AvailabilityContext.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,16 @@ AvailabilityRange AvailabilityContext::getPlatformRange() const {
133133
return storage->info.Range;
134134
}
135135

136-
std::optional<AvailabilityDomain>
137-
AvailabilityContext::getUnavailableDomain() const {
138-
return storage->info.UnavailableDomain;
136+
bool AvailabilityContext::isUnavailable() const {
137+
return storage->info.UnavailableDomain.has_value();
138+
}
139+
140+
bool AvailabilityContext::containsUnavailableDomain(
141+
AvailabilityDomain domain) const {
142+
if (auto unavailableDomain = storage->info.UnavailableDomain)
143+
return unavailableDomain->contains(domain);
144+
145+
return false;
139146
}
140147

141148
bool AvailabilityContext::isDeprecated() const {
@@ -212,7 +219,7 @@ stringForAvailability(const AvailabilityRange &availability) {
212219
void AvailabilityContext::print(llvm::raw_ostream &os) const {
213220
os << "version=" << stringForAvailability(getPlatformRange());
214221

215-
if (auto unavailableDomain = getUnavailableDomain())
222+
if (auto unavailableDomain = storage->info.UnavailableDomain)
216223
os << " unavailable=" << unavailableDomain->getNameForAttributePrinting();
217224

218225
if (isDeprecated())

lib/Sema/TypeCheckAttr.cpp

+25-26
Original file line numberDiff line numberDiff line change
@@ -5125,34 +5125,33 @@ void AttributeChecker::checkBackDeployedAttrs(
51255125
D->getLoc(), D->getInnermostDeclContext());
51265126

51275127
// Unavailable decls cannot be back deployed.
5128-
if (auto unavailableDomain = availability.getUnavailableDomain()) {
5129-
auto backDeployedDomain = AvailabilityDomain::forPlatform(Attr->Platform);
5130-
if (unavailableDomain->contains(backDeployedDomain)) {
5131-
auto platformString = prettyPlatformString(Attr->Platform);
5132-
llvm::VersionTuple ignoredVersion;
5133-
5134-
AvailabilityInference::updateBeforePlatformForFallback(
5135-
Attr, Ctx, platformString, ignoredVersion);
5136-
5137-
diagnose(AtLoc, diag::attr_has_no_effect_on_unavailable_decl, Attr, VD,
5138-
platformString);
5139-
5140-
// Find the attribute that makes the declaration unavailable.
5141-
const Decl *attrDecl = D;
5142-
do {
5143-
if (auto unavailableAttr = attrDecl->getUnavailableAttr()) {
5144-
diagnose(unavailableAttr->getParsedAttr()->AtLoc,
5145-
diag::availability_marked_unavailable, VD)
5146-
.highlight(unavailableAttr->getParsedAttr()->getRange());
5147-
break;
5148-
}
5128+
auto backDeployedDomain = AvailabilityDomain::forPlatform(Attr->Platform);
5129+
if (auto unavailableDomain =
5130+
availability.containsUnavailableDomain(backDeployedDomain)) {
5131+
auto platformString = prettyPlatformString(Attr->Platform);
5132+
llvm::VersionTuple ignoredVersion;
5133+
5134+
AvailabilityInference::updateBeforePlatformForFallback(
5135+
Attr, Ctx, platformString, ignoredVersion);
5136+
5137+
diagnose(AtLoc, diag::attr_has_no_effect_on_unavailable_decl, Attr, VD,
5138+
platformString);
5139+
5140+
// Find the attribute that makes the declaration unavailable.
5141+
const Decl *attrDecl = D;
5142+
do {
5143+
if (auto unavailableAttr = attrDecl->getUnavailableAttr()) {
5144+
diagnose(unavailableAttr->getParsedAttr()->AtLoc,
5145+
diag::availability_marked_unavailable, VD)
5146+
.highlight(unavailableAttr->getParsedAttr()->getRange());
5147+
break;
5148+
}
51495149

5150-
attrDecl = AvailabilityInference::parentDeclForInferredAvailability(
5151-
attrDecl);
5152-
} while (attrDecl);
5150+
attrDecl =
5151+
AvailabilityInference::parentDeclForInferredAvailability(attrDecl);
5152+
} while (attrDecl);
51535153

5154-
continue;
5155-
}
5154+
continue;
51565155
}
51575156

51585157
// Verify that the decl is available before the back deployment boundary.

lib/Sema/TypeCheckAvailability.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,7 @@ static bool computeContainedByDeploymentTarget(AvailabilityScope *scope,
349349
static bool isInsideCompatibleUnavailableDeclaration(
350350
const Decl *D, AvailabilityContext availabilityContext,
351351
const SemanticAvailableAttr &attr) {
352-
auto contextDomain = availabilityContext.getUnavailableDomain();
353-
if (!contextDomain)
352+
if (!availabilityContext.isUnavailable())
354353
return false;
355354

356355
if (!attr.isUnconditionallyUnavailable())
@@ -364,7 +363,7 @@ static bool isInsideCompatibleUnavailableDeclaration(
364363
return false;
365364
}
366365

367-
return contextDomain->contains(declDomain);
366+
return availabilityContext.containsUnavailableDomain(declDomain);
368367
}
369368

370369
std::optional<SemanticAvailableAttr>

unittests/AST/AvailabilityContextTests.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,20 @@ TEST_F(AvailabilityContextTest, UnavailableDomains) {
7575

7676
auto macOS10_9 = AvailabilityContext::forDeploymentTarget(ctx);
7777
EXPECT_FALSE(macOS10_9.isUnavailable());
78+
EXPECT_FALSE(macOS10_9.containsUnavailableDomain(domains.macOS));
79+
EXPECT_FALSE(macOS10_9.containsUnavailableDomain(domains.macOSAppExt));
80+
EXPECT_FALSE(macOS10_9.containsUnavailableDomain(domains.universal));
7881

7982
// Constrain the deployment target context by adding unavailability on macOS.
8083
// The resulting context should be a new context that is less available than
8184
// the deployment target context (a.k.a. "contained by").
8285
auto unavailableOnMacOS = macOS10_9;
8386
unavailableOnMacOS.constrainWithUnavailableDomain(domains.macOS, ctx);
8487
EXPECT_TRUE(unavailableOnMacOS.isUnavailable());
85-
// FIXME: [availability] query unavailable domains
88+
EXPECT_TRUE(unavailableOnMacOS.containsUnavailableDomain(domains.macOS));
89+
EXPECT_TRUE(
90+
unavailableOnMacOS.containsUnavailableDomain(domains.macOSAppExt));
91+
EXPECT_FALSE(unavailableOnMacOS.containsUnavailableDomain(domains.universal));
8692
EXPECT_NE(unavailableOnMacOS, macOS10_9);
8793
EXPECT_TRUE(unavailableOnMacOS.isContainedIn(macOS10_9));
8894
EXPECT_FALSE(macOS10_9.isContainedIn(unavailableOnMacOS));
@@ -106,7 +112,11 @@ TEST_F(AvailabilityContextTest, UnavailableDomains) {
106112
auto unavailableUniversally = unavailableOnMacOS;
107113
unavailableUniversally.constrainWithUnavailableDomain(domains.universal, ctx);
108114
EXPECT_TRUE(unavailableUniversally.isUnavailable());
109-
// FIXME: [availability] query unavailable domains
115+
EXPECT_TRUE(unavailableUniversally.containsUnavailableDomain(domains.macOS));
116+
EXPECT_TRUE(
117+
unavailableUniversally.containsUnavailableDomain(domains.macOSAppExt));
118+
EXPECT_TRUE(
119+
unavailableUniversally.containsUnavailableDomain(domains.universal));
110120
EXPECT_NE(unavailableUniversally, unavailableOnMacOS);
111121
EXPECT_TRUE(unavailableUniversally.isContainedIn(unavailableOnMacOS));
112122
EXPECT_TRUE(unavailableUniversally.isContainedIn(macOS10_9));

0 commit comments

Comments
 (0)