@@ -16,14 +16,16 @@ struct IgnoreCodingTests {
1616 var one: String
1717 @IgnoreDecoding
1818 var two: String
19+ @IgnoreDecoding
20+ let three: String?
1921 @IgnoreCoding
20- var three : String { " some " }
22+ var four : String { " some " }
2123 @IgnoreDecoding
22- var four : String { get { " some " } }
24+ var five : String { get { " some " } }
2325 @IgnoreCoding
24- var five : String = " some " {
26+ var six : String = " some " {
2527 didSet {
26- print(five )
28+ print(six )
2729 }
2830 }
2931 }
@@ -33,11 +35,12 @@ struct IgnoreCodingTests {
3335 struct SomeCodable {
3436 var one: String
3537 var two: String
36- var three: String { " some " }
37- var four: String { get { " some " } }
38- var five: String = " some " {
38+ let three: String?
39+ var four: String { " some " }
40+ var five: String { get { " some " } }
41+ var six: String = " some " {
3942 didSet {
40- print(five )
43+ print(six )
4144 }
4245 }
4346 }
@@ -51,20 +54,22 @@ struct IgnoreCodingTests {
5154 func encode(to encoder: any Encoder) throws {
5255 var container = encoder.container(keyedBy: CodingKeys.self)
5356 try container.encode(self.two, forKey: CodingKeys.two)
57+ try container.encodeIfPresent(self.three, forKey: CodingKeys.three)
5458 }
5559 }
5660
5761 extension SomeCodable {
5862 enum CodingKeys: String, CodingKey {
5963 case two = " two "
64+ case three = " three "
6065 }
6166 }
6267 """ ,
6368 diagnostics: [
6469 . init(
6570 id: IgnoreCoding . misuseID,
6671 message:
67- " @IgnoreCoding can't be used with uninitialized variable one " ,
72+ " @IgnoreCoding can't be used with uninitialized non-optional variable one " ,
6873 line: 3 , column: 5 ,
6974 fixIts: [
7075 . init( message: " Remove @IgnoreCoding attribute " )
@@ -73,12 +78,21 @@ struct IgnoreCodingTests {
7378 . init(
7479 id: IgnoreDecoding . misuseID,
7580 message:
76- " @IgnoreDecoding can't be used with uninitialized variable two " ,
81+ " @IgnoreDecoding can't be used with uninitialized non-optional variable two " ,
7782 line: 5 , column: 5 ,
7883 fixIts: [
7984 . init( message: " Remove @IgnoreDecoding attribute " )
8085 ]
8186 ) ,
87+ . init(
88+ id: IgnoreDecoding . misuseID,
89+ message:
90+ " @IgnoreDecoding can't be used with uninitialized non-optional variable three " ,
91+ line: 7 , column: 5 ,
92+ fixIts: [
93+ . init( message: " Remove @IgnoreDecoding attribute " )
94+ ]
95+ ) ,
8296 ]
8397 )
8498 }
@@ -168,6 +182,86 @@ struct IgnoreCodingTests {
168182 """
169183 )
170184 }
185+
186+ struct Optional {
187+ @Codable
188+ struct SomeCodable {
189+ @IgnoreCoding
190+ var one : String ?
191+ @IgnoreCoding
192+ var two : String !
193+ // @IgnoreCoding
194+ // var three: Swift.Optional<String>
195+ let four : String
196+ }
197+
198+ @Test
199+ func expansion( ) throws {
200+ assertMacroExpansion (
201+ """
202+ @Codable
203+ struct SomeCodable {
204+ @IgnoreCoding
205+ var one: String?
206+ @IgnoreCoding
207+ var two: String!
208+ @IgnoreCoding
209+ var three: Optional<String>
210+ let four: String
211+ }
212+ """ ,
213+ expandedSource:
214+ """
215+ struct SomeCodable {
216+ var one: String?
217+ var two: String!
218+ var three: Optional<String>
219+ let four: String
220+ }
221+
222+ extension SomeCodable: Decodable {
223+ init(from decoder: any Decoder) throws {
224+ let container = try decoder.container(keyedBy: CodingKeys.self)
225+ self.four = try container.decode(String.self, forKey: CodingKeys.four)
226+ }
227+ }
228+
229+ extension SomeCodable: Encodable {
230+ func encode(to encoder: any Encoder) throws {
231+ var container = encoder.container(keyedBy: CodingKeys.self)
232+ try container.encode(self.four, forKey: CodingKeys.four)
233+ }
234+ }
235+
236+ extension SomeCodable {
237+ enum CodingKeys: String, CodingKey {
238+ case four = " four "
239+ }
240+ }
241+ """
242+ )
243+ }
244+
245+ @Test
246+ func decoding( ) throws {
247+ let json = try #require( " { \" four \" : \" som \" } " . data ( using: . utf8) )
248+ let obj = try JSONDecoder ( ) . decode ( SomeCodable . self, from: json)
249+ #expect( obj. one == nil )
250+ #expect( obj. two == nil )
251+ // #expect(obj.three == nil)
252+ #expect( obj. four == " som " )
253+ }
254+
255+ @Test
256+ func encoding( ) throws {
257+ let obj = SomeCodable ( one: " one " , two: " two " , four: " some " )
258+ let json = try JSONEncoder ( ) . encode ( obj)
259+ let jObj = try JSONSerialization . jsonObject ( with: json)
260+ let dict = try #require( jObj as? [ String : Any ] )
261+ #expect( dict. count == 1 )
262+ #expect( dict [ " four " ] as? String == " some " )
263+ }
264+ }
171265 }
172266
173267 struct EnumDecodingEncodingIgnore {
@@ -736,7 +830,7 @@ struct IgnoreCodingTests {
736830 var one : String = " some "
737831 @IgnoreDecoding
738832 @CodedAt ( " deeply " , " nested " , " key " )
739- var two : String = " some "
833+ var two : String !
740834 @IgnoreEncoding
741835 @CodedIn ( " deeply " , " nested " )
742836 var three : String = " some "
@@ -756,7 +850,7 @@ struct IgnoreCodingTests {
756850 var one: String = " some "
757851 @IgnoreDecoding
758852 @CodedAt( " deeply " , " nested " , " key " )
759- var two: String = " some "
853+ var two: String!
760854 @IgnoreEncoding
761855 @CodedIn( " deeply " , " nested " )
762856 var three: String = " some "
@@ -769,7 +863,7 @@ struct IgnoreCodingTests {
769863 """
770864 struct SomeCodable {
771865 var one: String = " some "
772- var two: String = " some "
866+ var two: String!
773867 var three: String = " some "
774868 var four: String = " some "
775869 }
@@ -790,7 +884,7 @@ struct IgnoreCodingTests {
790884 var deeply_container = container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.deeply)
791885 var nested_deeply_container = deeply_container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.nested)
792886 try nested_deeply_container.encode(self.one, forKey: CodingKeys.one)
793- try nested_deeply_container.encode (self.two, forKey: CodingKeys.two)
887+ try nested_deeply_container.encodeIfPresent (self.two, forKey: CodingKeys.two)
794888 }
795889 }
796890
@@ -816,7 +910,7 @@ struct IgnoreCodingTests {
816910 var one : String = " some "
817911 @IgnoreDecoding
818912 @CodedAt ( " deeply " , " nested " , " key " )
819- var two : String = " some "
913+ var two : String !
820914 @IgnoreEncoding
821915 @CodedIn ( " deeply " , " nested " )
822916 var three : String = " some "
@@ -836,7 +930,7 @@ struct IgnoreCodingTests {
836930 var one: String = " some "
837931 @IgnoreDecoding
838932 @CodedAt( " deeply " , " nested " , " key " )
839- var two: String = " some "
933+ var two: String!
840934 @IgnoreEncoding
841935 @CodedIn( " deeply " , " nested " )
842936 var three: String = " some "
@@ -849,7 +943,7 @@ struct IgnoreCodingTests {
849943 """
850944 class SomeCodable {
851945 var one: String = " some "
852- var two: String = " some "
946+ var two: String!
853947 var three: String = " some "
854948 var four: String = " some "
855949
@@ -866,7 +960,7 @@ struct IgnoreCodingTests {
866960 var deeply_container = container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.deeply)
867961 var nested_deeply_container = deeply_container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.nested)
868962 try nested_deeply_container.encode(self.one, forKey: CodingKeys.one)
869- try nested_deeply_container.encode (self.two, forKey: CodingKeys.two)
963+ try nested_deeply_container.encodeIfPresent (self.two, forKey: CodingKeys.two)
870964 }
871965
872966 enum CodingKeys: String, CodingKey {
0 commit comments