test: 新增 JsonSerializer 单元测试(cjpm test,13 用例);fix: 顶层 Deserialize<?T>(null) 返回类型化 None
- 覆盖:基础类型、对象字段输出(下划线保留/注解/忽略/None→null/继承限制)、 Array/ArrayList/HashSet/HashMap 往返、枚举、命名策略、Option 字段、 宽松类型转换、maxDepth - 修复 JsonReader:Option 反序列化 null 时用反射构造目标类型 None 构造器 (反射层 Option 构造器统一按 1 参数槽登记),而非返回裸 None 导致 read<T> 类型不匹配异常
This commit is contained in:
@@ -55,6 +55,15 @@ public class JsonReader {
|
||||
// Option<X>:null → None;否则读取内层并用枚举构造器包 Some
|
||||
if (typeName.startsWith("Option<")) {
|
||||
if (value is JsonNull) {
|
||||
// 必须用目标类型 Option<X> 的 None 构造器创建,保证运行时类型匹配。
|
||||
// 反射层将 Option 构造器统一登记为 1 参数槽(None 的参数类型是内层 X),
|
||||
// 传一个 X 的占位值即可(None 构造器忽略实参语义)。
|
||||
if (let et: EnumTypeInfo <- typeInfo) {
|
||||
let ctor = et.getConstructor("None", argsCount: 1)
|
||||
let innerName = JsonWriter.extractTypeArgs(typeName)[0]
|
||||
let placeholder = defaultValueFor(innerName)
|
||||
return ctor.apply([placeholder])
|
||||
}
|
||||
return None
|
||||
}
|
||||
let innerName = JsonWriter.extractTypeArgs(typeName)[0]
|
||||
@@ -240,4 +249,35 @@ public class JsonReader {
|
||||
}
|
||||
throw Exception("JsonSerializer: 无法转换为 Char")
|
||||
}
|
||||
|
||||
/// 生成某类型的占位默认值(用于构造 Option<X> 的 None:None 的参数槽类型是 X)。
|
||||
private static func defaultValueFor(typeName: String): Any {
|
||||
match (typeName) {
|
||||
case "String" => return ""
|
||||
case "Bool" => return false
|
||||
case "Int64" => return Int64(0)
|
||||
case "Int32" => return Int32(0)
|
||||
case "Int16" => return Int16(0)
|
||||
case "Int8" => return Int8(0)
|
||||
case "UInt64" => return UInt64(0)
|
||||
case "UInt32" => return UInt32(0)
|
||||
case "UInt16" => return UInt16(0)
|
||||
case "UInt8" => return UInt8(0)
|
||||
case "Float64" => return Float64(0.0)
|
||||
case "Float32" => return Float32(0.0)
|
||||
case "Rune" => return Rune(0)
|
||||
case _ => ()
|
||||
}
|
||||
// 集合/对象/枚举:反射无参构造;失败则抛异常
|
||||
if (let ct: ClassTypeInfo <- TypeInfo.get(typeName)) {
|
||||
return ct.construct([])
|
||||
}
|
||||
if (let et: EnumTypeInfo <- TypeInfo.get(typeName)) {
|
||||
// constructors 是 Collection:取第一个构造器名
|
||||
let first = et.constructors.iterator().next().getOrThrow()
|
||||
let ctor = et.getConstructor(first.name, argsCount: 0)
|
||||
return ctor.apply([])
|
||||
}
|
||||
throw Exception("JsonSerializer: 无法为 Option 占位值构造类型 ${typeName}")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user