feat: 实现 @JsonParent 宏——父类字段序列化/反序列化支持
- 新增 src/macros/JsonParentMacro.cj(macro package simapi_serialization.macros):
标注父类自动补 open,收集 public var 字段(跳过 @JsonIgnore,
@JsonPropertyName 用注解名),字符串拼接生成静态方法:
exportJsonFields(instance: T): HashMap<String, Any>
importJsonFields(instance: T, json: HashMap<String, Any>): Unit
- JsonWriter.writeParentFields:沿 superClass 链调用 exportJsonFields 合并父类字段
- JsonReader.readParentFields:沿 superClass 链调用 importJsonFields 回填父类字段
- ReflectionCache 增加 hasExportFields/hasImportFields 缓存(避免每次反射查找)
- 测试:16 用例全绿——新增 parentMacroMethods、multiLevelInheritance、
parentAutoOpen;更新 objectSerialize/objectRoundTrip 断言父类字段输出
This commit is contained in:
@@ -133,9 +133,38 @@ public class JsonReader {
|
||||
case None => ()
|
||||
}
|
||||
}
|
||||
// 父类字段(@JsonParent 宏生成的静态导入方法,沿继承链逐层回填)
|
||||
readParentFields(value, ct, instance, options)
|
||||
instance
|
||||
}
|
||||
|
||||
/// 沿 superClass 链调用每层的 importJsonFields 静态方法回填父类字段。
|
||||
/// 无宏的父类(hasImportFields 缓存判断)静默跳过;宏生成的方法内部按
|
||||
/// if (k == "字段名") 忽略未知键,因此直接把全部 JSON 键传入即可。
|
||||
private static func readParentFields(value: JsonValue, ct: ClassTypeInfo, instance: Any, options: JsonOption): Unit {
|
||||
let jobj = value.asObject()
|
||||
var parent = ct.superClass
|
||||
while (let Some(p) <- parent) {
|
||||
if (ReflectionCache.hasImportFields(p)) {
|
||||
try {
|
||||
let fn = p.getStaticFunction("importJsonFields",
|
||||
[p, TypeInfo.of<HashMap<String, Any>>()])
|
||||
var pjson = HashMap<String, Any>()
|
||||
for ((k, jv) in jobj.getFields()) {
|
||||
if (!(jv is JsonNull)) {
|
||||
pjson[k] = jsonToAny(jv)
|
||||
}
|
||||
}
|
||||
let args: Array<Any> = [instance, pjson]
|
||||
fn.apply(p, args)
|
||||
} catch (_: Exception) {
|
||||
// 导入失败(如类型不匹配)不中断整体反序列化
|
||||
}
|
||||
}
|
||||
parent = p.superClass
|
||||
}
|
||||
}
|
||||
|
||||
/// Array<X>:经 ArrayList<X> 构造 + add + toArray
|
||||
private static func readArray(value: JsonValue, elemName: String, options: JsonOption, depth: Int64): Any {
|
||||
let listTypeName = "std.collection.ArrayList<${elemName}>"
|
||||
|
||||
Reference in New Issue
Block a user