Files
simapi-cj/src/openapi/reflect_utilities.cj
T
2026-09-01 23:36:07 +08:00

110 lines
4.3 KiB
Plaintext

/*
* Copyright (c) 杭州颉创科技有限公司 2025. All rights reserved.
* This source file is licensed under the MIT License found in the
* LICENSE file in the root directory of this source tree.
*/
package simcu::simapi.openapi
import std.reflect.*
import std.collection.*
protected class ReflectUtilities {
/**
* 收集给定类型在最终可见视角下的 public 实例属性。
*
* 对 class 类型会沿继承链向上收集,并在子类 override 父类同名属性时,
* 仅保留子类的最终实现;非 class 类型返回空数组。
*/
public static func collectInstanceProperties(typeInfo: TypeInfo): Array<InstancePropertyInfo> {
if (let classTypeInfo: ClassTypeInfo <- typeInfo) {
let result = ArrayList<InstancePropertyInfo>(classTypeInfo.instanceProperties.size)
collectInstanceProperties(classTypeInfo, result)
return result.toArray()
}
return []
}
/**
* 递归收集继承链上的 public 实例属性。
*
* 先处理父类,再处理当前类;如果当前类 override 了父类同名属性,
* 则用当前类属性覆盖父类项,只保留最终可见的那一个。
*/
private static func collectInstanceProperties(classTypeInfo: ClassTypeInfo, result: ArrayList<InstancePropertyInfo>): Unit {
if (let Some(superClass) <- classTypeInfo.superClass && superClass != TypeInfo.of<Object>()) {
if (let superClassTypeInfo: ClassTypeInfo <- superClass) {
collectInstanceProperties(superClassTypeInfo, result)
}
}
for (pattern in classTypeInfo.instanceProperties) {
if (pattern.isAbstract()) {
continue
}
addOrReplaceProperty(result, pattern)
}
}
/**
* 子类同名属性覆盖父类属性,避免 open/override 场景下重复收集。
*/
private static func addOrReplaceProperty(result: ArrayList<InstancePropertyInfo>, propertyInfo: InstancePropertyInfo): Unit {
for ((index, existingProperty) in result |> enumerate) {
if (existingProperty.name == propertyInfo.name) {
result[index] = propertyInfo
return
}
}
result.add(propertyInfo)
}
/**
* 收集给定类型在最终可见视角下的 public 实例变量(var 字段)。
*
* std.reflect 的 instanceProperties 仅收录 prop 属性,而 DTO 常以 public var 字段定义,
* 需通过 instanceVariables 补充收集。对 class 类型会沿继承链向上收集,
* 子类覆盖父类同名变量时仅保留子类实现;非 class 类型返回空数组。
*/
public static func collectInstanceVariables(typeInfo: TypeInfo): Array<InstanceVariableInfo> {
if (let classTypeInfo: ClassTypeInfo <- typeInfo) {
let result = ArrayList<InstanceVariableInfo>(classTypeInfo.instanceVariables.size)
collectInstanceVariables(classTypeInfo, result)
return result.toArray()
}
return []
}
/**
* 递归收集继承链上的 public 实例变量(var 字段)。
*
* 先处理父类,再处理当前类;如果当前类覆盖了父类同名变量,
* 则用当前类变量覆盖父类项,只保留最终可见的那一个。
*/
private static func collectInstanceVariables(classTypeInfo: ClassTypeInfo, result: ArrayList<InstanceVariableInfo>): Unit {
if (let Some(superClass) <- classTypeInfo.superClass && superClass != TypeInfo.of<Object>()) {
if (let superClassTypeInfo: ClassTypeInfo <- superClass) {
collectInstanceVariables(superClassTypeInfo, result)
}
}
for (pattern in classTypeInfo.instanceVariables) {
addOrReplaceVariable(result, pattern)
}
}
/**
* 子类同名变量覆盖父类变量,避免 open/override 场景下重复收集。
*/
private static func addOrReplaceVariable(result: ArrayList<InstanceVariableInfo>, variableInfo: InstanceVariableInfo): Unit {
for ((index, existingVariable) in result |> enumerate) {
if (existingVariable.name == variableInfo.name) {
result[index] = variableInfo
return
}
}
result.add(variableInfo)
}
}