Skip to content

Commit 1284001

Browse files
committed
Sema: Canonicalize platform versions in SemanticAvailableAttrRequest.
This should really be done on-demand during version remapping, but for now the goal of this change is to be as NFC as possible.
1 parent 9045180 commit 1284001

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

include/swift/AST/Attr.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,11 @@ class AvailableAttr : public DeclAttribute {
767767
const StringRef Message;
768768
const StringRef Rename;
769769

770-
const llvm::VersionTuple Introduced;
770+
llvm::VersionTuple Introduced;
771771
const SourceRange IntroducedRange;
772-
const llvm::VersionTuple Deprecated;
772+
llvm::VersionTuple Deprecated;
773773
const SourceRange DeprecatedRange;
774-
const llvm::VersionTuple Obsoleted;
774+
llvm::VersionTuple Obsoleted;
775775
const SourceRange ObsoletedRange;
776776

777777
public:
@@ -912,6 +912,12 @@ class AvailableAttr : public DeclAttribute {
912912
private:
913913
friend class SemanticAvailableAttrRequest;
914914

915+
void setRawIntroduced(llvm::VersionTuple version) { Introduced = version; }
916+
917+
void setRawDeprecated(llvm::VersionTuple version) { Deprecated = version; }
918+
919+
void setRawObsoleted(llvm::VersionTuple version) { Obsoleted = version; }
920+
915921
void setCachedDomain(AvailabilityDomain domain) {
916922
assert(!Bits.AvailableAttr.HasDomain);
917923
Domain = domain;

lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -565,20 +565,6 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
565565
return nullptr;
566566
}
567567

568-
if (auto PlatformKind = platformFromString(Platform)) {
569-
if (!Introduced.empty())
570-
Introduced.Version =
571-
canonicalizePlatformVersion(*PlatformKind, Introduced.Version);
572-
573-
if (!Deprecated.empty())
574-
Deprecated.Version =
575-
canonicalizePlatformVersion(*PlatformKind, Deprecated.Version);
576-
577-
if (!Obsoleted.empty())
578-
Obsoleted.Version =
579-
canonicalizePlatformVersion(*PlatformKind, Obsoleted.Version);
580-
}
581-
582568
auto Attr = new (Context) AvailableAttr(
583569
AtLoc, SourceRange(AttrLoc, Tok.getLoc()), Platform, PlatformLoc,
584570
AttrKind, Message, Renamed, Introduced.Version, Introduced.Range,
@@ -846,10 +832,6 @@ bool Parser::parseAvailability(
846832
continue;
847833
}
848834

849-
if (Domain.isPlatform())
850-
Version =
851-
canonicalizePlatformVersion(Domain.getPlatformKind(), Version);
852-
853835
addAttribute(new (Context) AvailableAttr(
854836
AtLoc, attrRange, Domain, Spec->getSourceRange().Start,
855837
AvailableAttr::Kind::Default,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8278,56 +8278,83 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
82788278
auto attrName = attr->getAttrName();
82798279
auto attrKind = attr->getKind();
82808280
auto domainLoc = attr->getDomainLoc();
8281-
auto string = attr->getDomainString();
8282-
ASSERT(string);
8281+
auto introducedVersion = attr->getRawIntroduced();
8282+
auto deprecatedVersion = attr->getRawDeprecated();
8283+
auto obsoletedVersion = attr->getRawObsoleted();
8284+
auto mutableAttr = const_cast<AvailableAttr *>(attr);
8285+
auto domain = attr->getCachedDomain();
82838286

8284-
// Attempt to resolve the domain specified for the attribute and diagnose
8285-
// if no domain is found.
8286-
auto domain = AvailabilityDomain::builtinDomainForString(*string);
82878287
if (!domain) {
8288-
if (auto suggestion = closestCorrectedPlatformString(*string)) {
8289-
diags
8290-
.diagnose(domainLoc, diag::attr_availability_suggest_platform,
8291-
*string, attrName, *suggestion)
8292-
.fixItReplace(SourceRange(domainLoc), *suggestion);
8293-
} else {
8294-
diags.diagnose(attrLoc, diag::attr_availability_unknown_platform, *string,
8295-
attrName);
8288+
auto string = attr->getDomainString();
8289+
ASSERT(string);
8290+
8291+
// Attempt to resolve the domain specified for the attribute and diagnose
8292+
// if no domain is found.
8293+
domain = AvailabilityDomain::builtinDomainForString(*string);
8294+
if (!domain) {
8295+
if (auto suggestion = closestCorrectedPlatformString(*string)) {
8296+
diags
8297+
.diagnose(domainLoc, diag::attr_availability_suggest_platform,
8298+
*string, attrName, *suggestion)
8299+
.fixItReplace(SourceRange(domainLoc), *suggestion);
8300+
} else {
8301+
diags.diagnose(attrLoc, diag::attr_availability_unknown_platform,
8302+
*string, attrName);
8303+
}
8304+
return std::nullopt;
82968305
}
8297-
return std::nullopt;
8306+
8307+
mutableAttr->setCachedDomain(*domain);
82988308
}
82998309

8310+
auto domainName = domain->getNameForAttributePrinting();
8311+
83008312
if (domain->isSwiftLanguage() || domain->isPackageDescription()) {
83018313
switch (attrKind) {
83028314
case AvailableAttr::Kind::Deprecated:
83038315
diags.diagnose(attrLoc,
83048316
diag::attr_availability_expected_deprecated_version,
8305-
attrName, *string);
8317+
attrName, domainName);
83068318
return std::nullopt;
83078319

83088320
case AvailableAttr::Kind::Unavailable:
83098321
diags.diagnose(attrLoc, diag::attr_availability_cannot_be_used_for_domain,
8310-
"unavailable", attrName, *string);
8322+
"unavailable", attrName, domainName);
83118323
return std::nullopt;
83128324

83138325
case AvailableAttr::Kind::NoAsync:
83148326
diags.diagnose(attrLoc, diag::attr_availability_cannot_be_used_for_domain,
8315-
"noasync", attrName, *string);
8327+
"noasync", attrName, domainName);
83168328
break;
83178329
case AvailableAttr::Kind::Default:
83188330
break;
83198331
}
83208332

8321-
bool hasVersionSpec = (attr->getRawIntroduced() ||
8322-
attr->getRawDeprecated() || attr->getRawObsoleted());
8333+
bool hasVersionSpec =
8334+
(introducedVersion || deprecatedVersion || obsoletedVersion);
83238335
if (!hasVersionSpec) {
83248336
diags.diagnose(attrLoc, diag::attr_availability_expected_version_spec,
8325-
attrName, *string);
8337+
attrName, domainName);
83268338
return std::nullopt;
83278339
}
83288340
}
83298341

8330-
const_cast<AvailableAttr *>(attr)->setCachedDomain(*domain);
8342+
// Canonicalize platform versions.
8343+
// FIXME: [availability] This should be done when remapping versions instead.
8344+
if (domain->isPlatform()) {
8345+
auto canonicalizeVersion = [&](llvm::VersionTuple version) {
8346+
return canonicalizePlatformVersion(domain->getPlatformKind(), version);
8347+
};
8348+
if (introducedVersion)
8349+
mutableAttr->setRawIntroduced(canonicalizeVersion(*introducedVersion));
8350+
8351+
if (deprecatedVersion)
8352+
mutableAttr->setRawDeprecated(canonicalizeVersion(*deprecatedVersion));
8353+
8354+
if (obsoletedVersion)
8355+
mutableAttr->setRawObsoleted(canonicalizeVersion(*obsoletedVersion));
8356+
}
8357+
83318358
return SemanticAvailableAttr(attr);
83328359
}
83338360

0 commit comments

Comments
 (0)