Skip to content

Commit d29fd40

Browse files
arthurcroczechboy0
andauthored
Fix warning in generated server code (#209)
### Motivation Fixes #190. ### Modifications We fix the issue buy only generating this initializer if there's at least one operation. Otherwise keep the method empty. ### Result The warning is fixed since the `server` variable declaration is not added to the `registerHandlers` body when it's not used. ### Test Plan We add a test in `SnippetBasedReferenceTests.swift` called `testServerRegisterHandlers_noOperations` asserting the `server` variable delcaration is not added to the `registerHandlers` body. --------- Co-authored-by: Honza Dvorsky <[email protected]>
1 parent 7615536 commit d29fd40

File tree

2 files changed

+142
-50
lines changed

2 files changed

+142
-50
lines changed

Sources/_OpenAPIGeneratorCore/Translator/ServerTranslator/ServerTranslator.swift

Lines changed: 70 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -39,31 +39,86 @@ struct ServerFileTranslator: FileTranslator {
3939
+ config.additionalImports
4040
.map { ImportDescription(moduleName: $0) }
4141

42-
let serverMethodDeclPairs =
42+
let allOperations =
4343
try OperationDescription
4444
.all(
4545
from: doc.paths,
4646
in: components,
4747
asSwiftSafeName: swiftSafeName
4848
)
49+
50+
let (registerHandlersDecl, serverMethodDecls) = try translateRegisterHandlers(allOperations)
51+
52+
let protocolExtensionDecl: Declaration = .extension(
53+
accessModifier: nil,
54+
onType: Constants.APIProtocol.typeName,
55+
declarations: [
56+
registerHandlersDecl
57+
]
58+
)
59+
60+
let serverExtensionDecl: Declaration = .extension(
61+
accessModifier: .fileprivate,
62+
onType: Constants.Server.Universal.typeName,
63+
whereClause: .init(requirements: [
64+
.conformance(
65+
Constants.Server.Universal.apiHandlerName,
66+
Constants.APIProtocol.typeName
67+
)
68+
]),
69+
declarations: serverMethodDecls
70+
)
71+
72+
return StructuredSwiftRepresentation(
73+
file: .init(
74+
name: GeneratorMode.server.outputFileName,
75+
contents: .init(
76+
topComment: topComment,
77+
imports: imports,
78+
codeBlocks: [
79+
.declaration(protocolExtensionDecl),
80+
.declaration(serverExtensionDecl),
81+
]
82+
)
83+
)
84+
)
85+
}
86+
87+
/// Returns a declaration of the registerHandlers method and
88+
/// the declarations of the individual operation methods.
89+
/// - Parameter operations: The operations found in the OpenAPI document.
90+
func translateRegisterHandlers(
91+
_ operations: [OperationDescription]
92+
) throws -> (Declaration, [Declaration]) {
93+
var registerHandlersDeclBody: [CodeBlock] = []
94+
let serverMethodDeclPairs =
95+
try operations
4996
.map { operation in
5097
try translateServerMethod(operation, serverUrlVariableName: "server")
5198
}
5299
let serverMethodDecls = serverMethodDeclPairs.map(\.functionDecl)
53100

54-
let serverMethodRegisterCalls = serverMethodDeclPairs.map(\.registerCall)
101+
// To avoid an unused variable warning, we add the server variable declaration
102+
// and server method register calls to the body of the register handler declaration
103+
// only when there is at least one registration call.
104+
if !serverMethodDeclPairs.isEmpty {
105+
let serverMethodRegisterCalls = serverMethodDeclPairs.map(\.registerCall)
106+
let registerHandlerServerVarDecl: Declaration = .variable(
107+
kind: .let,
108+
left: "server",
109+
right: .identifier(Constants.Server.Universal.typeName)
110+
.call([
111+
.init(label: "serverURL", expression: .identifier("serverURL")),
112+
.init(label: "handler", expression: .identifier("self")),
113+
.init(label: "configuration", expression: .identifier("configuration")),
114+
.init(label: "middlewares", expression: .identifier("middlewares")),
115+
])
116+
)
117+
118+
registerHandlersDeclBody.append(.declaration(registerHandlerServerVarDecl))
119+
registerHandlersDeclBody.append(contentsOf: serverMethodRegisterCalls.map { .expression($0) })
120+
}
55121

56-
let registerHandlerServerVarDecl: Declaration = .variable(
57-
kind: .let,
58-
left: "server",
59-
right: .identifier(Constants.Server.Universal.typeName)
60-
.call([
61-
.init(label: "serverURL", expression: .identifier("serverURL")),
62-
.init(label: "handler", expression: .identifier("self")),
63-
.init(label: "configuration", expression: .identifier("configuration")),
64-
.init(label: "middlewares", expression: .identifier("middlewares")),
65-
])
66-
)
67122
let registerHandlersDecl: Declaration = .commentable(
68123
.doc(
69124
#"""
@@ -104,44 +159,9 @@ struct ServerFileTranslator: FileTranslator {
104159
keywords: [
105160
.throws
106161
],
107-
body: [
108-
.declaration(registerHandlerServerVarDecl)
109-
] + serverMethodRegisterCalls.map { .expression($0) }
110-
)
111-
)
112-
113-
let protocolExtensionDecl: Declaration = .extension(
114-
accessModifier: nil,
115-
onType: Constants.APIProtocol.typeName,
116-
declarations: [
117-
registerHandlersDecl
118-
]
119-
)
120-
121-
let serverExtensionDecl: Declaration = .extension(
122-
accessModifier: .fileprivate,
123-
onType: Constants.Server.Universal.typeName,
124-
whereClause: .init(requirements: [
125-
.conformance(
126-
Constants.Server.Universal.apiHandlerName,
127-
Constants.APIProtocol.typeName
128-
)
129-
]),
130-
declarations: serverMethodDecls
131-
)
132-
133-
return StructuredSwiftRepresentation(
134-
file: .init(
135-
name: GeneratorMode.server.outputFileName,
136-
contents: .init(
137-
topComment: topComment,
138-
imports: imports,
139-
codeBlocks: [
140-
.declaration(protocolExtensionDecl),
141-
.declaration(serverExtensionDecl),
142-
]
143-
)
162+
body: registerHandlersDeclBody
144163
)
145164
)
165+
return (registerHandlersDecl, serverMethodDecls)
146166
}
147167
}

Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,61 @@ final class SnippetBasedReferenceTests: XCTestCase {
11851185
)
11861186
}
11871187

