Skip to content

Commit f42ca1e

Browse files
committed
AST: Introduce Decl::getSemanticAvailableAttr().
This convenience returns an optional `SemanticAvailableAttr` (since in the future, lookup of the `AvailabilityDomain` can fail). It replaces `Decl::getDomainForAvailableAttr()`, since most callers will need to form a `SemanticAvailableAttr` with the resulting domain anyways.
1 parent 6ce7e3c commit f42ca1e

File tree

6 files changed

+80
-47
lines changed

6 files changed

+80
-47
lines changed

include/swift/AST/Attr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,6 +3205,18 @@ class SemanticAvailableAttr final {
32053205

32063206
const AvailableAttr *getParsedAttr() const { return attr; }
32073207
const AvailabilityDomain getDomain() const { return domain; }
3208+
3209+
/// Returns the platform kind that the attribute applies to, or
3210+
/// `PlatformKind::none` if the attribute is not platform specific.
3211+
bool isPlatformSpecific() const { return domain.isPlatform(); }
3212+
3213+
/// Returns the platform kind that the attribute applies to, or
3214+
/// `PlatformKind::none` if the attribute is not platform specific.
3215+
PlatformKind getPlatformKind() const { return domain.getPlatformKind(); }
3216+
3217+
/// Returns true if this attribute is considered active in the current
3218+
/// compilation context.
3219+
bool isActive(ASTContext &ctx) const;
32083220
};
32093221

32103222
/// An iterable range of `SemanticAvailableAttr`s.

include/swift/AST/Decl.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,9 +1401,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
14011401
SemanticAvailableAttributes
14021402
getSemanticAvailableAttrs(bool includeInactive = true) const;
14031403

1404-
/// Returns the availability domain associated with the given `AvailableAttr`
1405-
/// that is attached to this decl.
1406-
AvailabilityDomain getDomainForAvailableAttr(const AvailableAttr *attr) const;
1404+
/// Returns the SemanticAvailableAttr associated with the given
1405+
/// `AvailableAttr` that is attached to this decl. Returns `std::nullopt` if a
1406+
/// valid semantic version of the attribute cannot be constructed (e.g. the
1407+
/// domain cannot be resolved).
1408+
std::optional<SemanticAvailableAttr>
1409+
getSemanticAvailableAttr(const AvailableAttr *attr) const;
14071410

14081411
/// Returns the active platform-specific `@available` attribute for this decl.
14091412
/// There may be multiple `@available` attributes that are relevant to the

