Skip to content

Commit 2e1b6fc

Browse files
Access properties with explicit self in encode(to encoder:) (#699)
### Motivation In #696 we avoided clashing with a property called `container` in certain schemas by making use of explicit self in `init(from decoder:)`. We didn't have access to the OpenAPI document and hadn't caught the case where this was used in a schema that supported additional properties, where we also need to avoid the clash in `encode(to encoder:)`. ### Modifications - Access properties with explicit self in `encode(to encoder:)`. ### Result - Fixes #695 ### Test Plan More snippet tests and reference tests.
1 parent 8a3dd4d commit 2e1b6fc

File tree

4 files changed

+76
-6
lines changed

4 files changed

+76
-6
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ extension FileTranslator {
156156
.try(
157157
.identifierPattern("container").dot("encode\(property.typeUsage.isOptional ? "IfPresent" : "")")
158158
.call([
159-
.init(label: nil, expression: .identifierPattern(property.swiftSafeName)),
159+
.init(label: nil, expression: .identifierPattern("self").dot(property.swiftSafeName)),
160160
.init(label: "forKey", expression: .dot(property.swiftSafeName)),
161161
])
162162
)

Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,14 @@ components:
406406
type: [array, null]
407407
items:
408408
type: [string, null]
409+
# To catch the clashes of members and the decoding container.
410+
TypedAdditionalPropertiesWithPropertyNamedContainer:
411+
type: object
412+
properties:
413+
container:
414+
type: string
415+
additionalProperties:
416+
type: integer
409417
CodeError:
410418
type: object
411419
properties:

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

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ public enum Components {
637637
public func encode(to encoder: any Encoder) throws {
638638
var container = encoder.container(keyedBy: CodingKeys.self)
639639
try container.encodeIfPresent(
640-
foo,
640+
self.foo,
641641
forKey: .foo
642642
)
643643
try encoder.encodeAdditionalProperties(additionalProperties)
@@ -677,7 +677,7 @@ public enum Components {
677677
public func encode(to encoder: any Encoder) throws {
678678
var container = encoder.container(keyedBy: CodingKeys.self)
679679
try container.encodeIfPresent(
680-
foo,
680+
self.foo,
681681
forKey: .foo
682682
)
683683
try encoder.encodeAdditionalProperties(additionalProperties)
@@ -698,6 +698,46 @@ public enum Components {
698698
case foo
699699
}
700700
}
701+
/// - Remark: Generated from `#/components/schemas/TypedAdditionalPropertiesWithPropertyNamedContainer`.
702+
public struct TypedAdditionalPropertiesWithPropertyNamedContainer: Codable, Hashable, Sendable {
703+
/// - Remark: Generated from `#/components/schemas/TypedAdditionalPropertiesWithPropertyNamedContainer/container`.
704+
public var container: Swift.String?
705+
/// A container of undocumented properties.
706+
public var additionalProperties: [String: Swift.Int]
707+
/// Creates a new `TypedAdditionalPropertiesWithPropertyNamedContainer`.
708+
///
709+
/// - Parameters:
710+
/// - container:
711+
/// - additionalProperties: A container of undocumented properties.
712+
public init(
713+
container: Swift.String? = nil,
714+
additionalProperties: [String: Swift.Int] = .init()
715+
) {
716+
self.container = container
717+
self.additionalProperties = additionalProperties
718+
}
719+
public enum CodingKeys: String, CodingKey {
720+
case container
721+
}
722+
public init(from decoder: any Decoder) throws {
723+
let container = try decoder.container(keyedBy: CodingKeys.self)
724+
self.container = try container.decodeIfPresent(
725+
Swift.String.self,
726+
forKey: .container
727+
)
728+
additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: [
729+
"container"
730+
])
731+
}
732+
public func encode(to encoder: any Encoder) throws {
733+
var container = encoder.container(keyedBy: CodingKeys.self)
734+
try container.encodeIfPresent(
735+
self.container,
736+
forKey: .container
737+
)
738+
try encoder.encodeAdditionalProperties(additionalProperties)
739+
}
740+
}
701741
/// - Remark: Generated from `#/components/schemas/CodeError`.
702742
public struct CodeError: Codable, Hashable, Sendable {
703743
/// - Remark: Generated from `#/components/schemas/CodeError/code`.

Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,20 +547,42 @@ final class SnippetBasedReferenceTests: XCTestCase {
547547
schemas:
548548
MyObject:
549549
type: object
550-
properties: {}
550+
properties:
551+
id:
552+
type: string
551553
additionalProperties: true
552554
""",
553555
"""
554556
public enum Schemas {
555557
public struct MyObject: Codable, Hashable, Sendable {
558+
public var id: Swift.String?
556559
public var additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer
557-
public init(additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()) {
560+
public init(
561+
id: Swift.String? = nil,
562+
additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()
563+
) {
564+
self.id = id
558565
self.additionalProperties = additionalProperties
559566
}
567+
public enum CodingKeys: String, CodingKey {
568+
case id
569+
}
560570
public init(from decoder: any Decoder) throws {
561-
additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: [])
571+
let container = try decoder.container(keyedBy: CodingKeys.self)
572+
self.id = try container.decodeIfPresent(
573+
Swift.String.self,
574+
forKey: .id
575+
)
576+
additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: [
577+
"id"
578+
])
562579
}
563580
public func encode(to encoder: any Encoder) throws {
581+
var container = encoder.container(keyedBy: CodingKeys.self)
582+
try container.encodeIfPresent(
583+
self.id,
584+
forKey: .id
585+
)
564586
try encoder.encodeAdditionalProperties(additionalProperties)
565587
}
566588
}

0 commit comments

Comments
 (0)