1188+
func testServerRegisterHandlers_oneOperation() throws {
1189+
try self.assertServerRegisterHandlers(
1190+
"""
1191+
/health:
1192+
get:
1193+
operationId: getHealth
1194+
responses:
1195+
'200':
1196+
description: A success response with a greeting.
1197+
content:
1198+
text/plain:
1199+
schema:
1200+
type: string
1201+
""",
1202+
"""
1203+
public func registerHandlers(
1204+
on transport: any ServerTransport,
1205+
serverURL: URL = .defaultOpenAPIServerURL,
1206+
configuration: Configuration = .init(),
1207+
middlewares: [any ServerMiddleware] = []
1208+
) throws {
1209+
let server = UniversalServer(
1210+
serverURL: serverURL,
1211+
handler: self,
1212+
configuration: configuration,
1213+
middlewares: middlewares
1214+
)
1215+
try transport.register(
1216+
{ try await server.getHealth(request: $0, metadata: $1) },
1217+
method: .get,
1218+
path: server.apiPathComponentsWithServerPrefix(["health"]),
1219+
queryItemNames: []
1220+
)
1221+
}
1222+
"""
1223+
)
1224+
}
1225+
1226+
func testServerRegisterHandlers_noOperation() throws {
1227+
try self.assertServerRegisterHandlers(
1228+
"""
1229+
{}
1230+
""",
1231+
"""
1232+
public func registerHandlers(
1233+
on transport: any ServerTransport,
1234+
serverURL: URL = .defaultOpenAPIServerURL,
1235+
configuration: Configuration = .init(),
1236+
middlewares: [any ServerMiddleware] = []
1237+
) throws {
1238+
}
1239+
"""
1240+
)
1241+
}
1242+
11881243
func testPathWithPathItemReference() throws {
11891244
XCTAssertThrowsError(
11901245
try self.assertPathsTranslation(
@@ -1595,6 +1650,23 @@ extension SnippetBasedReferenceTests {
15951650
let translation = try translator.translateAPIProtocol(paths)
15961651
try XCTAssertSwiftEquivalent(translation, expectedSwift, file: file, line: line)
15971652
}
1653+
1654+
func assertServerRegisterHandlers(
1655+
_ pathsYAML: String,
1656+
_ expectedSwift: String,
1657+
file: StaticString = #filePath,
1658+
line: UInt = #line
1659+
) throws {
1660+
let (_, _, translator) = try makeTranslators()
1661+
let paths = try YAMLDecoder().decode(OpenAPI.PathItem.Map.self, from: pathsYAML)
1662+
let operations = try OperationDescription.all(
1663+
from: paths,
1664+
in: .noComponents,
1665+
asSwiftSafeName: translator.swiftSafeName
1666+
)
1667+
let (registerHandlersDecl, _) = try translator.translateRegisterHandlers(operations)
1668+
try XCTAssertSwiftEquivalent(registerHandlersDecl, expectedSwift, file: file, line: line)
1669+
}
15981670
}
15991671

16001672
private func XCTAssertEqualWithDiff(

0 commit comments

Comments
 (0)