Skip to content

Commit

Permalink
[Refactor] Introduce TranslatorContext
Browse files Browse the repository at this point in the history
  • Loading branch information
czechboy0 committed Oct 1, 2024
1 parent 0eb9afa commit 6218f4b
Show file tree
Hide file tree
Showing 28 changed files with 103 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ struct ClientFileTranslator: FileTranslator {
let imports =
Constants.File.clientServerImports + config.additionalImports.map { ImportDescription(moduleName: $0) }

let clientMethodDecls =
try OperationDescription.all(from: doc.paths, in: components, asSwiftSafeName: swiftSafeName)
let clientMethodDecls = try OperationDescription.all(from: doc.paths, in: components, context: context)
.map(translateClientMethod(_:))

let clientStructPropertyDecl: Declaration = .commentable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,7 @@
//===----------------------------------------------------------------------===//
import Foundation

extension FileTranslator {

/// Returns a copy of the string modified to be a valid Swift identifier.
///
/// - Parameter string: The string to convert to be safe for Swift.
/// - Returns: A Swift-safe version of the input string.
func swiftSafeName(for string: String) -> String { string.safeForSwiftCode }
}

fileprivate extension String {
extension String {

/// Returns a string sanitized to be usable as a Swift identifier.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension TypesFileTranslator {
originalName: key,
typeUsage: propertyType,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
var referenceStack = ReferenceStack.empty
let isKeyValuePairSchema = try TypeMatcher.isKeyValuePair(
Expand Down Expand Up @@ -209,7 +209,7 @@ extension TypesFileTranslator {
let decoder: Declaration
if let discriminator {
let originalName = discriminator.propertyName
let swiftName = swiftSafeName(for: originalName)
let swiftName = context.asSwiftSafeName(originalName)
codingKeysDecls = [
.enum(
accessModifier: config.access,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ extension TypesFileTranslator {
originalName: key,
typeUsage: propertyType,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
}

Expand Down Expand Up @@ -175,7 +175,7 @@ extension TypesFileTranslator {
default: .emptyInit,
isSerializedInTopLevelDictionary: false,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
return (.allowingAdditionalProperties, extraProperty)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ extension FileTranslator {
// In nullable enum schemas, empty strings are parsed as Void.
// This is unlikely to be fixed, so handling that case here.
// https://github.com/apple/swift-openapi-generator/issues/118
if isNullable && anyValue is Void { return (swiftSafeName(for: ""), .string("")) }
if isNullable && anyValue is Void { return (context.asSwiftSafeName(""), .string("")) }
guard let rawValue = anyValue as? String else {
throw GenericError(message: "Disallowed value for a string enum '\(typeName)': \(anyValue)")
}
let caseName = swiftSafeName(for: rawValue)
let caseName = context.asSwiftSafeName(rawValue)
return (caseName, .string(rawValue))
case .integer:
let rawValue: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ extension FileTranslator {
/// component.
/// - Parameter type: The `OneOfMappedType` for which to determine the case name.
/// - Returns: A string representing the safe Swift name for the specified `OneOfMappedType`.
func safeSwiftNameForOneOfMappedType(_ type: OneOfMappedType) -> String { swiftSafeName(for: type.rawNames[0]) }
func safeSwiftNameForOneOfMappedType(_ type: OneOfMappedType) -> String {
context.asSwiftSafeName(type.rawNames[0])
}
}

extension OpenAPI.Discriminator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,14 @@ struct PropertyBlueprint {
/// referring to them in the property.
var associatedDeclarations: [Declaration] = []

/// A converted function from user-provided strings to strings
/// safe to be used as a Swift identifier.
var asSwiftSafeName: (String) -> String
/// A set of configuration values that inform translation.
var context: TranslatorContext
}

extension PropertyBlueprint {

/// A name that is verified to be a valid Swift identifier.
var swiftSafeName: String { asSwiftSafeName(originalName) }
var swiftSafeName: String { context.asSwiftSafeName(originalName) }

/// The JSON path to the property.
///
Expand Down
16 changes: 16 additions & 0 deletions Sources/_OpenAPIGeneratorCore/Translator/FileTranslator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,19 @@ protocol FileTranslator {
/// - Throws: An error if translation encounters issues or errors during the process.
func translateFile(parsedOpenAPI: ParsedOpenAPIRepresentation) throws -> StructuredSwiftRepresentation
}

extension FileTranslator {

/// A new context from the file translator.
var context: TranslatorContext { TranslatorContext(asSwiftSafeName: { $0.safeForSwiftCode }) }
}

/// A set of configuration values for concrete file translators.
struct TranslatorContext {

/// A closure that returns a copy of the string modified to be a valid Swift identifier.
///
/// - Parameter string: The string to convert to be safe for Swift.
/// - Returns: A Swift-safe version of the input string.
var asSwiftSafeName: (String) -> String
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ extension FileTranslator {
}
var parts: [MultipartSchemaTypedContent] = try topLevelObject.properties.compactMap {
(key, value) -> MultipartSchemaTypedContent? in
let swiftSafeName = swiftSafeName(for: key)
let swiftSafeName = context.asSwiftSafeName(key)
let typeName = typeName.appending(
swiftComponent: swiftSafeName + Constants.Global.inlineTypeSuffix,
jsonComponent: key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ extension TypesFileTranslator {
typeUsage: headersTypeName.asUsage,
default: headersStructBlueprint.hasEmptyInit ? .emptyInit : nil,
associatedDeclarations: [headersStructDecl],
asSwiftSafeName: swiftSafeName
context: context
)
} else {
headersProperty = nil
Expand All @@ -90,7 +90,7 @@ extension TypesFileTranslator {
originalName: Constants.Operation.Body.variableName,
typeUsage: bodyTypeUsage,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
let structDecl = translateStructBlueprint(
.init(
Expand Down Expand Up @@ -137,7 +137,7 @@ extension TypesFileTranslator {
switch part {
case .documentedTyped(let documentedPart):
let caseDecl: Declaration = .enumCase(
name: swiftSafeName(for: documentedPart.originalName),
name: context.asSwiftSafeName(documentedPart.originalName),
kind: .nameWithAssociatedValues([.init(type: .init(part.wrapperTypeUsage))])
)
let decl = try translateMultipartPartContent(
Expand Down Expand Up @@ -404,7 +404,7 @@ extension FileTranslator {
switch part {
case .documentedTyped(let part):
let originalName = part.originalName
let identifier = swiftSafeName(for: originalName)
let identifier = context.asSwiftSafeName(originalName)
let contentType = part.partInfo.contentType
let partTypeName = part.typeName
let schema = part.schema
Expand Down Expand Up @@ -613,7 +613,7 @@ extension FileTranslator {
switch part {
case .documentedTyped(let part):
let originalName = part.originalName
let identifier = swiftSafeName(for: originalName)
let identifier = context.asSwiftSafeName(originalName)
let contentType = part.partInfo.contentType
let headersTypeName = part.typeName.appending(
swiftComponent: Constants.Operation.Output.Payload.Headers.typeName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ struct OperationDescription {
/// The OpenAPI components, used to resolve JSON references.
var components: OpenAPI.Components

/// A converted function from user-provided strings to strings
/// safe to be used as a Swift identifier.
var asSwiftSafeName: (String) -> String
/// A set of configuration values that inform translation.
var context: TranslatorContext

/// The OpenAPI operation object.
var operation: OpenAPI.Operation { endpoint.operation }
Expand All @@ -52,7 +51,7 @@ extension OperationDescription {
/// - Parameters:
/// - map: The paths from the OpenAPI document.
/// - components: The components from the OpenAPI document.
/// - asSwiftSafeName: A converted function from user-provided strings
/// - context: A set of configuration values that inform translation.
/// to strings safe to be used as a Swift identifier.
/// - Returns: An array of `OperationDescription` instances, each representing
/// an operation discovered in the provided paths.
Expand All @@ -62,11 +61,9 @@ extension OperationDescription {
/// 1. OpenAPI 3.0.3 only supports external path references (cf. 3.1, which supports internal references too)
/// 2. Swift OpenAPI Generator currently only supports OpenAPI 3.0.x.
/// 3. Swift OpenAPI Generator currently doesn't support external references.
static func all(
from map: OpenAPI.PathItem.Map,
in components: OpenAPI.Components,
asSwiftSafeName: @escaping (String) -> String
) throws -> [OperationDescription] {
static func all(from map: OpenAPI.PathItem.Map, in components: OpenAPI.Components, context: TranslatorContext)
throws -> [OperationDescription]
{
try map.flatMap { path, value in
let value = try value.resolve(in: components)
return value.endpoints.map { endpoint in
Expand All @@ -75,7 +72,7 @@ extension OperationDescription {
endpoint: endpoint,
pathParameters: value.parameters,
components: components,
asSwiftSafeName: asSwiftSafeName
context: context
)
}
}
Expand All @@ -86,7 +83,7 @@ extension OperationDescription {
/// Uses the `operationID` value in the OpenAPI operation, if one was
/// specified. Otherwise, computes a unique name from the operation's
/// path and HTTP method.
var methodName: String { asSwiftSafeName(operationID) }
var methodName: String { context.asSwiftSafeName(operationID) }

/// Returns the identifier for the operation.
///
Expand Down Expand Up @@ -295,7 +292,7 @@ extension OperationDescription {
}
let newPath = OpenAPI.Path(newComponents, trailingSlash: path.trailingSlash)
let names: [Expression] = orderedPathParameters.map { param in
.identifierPattern("input").dot("path").dot(asSwiftSafeName(param))
.identifierPattern("input").dot("path").dot(context.asSwiftSafeName(param))
}
let arrayExpr: Expression = .literal(.array(names))
return (newPath.rawValue, arrayExpr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,27 @@ import OpenAPIKit

/// A container for an OpenAPI parameter and its computed Swift type usage.
struct TypedParameter {

/// The OpenAPI parameter.
var parameter: OpenAPI.Parameter

/// The underlying schema.
var schema: UnresolvedSchema

/// The parameter serialization style.
var style: OpenAPI.Parameter.SchemaContext.Style

/// The parameter explode value.
var explode: Bool

/// The computed type usage.
var typeUsage: TypeUsage

/// The coding strategy appropriate for this parameter.
var codingStrategy: CodingStrategy

/// A converted function from user-provided strings to strings
/// safe to be used as a Swift identifier.
var asSwiftSafeName: (String) -> String
/// A set of configuration values that inform translation.
var context: TranslatorContext
}

extension TypedParameter: CustomStringConvertible {
Expand All @@ -49,7 +48,7 @@ extension TypedParameter {
var name: String { parameter.name }

/// The name of the parameter sanitized to be a valid Swift identifier.
var variableName: String { asSwiftSafeName(name) }
var variableName: String { context.asSwiftSafeName(name) }

/// A Boolean value that indicates whether the parameter must be specified
/// when performing the OpenAPI operation.
Expand Down Expand Up @@ -208,7 +207,7 @@ extension FileTranslator {
explode: explode,
typeUsage: usage,
codingStrategy: codingStrategy,
asSwiftSafeName: swiftSafeName
context: context
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extension TypesFileTranslator {
originalName: parameter.name,
typeUsage: parameter.typeUsage,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ extension TypesFileTranslator {
typeUsage: bodyEnumTypeUsage,
default: nil,
associatedDeclarations: extraDecls,
asSwiftSafeName: swiftSafeName
context: context
)
return bodyProperty
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,30 @@ import OpenAPIKit
/// A container for an OpenAPI response header and its computed
/// Swift type usage.
struct TypedResponseHeader {

/// The OpenAPI response header.
var header: OpenAPI.Header

/// The name of the header.
var name: String

/// The underlying schema.
var schema: UnresolvedSchema

/// The Swift type representing the response header.
var typeUsage: TypeUsage

/// The coding strategy appropriate for this parameter.
var codingStrategy: CodingStrategy

/// A converted function from user-provided strings to strings
/// safe to be used as a Swift identifier.
var asSwiftSafeName: (String) -> String
/// A set of configuration values that inform translation.
var context: TranslatorContext
}

extension TypedResponseHeader {

/// The name of the header sanitized to be a valid Swift identifier.
var variableName: String { asSwiftSafeName(name) }
var variableName: String { context.asSwiftSafeName(name) }

/// A Boolean value that indicates whether the response header can
/// be omitted in the HTTP response.
Expand Down Expand Up @@ -152,7 +151,7 @@ extension FileTranslator {
schema: schema,
typeUsage: usage,
codingStrategy: codingStrategy,
asSwiftSafeName: swiftSafeName
context: context
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extension TypesFileTranslator {
typeUsage: headersTypeName.asUsage,
default: headersStructBlueprint.hasEmptyInit ? .emptyInit : nil,
associatedDeclarations: [headersStructDecl],
asSwiftSafeName: swiftSafeName
context: context
)
} else {
headersProperty = nil
Expand Down Expand Up @@ -92,7 +92,7 @@ extension TypesFileTranslator {
typeUsage: contentTypeUsage,
default: hasNoContent ? .nil : nil,
associatedDeclarations: [contentEnumDecl],
asSwiftSafeName: swiftSafeName
context: context
)
} else {
bodyProperty = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension TypesFileTranslator {
typeUsage: typeUsage,
default: header.header.required ? nil : .nil,
associatedDeclarations: associatedDeclarations,
asSwiftSafeName: swiftSafeName
context: context
)
}

Expand Down
Loading

0 comments on commit 6218f4b

Please sign in to comment.