lib/AST/Attr.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -826,15 +826,18 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
826826
// Be careful not to coalesce `@available(swift 5)` with other short
827827
// `available' attributes.
828828
if (auto *availableAttr = dyn_cast<AvailableAttr>(DA)) {
829-
auto domain = D->getDomainForAvailableAttr(availableAttr);
830-
auto semanticAttr = SemanticAvailableAttr(availableAttr, domain);
831-
if (isShortAvailable(semanticAttr)) {
829+
auto semanticAttr = D->getSemanticAvailableAttr(availableAttr);
830+
if (!semanticAttr)
831+
continue;
832+
833+
auto domain = semanticAttr->getDomain();
834+
if (isShortAvailable(*semanticAttr)) {
832835
if (domain.isSwiftLanguage())
833-
swiftVersionAvailableAttribute.emplace(semanticAttr);
836+
swiftVersionAvailableAttribute.emplace(*semanticAttr);
834837
else if (domain.isPackageDescription())
835-
packageDescriptionVersionAvailableAttribute.emplace(semanticAttr);
838+
packageDescriptionVersionAvailableAttribute.emplace(*semanticAttr);
836839
else
837-
shortAvailableAttributes.push_back(semanticAttr);
840+
shortAvailableAttributes.push_back(*semanticAttr);
838841

839842
continue;
840843
}
@@ -912,6 +915,10 @@ ParsedDeclAttrFilter::operator()(const DeclAttribute *Attr) const {
912915
return Attr;
913916
}
914917

918+
bool SemanticAvailableAttr::isActive(ASTContext &ctx) const {
919+
return domain.isActive(ctx);
920+
}
921+
915922
std::optional<SemanticAvailableAttr>
916923
SemanticAvailableAttributes::Filter::operator()(
917924
const DeclAttribute *attr) const {
@@ -922,11 +929,14 @@ SemanticAvailableAttributes::Filter::operator()(
922929
if (availableAttr->isInvalid())
923930
return std::nullopt;
924931

925-
auto domain = decl->getDomainForAvailableAttr(availableAttr);
926-
if (!includeInactive && !domain.isActive(decl->getASTContext()))
932+
auto semanticAttr = decl->getSemanticAvailableAttr(availableAttr);
933+
if (!semanticAttr)
927934
return std::nullopt;
928935

929-
return SemanticAvailableAttr(availableAttr, domain);
936+
if (!includeInactive && !semanticAttr->isActive(decl->getASTContext()))
937+
return std::nullopt;
938+
939+
return *semanticAttr;
930940
}
931941

932942
static void printAvailableAttr(const Decl *D,
@@ -1164,8 +1174,9 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11641174

11651175
case DeclAttrKind::Available: {
11661176
auto Attr = cast<AvailableAttr>(this);
1167-
auto Domain = D->getDomainForAvailableAttr(Attr);
1168-
auto SemanticAttr = SemanticAvailableAttr(Attr, Domain);
1177+
auto SemanticAttr = D->getSemanticAvailableAttr(Attr);
1178+
if (!SemanticAttr)
1179+
return false;
11691180

11701181
if (Options.printPublicInterface() && Attr->isSPI()) {
11711182
assert(Attr->hasPlatform());
@@ -1190,7 +1201,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11901201
Printer.printAttrName("@available");
11911202
}
11921203
Printer << "(";
1193-
printAvailableAttr(D, SemanticAttr, Printer, Options);
1204+
printAvailableAttr(D, *SemanticAttr, Printer, Options);
11941205
Printer << ")";
11951206
break;
11961207
}
@@ -1286,8 +1297,8 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
12861297
Printer << "target: " << target << ", ";
12871298
SmallVector<SemanticAvailableAttr, 8> semanticAvailAttrs;
12881299
for (auto availAttr : attr->getAvailableAttrs()) {
1289-
auto domain = D->getDomainForAvailableAttr(availAttr);
1290-
semanticAvailAttrs.push_back(SemanticAvailableAttr(availAttr, domain));
1300+
if (auto semanticAttr = D->getSemanticAvailableAttr(availAttr))
1301+
semanticAvailAttrs.push_back(*semanticAttr);
12911302
}
12921303

12931304
if (!semanticAvailAttrs.empty()) {

lib/AST/Availability.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,35 @@ bool Decl::isAvailableAsSPI() const {
464464
return AvailabilityInference::isAvailableAsSPI(this);
465465
}
466466

467+
SemanticAvailableAttributes
468+
Decl::getSemanticAvailableAttrs(bool includeInactive) const {
469+
return SemanticAvailableAttributes(getAttrs(), this, includeInactive);
470+
}
471+
472+
std::optional<SemanticAvailableAttr>
473+
Decl::getSemanticAvailableAttr(const AvailableAttr *attr) const {
474+
auto domainForAvailableAttr = [](const AvailableAttr *attr) {
475+
if (attr->hasPlatform())
476+
return AvailabilityDomain::forPlatform(attr->getPlatform());
477+
478+
switch (attr->getPlatformAgnosticAvailability()) {
479+
case PlatformAgnosticAvailabilityKind::Deprecated:
480+
case PlatformAgnosticAvailabilityKind::Unavailable:
481+
case PlatformAgnosticAvailabilityKind::NoAsync:
482+
case PlatformAgnosticAvailabilityKind::None:
483+
return AvailabilityDomain::forUniversal();
484+
485+
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
486+
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
487+
return AvailabilityDomain::forSwiftLanguage();
488+
489+
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
490+
return AvailabilityDomain::forPackageDescription();
491+
}
492+
};
493+
return SemanticAvailableAttr(attr, domainForAvailableAttr(attr));
494+
}
495+
467496
const AvailableAttr *
468497
Decl::getActiveAvailableAttrForCurrentPlatform(bool ignoreAppExtensions) const {
469498
const AvailableAttr *bestAttr = nullptr;

lib/AST/AvailabilityDomain.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,6 @@
1616

1717
using namespace swift;
1818

19-
SemanticAvailableAttributes
20-
Decl::getSemanticAvailableAttrs(bool includeInactive) const {
21-
return SemanticAvailableAttributes(getAttrs(), this, includeInactive);
22-
}
23-
24-
AvailabilityDomain
25-
Decl::getDomainForAvailableAttr(const AvailableAttr *attr) const {
26-
if (attr->hasPlatform())
27-
return AvailabilityDomain::forPlatform(attr->getPlatform());
28-
29-
switch (attr->getPlatformAgnosticAvailability()) {
30-
case PlatformAgnosticAvailabilityKind::Deprecated:
31-
case PlatformAgnosticAvailabilityKind::Unavailable:
32-
case PlatformAgnosticAvailabilityKind::NoAsync:
33-
case PlatformAgnosticAvailabilityKind::None:
34-
return AvailabilityDomain::forUniversal();
35-
36-
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
37-
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
38-
return AvailabilityDomain::forSwiftLanguage();
39-
40-
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
41-
return AvailabilityDomain::forPackageDescription();
42-
}
43-
}
44-
4519
bool AvailabilityDomain::isActive(ASTContext &ctx) const {
4620
switch (kind) {
4721
case Kind::Universal:

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,8 +3061,11 @@ getExplicitUnavailabilityDiagnosticInfo(const Decl *decl,
30613061
if (!attr)
30623062
return std::nullopt;
30633063

3064+
auto semanticAttr = decl->getSemanticAvailableAttr(attr);
3065+
if (!semanticAttr)
3066+
return std::nullopt;
3067+
30643068
ASTContext &ctx = decl->getASTContext();
3065-
auto domain = decl->getDomainForAvailableAttr(attr);
30663069

30673070
switch (attr->getVersionAvailability(ctx)) {
30683071
case AvailableVersionComparison::Available:
@@ -3075,17 +3078,18 @@ getExplicitUnavailabilityDiagnosticInfo(const Decl *decl,
30753078
attr->Introduced.has_value()) {
30763079
return UnavailabilityDiagnosticInfo(
30773080
UnavailabilityDiagnosticInfo::Status::IntroducedInVersion, attr,
3078-
domain);
3081+
semanticAttr->getDomain());
30793082
} else {
30803083
return UnavailabilityDiagnosticInfo(
30813084
UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable, attr,
3082-
domain);
3085+
semanticAttr->getDomain());
30833086
}
30843087
break;
30853088

30863089
case AvailableVersionComparison::Obsoleted:
30873090
return UnavailabilityDiagnosticInfo(
3088-
UnavailabilityDiagnosticInfo::Status::Obsoleted, attr, domain);
3091+
UnavailabilityDiagnosticInfo::Status::Obsoleted, attr,
3092+
semanticAttr->getDomain());
30893093
}
30903094
}
30913095

0 commit comments

Comments
 (0)