Skip to content

Commit 9f53cc5

Browse files
authored
Merge pull request #4807 from ypli-chn/bugfix/jsondecoder-generic
Fix JSONDecoder.decode(_:,from:) behavior
2 parents 8ff7ba3 + 6c3ff7e commit 9f53cc5

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

Sources/Foundation/JSONDecoder.swift

+11-11
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ open class JSONDecoder {
197197
do {
198198
var parser = JSONParser(bytes: Array(data))
199199
let json = try parser.parse()
200-
return try JSONDecoderImpl(userInfo: self.userInfo, from: json, codingPath: [], options: self.options).unwrap(as: T.self)
200+
return try JSONDecoderImpl(userInfo: self.userInfo, from: json, codingPath: [], options: self.options).unwrap(as: type)
201201
} catch let error as JSONError {
202202
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: error))
203203
} catch {
@@ -292,11 +292,11 @@ extension JSONDecoderImpl: Decoder {
292292
if type == Decimal.self {
293293
return try self.unwrapDecimal() as! T
294294
}
295-
if T.self is _JSONStringDictionaryDecodableMarker.Type {
296-
return try self.unwrapDictionary(as: T.self)
295+
if type is _JSONStringDictionaryDecodableMarker.Type {
296+
return try self.unwrapDictionary(as: type)
297297
}
298298

299-
return try T(from: self)
299+
return try type.init(from: self)
300300
}
301301

302302
private func unwrapDate() throws -> Date {
@@ -611,8 +611,8 @@ extension JSONDecoderImpl {
611611
try decodeFixedWidthInteger()
612612
}
613613

614-
func decode<T>(_: T.Type) throws -> T where T: Decodable {
615-
try self.impl.unwrap(as: T.self)
614+
func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
615+
try self.impl.unwrap(as: type)
616616
}
617617

618618
@inline(__always) private func decodeFixedWidthInteger<T: FixedWidthInteger>() throws -> T {
@@ -746,9 +746,9 @@ extension JSONDecoderImpl {
746746
try decodeFixedWidthInteger(key: key)
747747
}
748748

749-
func decode<T>(_: T.Type, forKey key: K) throws -> T where T: Decodable {
749+
func decode<T>(_ type: T.Type, forKey key: K) throws -> T where T: Decodable {
750750
let newDecoder = try decoderForKey(key)
751-
return try newDecoder.unwrap(as: T.self)
751+
return try newDecoder.unwrap(as: type)
752752
}
753753

754754
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: K) throws
@@ -926,9 +926,9 @@ extension JSONDecoderImpl {
926926
try decodeFixedWidthInteger()
927927
}
928928

929-
mutating func decode<T>(_: T.Type) throws -> T where T: Decodable {
930-
let newDecoder = try decoderForNextElement(ofType: T.self)
931-
let result = try newDecoder.unwrap(as: T.self)
929+
mutating func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
930+
let newDecoder = try decoderForNextElement(ofType: type)
931+
let result = try newDecoder.unwrap(as: type)
932932

933933
// Because of the requirement that the index not be incremented unless
934934
// decoding the desired result type succeeds, it can not be a tail call.

Tests/Foundation/Tests/TestJSONEncoder.swift

+19
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,24 @@ class TestJSONEncoder : XCTestCase {
474474
XCTFail("Caught error during decoding empty super decoder: \(error)")
475475
}
476476
}
477+
478+
func test_childTypeDecoder() {
479+
class BaseTestType: Decodable { }
480+
class ChildTestType: BaseTestType { }
481+
482+
func dynamicTestType() -> BaseTestType.Type {
483+
return ChildTestType.self
484+
}
485+
486+
let decoder = JSONDecoder()
487+
do {
488+
let testType = dynamicTestType()
489+
let instance = try decoder.decode(testType, from: Data(#"{}"#.utf8))
490+
XCTAssertTrue(instance is ChildTestType)
491+
} catch {
492+
XCTFail("Caught error during decoding empty super decoder: \(error)")
493+
}
494+
}
477495

478496
// MARK: - Test encoding and decoding of built-in Codable types
479497
func test_codingOfBool() {
@@ -1562,6 +1580,7 @@ extension TestJSONEncoder {
15621580
("test_nestedContainerCodingPaths", test_nestedContainerCodingPaths),
15631581
("test_superEncoderCodingPaths", test_superEncoderCodingPaths),
15641582
("test_notFoundSuperDecoder", test_notFoundSuperDecoder),
1583+
("test_childTypeDecoder", test_childTypeDecoder),
15651584
("test_codingOfBool", test_codingOfBool),
15661585
("test_codingOfNil", test_codingOfNil),
15671586
("test_codingOfInt8", test_codingOfInt8),

0 commit comments

Comments
 (0)