Skip to content

AST: Consolidate instantiation of AvailabilityContext from AvailabilityAttr #63099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/swift/AST/Availability.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ class UnavailabilityReason {
/// See #unionWith, #intersectWith, and #constrainWith.
///
/// [lattice]: http://mathworld.wolfram.com/Lattice.html
///
/// NOTE: Generally you should use the utilities on \c AvailabilityInference
/// to create an \c AvailabilityContext, rather than creating one directly.
class AvailabilityContext {
VersionRange OSVersion;
llvm::Optional<bool> SPI;
Expand Down Expand Up @@ -345,6 +348,13 @@ class AvailabilityInference {
/// We assume a declaration without an annotation is always available.
static AvailabilityContext availableRange(const Decl *D, ASTContext &C);

/// Returns the availability context for a declaration with the given
/// @available attribute.
///
/// NOTE: The attribute must be active on the current platform.
static AvailabilityContext availableRange(const AvailableAttr *attr,
ASTContext &C);

/// Returns the attribute that should be used to determine the availability
/// range of the given declaration, or nullptr if there is none.
static const AvailableAttr *attrForAnnotatedAvailableRange(const Decl *D,
Expand Down
19 changes: 11 additions & 8 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,7 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
if (!bestAvailAttr)
return None;

return AvailabilityContext{
VersionRange::allGTE(bestAvailAttr->Introduced.value()),
bestAvailAttr->IsSPI};
return availableRange(bestAvailAttr, Ctx);
}

bool Decl::isAvailableAsSPI() const {
Expand Down Expand Up @@ -283,11 +281,8 @@ AvailabilityInference::annotatedAvailableRangeForAttr(const SpecializeAttr* attr
bestAvailAttr = availAttr;
}

if (bestAvailAttr) {
return AvailabilityContext{
VersionRange::allGTE(bestAvailAttr->Introduced.value())
};
}
if (bestAvailAttr)
return availableRange(bestAvailAttr, ctx);

return AvailabilityContext::alwaysAvailable();
}
Expand Down Expand Up @@ -320,6 +315,14 @@ AvailabilityContext AvailabilityInference::availableRange(const Decl *D,
return AvailabilityContext::alwaysAvailable();
}

AvailabilityContext
AvailabilityInference::availableRange(const AvailableAttr *attr,
ASTContext &Ctx) {
assert(attr->isActivePlatform(Ctx));
return AvailabilityContext{VersionRange::allGTE(attr->Introduced.value()),
attr->IsSPI};
}

namespace {
/// Infers the availability required to access a type.
class AvailabilityInferenceTypeWalker : public TypeWalker {
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1885,8 +1885,8 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
// is fully contained within that declaration's range. If there is no such
// enclosing declaration, then there is nothing to check.
Optional<AvailabilityContext> EnclosingAnnotatedRange;
AvailabilityContext AttrRange{
VersionRange::allGTE(attr->Introduced.value())};
AvailabilityContext AttrRange =
AvailabilityInference::availableRange(attr, Ctx);

if (auto *parent = getEnclosingDeclForDecl(D)) {
if (auto enclosingUnavailable = parent->getSemanticUnavailableAttr()) {
Expand All @@ -1904,7 +1904,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
const AvailableAttr *enclosingAttr = enclosingAvailable.value().first;
const Decl *enclosingDecl = enclosingAvailable.value().second;
EnclosingAnnotatedRange.emplace(
VersionRange::allGTE(enclosingAttr->Introduced.value()));
AvailabilityInference::availableRange(enclosingAttr, Ctx));
if (!AttrRange.isContainedIn(*EnclosingAnnotatedRange)) {
// Members of extensions of nominal types with available ranges were
// not diagnosed previously, so only emit a warning in that case.
Expand Down