Skip to content

Commit 8a3dd4d

Browse files
Assign to properties with explicit self in init(from decoder:) (#696)
### Motivation Our generated `init(from decoder:)` assigns to properties without using explicit self. This is a problem because it can produce conflicts with the local variables created in the initializer, e.g. the decoding container, which will then fail to compile for schemas with properties named `container`, as found by an adopter in #695. We should probably take a broader pass with regard to the use of explicit self in our generated code, but for now we can resolve this by focussing on this problematic generation, where a schema with named and additional properties. ### Modifications - Assign to properties with explicit self in `init(from decoder:)` ### Result - Fixes #695. ### Test Plan - Add a snippet test. - Update the reference tests.
1 parent 61ec6b6 commit 8a3dd4d

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ extension FileTranslator {
118118
let assignExprs: [Expression] = properties.map { property in
119119
let typeUsage = property.typeUsage
120120
return .assignment(
121-
left: .identifierPattern(property.swiftSafeName),
121+
left: .identifierPattern("self").dot(property.swiftSafeName),
122122
right: .try(
123123
.identifierPattern("container").dot("decode\(typeUsage.isOptional ? "IfPresent" : "")")
124124
.call([

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ public enum Components {
594594
}
595595
public init(from decoder: any Decoder) throws {
596596
let container = try decoder.container(keyedBy: CodingKeys.self)
597-
foo = try container.decodeIfPresent(
597+
self.foo = try container.decodeIfPresent(
598598
Swift.String.self,
599599
forKey: .foo
600600
)
@@ -626,7 +626,7 @@ public enum Components {
626626
}
627627
public init(from decoder: any Decoder) throws {
628628
let container = try decoder.container(keyedBy: CodingKeys.self)
629-
foo = try container.decodeIfPresent(
629+
self.foo = try container.decodeIfPresent(
630630
Swift.String.self,
631631
forKey: .foo
632632
)
@@ -666,7 +666,7 @@ public enum Components {
666666
}
667667
public init(from decoder: any Decoder) throws {
668668
let container = try decoder.container(keyedBy: CodingKeys.self)
669-
foo = try container.decodeIfPresent(
669+
self.foo = try container.decodeIfPresent(
670670
Swift.String.self,
671671
forKey: .foo
672672
)

Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,15 +510,30 @@ final class SnippetBasedReferenceTests: XCTestCase {
510510
schemas:
511511
MyObject:
512512
type: object
513-
properties: {}
513+
properties:
514+
id:
515+
type: string
514516
additionalProperties: false
515517
""",
516518
"""
517519
public enum Schemas {
518520
public struct MyObject: Codable, Hashable, Sendable {
519-
public init() {}
521+
public var id: Swift.String?
522+
public init(id: Swift.String? = nil) {
523+
self.id = id
524+
}
525+
public enum CodingKeys: String, CodingKey {
526+
case id
527+
}
520528
public init(from decoder: any Decoder) throws {
521-
try decoder.ensureNoAdditionalProperties(knownKeys: [])
529+
let container = try decoder.container(keyedBy: CodingKeys.self)
530+
self.id = try container.decodeIfPresent(
531+
Swift.String.self,
532+
forKey: .id
533+
)
534+
try decoder.ensureNoAdditionalProperties(knownKeys: [
535+
"id"
536+
])
522537
}
523538
}
524539
}

0 commit comments

Comments
 (0)