Skip to content

Commit 5250447

Browse files
committed
[JSON] Emit DecodingError.valueNotFound error if the value is null
1 parent 585dae0 commit 5250447

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

Sources/SwiftCompilerPluginMessageHandling/JSON/JSONDecoding.swift

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private struct JSONMapBuilder {
109109

110110
init() {
111111
mapData = []
112-
mapData.reserveCapacity(128) // 128 is good enough for most PluginMessage.
112+
mapData.reserveCapacity(128) // 128 is good enough for most PluginMessage.
113113
}
114114

115115
@inline(__always)
@@ -550,7 +550,7 @@ extension JSONMapValue {
550550
}
551551

552552
@inline(__always)
553-
func asString() -> String? {
553+
func asString() -> String? {
554554
if self.is(.simpleString) {
555555
return _JSONStringParser.decodeSimpleString(source: valueBuffer())
556556
}
@@ -681,21 +681,41 @@ private struct JSONDecoding {
681681
// MARK: Pure decoding functions.
682682
extension JSONDecoding {
683683
@inline(__always)
684-
static func _unwrapOrThrow<T>(
685-
_ v: T?,
686-
codingPathNode: _CodingPathNode,
684+
static func _checkNotNull<T>(
685+
_ value: JSONMapValue,
686+
expectedType: T.Type,
687+
for codingPathNode: _CodingPathNode,
687688
_ additionalKey: (some CodingKey)?
688-
) throws -> T {
689-
guard let v = v else {
690-
throw DecodingError.typeMismatch(
691-
T.self,
692-
.init(
689+
) throws {
690+
guard !value.isNull else {
691+
throw DecodingError.valueNotFound(
692+
expectedType,
693+
DecodingError.Context(
693694
codingPath: codingPathNode.path(byAppending: additionalKey),
694-
debugDescription: "type mismatch"
695+
debugDescription: "Cannot get value of type \(expectedType) -- found null value instead"
695696
)
696697
)
697698
}
698-
return v
699+
}
700+
701+
@inline(__always)
702+
static func _unwrapOrThrow<T>(
703+
_ result: T?,
704+
decoding value: JSONMapValue,
705+
codingPathNode: _CodingPathNode,
706+
_ additionalKey: (some CodingKey)?
707+
) throws -> T {
708+
if let result = result {
709+
return result
710+
}
711+
try _checkNotNull(value, expectedType: T.self, for: codingPathNode, additionalKey)
712+
throw DecodingError.typeMismatch(
713+
T.self,
714+
.init(
715+
codingPath: codingPathNode.path(byAppending: additionalKey),
716+
debugDescription: "type mismatch"
717+
)
718+
)
699719
}
700720
@inline(__always)
701721
static func _decode(
@@ -704,7 +724,7 @@ extension JSONDecoding {
704724
codingPathNode: _CodingPathNode,
705725
_ additionalKey: (some CodingKey)?
706726
) throws -> Bool {
707-
try _unwrapOrThrow(value.asBool(), codingPathNode: codingPathNode, additionalKey)
727+
try _unwrapOrThrow(value.asBool(), decoding: value, codingPathNode: codingPathNode, additionalKey)
708728
}
709729
@inline(__always)
710730
static func _decode(
@@ -713,7 +733,7 @@ extension JSONDecoding {
713733
codingPathNode: _CodingPathNode,
714734
_ additionalKey: (some CodingKey)?
715735
) throws -> String {
716-
try _unwrapOrThrow(value.asString(), codingPathNode: codingPathNode, additionalKey)
736+
try _unwrapOrThrow(value.asString(), decoding: value, codingPathNode: codingPathNode, additionalKey)
717737
}
718738
@inline(__always)
719739
static func _decode<Integer: FixedWidthInteger>(
@@ -722,7 +742,7 @@ extension JSONDecoding {
722742
codingPathNode: _CodingPathNode,
723743
_ additionalKey: (some CodingKey)?
724744
) throws -> Integer {
725-
try _unwrapOrThrow(value.asInteger(type), codingPathNode: codingPathNode, additionalKey)
745+
try _unwrapOrThrow(value.asInteger(type), decoding: value, codingPathNode: codingPathNode, additionalKey)
726746
}
727747
@inline(__always)
728748
static func _decode<Floating: BinaryFloatingPoint>(
@@ -731,7 +751,7 @@ extension JSONDecoding {
731751
codingPathNode: _CodingPathNode,
732752
_ additionalKey: (some CodingKey)?
733753
) throws -> Floating {
734-
try _unwrapOrThrow(value.asFloatingPoint(type), codingPathNode: codingPathNode, additionalKey)
754+
try _unwrapOrThrow(value.asFloatingPoint(type), decoding: value, codingPathNode: codingPathNode, additionalKey)
735755
}
736756

737757
static func _decodeGeneric<T: Decodable>(
@@ -740,6 +760,7 @@ extension JSONDecoding {
740760
codingPathNode: _CodingPathNode,
741761
_ additionalKey: (some CodingKey)?
742762
) throws -> T {
763+
try _checkNotNull(value, expectedType: type, for: codingPathNode, additionalKey)
743764
let decoder = Self(value: value, codingPathNode: codingPathNode.appending(additionalKey))
744765
return try T.init(from: decoder)
745766
}

0 commit comments

Comments
 (0)