Skip to content

Commit 6ce7e3c

Browse files
committed
AST: Adopt SemanticAvailableAttr in attribute printing.
1 parent 88345f9 commit 6ce7e3c

File tree

3 files changed

+77
-68
lines changed

3 files changed

+77
-68
lines changed

include/swift/AST/Attr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3199,7 +3199,9 @@ class SemanticAvailableAttr final {
31993199

32003200
public:
32013201
SemanticAvailableAttr(const AvailableAttr *attr, AvailabilityDomain domain)
3202-
: attr(attr), domain(domain) {}
3202+
: attr(attr), domain(domain) {
3203+
assert(attr);
3204+
}
32033205

32043206
const AvailableAttr *getParsedAttr() const { return attr; }
32053207
const AvailabilityDomain getDomain() const { return domain; }

include/swift/AST/AvailabilityDomain.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ class AvailabilityDomain final {
8484
bool isPackageDescription() const { return kind == Kind::PackageDescription; }
8585

8686
/// Returns the platform kind for this domain if applicable.
87-
PlatformKind getPlatformKind() const {
88-
assert(kind == Kind::Platform);
89-
return platform;
90-
}
87+
PlatformKind getPlatformKind() const { return platform; }
9188

9289
/// Returns true if this domain is considered active in the current
9390
/// compilation context.

lib/AST/Attr.cpp

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -418,11 +418,8 @@ void DeclAttributes::dump(const Decl *D) const {
418418
/// introduction version and does not support deprecation, obsoletion, or
419419
/// messages.
420420
LLVM_READONLY
421-
static bool isShortAvailable(const DeclAttribute *DA) {
422-
auto *AvailAttr = dyn_cast<AvailableAttr>(DA);
423-
if (!AvailAttr)
424-
return false;
425-
421+
static bool isShortAvailable(const SemanticAvailableAttr &semanticAttr) {
422+
auto *AvailAttr = semanticAttr.getParsedAttr();
426423
if (AvailAttr->isSPI())
427424
return false;
428425

@@ -462,20 +459,21 @@ static bool isShortAvailable(const DeclAttribute *DA) {
462459
/// For example, iOS availability implies macCatalyst availability so if attributes for
463460
/// both are present and they have the same 'introduced' version, we can skip printing an
464461
/// explicit availability for macCatalyst.
465-
static bool isShortFormAvailabilityImpliedByOther(const AvailableAttr *Attr,
466-
ArrayRef<const DeclAttribute *> Others) {
462+
static bool
463+
isShortFormAvailabilityImpliedByOther(SemanticAvailableAttr Attr,
464+
ArrayRef<SemanticAvailableAttr> Others) {
467465
assert(isShortAvailable(Attr));
468466

469-
for (auto *DA : Others) {
470-
auto *Other = cast<AvailableAttr>(DA);
471-
if (Attr->getPlatform() == Other->getPlatform())
467+
auto platform = Attr.getDomain().getPlatformKind();
468+
for (auto other : Others) {
469+
auto otherPlatform = other.getDomain().getPlatformKind();
470+
if (platform == otherPlatform)
472471
continue;
473472

474-
if (!inheritsAvailabilityFromPlatform(Attr->getPlatform(),
475-
Other->getPlatform()))
473+
if (!inheritsAvailabilityFromPlatform(platform, otherPlatform))
476474
continue;
477475

478-
if (Attr->Introduced == Other->Introduced)
476+
if (Attr.getParsedAttr()->Introduced == other.getParsedAttr()->Introduced)
479477
return true;
480478
}
481479
return false;
@@ -489,39 +487,43 @@ static bool isShortFormAvailabilityImpliedByOther(const AvailableAttr *Attr,
489487
/// this will print:
490488
/// @available(OSX 10.10, iOS 8.0, *)
491489
static void printShortFormAvailable(const Decl *D,
492-
ArrayRef<const DeclAttribute *> Attrs,
490+
ArrayRef<SemanticAvailableAttr> Attrs,
493491
ASTPrinter &Printer,
494492
const PrintOptions &Options,
495493
bool forAtSpecialize = false) {
496494
assert(!Attrs.empty());
497495
if (!forAtSpecialize)
498496
Printer << "@available(";
499-
auto FirstAvail = cast<AvailableAttr>(Attrs.front());
500-
auto FirstAvailDomain = D->getDomainForAvailableAttr(FirstAvail);
501-
if (Attrs.size() == 1 && !FirstAvailDomain.isPlatform()) {
502-
assert(FirstAvail->Introduced.has_value());
503-
Printer << FirstAvailDomain.getNameForAttributePrinting() << " ";
504-
Printer << FirstAvail->Introduced.value().getAsString();
505-
if (!forAtSpecialize)
506-
Printer << ")";
507-
} else {
508-
for (auto *DA : Attrs) {
509-
auto *AvailAttr = cast<AvailableAttr>(DA);
510-
auto AvailAttrDomain = D->getDomainForAvailableAttr(AvailAttr);
511-
assert(AvailAttr->Introduced.has_value());
512-
// Avoid omitting available attribute when we are printing module interface.
513-
if (!Options.IsForSwiftInterface &&
514-
isShortFormAvailabilityImpliedByOther(AvailAttr, Attrs))
515-
continue;
516-
Printer << AvailAttrDomain.getNameForAttributePrinting() << " "
517-
<< AvailAttr->Introduced.value().getAsString() << ", ";
518-
}
519-
Printer << "*";
520-
if (!forAtSpecialize)
521-
Printer << ")";
497+
498+
bool isFirst = true;
499+
bool isPlatformAvailability = false;
500+
for (auto semanticAttr : Attrs) {
501+
auto *availAttr = semanticAttr.getParsedAttr();
502+
auto domain = semanticAttr.getDomain();
503+
assert(availAttr->Introduced.has_value());
504+
505+
// Avoid omitting available attribute when we are printing module interface.
506+
if (!Options.IsForSwiftInterface &&
507+
isShortFormAvailabilityImpliedByOther(semanticAttr, Attrs))
508+
continue;
509+
510+
Printer << (isFirst ? "" : ", ");
511+
isFirst = false;
512+
513+
if (domain.isPlatform())
514+
isPlatformAvailability = true;
515+
516+
Printer << domain.getNameForAttributePrinting() << " "
517+
<< availAttr->Introduced.value().getAsString();
522518
}
523-
if (!forAtSpecialize)
519+
520+
if (isPlatformAvailability)
521+
Printer << ", *";
522+
523+
if (!forAtSpecialize) {
524+
Printer << ")";
524525
Printer.printNewline();
526+
}
525527
}
526528

527529
static void printShortFormBackDeployed(ArrayRef<const DeclAttribute *> Attrs,
@@ -775,9 +777,9 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
775777
using AttributeVector = SmallVector<const DeclAttribute *, 8>;
776778

777779
// Process attributes in passes.
778-
AttributeVector shortAvailableAttributes;
779-
const DeclAttribute *swiftVersionAvailableAttribute = nullptr;
780-
const DeclAttribute *packageDescriptionVersionAvailableAttribute = nullptr;
780+
SmallVector<SemanticAvailableAttr, 8> shortAvailableAttributes;
781+
std::optional<SemanticAvailableAttr> swiftVersionAvailableAttribute;
782+
std::optional<SemanticAvailableAttr> packageDescriptionVersionAvailableAttribute;
781783
AttributeVector backDeployedAttributes;
782784
AttributeVector longAttributes;
783785
AttributeVector attributes;
@@ -824,30 +826,31 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
824826
// Be careful not to coalesce `@available(swift 5)` with other short
825827
// `available' attributes.
826828
if (auto *availableAttr = dyn_cast<AvailableAttr>(DA)) {
827-
if (availableAttr->isLanguageVersionSpecific() &&
828-
isShortAvailable(availableAttr)) {
829-
swiftVersionAvailableAttribute = availableAttr;
830-
continue;
831-
}
832-
if (availableAttr->isPackageDescriptionVersionSpecific() &&
833-
isShortAvailable(availableAttr)) {
834-
packageDescriptionVersionAvailableAttribute = availableAttr;
829+
auto domain = D->getDomainForAvailableAttr(availableAttr);
830+
auto semanticAttr = SemanticAvailableAttr(availableAttr, domain);
831+
if (isShortAvailable(semanticAttr)) {
832+
if (domain.isSwiftLanguage())
833+
swiftVersionAvailableAttribute.emplace(semanticAttr);
834+
else if (domain.isPackageDescription())
835+
packageDescriptionVersionAvailableAttribute.emplace(semanticAttr);
836+
else
837+
shortAvailableAttributes.push_back(semanticAttr);
838+
835839
continue;
836840
}
837841
}
838842

839843
AttributeVector &which = DA->isDeclModifier() ? modifiers :
840844
isa<BackDeployedAttr>(DA) ? backDeployedAttributes :
841-
isShortAvailable(DA) ? shortAvailableAttributes :
842845
DA->isLongAttribute() ? longAttributes :
843846
attributes;
844847
which.push_back(DA);
845848
}
846849

847850
if (swiftVersionAvailableAttribute)
848-
printShortFormAvailable(D, swiftVersionAvailableAttribute, Printer, Options);
851+
printShortFormAvailable(D, *swiftVersionAvailableAttribute, Printer, Options);
849852
if (packageDescriptionVersionAvailableAttribute)
850-
printShortFormAvailable(D, packageDescriptionVersionAvailableAttribute, Printer, Options);
853+
printShortFormAvailable(D, *packageDescriptionVersionAvailableAttribute, Printer, Options);
851854
if (!shortAvailableAttributes.empty())
852855
printShortFormAvailable(D, shortAvailableAttributes, Printer, Options);
853856
if (!backDeployedAttributes.empty())
@@ -926,10 +929,12 @@ SemanticAvailableAttributes::Filter::operator()(
926929
return SemanticAvailableAttr(availableAttr, domain);
927930
}
928931

929-
static void printAvailableAttr(const Decl *D, const AvailableAttr *Attr,
932+
static void printAvailableAttr(const Decl *D,
933+
const SemanticAvailableAttr &SemanticAttr,
930934
ASTPrinter &Printer,
931935
const PrintOptions &Options) {
932-
auto Domain = D->getDomainForAvailableAttr(Attr);
936+
auto Attr = SemanticAttr.getParsedAttr();
937+
auto Domain = SemanticAttr.getDomain();
933938

934939
// The parser rejects `@available(swift, unavailable)`, so when printing
935940
// attributes that are universally unavailable in Swift, we must print them
@@ -1159,6 +1164,9 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11591164

11601165
case DeclAttrKind::Available: {
11611166
auto Attr = cast<AvailableAttr>(this);
1167+
auto Domain = D->getDomainForAvailableAttr(Attr);
1168+
auto SemanticAttr = SemanticAvailableAttr(Attr, Domain);
1169+
11621170
if (Options.printPublicInterface() && Attr->isSPI()) {
11631171
assert(Attr->hasPlatform());
11641172
assert(Attr->Introduced.has_value());
@@ -1182,7 +1190,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11821190
Printer.printAttrName("@available");
11831191
}
11841192
Printer << "(";
1185-
printAvailableAttr(D, Attr, Printer, Options);
1193+
printAvailableAttr(D, SemanticAttr, Printer, Options);
11861194
Printer << ")";
11871195
break;
11881196
}
@@ -1276,17 +1284,19 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
12761284
Printer << "kind: " << kind << ", ";
12771285
if (target)
12781286
Printer << "target: " << target << ", ";
1279-
auto availAttrs = attr->getAvailableAttrs();
1280-
if (!availAttrs.empty()) {
1287+
SmallVector<SemanticAvailableAttr, 8> semanticAvailAttrs;
1288+
for (auto availAttr : attr->getAvailableAttrs()) {
1289+
auto domain = D->getDomainForAvailableAttr(availAttr);
1290+
semanticAvailAttrs.push_back(SemanticAvailableAttr(availAttr, domain));
1291+
}
1292+
1293+
if (!semanticAvailAttrs.empty()) {
12811294
Printer << "availability: ";
1282-
auto numAttrs = availAttrs.size();
1283-
if (numAttrs == 1) {
1284-
printAvailableAttr(D, availAttrs[0], Printer, Options);
1295+
if (semanticAvailAttrs.size() == 1) {
1296+
printAvailableAttr(D, semanticAvailAttrs[0], Printer, Options);
12851297
Printer << "; ";
12861298
} else {
1287-
SmallVector<const DeclAttribute *, 8> tmp(availAttrs.begin(),
1288-
availAttrs.end());
1289-
printShortFormAvailable(D, tmp, Printer, Options,
1299+
printShortFormAvailable(D, semanticAvailAttrs, Printer, Options,
12901300
true /*forAtSpecialize*/);
12911301
Printer << "; ";
12921302
}

0 commit comments

Comments
 (0)