@@ -418,11 +418,8 @@ void DeclAttributes::dump(const Decl *D) const {
418
418
// / introduction version and does not support deprecation, obsoletion, or
419
419
// / messages.
420
420
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 ();
426
423
if (AvailAttr->isSPI ())
427
424
return false ;
428
425
@@ -462,20 +459,21 @@ static bool isShortAvailable(const DeclAttribute *DA) {
462
459
// / For example, iOS availability implies macCatalyst availability so if attributes for
463
460
// / both are present and they have the same 'introduced' version, we can skip printing an
464
461
// / 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) {
467
465
assert (isShortAvailable (Attr));
468
466
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)
472
471
continue ;
473
472
474
- if (!inheritsAvailabilityFromPlatform (Attr->getPlatform (),
475
- Other->getPlatform ()))
473
+ if (!inheritsAvailabilityFromPlatform (platform, otherPlatform))
476
474
continue ;
477
475
478
- if (Attr->Introduced == Other ->Introduced )
476
+ if (Attr. getParsedAttr () ->Introduced == other. getParsedAttr () ->Introduced )
479
477
return true ;
480
478
}
481
479
return false ;
@@ -489,39 +487,43 @@ static bool isShortFormAvailabilityImpliedByOther(const AvailableAttr *Attr,
489
487
// / this will print:
490
488
// / @available(OSX 10.10, iOS 8.0, *)
491
489
static void printShortFormAvailable (const Decl *D,
492
- ArrayRef<const DeclAttribute * > Attrs,
490
+ ArrayRef<SemanticAvailableAttr > Attrs,
493
491
ASTPrinter &Printer,
494
492
const PrintOptions &Options,
495
493
bool forAtSpecialize = false ) {
496
494
assert (!Attrs.empty ());
497
495
if (!forAtSpecialize)
498
496
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 ();
522
518
}
523
- if (!forAtSpecialize)
519
+
520
+ if (isPlatformAvailability)
521
+ Printer << " , *" ;
522
+
523
+ if (!forAtSpecialize) {
524
+ Printer << " )" ;
524
525
Printer.printNewline ();
526
+ }
525
527
}
526
528
527
529
static void printShortFormBackDeployed (ArrayRef<const DeclAttribute *> Attrs,
@@ -775,9 +777,9 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
775
777
using AttributeVector = SmallVector<const DeclAttribute *, 8 >;
776
778
777
779
// 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;
781
783
AttributeVector backDeployedAttributes;
782
784
AttributeVector longAttributes;
783
785
AttributeVector attributes;
@@ -824,30 +826,31 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
824
826
// Be careful not to coalesce `@available(swift 5)` with other short
825
827
// `available' attributes.
826
828
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
+
835
839
continue ;
836
840
}
837
841
}
838
842
839
843
AttributeVector &which = DA->isDeclModifier () ? modifiers :
840
844
isa<BackDeployedAttr>(DA) ? backDeployedAttributes :
841
- isShortAvailable (DA) ? shortAvailableAttributes :
842
845
DA->isLongAttribute () ? longAttributes :
843
846
attributes;
844
847
which.push_back (DA);
845
848
}
846
849
847
850
if (swiftVersionAvailableAttribute)
848
- printShortFormAvailable (D, swiftVersionAvailableAttribute, Printer, Options);
851
+ printShortFormAvailable (D, * swiftVersionAvailableAttribute, Printer, Options);
849
852
if (packageDescriptionVersionAvailableAttribute)
850
- printShortFormAvailable (D, packageDescriptionVersionAvailableAttribute, Printer, Options);
853
+ printShortFormAvailable (D, * packageDescriptionVersionAvailableAttribute, Printer, Options);
851
854
if (!shortAvailableAttributes.empty ())
852
855
printShortFormAvailable (D, shortAvailableAttributes, Printer, Options);
853
856
if (!backDeployedAttributes.empty ())
@@ -926,10 +929,12 @@ SemanticAvailableAttributes::Filter::operator()(
926
929
return SemanticAvailableAttr (availableAttr, domain);
927
930
}
928
931
929
- static void printAvailableAttr (const Decl *D, const AvailableAttr *Attr,
932
+ static void printAvailableAttr (const Decl *D,
933
+ const SemanticAvailableAttr &SemanticAttr,
930
934
ASTPrinter &Printer,
931
935
const PrintOptions &Options) {
932
- auto Domain = D->getDomainForAvailableAttr (Attr);
936
+ auto Attr = SemanticAttr.getParsedAttr ();
937
+ auto Domain = SemanticAttr.getDomain ();
933
938
934
939
// The parser rejects `@available(swift, unavailable)`, so when printing
935
940
// attributes that are universally unavailable in Swift, we must print them
@@ -1159,6 +1164,9 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
1159
1164
1160
1165
case DeclAttrKind::Available: {
1161
1166
auto Attr = cast<AvailableAttr>(this );
1167
+ auto Domain = D->getDomainForAvailableAttr (Attr);
1168
+ auto SemanticAttr = SemanticAvailableAttr (Attr, Domain);
1169
+
1162
1170
if (Options.printPublicInterface () && Attr->isSPI ()) {
1163
1171
assert (Attr->hasPlatform ());
1164
1172
assert (Attr->Introduced .has_value ());
@@ -1182,7 +1190,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
1182
1190
Printer.printAttrName (" @available" );
1183
1191
}
1184
1192
Printer << " (" ;
1185
- printAvailableAttr (D, Attr , Printer, Options);
1193
+ printAvailableAttr (D, SemanticAttr , Printer, Options);
1186
1194
Printer << " )" ;
1187
1195
break ;
1188
1196
}
@@ -1276,17 +1284,19 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
1276
1284
Printer << " kind: " << kind << " , " ;
1277
1285
if (target)
1278
1286
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 ()) {
1281
1294
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);
1285
1297
Printer << " ; " ;
1286
1298
} else {
1287
- SmallVector<const DeclAttribute *, 8 > tmp (availAttrs.begin (),
1288
- availAttrs.end ());
1289
- printShortFormAvailable (D, tmp, Printer, Options,
1299
+ printShortFormAvailable (D, semanticAvailAttrs, Printer, Options,
1290
1300
true /* forAtSpecialize*/ );
1291
1301
Printer << " ; " ;
1292
1302
}
0 commit comments