Skip to content

Commit 135e9b9

Browse files
committed
[PrintAsObjC] Emit Xcode-7-compatible class properties.
There's not yet a released version of Apple Clang that supports Objective-C class properties, so make sure the generated header guards any uses of them with a __has_feature check, and provides declarations of the accessor methods as well. https://bugs.swift.org/browse/SR-1442
1 parent 75bd780 commit 135e9b9

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,15 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
566566

567567
printDocumentationComment(VD);
568568

569+
if (VD->isStatic()) {
570+
// Older Clangs don't support class properties.
571+
os << "SWIFT_CLASS_PROPERTY(";
572+
}
573+
569574
// For now, never promise atomicity.
570575
os << "@property (nonatomic";
571576

572-
if (!VD->isInstanceMember())
577+
if (VD->isStatic())
573578
os << ", class";
574579

575580
ASTContext &ctx = M.getASTContext();
@@ -670,7 +675,17 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
670675
print(ty, OTK_None, objCName);
671676
}
672677

673-
os << ";\n";
678+
os << ";";
679+
if (VD->isStatic()) {
680+
os << ")\n";
681+
// Older Clangs don't support class properties, so print the accessors as
682+
// well. This is harmless.
683+
printAbstractFunctionAsMethod(VD->getGetter(), true);
684+
if (auto setter = VD->getSetter())
685+
printAbstractFunctionAsMethod(setter, true);
686+
} else {
687+
os << "\n";
688+
}
674689
}
675690

676691
void visitSubscriptDecl(SubscriptDecl *SD) {
@@ -1751,6 +1766,13 @@ class ModuleWriter {
17511766
"#if !defined(SWIFT_METATYPE)\n"
17521767
"# define SWIFT_METATYPE(X) Class\n"
17531768
"#endif\n"
1769+
"#if !defined(SWIFT_CLASS_PROPERTY)\n"
1770+
"# if __has_feature(objc_class_property)\n"
1771+
"# define SWIFT_CLASS_PROPERTY(X) X\n"
1772+
"# else\n"
1773+
"# define SWIFT_CLASS_PROPERTY(X)\n"
1774+
"# endif\n"
1775+
"#endif\n"
17541776
"\n"
17551777
"#if defined(__has_attribute) && "
17561778
"__has_attribute(objc_runtime_name)\n"

test/PrintAsObjC/Inputs/comments-expected-output.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ SWIFT_CLASS("_TtC8comments21A010_AttachToEntities")
2222
/**
2323
Aaa. v2.
2424
*/
25-
@property (nonatomic, class, readonly) NSInteger v2;
25+
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly) NSInteger v2;)
26+
+ (NSInteger)v2;
2627
@end
2728

2829

test/PrintAsObjC/classes.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,11 @@ public class NonObjCClass { }
369369
// CHECK-NEXT: @property (nonatomic, readonly, strong) Properties * _Nonnull mySelf;
370370
// CHECK-NEXT: @property (nonatomic, readonly) double pi;
371371
// CHECK-NEXT: @property (nonatomic) NSInteger computed;
372-
// CHECK-NEXT: @property (nonatomic, class, strong) Properties * _Nonnull shared;
373-
// CHECK-NEXT: @property (nonatomic, class, readonly, strong) Properties * _Nonnull sharedRO;
372+
// CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) Properties * _Nonnull shared;)
373+
// CHECK-NEXT: + (Properties * _Nonnull)shared;
374+
// CHECK-NEXT: + (void)setShared:(Properties * _Nonnull)newValue;
375+
// CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) Properties * _Nonnull sharedRO;)
376+
// CHECK-NEXT: + (Properties * _Nonnull)sharedRO;
374377
// CHECK-NEXT: @property (nonatomic, weak) Properties * _Nullable weakOther;
375378
// CHECK-NEXT: @property (nonatomic, assign) Properties * _Nonnull unownedOther;
376379
// CHECK-NEXT: @property (nonatomic, unsafe_unretained) Properties * _Nonnull unmanagedOther;
@@ -399,9 +402,13 @@ public class NonObjCClass { }
399402
// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(CustomName) NSArray<CustomName *> * _Nullable outletCollectionOptional;
400403
// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray * _Nullable outletCollectionAnyObject;
401404
// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray<id <NSObject>> * _Nullable outletCollectionProto;
402-
// CHECK-NEXT: @property (nonatomic, class, readonly) NSInteger staticInt;
403-
// CHECK-NEXT: @property (nonatomic, class, copy) NSString * _Nonnull staticString;
404-
// CHECK-NEXT: @property (nonatomic, class, readonly) double staticDouble;
405+
// CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly) NSInteger staticInt;)
406+
// CHECK-NEXT: + (NSInteger)staticInt;
407+
// CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, copy) NSString * _Nonnull staticString;)
408+
// CHECK-NEXT: + (NSString * _Nonnull)staticString;
409+
// CHECK-NEXT: + (void)setStaticString:(NSString * _Nonnull)value;
410+
// CHECK-NEXT: SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly) double staticDouble;)
411+
// CHECK-NEXT: + (double)staticDouble;
405412
// CHECK-NEXT: @property (nonatomic, strong) Properties * _Nullable wobble;
406413
// CHECK-NEXT: @property (nonatomic, getter=isEnabled, setter=setIsEnabled:) BOOL enabled;
407414
// CHECK-NEXT: @property (nonatomic, getter=isAnimated) BOOL animated;

0 commit comments

Comments
 (0)