@@ -45,12 +45,15 @@ extension DistributedProtocolMacro {
45
45
return [ ]
46
46
}
47
47
48
+ let accessModifiers : String = proto. accessModifiersString
49
+
48
50
let requirements =
49
51
proto. memberBlock. members. map { member in
50
52
member. trimmed
51
53
}
52
54
let requirementStubs = requirements
53
- . map ( stubMethod) . joined ( separator: " \n " )
55
+ . map { stubMethod ( access: accessModifiers, $0) }
56
+ . joined ( separator: " \n " )
54
57
55
58
let extensionDecl : DeclSyntax =
56
59
"""
@@ -61,9 +64,9 @@ extension DistributedProtocolMacro {
61
64
return [ extensionDecl. cast ( ExtensionDeclSyntax . self) ]
62
65
}
63
66
64
- static func stubMethod( _ requirementDeclaration: MemberBlockItemListSyntax . Element ) -> String {
67
+ static func stubMethod( access : String , _ requirementDeclaration: MemberBlockItemListSyntax . Element ) -> String {
65
68
"""
66
- \( requirementDeclaration) {
69
+ \( access ) \( requirementDeclaration) {
67
70
\( stubFunctionBody ( ) )
68
71
}
69
72
"""
@@ -109,6 +112,8 @@ extension DistributedProtocolMacro {
109
112
""" , id: . invalidApplication)
110
113
}
111
114
115
+ let accessModifiers = proto. accessModifiersString
116
+
112
117
for req in proto. genericWhereClause? . requirements ?? [ ] {
113
118
switch req. requirement {
114
119
case . conformanceRequirement( let conformanceReq)
@@ -126,51 +131,68 @@ extension DistributedProtocolMacro {
126
131
}
127
132
}
128
133
129
- if isGenericStub, let specificActorSystemRequirement {
130
- return [
131
- """
132
- \( proto. modifiers) distributed actor $ \( proto. name. trimmed) <ActorSystem>: \( proto. name. trimmed) ,
133
- Distributed._DistributedActorStub
134
- where ActorSystem: \( specificActorSystemRequirement)
135
- { }
136
- """
137
- ]
138
- } else if let specificActorSystemRequirement {
139
- return [
140
- """
141
- \( proto. modifiers) distributed actor $ \( proto. name. trimmed) : \( proto. name. trimmed) ,
142
- Distributed._DistributedActorStub
143
- {
144
- \( typealiasActorSystem ( proto, specificActorSystemRequirement) )
145
- }
146
- """
147
- ]
148
- } else {
149
- // there may be no `where` clause specifying an actor system,
150
- // but perhaps there is a typealias (or extension with a typealias),
151
- // specifying a concrete actor system so we let this synthesize
152
- // an empty `$Greeter` -- this may fail, or succeed depending on
153
- // surrounding code using a default distributed actor system,
154
- // or extensions providing it.
155
- return [
156
- """
157
- \( proto. modifiers) distributed actor $ \( proto. name. trimmed) : \( proto. name. trimmed) ,
158
- Distributed._DistributedActorStub
159
- {
160
- }
161
- """
162
- ]
163
- }
134
+ if isGenericStub, let specificActorSystemRequirement {
135
+ return [
136
+ """
137
+ \( proto. modifiers) distributed actor $ \( proto. name. trimmed) <ActorSystem>: \( proto. name. trimmed) ,
138
+ Distributed._DistributedActorStub
139
+ where ActorSystem: \( specificActorSystemRequirement)
140
+ { }
141
+ """
142
+ ]
143
+ } else if let specificActorSystemRequirement {
144
+ return [
145
+ """
146
+ \( proto. modifiers) distributed actor $ \( proto. name. trimmed) : \( proto. name. trimmed) ,
147
+ Distributed._DistributedActorStub
148
+ {
149
+ \( typealiasActorSystem ( access : accessModifiers , proto, specificActorSystemRequirement) )
150
+ }
151
+ """
152
+ ]
153
+ } else {
154
+ // there may be no `where` clause specifying an actor system,
155
+ // but perhaps there is a typealias (or extension with a typealias),
156
+ // specifying a concrete actor system so we let this synthesize
157
+ // an empty `$Greeter` -- this may fail, or succeed depending on
158
+ // surrounding code using a default distributed actor system,
159
+ // or extensions providing it.
160
+ return [
161
+ """
162
+ \( proto. modifiers) distributed actor $ \( proto. name. trimmed) : \( proto. name. trimmed) ,
163
+ Distributed._DistributedActorStub
164
+ {
165
+ }
166
+ """
167
+ ]
168
+ }
164
169
}
165
170
166
- private static func typealiasActorSystem( _ proto: ProtocolDeclSyntax , _ type: TypeSyntax ) -> DeclSyntax {
167
- " typealias ActorSystem = \( type) "
171
+ private static func typealiasActorSystem( access : String , _ proto: ProtocolDeclSyntax , _ type: TypeSyntax ) -> DeclSyntax {
172
+ " \( raw : access ) typealias ActorSystem = \( type) "
168
173
}
169
174
}
170
175
171
176
// ===== -----------------------------------------------------------------------
172
177
// MARK: Convenience Extensions
173
178
179
+ extension ProtocolDeclSyntax {
180
+ var accessModifiersString : String {
181
+ let modifiers = modifiers. filter { modifier in
182
+ modifier. isAccessControl
183
+ }
184
+
185
+ guard !modifiers. isEmpty else {
186
+ return " "
187
+ }
188
+
189
+ let string = modifiers
190
+ . map { " \( $0. trimmed) " }
191
+ . joined ( separator: " " )
192
+ return " \( string) "
193
+ }
194
+ }
195
+
174
196
extension TypeSyntax {
175
197
fileprivate var isActorSystem : Bool {
176
198
self . trimmedDescription == " ActorSystem "
@@ -195,23 +217,38 @@ extension DeclSyntaxProtocol {
195
217
}
196
218
}
197
219
220
+ extension DeclModifierSyntax {
221
+ var isAccessControl : Bool {
222
+ switch self . name. tokenKind {
223
+ case . keyword( . private) : fallthrough
224
+ case . keyword( . fileprivate) : fallthrough
225
+ case . keyword( . internal) : fallthrough
226
+ case . keyword( . package ) : fallthrough
227
+ case . keyword( . public) :
228
+ return true
229
+ default :
230
+ return false
231
+ }
232
+ }
233
+ }
234
+
198
235
// ===== -----------------------------------------------------------------------
199
236
// MARK: DistributedProtocol macro errors
200
237
201
238
extension DistributedProtocolMacro {
202
239
static func throwIllegalTargetDecl( node: AttributeSyntax , _ declaration: some DeclSyntaxProtocol ) throws -> Never {
203
- let kind =
204
- if declaration. isClass {
205
- " class "
206
- } else if declaration. isActor {
207
- " actor "
208
- } else if declaration. isStruct {
209
- " struct "
210
- } else if declaration. isStruct {
211
- " enum "
212
- } else {
213
- " \( declaration. kind) "
214
- }
240
+ let kind : String
241
+ if declaration. isClass {
242
+ kind = " class "
243
+ } else if declaration. isActor {
244
+ kind = " actor "
245
+ } else if declaration. isStruct {
246
+ kind = " struct "
247
+ } else if declaration. isStruct {
248
+ kind = " enum "
249
+ } else {
250
+ kind = " \( declaration. kind) "
251
+ }
215
252
216
253
throw DiagnosticsError (
217
254
syntax: node,
0 commit comments