Skip to content

Commit 6057654

Browse files
authored
Safe server variable names when used in Swift identifiers (#351)
Safe server variable names when used in Swift identifiers ### Motivation In the original introduction of server variable support, we didn't properly safe the variable names coming from the OpenAPI document for use as Swift identifiers. ### Modifications Fix that by running the name server variable name, provided in the OpenAPI document, through the function that safes the string for use as a Swift identifier. ### Result Documents that use variable names like `protocol` compile again. ### Test Plan Adapted the tests. Reviewed by: simonjbeaumont Builds: ✔︎ pull request validation (5.10) - Build finished. ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (compatibility test) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #351
1 parent 2ea4267 commit 6057654

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateServers.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ extension TypesFileTranslator {
2525
/// declare the method under.
2626
func translateServer(index: Int, server: OpenAPI.Server) -> Declaration {
2727
let methodName = "\(Constants.ServerURL.propertyPrefix)\(index+1)"
28-
let parameters: [ParameterDescription] = server.variables.map { (key, value) in
29-
.init(label: key, type: .init(TypeName.string), defaultValue: .literal(value.default))
28+
let safeVariables = server.variables.map { (key, value) in
29+
(originalKey: key, swiftSafeKey: swiftSafeName(for: key), value: value)
3030
}
31-
let variableInitializers: [Expression] = server.variables.map { (key, value) in
31+
let parameters: [ParameterDescription] = safeVariables.map { (originalKey, swiftSafeKey, value) in
32+
.init(label: swiftSafeKey, type: .init(TypeName.string), defaultValue: .literal(value.default))
33+
}
34+
let variableInitializers: [Expression] = safeVariables.map { (originalKey, swiftSafeKey, value) in
3235
let allowedValuesArg: FunctionArgumentDescription?
3336
if let allowedValues = value.enum {
3437
allowedValuesArg = .init(
@@ -41,13 +44,13 @@ extension TypesFileTranslator {
4144
return .dot("init")
4245
.call(
4346
[
44-
.init(label: "name", expression: .literal(key)),
45-
.init(label: "value", expression: .identifierPattern(key)),
47+
.init(label: "name", expression: .literal(originalKey)),
48+
.init(label: "value", expression: .identifierPattern(swiftSafeKey)),
4649
] + (allowedValuesArg.flatMap { [$0] } ?? [])
4750
)
4851
}
4952
let methodDecl = Declaration.commentable(
50-
.functionComment(abstract: server.description, parameters: server.variables.map { ($0, $1.description) }),
53+
.functionComment(abstract: server.description, parameters: safeVariables.map { ($1, $2.description) }),
5154
.function(
5255
accessModifier: config.access,
5356
kind: .function(name: methodName, isStatic: true),

Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ servers:
1010
- url: https://example.com/api
1111
description: Example Petstore implementation service
1212
- url: /api
13-
- url: https://{subdomain}.example.com:{port}/{basePath}
13+
- url: '{protocol}://{subdomain}.example.com:{port}/{basePath}'
1414
description: A custom domain.
1515
variables:
16+
protocol:
17+
default: https
1618
subdomain:
1719
default: test
1820
description: A subdomain name.

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,23 @@ public enum Servers {
153153
/// A custom domain.
154154
///
155155
/// - Parameters:
156+
/// - _protocol:
156157
/// - subdomain: A subdomain name.
157158
/// - port:
158159
/// - basePath: The base API path.
159160
public static func server3(
161+
_protocol: Swift.String = "https",
160162
subdomain: Swift.String = "test",
161163
port: Swift.String = "443",
162164
basePath: Swift.String = "v1"
163165
) throws -> Foundation.URL {
164166
try Foundation.URL(
165-
validatingOpenAPIServerURL: "https://{subdomain}.example.com:{port}/{basePath}",
167+
validatingOpenAPIServerURL: "{protocol}://{subdomain}.example.com:{port}/{basePath}",
166168
variables: [
169+
.init(
170+
name: "protocol",
171+
value: _protocol
172+
),
167173
.init(
168174
name: "subdomain",
169175
value: subdomain

0 commit comments

Comments
 (0)