Skip to content

Commit 0ccf43d

Browse files
authored
Merge pull request #38688 from apple/add-available-to-getters
[ClangImporter] Add @available(*, renamed:) to imported async getters
2 parents 022d44d + 0389ea5 commit 0ccf43d

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

lib/AST/Attr.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,23 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
884884
if (!Attr->Rename.empty()) {
885885
Printer << ", renamed: \"" << Attr->Rename << "\"";
886886
} else if (Attr->RenameDecl) {
887-
Printer << ", renamed: \"" << Attr->RenameDecl->getName() << "\"";
887+
Printer << ", renamed: \"";
888+
if (auto *Accessor = dyn_cast<AccessorDecl>(Attr->RenameDecl)) {
889+
switch (Accessor->getAccessorKind()) {
890+
case AccessorKind::Get:
891+
Printer << "getter:";
892+
break;
893+
case AccessorKind::Set:
894+
Printer << "setter:";
895+
break;
896+
default:
897+
break;
898+
}
899+
Printer << Accessor->getStorage()->getName() << "()";
900+
} else {
901+
Printer << Attr->RenameDecl->getName();
902+
}
903+
Printer << "\"";
888904
}
889905

890906
// If there's no message, but this is specifically an imported

lib/ClangImporter/ImportDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8161,11 +8161,18 @@ void addCompletionHandlerAttribute(Decl *asyncImport,
81618161
ArrayRef<Decl *> members,
81628162
ASTContext &SwiftContext) {
81638163
auto *asyncFunc = dyn_cast_or_null<AbstractFunctionDecl>(asyncImport);
8164+
// Completion handler functions can be imported as getters, but the decl
8165+
// given back from the import is the property. Grab the underlying getter
8166+
if (auto *property = dyn_cast_or_null<AbstractStorageDecl>(asyncImport))
8167+
asyncFunc = property->getAccessor(AccessorKind::Get);
8168+
81648169
if (!asyncFunc)
81658170
return;
81668171

81678172
for (auto *member : members) {
8168-
if (member != asyncImport) {
8173+
// Only add the attribute to functions that don't already have availability
8174+
if (member != asyncImport && isa<AbstractFunctionDecl>(member) &&
8175+
!member->getAttrs().hasAttribute<AvailableAttr>()) {
81698176
member->getAttrs().add(
81708177
AvailableAttr::createForAlternative(SwiftContext, asyncFunc));
81718178
}

test/IDE/print_clang_objc_effectful_properties.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,32 @@
77
// REQUIRES: objc_interop
88

99
// CHECK-LABEL: class EffProps : NSObject {
10-
// CHECK: func getDogWithCompletion(_ completionHandler: @escaping (NSObject) -> Void)
11-
// CHECK: var doggo: NSObject { get async }
10+
// CHECK: @available(*, renamed: "getter:doggo()")
11+
// CHECK-NEXT: func getDogWithCompletion(_ completionHandler: @escaping (NSObject) -> Void)
12+
// CHECK: var doggo: NSObject { get async }
1213

13-
// CHECK: func obtainCat(_ completionHandler: @escaping (NSObject?, Error?) -> Void)
14+
// CHECK: @available(*, renamed: "getter:catto()")
15+
// CHECK-NEXT: func obtainCat(_ completionHandler: @escaping (NSObject?, Error?) -> Void)
1416
// CHECK-NEXT: var catto: NSObject? { get async throws }
1517

16-
// CHECK: func checkAvailability(completionHandler: @escaping (Bool) -> Void)
18+
// CHECK: @available(*, renamed: "getter:available()")
19+
// CHECK-NEXT: func checkAvailability(completionHandler: @escaping (Bool) -> Void)
1720
// CHECK-NEXT: var available: Bool { get async }
1821
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "checkAvailability(completionHandler:)")
1922
// CHECK-NEXT: func checkAvailabilityWithCompletionHandler(_ completionHandler: @escaping (Bool) -> Void)
2023

21-
// CHECK: func returnNothing(completion completionHandler: @escaping () -> Void)
24+
// CHECK: @available(*, renamed: "getter:touch()")
25+
// CHECK-NEXT: func returnNothing(completion completionHandler: @escaping () -> Void)
2226
// CHECK-NEXT: var touch: Void { get async }
2327
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "returnNothing(completion:)")
2428
// CHECK-NEXT: func returnNothingWithCompletion(_ completionHandler: @escaping () -> Void)
2529

26-
// CHECK: func nullableHandler(_ completion: ((String) -> Void)? = nil)
30+
// CHECK: @available(*, renamed: "getter:fromNullableHandler()")
31+
// CHECK-NEXT: func nullableHandler(_ completion: ((String) -> Void)? = nil)
2732
// CHECK-NEXT: var fromNullableHandler: String { get async }
2833

29-
// CHECK: func getMainDog(_ completion: @escaping (String) -> Void)
34+
// CHECK: @available(*, renamed: "getter:mainDogProp()")
35+
// CHECK-NEXT: func getMainDog(_ completion: @escaping (String) -> Void)
3036
// CHECK-NEXT: var mainDogProp: String { get async }
3137

3238
// CHECK: @available(*, renamed: "regularMainDog()")

0 commit comments

Comments
 (0)