Skip to content

Commit 531924b

Browse files
authored
Ensures namespace enums are marked as Sendable (#33)
Motivation: Code that relies on grpc-swift-2 code generation capability cannot build with `-require-explicit-sendable` compiler flag. Modifications: Modified places where `EnumDescription` is built for namespace to include conformance with `Sendable`. Result: Generated code now works with `-require-explicit-sendable` compiler flag enabled.
1 parent e7e9515 commit 531924b

File tree

4 files changed

+35
-26
lines changed

4 files changed

+35
-26
lines changed

Sources/GRPCCodeGen/Internal/StructuredSwift+ServiceMetadata.swift

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ extension VariableDescription {
188188
@available(gRPCSwift 2.0, *)
189189
extension EnumDescription {
190190
/// ```
191-
/// enum <Method> {
191+
/// enum <Method>: Sendable {
192192
/// typealias Input = <InputType>
193193
/// typealias Output = <OutputType>
194194
/// static let descriptor = GRPCCore.MethodDescriptor(
@@ -209,6 +209,7 @@ extension EnumDescription {
209209
return EnumDescription(
210210
accessModifier: accessModifier,
211211
name: name,
212+
conformances: ["Sendable"],
212213
members: [
213214
.commentable(
214215
.doc("Request type for \"\(literalMethod)\"."),
@@ -235,7 +236,7 @@ extension EnumDescription {
235236

236237
/// ```
237238
/// enum Method {
238-
/// enum <Method> {
239+
/// enum <Method>: Sendable {
239240
/// typealias Input = <MethodInput>
240241
/// typealias Output = <MethodOutput>
241242
/// static let descriptor = GRPCCore.MethodDescriptor(
@@ -256,7 +257,11 @@ extension EnumDescription {
256257
methods: [MethodDescriptor],
257258
namer: Namer = Namer()
258259
) -> EnumDescription {
259-
var description = EnumDescription(accessModifier: accessModifier, name: "Method")
260+
var description = EnumDescription(
261+
accessModifier: accessModifier,
262+
name: "Method",
263+
conformances: ["Sendable"]
264+
)
260265

261266
// Add a namespace for each method.
262267
let methodNamespaces: [Declaration] = methods.map { method in
@@ -294,9 +299,9 @@ extension EnumDescription {
294299
}
295300

296301
/// ```
297-
/// enum <Name> {
302+
/// enum <Name>: Sendable {
298303
/// static let descriptor = GRPCCore.ServiceDescriptor.<namespacedServicePropertyName>
299-
/// enum Method {
304+
/// enum Method: Sendable {
300305
/// ...
301306
/// }
302307
/// }
@@ -308,7 +313,11 @@ extension EnumDescription {
308313
methods: [MethodDescriptor],
309314
namer: Namer = Namer()
310315
) -> EnumDescription {
311-
var description = EnumDescription(accessModifier: accessModifier, name: name)
316+
var description = EnumDescription(
317+
accessModifier: accessModifier,
318+
name: name,
319+
conformances: ["Sendable"]
320+
)
312321

313322
// static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "...")
314323
let descriptor = VariableDescription.serviceDescriptor(
@@ -344,7 +353,7 @@ extension EnumDescription {
344353
@available(gRPCSwift 2.0, *)
345354
extension [CodeBlock] {
346355
/// ```
347-
/// enum <Service> {
356+
/// enum <Service>: Sendable {
348357
/// ...
349358
/// }
350359
///

Tests/GRPCCodeGenTests/Internal/StructuredSwift+MetadataTests.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ extension StructuredSwiftTests {
114114
#expect(render(.variable(decl)) == expected)
115115
}
116116

117-
@Test("enum <Method> { ... }", arguments: AccessModifier.allCases)
117+
@Test("enum <Method>: Sendable { ... }", arguments: AccessModifier.allCases)
118118
@available(gRPCSwift 2.0, *)
119119
func methodNamespaceEnum(access: AccessModifier) {
120120
let decl: EnumDescription = .methodNamespace(
@@ -127,7 +127,7 @@ extension StructuredSwiftTests {
127127
)
128128

129129
let expected = """
130-
\(access) enum Foo {
130+
\(access) enum Foo: Sendable {
131131
/// Request type for "Foo".
132132
\(access) typealias Input = FooInput
133133
/// Response type for "Foo".
@@ -142,7 +142,7 @@ extension StructuredSwiftTests {
142142
#expect(render(.enum(decl)) == expected)
143143
}
144144

145-
@Test("enum Method { ... }", arguments: AccessModifier.allCases)
145+
@Test("enum Method: Sendable { ... }", arguments: AccessModifier.allCases)
146146
@available(gRPCSwift 2.0, *)
147147
func methodsNamespaceEnum(access: AccessModifier) {
148148
let decl: EnumDescription = .methodsNamespace(
@@ -161,9 +161,9 @@ extension StructuredSwiftTests {
161161
)
162162

163163
let expected = """
164-
\(access) enum Method {
164+
\(access) enum Method: Sendable {
165165
/// Namespace for "Foo" metadata.
166-
\(access) enum Foo {
166+
\(access) enum Foo: Sendable {
167167
/// Request type for "Foo".
168168
\(access) typealias Input = FooInput
169169
/// Response type for "Foo".
@@ -183,7 +183,7 @@ extension StructuredSwiftTests {
183183
#expect(render(.enum(decl)) == expected)
184184
}
185185

186-
@Test("enum Method { ... } (no methods)", arguments: AccessModifier.allCases)
186+
@Test("enum Method: Sendable { ... } (no methods)", arguments: AccessModifier.allCases)
187187
@available(gRPCSwift 2.0, *)
188188
func methodsNamespaceEnumNoMethods(access: AccessModifier) {
189189
let decl: EnumDescription = .methodsNamespace(
@@ -193,15 +193,15 @@ extension StructuredSwiftTests {
193193
)
194194

195195
let expected = """
196-
\(access) enum Method {
196+
\(access) enum Method: Sendable {
197197
/// Descriptors for all methods in the "bar.Bar" service.
198198
\(access) static let descriptors: [GRPCCore.MethodDescriptor] = []
199199
}
200200
"""
201201
#expect(render(.enum(decl)) == expected)
202202
}
203203

204-
@Test("enum <Service> { ... }", arguments: AccessModifier.allCases)
204+
@Test("enum <Service>: Sendable { ... }", arguments: AccessModifier.allCases)
205205
@available(gRPCSwift 2.0, *)
206206
func serviceNamespaceEnum(access: AccessModifier) {
207207
let decl: EnumDescription = .serviceNamespace(
@@ -221,13 +221,13 @@ extension StructuredSwiftTests {
221221
)
222222

223223
let expected = """
224-
\(access) enum Foo {
224+
\(access) enum Foo: Sendable {
225225
/// Service descriptor for the "Foo" service.
226226
\(access) static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "Foo")
227227
/// Namespace for method metadata.
228-
\(access) enum Method {
228+
\(access) enum Method: Sendable {
229229
/// Namespace for "Bar" metadata.
230-
\(access) enum Bar {
230+
\(access) enum Bar: Sendable {
231231
/// Request type for "Bar".
232232
\(access) typealias Input = BarInput
233233
/// Response type for "Bar".
@@ -248,7 +248,7 @@ extension StructuredSwiftTests {
248248
#expect(render(.enum(decl)) == expected)
249249
}
250250

251-
@Test("enum <Service> { ... } (no methods)", arguments: AccessModifier.allCases)
251+
@Test("enum <Service>: Sendable { ... } (no methods)", arguments: AccessModifier.allCases)
252252
@available(gRPCSwift 2.0, *)
253253
func serviceNamespaceEnumNoMethods(access: AccessModifier) {
254254
let decl: EnumDescription = .serviceNamespace(
@@ -259,11 +259,11 @@ extension StructuredSwiftTests {
259259
)
260260

261261
let expected = """
262-
\(access) enum Foo {
262+
\(access) enum Foo: Sendable {
263263
/// Service descriptor for the "Foo" service.
264264
\(access) static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "Foo")
265265
/// Namespace for method metadata.
266-
\(access) enum Method {
266+
\(access) enum Method: Sendable {
267267
/// Descriptors for all methods in the "Foo" service.
268268
\(access) static let descriptors: [GRPCCore.MethodDescriptor] = []
269269
}

Tests/GRPCCodeGenTests/Internal/Translator/IDLToStructuredSwiftTranslatorSnippetBasedTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ final class IDLToStructuredSwiftTranslatorSnippetBasedTests: XCTestCase {
5858
5959
/// Namespace containing generated types for the "namespaceA.ServiceA" service.
6060
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
61-
public enum NamespaceA_ServiceA {
61+
public enum NamespaceA_ServiceA: Sendable {
6262
/// Service descriptor for the "namespaceA.ServiceA" service.
6363
public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "namespaceA.ServiceA")
6464
/// Namespace for method metadata.
65-
public enum Method {
65+
public enum Method: Sendable {
6666
/// Descriptors for all methods in the "namespaceA.ServiceA" service.
6767
public static let descriptors: [GRPCCore.MethodDescriptor] = []
6868
}

Tests/GRPCCodeGenTests/Internal/Translator/TypealiasTranslatorSnippetBasedTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ struct TypealiasTranslatorSnippetBasedTests {
4444
let expectedSwift = """
4545
/// Namespace containing generated types for the "namespaceA.ServiceA" service.
4646
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
47-
public enum NamespaceA_ServiceA {
47+
public enum NamespaceA_ServiceA: Sendable {
4848
/// Service descriptor for the "namespaceA.ServiceA" service.
4949
public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "namespaceA.ServiceA")
5050
/// Namespace for method metadata.
51-
public enum Method {
51+
public enum Method: Sendable {
5252
/// Namespace for "MethodA" metadata.
53-
public enum MethodA {
53+
public enum MethodA: Sendable {
5454
/// Request type for "MethodA".
5555
public typealias Input = NamespaceA_ServiceARequest
5656
/// Response type for "MethodA".

0 commit comments

Comments
 (0)