Skip to content

Commit 413936c

Browse files
committed
[Distributed] Allow @resolvable to work with available on specific func
resolves rdar://147892011
1 parent 2f4a8a8 commit 413936c

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

lib/Macros/Sources/SwiftMacros/DistributedResolvableMacro.swift

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ extension DistributedResolvableMacro {
7878
static func stubMethodDecl(access: DeclModifierListSyntax, _ requirement: MemberBlockItemListSyntax.Element) -> String {
7979
// do we need to stub a computed variable?
8080
if let variable = requirement.decl.as(VariableDeclSyntax.self) {
81+
8182
var accessorStubs: [String] = []
82-
8383
for binding in variable.bindings {
8484
if let accessorBlock = binding.accessorBlock {
8585
for accessor in accessorBlock.accessors.children(viewMode: .all) {
@@ -92,18 +92,27 @@ extension DistributedResolvableMacro {
9292
let name = variable.bindings.first!.pattern.trimmed
9393
let typeAnnotation = variable.bindings.first?.typeAnnotation.map { "\($0.trimmed)" } ?? "Any"
9494
return """
95-
\(access)\(variable.modifiers)\(variable.bindingSpecifier) \(name) \(typeAnnotation) {
95+
\(variable.attributes)
96+
\(access)
97+
\(variable.modifiers)\(variable.bindingSpecifier) \(name) \(typeAnnotation) {
9698
\(accessorStubs.joined(separator: "\n "))
9799
}
98100
"""
99-
}
101+
} else if var fun = requirement.decl.as(FunctionDeclSyntax.self) {
102+
fun.modifiers = fun.modifiers.filter { !$0.isAccessControl }
103+
fun.modifiers = fun.modifiers.prepending(DeclModifierSyntax(name: .keyword(.public)))
100104

101-
// normal function stub
102-
return """
103-
\(access)\(requirement) {
104-
\(stubFunctionBody())
105-
}
106-
"""
105+
// normal function stub
106+
return """
107+
\(fun) {
108+
\(stubFunctionBody())
109+
}
110+
"""
111+
} else {
112+
// some declaration type we could not handle, let's silently ignore; we should not really need to emit
113+
// anything others than var and func here, and it's cleaner to just ignore rather than crash here.
114+
return ""
115+
}
107116
}
108117

109118
static func stubFunctionBody() -> DeclSyntax {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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, *) public
33+
// CHECK: distributed func greet(name: String) -> String {
34+
// CHECK: if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
35+
// CHECK: Distributed._distributedStubFatalError()
36+
// CHECK: } else {
37+
// CHECK: fatalError()
38+
// CHECK: }
39+
// CHECK: }
40+
41+
// CHECK: @available(iOS 6666, macOS 7777, tvOS 8888, visionOS 9999, *)
42+
// CHECK: public
43+
// CHECK: distributed var name : String {
44+
// CHECK: get {
45+
// CHECK: if #available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
46+
// CHECK: Distributed._distributedStubFatalError()
47+
// CHECK: } else {
48+
// CHECK: fatalError()
49+
// CHECK: }
50+
// CHECK: }
51+
// CHECK: }
52+
53+
// CHECK: }

0 commit comments

Comments
 (0)