@@ -310,11 +310,13 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
310
310
StringRef customName = getNameForObjC (CD, CustomNamesOnly);
311
311
if (customName.empty ()) {
312
312
llvm::SmallString<32 > scratch;
313
- os << " SWIFT_CLASS(\" " << CD->getObjCRuntimeName (scratch) << " \" )\n "
314
- << " @interface " << CD->getName ();
313
+ os << " SWIFT_CLASS(\" " << CD->getObjCRuntimeName (scratch) << " \" )" ;
314
+ printAvailability (CD);
315
+ os << " \n @interface " << CD->getName ();
315
316
} else {
316
- os << " SWIFT_CLASS_NAMED(\" " << CD->getName () << " \" )\n "
317
- << " @interface " << customName;
317
+ os << " SWIFT_CLASS_NAMED(\" " << CD->getName () << " \" )" ;
318
+ printAvailability (CD);
319
+ os << " \n @interface " << customName;
318
320
}
319
321
320
322
if (Type superTy = CD->getSuperclass ())
@@ -350,6 +352,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
350
352
351
353
auto baseClass = ED->getExtendedType ()->getClassOrBoundGenericClass ();
352
354
355
+ if (printAvailability (ED, PrintLeadingSpace::No))
356
+ os << " \n " ;
353
357
os << " @interface " << getNameForObjC (baseClass);
354
358
maybePrintObjCGenericParameters (baseClass);
355
359
os << " (SWIFT_EXTENSION(" << ED->getModuleContext ()->getName () << " ))" ;
@@ -365,11 +369,13 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
365
369
StringRef customName = getNameForObjC (PD, CustomNamesOnly);
366
370
if (customName.empty ()) {
367
371
llvm::SmallString<32 > scratch;
368
- os << " SWIFT_PROTOCOL(\" " << PD->getObjCRuntimeName (scratch) << " \" )\n "
369
- << " @protocol " << PD->getName ();
372
+ os << " SWIFT_PROTOCOL(\" " << PD->getObjCRuntimeName (scratch) << " \" )" ;
373
+ printAvailability (PD);
374
+ os << " \n @protocol " << PD->getName ();
370
375
} else {
371
- os << " SWIFT_PROTOCOL_NAMED(\" " << PD->getName () << " \" )\n "
372
- << " @protocol " << customName;
376
+ os << " SWIFT_PROTOCOL_NAMED(\" " << PD->getName () << " \" )" ;
377
+ printAvailability (PD);
378
+ os << " \n @protocol " << customName;
373
379
}
374
380
375
381
printProtocols (PD->getInheritedProtocols ());
@@ -626,7 +632,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
626
632
}
627
633
628
634
if (!skipAvailability) {
629
- appendAvailabilityAttribute (AFD);
635
+ printAvailability (AFD);
630
636
}
631
637
632
638
if (isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->isAccessor ()) {
@@ -683,132 +689,154 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
683
689
os << " SWIFT_WARN_UNUSED_RESULT" ;
684
690
}
685
691
686
- appendAvailabilityAttribute (FD);
692
+ printAvailability (FD);
687
693
688
694
os << ' ;' ;
689
695
}
690
696
691
- void appendAvailabilityAttribute (const ValueDecl *VD) {
692
- for (auto Attr : VD->getAttrs ()) {
693
- if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) {
694
- if (AvAttr->isInvalid ()) continue ;
695
- if (AvAttr->Platform == PlatformKind::none) {
696
- if (AvAttr->PlatformAgnostic == PlatformAgnosticAvailabilityKind::Unavailable) {
697
- // Availability for *
698
- if (!AvAttr->Rename .empty ()) {
699
- // NB: Don't bother getting obj-c names, we can't get one for the
700
- // rename
701
- os << " SWIFT_UNAVAILABLE_MSG(\" '" << VD->getBaseName ()
702
- << " ' has been renamed to '" ;
703
- printEncodedString (AvAttr->Rename , false );
704
- os << ' \' ' ;
705
- if (!AvAttr->Message .empty ()) {
706
- os << " : " ;
707
- printEncodedString (AvAttr->Message , false );
708
- }
709
- os << " \" )" ;
710
- } else if (!AvAttr->Message .empty ()) {
711
- os << " SWIFT_UNAVAILABLE_MSG(" ;
712
- printEncodedString (AvAttr->Message );
713
- os << " )" ;
714
- } else {
715
- os << " SWIFT_UNAVAILABLE" ;
716
- }
717
- break ;
718
- }
719
- if (AvAttr->isUnconditionallyDeprecated ()) {
720
- if (!AvAttr->Rename .empty () || !AvAttr->Message .empty ()) {
721
- os << " SWIFT_DEPRECATED_MSG(" ;
722
- printEncodedString (AvAttr->Message );
723
- if (!AvAttr->Rename .empty ()) {
724
- os << " , " ;
725
- printEncodedString (AvAttr->Rename );
726
- }
727
- os << " )" ;
728
- } else {
729
- os << " SWIFT_DEPRECATED" ;
730
- }
731
- }
732
- continue ;
733
- }
734
- // Availability for a specific platform
735
- if (!AvAttr->Introduced .hasValue ()
736
- && !AvAttr->Deprecated .hasValue ()
737
- && !AvAttr->Obsoleted .hasValue ()
738
- && !AvAttr->isUnconditionallyDeprecated ()
739
- && !AvAttr->isUnconditionallyUnavailable ()) {
740
- continue ;
741
- }
742
- const char *plat = nullptr ;
743
- switch (AvAttr->Platform ) {
744
- case PlatformKind::OSX:
745
- plat = " macos" ;
746
- break ;
747
- case PlatformKind::iOS:
748
- plat = " ios" ;
749
- break ;
750
- case PlatformKind::tvOS:
751
- plat = " tvos" ;
752
- break ;
753
- case PlatformKind::watchOS:
754
- plat = " watchos" ;
755
- break ;
756
- case PlatformKind::OSXApplicationExtension:
757
- plat = " macos_app_extension" ;
758
- break ;
759
- case PlatformKind::iOSApplicationExtension:
760
- plat = " ios_app_extension" ;
761
- break ;
762
- case PlatformKind::tvOSApplicationExtension:
763
- plat = " tvos_app_extension" ;
764
- break ;
765
- case PlatformKind::watchOSApplicationExtension:
766
- plat = " watchos_app_extension" ;
767
- break ;
768
- default :
769
- break ;
770
- }
771
- if (!plat) continue ;
772
- os << " SWIFT_AVAILABILITY(" << plat;
773
- if (AvAttr->isUnconditionallyUnavailable ()) {
774
- os << " ,unavailable" ;
775
- } else {
776
- if (AvAttr->Introduced .hasValue ()) {
777
- os << " ,introduced=" << AvAttr->Introduced .getValue ().getAsString ();
778
- }
779
- if (AvAttr->Deprecated .hasValue ()) {
780
- os << " ,deprecated=" << AvAttr->Deprecated .getValue ().getAsString ();
781
- } else if (AvAttr->isUnconditionallyDeprecated ()) {
782
- // We need to specify some version, we can't just say deprecated.
783
- // We also can't deprecate it before it's introduced.
784
- if (AvAttr->Introduced .hasValue ()) {
785
- os << " ,deprecated=" << AvAttr->Introduced .getValue ().getAsString ();
786
- } else {
787
- os << " ,deprecated=0.0.1" ;
788
- }
789
- }
790
- if (AvAttr->Obsoleted .hasValue ()) {
791
- os << " ,obsoleted=" << AvAttr->Obsoleted .getValue ().getAsString ();
792
- }
793
- if (!AvAttr->Rename .empty ()) {
794
- // NB: Don't bother getting obj-c names, we can't get one for the rename
795
- os << " ,message=\" '" << VD->getBaseName ()
697
+ enum class PrintLeadingSpace : bool {
698
+ No = false ,
699
+ Yes = true
700
+ };
701
+
702
+ // / Returns \c true if anything was printed.
703
+ bool printAvailability (
704
+ const Decl *D,
705
+ PrintLeadingSpace printLeadingSpace = PrintLeadingSpace::Yes) {
706
+ bool hasPrintedAnything = false ;
707
+ auto maybePrintLeadingSpace = [&] {
708
+ if (printLeadingSpace == PrintLeadingSpace::Yes || hasPrintedAnything)
709
+ os << " " ;
710
+ hasPrintedAnything = true ;
711
+ };
712
+
713
+ for (auto AvAttr : D->getAttrs ().getAttributes <AvailableAttr>()) {
714
+ if (AvAttr->Platform == PlatformKind::none) {
715
+ if (AvAttr->PlatformAgnostic == PlatformAgnosticAvailabilityKind::Unavailable) {
716
+ // Availability for *
717
+ if (!AvAttr->Rename .empty () && isa<ValueDecl>(D)) {
718
+ // NB: Don't bother getting obj-c names, we can't get one for the
719
+ // rename
720
+ maybePrintLeadingSpace ();
721
+ os << " SWIFT_UNAVAILABLE_MSG(\" '"
722
+ << cast<ValueDecl>(D)->getBaseName ()
796
723
<< " ' has been renamed to '" ;
797
724
printEncodedString (AvAttr->Rename , false );
798
725
os << ' \' ' ;
799
726
if (!AvAttr->Message .empty ()) {
800
727
os << " : " ;
801
728
printEncodedString (AvAttr->Message , false );
802
729
}
803
- os << " \" " ;
730
+ os << " \" ) " ;
804
731
} else if (!AvAttr->Message .empty ()) {
805
- os << " ,message=" ;
732
+ maybePrintLeadingSpace ();
733
+ os << " SWIFT_UNAVAILABLE_MSG(" ;
806
734
printEncodedString (AvAttr->Message );
735
+ os << " )" ;
736
+ } else {
737
+ maybePrintLeadingSpace ();
738
+ os << " SWIFT_UNAVAILABLE" ;
807
739
}
740
+ break ;
741
+ }
742
+ if (AvAttr->isUnconditionallyDeprecated ()) {
743
+ if (!AvAttr->Rename .empty () || !AvAttr->Message .empty ()) {
744
+ maybePrintLeadingSpace ();
745
+ os << " SWIFT_DEPRECATED_MSG(" ;
746
+ printEncodedString (AvAttr->Message );
747
+ if (!AvAttr->Rename .empty ()) {
748
+ os << " , " ;
749
+ printEncodedString (AvAttr->Rename );
750
+ }
751
+ os << " )" ;
752
+ } else {
753
+ maybePrintLeadingSpace ();
754
+ os << " SWIFT_DEPRECATED" ;
755
+ }
756
+ }
757
+ continue ;
758
+ }
759
+
760
+ // Availability for a specific platform
761
+ if (!AvAttr->Introduced .hasValue ()
762
+ && !AvAttr->Deprecated .hasValue ()
763
+ && !AvAttr->Obsoleted .hasValue ()
764
+ && !AvAttr->isUnconditionallyDeprecated ()
765
+ && !AvAttr->isUnconditionallyUnavailable ()) {
766
+ continue ;
767
+ }
768
+
769
+ const char *plat;
770
+ switch (AvAttr->Platform ) {
771
+ case PlatformKind::OSX:
772
+ plat = " macos" ;
773
+ break ;
774
+ case PlatformKind::iOS:
775
+ plat = " ios" ;
776
+ break ;
777
+ case PlatformKind::tvOS:
778
+ plat = " tvos" ;
779
+ break ;
780
+ case PlatformKind::watchOS:
781
+ plat = " watchos" ;
782
+ break ;
783
+ case PlatformKind::OSXApplicationExtension:
784
+ plat = " macos_app_extension" ;
785
+ break ;
786
+ case PlatformKind::iOSApplicationExtension:
787
+ plat = " ios_app_extension" ;
788
+ break ;
789
+ case PlatformKind::tvOSApplicationExtension:
790
+ plat = " tvos_app_extension" ;
791
+ break ;
792
+ case PlatformKind::watchOSApplicationExtension:
793
+ plat = " watchos_app_extension" ;
794
+ break ;
795
+ case PlatformKind::none:
796
+ llvm_unreachable (" handled above" );
797
+ }
798
+
799
+ maybePrintLeadingSpace ();
800
+ os << " SWIFT_AVAILABILITY(" << plat;
801
+ if (AvAttr->isUnconditionallyUnavailable ()) {
802
+ os << " ,unavailable" ;
803
+ } else {
804
+ if (AvAttr->Introduced .hasValue ()) {
805
+ os << " ,introduced=" << AvAttr->Introduced .getValue ().getAsString ();
806
+ }
807
+ if (AvAttr->Deprecated .hasValue ()) {
808
+ os << " ,deprecated=" << AvAttr->Deprecated .getValue ().getAsString ();
809
+ } else if (AvAttr->isUnconditionallyDeprecated ()) {
810
+ // We need to specify some version, we can't just say deprecated.
811
+ // We also can't deprecate it before it's introduced.
812
+ if (AvAttr->Introduced .hasValue ()) {
813
+ os << " ,deprecated=" << AvAttr->Introduced .getValue ().getAsString ();
814
+ } else {
815
+ os << " ,deprecated=0.0.1" ;
816
+ }
817
+ }
818
+ if (AvAttr->Obsoleted .hasValue ()) {
819
+ os << " ,obsoleted=" << AvAttr->Obsoleted .getValue ().getAsString ();
820
+ }
821
+ }
822
+ if (!AvAttr->Rename .empty () && isa<ValueDecl>(D)) {
823
+ // NB: Don't bother getting obj-c names, we can't get one for the rename
824
+ os << " ,message=\" '" << cast<ValueDecl>(D)->getBaseName ()
825
+ << " ' has been renamed to '" ;
826
+ printEncodedString (AvAttr->Rename , false );
827
+ os << ' \' ' ;
828
+ if (!AvAttr->Message .empty ()) {
829
+ os << " : " ;
830
+ printEncodedString (AvAttr->Message , false );
808
831
}
809
- os << " )" ;
832
+ os << " \" " ;
833
+ } else if (!AvAttr->Message .empty ()) {
834
+ os << " ,message=" ;
835
+ printEncodedString (AvAttr->Message );
810
836
}
837
+ os << " )" ;
811
838
}
839
+ return hasPrintedAnything;
812
840
}
813
841
814
842
void printSwift3ObjCDeprecatedInference (ValueDecl *VD) {
0 commit comments