Skip to content

Commit 8430749

Browse files
authored
[Distributed] Allow @resolvable to work with available on specific func (#80296)
resolves rdar://147892011
1 parent b719498 commit 8430749

File tree

3 files changed

+85
-15
lines changed

3 files changed

+85
-15
lines changed

lib/Macros/Sources/SwiftMacros/DistributedResolvableMacro.swift

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,13 @@ extension DistributedResolvableMacro {
7777

7878
static func stubMethodDecl(access: DeclModifierListSyntax, _ requirement: MemberBlockItemListSyntax.Element) -> String {
7979
// do we need to stub a computed variable?
80-
if let variable = requirement.decl.as(VariableDeclSyntax.self) {
81-
var accessorStubs: [String] = []
80+
if var variable = requirement.decl.as(VariableDeclSyntax.self) {
81+
variable.modifiers = variable.modifiers.filter { !$0.isAccessControl }
82+
access.reversed().forEach { modifier in
83+
variable.modifiers = variable.modifiers.prepending(modifier)
84+
}
8285

86+
var accessorStubs: [String] = []
8387
for binding in variable.bindings {
8488
if let accessorBlock = binding.accessorBlock {
8589
for accessor in accessorBlock.accessors.children(viewMode: .all) {
@@ -91,19 +95,31 @@ extension DistributedResolvableMacro {
9195

9296
let name = variable.bindings.first!.pattern.trimmed
9397
let typeAnnotation = variable.bindings.first?.typeAnnotation.map { "\($0.trimmed)" } ?? "Any"
98+
99+
// computed property stub
94100
return """
95-
\(access)\(variable.modifiers)\(variable.bindingSpecifier) \(name) \(typeAnnotation) {
101+
\(variable.attributes)
102+
\(variable.modifiers)\(variable.bindingSpecifier) \(name) \(typeAnnotation) {
96103
\(accessorStubs.joined(separator: "\n "))
97104
}
98105
"""
99-
}
106+
} else if var fun = requirement.decl.as(FunctionDeclSyntax.self) {
107+
fun.modifiers = fun.modifiers.filter { !$0.isAccessControl }
108+
access.reversed().forEach { modifier in
109+
fun.modifiers = fun.modifiers.prepending(modifier)
110+
}
100111

101-
// normal function stub
102-
return """
103-
\(access)\(requirement) {
104-
\(stubFunctionBody())
105-
}
106-
"""
112+
// normal function stub
113+
return """
114+
\(fun) {
115+
\(stubFunctionBody())
116+
}
117+
"""
118+
} else {
119+
// some declaration type we could not handle, let's silently ignore; we should not really need to emit
120+
// anything others than var and func here, and it's cleaner to just ignore rather than crash here.
121+
return ""
122+
}
107123
}
108124

109125
static func stubFunctionBody() -> DeclSyntax {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// REQUIRES: swift_swift_parser, asserts
2+
//
3+
// UNSUPPORTED: back_deploy_concurrency
4+
// REQUIRES: concurrency
5+
// REQUIRES: distributed
6+
//
7+
// RUN: %empty-directory(%t)
8+
// RUN: %empty-directory(%t-scratch)
9+
10+
// RUN: %target-swift-frontend -typecheck -target %target-swift-6.0-abi-triple -plugin-path %swift-plugin-dir -I %t -dump-macro-expansions %s -dump-macro-expansions 2>&1 | %FileCheck %s --color
11+
12+
import Distributed
13+
14+
@Resolvable
15+
public protocol Greeter: DistributedActor where ActorSystem: DistributedActorSystem<any Codable> {
16+
@available(iOS 6666, macOS 7777, tvOS 8888, visionOS 9999, *)
17+
distributed func greet(name: String) -> String
18+
19+
@available(iOS 6666, macOS 7777, tvOS 8888, visionOS 9999, *)
20+
distributed var name: String { get }
21+
}
22+
23+
// @Resolvable ->
24+
25+
// CHECK: public distributed actor $Greeter<ActorSystem>: Greeter,
26+
// CHECK: Distributed._DistributedActorStub
27+
// CHECK: where ActorSystem: DistributedActorSystem<any Codable>
28+
// CHECK: {
29+
// CHECK: }
30+
31+
// CHECK: extension Greeter where Self: Distributed._DistributedActorStub {
32+
// CHECK: @available(iOS 6666, macOS 7777, tvOS 8888, visionOS 9999, *)
33+
// CHECK: public
34+
// CHECK: distributed func greet(name: String) -> String {
35+
// CHECK: if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
36+
// CHECK: Distributed._distributedStubFatalError()
37+
// CHECK: } else {
38+
// CHECK: fatalError()
39+
// CHECK: }
40+
// CHECK: }
41+
42+
// CHECK: @available(iOS 6666, macOS 7777, tvOS 8888, visionOS 9999, *)
43+
// CHECK: public
44+
// CHECK: distributed var name : String {
45+
// CHECK: get {
46+
// CHECK: if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
47+
// CHECK: Distributed._distributedStubFatalError()
48+
// CHECK: } else {
49+
// CHECK: fatalError()
50+
// CHECK: }
51+
// CHECK: }
52+
// CHECK: }
53+
54+
// CHECK: }

test/Distributed/Macros/distributed_macro_expansion_DistributedProtocol_simple.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ protocol Greeter: DistributedActor where ActorSystem: DistributedActorSystem<any
1818

1919
// @Resolvable ->
2020

21-
// CHECK: distributed actor $Greeter<ActorSystem>: Greeter,
22-
// CHECK-NEXT: Distributed._DistributedActorStub
23-
// CHECK-NEXT: where ActorSystem: DistributedActorSystem<any Codable>
21+
// CHECK: distributed actor $Greeter<ActorSystem>: Greeter,
22+
// CHECK-NEXT: Distributed._DistributedActorStub
23+
// CHECK-NEXT: where ActorSystem: DistributedActorSystem<any Codable>
2424
// CHECK-NEXT: {
25-
// CHECK: }
25+
// CHECK: }
2626

27-
// CHECK: extension Greeter where Self: Distributed._DistributedActorStub {
27+
// CHECK: extension Greeter where Self: Distributed._DistributedActorStub {
2828
// CHECK-NEXT: distributed func greet(name: String) -> String {
2929
// CHECK-NEXT: if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
3030
// CHECK-NEXT: Distributed._distributedStubFatalError()

0 commit comments

Comments
 (0)