Skip to content

Commit f1d7d8b

Browse files
authored
[Refactor] Introduce TranslatorContext (2/2) (#640)
### Motivation Depends on #638, so don't review until that lands. Continuation of #638, broke up into multiple PRs for easier review. Also a non-functional change, purely a refactoring. ### Modifications Changed a bunch of TypeMatcher methods from static to being instance methods, which gives them access to the translator context. Moved a few other methods that depended on the static methods to be extensions on the closest type that already has access to the context. ### Result Now TypeAssigner/TypeMatcher can take runtime configuration, e.g. through feature flags. ### Test Plan All tests still pass.
1 parent 07ee940 commit f1d7d8b

File tree

11 files changed

+40
-48
lines changed

11 files changed

+40
-48
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateAllAnyOneOf.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ extension TypesFileTranslator {
6464
parent: typeName
6565
)
6666
let associatedDeclarations: [Declaration]
67-
if TypeMatcher.isInlinable(schema) {
67+
if typeMatcher.isInlinable(schema) {
6868
associatedDeclarations = try translateSchema(
6969
typeName: propertyType.typeName,
7070
schema: schema,
@@ -81,7 +81,7 @@ extension TypesFileTranslator {
8181
context: context
8282
)
8383
var referenceStack = ReferenceStack.empty
84-
let isKeyValuePairSchema = try TypeMatcher.isKeyValuePair(
84+
let isKeyValuePairSchema = try typeMatcher.isKeyValuePair(
8585
schema,
8686
referenceStack: &referenceStack,
8787
components: components
@@ -173,7 +173,7 @@ extension TypesFileTranslator {
173173
parent: typeName
174174
)
175175
let associatedDeclarations: [Declaration]
176-
if TypeMatcher.isInlinable(schema) {
176+
if typeMatcher.isInlinable(schema) {
177177
associatedDeclarations = try translateSchema(
178178
typeName: childType.typeName,
179179
schema: schema,
@@ -183,7 +183,7 @@ extension TypesFileTranslator {
183183
associatedDeclarations = []
184184
}
185185
var referenceStack = ReferenceStack.empty
186-
let isKeyValuePair = try TypeMatcher.isKeyValuePair(
186+
let isKeyValuePair = try typeMatcher.isKeyValuePair(
187187
schema,
188188
referenceStack: &referenceStack,
189189
components: components

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateObjectStruct.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ extension TypesFileTranslator {
8585
parent: typeName
8686
)
8787
let associatedDeclarations: [Declaration]
88-
if TypeMatcher.isInlinable(value) {
88+
if typeMatcher.isInlinable(value) {
8989
associatedDeclarations = try translateSchema(
9090
typeName: propertyType.typeName,
9191
schema: value,
@@ -153,7 +153,7 @@ extension TypesFileTranslator {
153153
components: components,
154154
inParent: parent
155155
)
156-
if TypeMatcher.isInlinable(schema) {
156+
if typeMatcher.isInlinable(schema) {
157157
associatedDeclarations = try translateSchema(
158158
typeName: valueTypeUsage.typeName,
159159
schema: schema,

Sources/_OpenAPIGeneratorCore/Translator/Multipart/MultipartContent.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ extension MultipartSchemaTypedContent {
9090
}
9191
}
9292

93-
extension SchemaContent {
93+
extension TypeMatcher {
9494
/// Returns a Boolean value whether the schema is a multipart content type and is referenceable.
95-
var isReferenceableMultipart: Bool {
96-
guard contentType.isMultipart else { return false }
97-
let ref = TypeMatcher.multipartElementTypeReferenceIfReferenceable(schema: schema, encoding: encoding)
95+
func isReferenceableMultipart(_ content: SchemaContent) -> Bool {
96+
guard content.contentType.isMultipart else { return false }
97+
let ref = multipartElementTypeReferenceIfReferenceable(schema: content.schema, encoding: content.encoding)
9898
return ref == nil
9999
}
100100
}

Sources/_OpenAPIGeneratorCore/Translator/Multipart/translateMultipart.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ extension TypesFileTranslator {
7676
inParent: typeName.appending(swiftComponent: nil, jsonComponent: "content")
7777
)
7878
let associatedDeclarations: [Declaration]
79-
if TypeMatcher.isInlinable(schema) {
79+
if typeMatcher.isInlinable(schema) {
8080
associatedDeclarations = try translateSchema(
8181
typeName: bodyTypeUsage.typeName,
8282
schema: schema,
@@ -117,7 +117,7 @@ extension TypesFileTranslator {
117117
schema: JSONSchema
118118
) throws -> [Declaration] {
119119
let associatedDeclarations: [Declaration]
120-
if TypeMatcher.isInlinable(schema) {
120+
if typeMatcher.isInlinable(schema) {
121121
associatedDeclarations = try translateSchema(typeName: typeName, schema: schema, overrides: .none)
122122
} else {
123123
associatedDeclarations = []

Sources/_OpenAPIGeneratorCore/Translator/Parameters/TypedParameter.swift

+2-10
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,14 @@ extension TypedParameter {
5757
/// The location of the parameter in the HTTP request.
5858
var location: OpenAPI.Parameter.Context.Location { parameter.location }
5959

60-
/// A schema to be inlined.
61-
///
62-
/// - Returns: Nil when schema is referenceable.
63-
var inlineableSchema: JSONSchema? { schema.inlineableSchema }
64-
}
65-
66-
extension UnresolvedSchema {
67-
6860
/// A schema to be inlined.
6961
///
7062
/// - Returns: Nil when schema is referenceable.
7163
var inlineableSchema: JSONSchema? {
72-
switch self {
64+
switch schema {
7365
case .a: return nil
7466
case let .b(schema):
75-
if TypeMatcher.isInlinable(schema) { return schema }
67+
if TypeMatcher(context: context).isInlinable(schema) { return schema }
7668
return nil
7769
}
7870
}

Sources/_OpenAPIGeneratorCore/Translator/RequestBody/translateRequestBody.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ extension TypesFileTranslator {
4646
let contentTypeName = typeName.appending(jsonComponent: "content")
4747
let contents = requestBody.contents
4848
for content in contents {
49-
if TypeMatcher.isInlinable(content.content.schema) || content.content.isReferenceableMultipart {
49+
if typeMatcher.isInlinable(content.content.schema) || typeMatcher.isReferenceableMultipart(content.content)
50+
{
5051
let inlineTypeDecls = try translateRequestBodyContentInTypes(content)
5152
bodyMembers.append(contentsOf: inlineTypeDecls)
5253
}

Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ extension TypesFileTranslator {
145145
let associatedType = typedContent.resolvedTypeUsage
146146
let content = typedContent.content
147147
let schema = content.schema
148-
if TypeMatcher.isInlinable(schema) || content.isReferenceableMultipart {
148+
if typeMatcher.isInlinable(schema) || typeMatcher.isReferenceableMultipart(content) {
149149
let decls: [Declaration]
150150
if contentType.isMultipart {
151151
decls = try translateMultipartBody(typedContent)

Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponseHeader.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extension TypesFileTranslator {
6666
let schema = header.schema
6767
let typeUsage = header.typeUsage
6868
let associatedDeclarations: [Declaration]
69-
if TypeMatcher.isInlinable(schema) {
69+
if typeMatcher.isInlinable(schema) {
7070
associatedDeclarations = try translateSchema(typeName: typeUsage.typeName, schema: schema, overrides: .none)
7171
} else {
7272
associatedDeclarations = []

Sources/_OpenAPIGeneratorCore/Translator/TypeAssignment/TypeAssigner.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ struct TypeAssigner {
122122
inParent parent: TypeName
123123
) throws -> TypeUsage {
124124
let multipartBodyElementTypeName: TypeName
125-
if let ref = TypeMatcher.multipartElementTypeReferenceIfReferenceable(schema: schema, encoding: encoding) {
125+
if let ref = TypeMatcher(context: context)
126+
.multipartElementTypeReferenceIfReferenceable(schema: schema, encoding: encoding)
127+
{
126128
multipartBodyElementTypeName = try typeName(for: ref)
127129
} else {
128130
let swiftSafeName = context.asSwiftSafeName(hint)

Sources/_OpenAPIGeneratorCore/Translator/TypeAssignment/TypeMatcher.swift

+13-15
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct TypeMatcher {
4242
func tryMatchBuiltinType(for schema: JSONSchema.Schema) -> TypeUsage? {
4343
Self._tryMatchRecursive(
4444
for: schema,
45-
test: { schema in Self._tryMatchBuiltinNonRecursive(for: schema) },
45+
test: { schema in _tryMatchBuiltinNonRecursive(for: schema) },
4646
matchedArrayHandler: { elementType, nullableItems in
4747
nullableItems ? elementType.asOptional.asArray : elementType.asArray
4848
},
@@ -68,7 +68,7 @@ struct TypeMatcher {
6868
try Self._tryMatchRecursive(
6969
for: schema.value,
7070
test: { (schema) -> TypeUsage? in
71-
if let builtinType = Self._tryMatchBuiltinNonRecursive(for: schema) { return builtinType }
71+
if let builtinType = _tryMatchBuiltinNonRecursive(for: schema) { return builtinType }
7272
guard case let .reference(ref, _) = schema else { return nil }
7373
return try TypeAssigner(context: context).typeName(for: ref).asUsage
7474
},
@@ -88,9 +88,9 @@ struct TypeMatcher {
8888
/// - A reference
8989
/// - Parameter schema: The schema to match a referenceable type for.
9090
/// - Returns: `true` if the schema is referenceable; `false` otherwise.
91-
static func isReferenceable(_ schema: JSONSchema) -> Bool {
91+
func isReferenceable(_ schema: JSONSchema) -> Bool {
9292
// This logic should be kept in sync with `tryMatchReferenceableType`.
93-
_tryMatchRecursive(
93+
Self._tryMatchRecursive(
9494
for: schema.value,
9595
test: { schema in
9696
if _tryMatchBuiltinNonRecursive(for: schema) != nil { return true }
@@ -110,7 +110,7 @@ struct TypeMatcher {
110110
/// - A reference
111111
/// - Parameter schema: The schema to match a referenceable type for.
112112
/// - Returns: `true` if the schema is referenceable; `false` otherwise.
113-
static func isReferenceable(_ schema: UnresolvedSchema?) -> Bool {
113+
func isReferenceable(_ schema: UnresolvedSchema?) -> Bool {
114114
guard let schema else {
115115
// fragment type is referenceable
116116
return true
@@ -132,7 +132,7 @@ struct TypeMatcher {
132132
/// referenceable.
133133
/// - Parameter schema: The schema to match a referenceable type for.
134134
/// - Returns: `true` if the schema is inlinable; `false` otherwise.
135-
static func isInlinable(_ schema: JSONSchema) -> Bool { !isReferenceable(schema) }
135+
func isInlinable(_ schema: JSONSchema) -> Bool { !isReferenceable(schema) }
136136

137137
/// Returns a Boolean value that indicates whether the schema
138138
/// needs to be defined inline.
@@ -143,14 +143,14 @@ struct TypeMatcher {
143143
/// referenceable.
144144
/// - Parameter schema: The schema to match a referenceable type for.
145145
/// - Returns: `true` if the schema is inlinable; `false` otherwise.
146-
static func isInlinable(_ schema: UnresolvedSchema?) -> Bool { !isReferenceable(schema) }
146+
func isInlinable(_ schema: UnresolvedSchema?) -> Bool { !isReferenceable(schema) }
147147

148148
/// Return a reference to a multipart element type if the provided schema is referenceable.
149149
/// - Parameters:
150150
/// - schema: The schema to try to reference.
151151
/// - encoding: The associated encoding.
152152
/// - Returns: A reference if the schema is referenceable, nil otherwise.
153-
static func multipartElementTypeReferenceIfReferenceable(
153+
func multipartElementTypeReferenceIfReferenceable(
154154
schema: UnresolvedSchema?,
155155
encoding: OrderedDictionary<String, OpenAPI.Content.Encoding>?
156156
) -> OpenAPI.Reference<JSONSchema>? {
@@ -174,11 +174,9 @@ struct TypeMatcher {
174174
/// - components: The reusable components from the OpenAPI document.
175175
/// - Throws: An error if there's an issue while checking the schema.
176176
/// - Returns: `true` if the schema is a key-value pair; `false` otherwise.
177-
static func isKeyValuePair(
178-
_ schema: JSONSchema,
179-
referenceStack: inout ReferenceStack,
180-
components: OpenAPI.Components
181-
) throws -> Bool {
177+
func isKeyValuePair(_ schema: JSONSchema, referenceStack: inout ReferenceStack, components: OpenAPI.Components)
178+
throws -> Bool
179+
{
182180
switch schema.value {
183181
case .object, .fragment: return true
184182
case .null, .boolean, .number, .integer, .string, .array, .not: return false
@@ -222,7 +220,7 @@ struct TypeMatcher {
222220
/// - components: The reusable components from the OpenAPI document.
223221
/// - Throws: An error if there's an issue while checking the schema.
224222
/// - Returns: `true` if the schema is a key-value pair; `false` otherwise.
225-
static func isKeyValuePair(
223+
func isKeyValuePair(
226224
_ schema: UnresolvedSchema?,
227225
referenceStack: inout ReferenceStack,
228226
components: OpenAPI.Components
@@ -285,7 +283,7 @@ struct TypeMatcher {
285283
/// - Parameter schema: The schema to match a referenceable type for.
286284
/// - Returns: A type usage for the schema if the schema is built-in.
287285
/// Otherwise, returns nil.
288-
private static func _tryMatchBuiltinNonRecursive(for schema: JSONSchema.Schema) -> TypeUsage? {
286+
private func _tryMatchBuiltinNonRecursive(for schema: JSONSchema.Schema) -> TypeUsage? {
289287
let typeName: TypeName
290288
switch schema {
291289
case .boolean(_): typeName = .swift("Bool")

Tests/OpenAPIGeneratorCoreTests/Translator/TypeAssignment/Test_TypeMatcher.swift

+6-7
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ final class Test_TypeMatcher: Test_Core {
127127
.fullyQualifiedSwiftName,
128128
name
129129
)
130-
XCTAssertTrue(TypeMatcher.isReferenceable(schema))
131-
XCTAssertFalse(TypeMatcher.isInlinable(schema))
130+
XCTAssertTrue(typeMatcher.isReferenceable(schema))
131+
XCTAssertFalse(typeMatcher.isInlinable(schema))
132132
}
133133
}
134134

@@ -145,8 +145,8 @@ final class Test_TypeMatcher: Test_Core {
145145
typeMatcher.tryMatchBuiltinType(for: schema.value),
146146
"Type is expected to not match a builtin type: \(schema)"
147147
)
148-
XCTAssertFalse(TypeMatcher.isReferenceable(schema), "Expected schema not to be referenceable: \(schema)")
149-
XCTAssertTrue(TypeMatcher.isInlinable(schema), "Expected schema to be inlinable: \(schema)")
148+
XCTAssertFalse(typeMatcher.isReferenceable(schema), "Expected schema not to be referenceable: \(schema)")
149+
XCTAssertTrue(typeMatcher.isInlinable(schema), "Expected schema to be inlinable: \(schema)")
150150
}
151151
}
152152

@@ -175,7 +175,7 @@ final class Test_TypeMatcher: Test_Core {
175175
for schema in Self.keyValuePairTypes {
176176
var referenceStack = ReferenceStack.empty
177177
XCTAssertTrue(
178-
try TypeMatcher.isKeyValuePair(schema, referenceStack: &referenceStack, components: components),
178+
try typeMatcher.isKeyValuePair(schema, referenceStack: &referenceStack, components: components),
179179
"Type is expected to be a key-value pair schema: \(schema)"
180180
)
181181
}
@@ -249,13 +249,12 @@ final class Test_TypeMatcher: Test_Core {
249249
]
250250
func testMultipartElementTypeReferenceIfReferenceableTypes() throws {
251251
for (schema, encoding, name) in Self.multipartElementTypeReferenceIfReferenceableTypes {
252-
let actualName = TypeMatcher.multipartElementTypeReferenceIfReferenceable(
252+
let actualName = typeMatcher.multipartElementTypeReferenceIfReferenceable(
253253
schema: schema,
254254
encoding: encoding
255255
)?
256256
.name
257257
XCTAssertEqual(actualName, name)
258258
}
259259
}
260-
261260
}

0 commit comments

Comments
 (0)