RrunningW```
9c507578创建于 1月13日历史提交
/*
Copyright (c) 2025 WuJingrun(吴京润)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
package f_base

import std.collection.concurrent.ConcurrentHashMap

public class TypeMemberInfos {
    private init() {}
    private static let staticPropertyMap = ConcurrentHashMap<TypeInfo, HashMap<String, StaticPropertyInfo>>()
    private static func getStaticPropertyMap(typeInfo: TypeInfo): HashMap<String, StaticPropertyInfo> {
        match (staticPropertyMap.get(typeInfo)) {
            case Some(map) => map
            case _ =>
                let map = HashMap<String, StaticPropertyInfo>()
                staticPropertyMap[typeInfo] = map
                func addProp(ti: TypeInfo){
                    for (p in typeInfo.staticProperties) {
                        map[p.name] = p
                    }
                }
                if(let cti: ClassTypeInfo <- typeInfo){
                    var ti = Some(cti)
                    while(let Some(c) <- ti && c != ClassTypeInfo.of<Object>()){
                        addProp(c)
                        ti = c.superClass
                    }
                }else{
                    addProp(typeInfo)
                }
                map
        }
    }
    public static func staticProperties<T>(): Collection<StaticPropertyInfo> {
        staticProperties(TypeInfo.of<T>())
    }
    public static func staticProperties(typeInfo: TypeInfo): Collection<StaticPropertyInfo> {
        getStaticPropertyMap(typeInfo).values()
    }
    public static func staticProperty<T>(name: String): ?StaticPropertyInfo {
        staticProperty(TypeInfo.of<T>(), name)
    }
    public static func staticProperty(typeInfo: TypeInfo, name: String): ?StaticPropertyInfo {
        getStaticPropertyMap(typeInfo).get(name)
    }

    private static let instancePropertyMap = ConcurrentHashMap<TypeInfo, HashMap<String, InstancePropertyInfo>>()
    private static func getInstancePropertyMap(typeInfo: TypeInfo): HashMap<String, InstancePropertyInfo> {
        match (instancePropertyMap.get(typeInfo)) {
            case Some(map) => map
            case _ =>
                let map = HashMap<String, InstancePropertyInfo>()
                func addProps(ti: TypeInfo){
                    for (p in ti.instanceProperties) {
                        map[p.name] = p
                    }
                }
                if(let cti: ClassTypeInfo <- typeInfo){
                    var ti = Some(cti)
                    while(let Some(c) <- ti && c != ClassTypeInfo.of<Object>()){
                        addProps(c)
                        ti = c.superClass
                    }
                }else{
                    addProps(typeInfo)
                }
                instancePropertyMap[typeInfo] = map
                map
        }
    }
    public static func instanceProperties<T>(): Collection<InstancePropertyInfo> {
        instanceProperties(TypeInfo.of<T>())
    }
    public static func instanceProperties(typeInfo: TypeInfo): Collection<InstancePropertyInfo> {
        getInstancePropertyMap(typeInfo).values()
    }
    public static func instanceProperty<T>(name: String): ?InstancePropertyInfo {
        instanceProperty(TypeInfo.of<T>(), name)
    }
    public static func instanceProperty(typeInfo: TypeInfo, name: String): ?InstancePropertyInfo {
        getInstancePropertyMap(typeInfo).get(name)
    }

    private static let staticFunctionMap = ConcurrentHashMap<TypeInfo, HashMap<FuncMeta, StaticFunctionInfo>>()
    private static func getStaticFunctionMap(typeInfo: TypeInfo): HashMap<FuncMeta, StaticFunctionInfo> {
        match (staticFunctionMap.get(typeInfo)) {
            case Some(map) => map
            case _ =>
                let map = HashMap<FuncMeta, StaticFunctionInfo>()
                staticFunctionMap[typeInfo] = map
                func addFunc(ti: TypeInfo){
                    for (f in typeInfo.staticFunctions) {
                        let params = f.parameters
                        map.addIfAbsent(FuncMeta(f.name, Array<TypeInfo>(params.size) {
                                i => params[i].typeInfo
                            }), f)
                    }
                }
                if(let cti: ClassTypeInfo <- typeInfo){
                    var ti = Some(cti)
                    while(let Some(c) <- ti && c != ClassTypeInfo.of<Object>()){
                        addFunc(c)
                        ti = c.superClass
                    }
                }else{
                    addFunc(typeInfo)
                }
                map
        }
    }
    public static func staticFunctions<T>(): Collection<StaticFunctionInfo> {
        staticFunctions(TypeInfo.of<T>())
    }
    public static func staticFunctions(typeInfo: TypeInfo): Collection<StaticFunctionInfo> {
        getStaticFunctionMap(typeInfo).values()
    }
    public static func staticFunction<T>(name: String, paramTypes: Array<TypeInfo>): ?StaticFunctionInfo {
        staticFunction(TypeInfo.of<T>(), name, paramTypes)
    }
    public static func staticFunction(typeInfo: TypeInfo, name: String, paramTypes: Array<TypeInfo>): ?StaticFunctionInfo {
        getStaticFunctionMap(typeInfo).get(FuncMeta(name, paramTypes))
    }

    private static let instanceFunctionMap = ConcurrentHashMap<TypeInfo, HashMap<FuncMeta, InstanceFunctionInfo>>()
    private static func getInstanceFunctionMap(typeInfo: TypeInfo): HashMap<FuncMeta, InstanceFunctionInfo> {
        match (instanceFunctionMap.get(typeInfo)) {
            case Some(map) => map
            case _ =>
                let map = HashMap<FuncMeta, InstanceFunctionInfo>()
                func addFunc(ti: TypeInfo){
                    for (f in ti.instanceFunctions) {
                        let params = f.parameters
                        map.addIfAbsent(FuncMeta(f.name, Array<TypeInfo>(params.size) {
                                i => params[i].typeInfo
                            }), f)
                    }
                }
                if(let cti: ClassTypeInfo <- typeInfo){
                    var ti = Some(cti)
                    while(let Some(c) <- ti && c != ClassTypeInfo.of<Object>()){
                        addFunc(c)
                        ti = c.superClass
                    }
                }else{
                    addFunc(typeInfo)
                }
                instanceFunctionMap[typeInfo] = map
                map
        }
    }
    public static func instanceFunctions<T>(): Collection<InstanceFunctionInfo> {
        instanceFunctions(TypeInfo.of<T>())
    }
    public static func instanceFunctions(typeInfo: TypeInfo): Collection<InstanceFunctionInfo> {
        getInstanceFunctionMap(typeInfo).values()
    }
    public static func instanceFunction<T>(name: String, paramTypes: Array<TypeInfo>): ?InstanceFunctionInfo {
        instanceFunction(TypeInfo.of<T>(), name, paramTypes)
    }
    public static func instanceFunction(typeInfo: TypeInfo, name: String, params: Array<TypeInfo>): ?InstanceFunctionInfo {
        getInstanceFunctionMap(typeInfo).get(FuncMeta(name, params))
    }

    private static let staticVariableMap = ConcurrentHashMap<TypeInfo, HashMap<String, StaticVariableInfo>>()
    private static func getStaticVariableMap(typeInfo: TypeInfo): Map<String, StaticVariableInfo> {
        match (staticVariableMap.get(typeInfo)) {
            case Some(map) => map
            case _ => match (typeInfo) {
                case x: StructTypeInfo =>
                    let map = HashMap<String, StaticVariableInfo>()
                    for (v in x.staticVariables) {
                        map[v.name] = v
                    }
                    staticVariableMap[typeInfo] = map
                    map
                case x: ClassTypeInfo =>
                    let map = HashMap<String, StaticVariableInfo>()
                    var cti = Some(x)
                    while(let Some(c) <- cti && c != ClassTypeInfo.of<Object>()){
                        for (v in c.staticVariables) {
                            map[v.name] = v
                        }
                        cti = c.superClass
                    }
                    staticVariableMap[typeInfo] = map
                    map
                case _ => EmptyMap<String, StaticVariableInfo>.INSTANCE()
            }
        }
    }
    public static func staticVariables<T>(): Collection<StaticVariableInfo> {
        staticVariables(TypeInfo.of<T>())
    }
    public static func staticVariables(typeInfo: TypeInfo): Collection<StaticVariableInfo> {
        getStaticVariableMap(typeInfo).values()
    }
    public static func staticVariable<T>(name: String): ?StaticVariableInfo {
        staticVariable(TypeInfo.of<T>(), name)
    }
    public static func staticVariable(typeInfo: TypeInfo, name: String): ?StaticVariableInfo {
        getStaticVariableMap(typeInfo).get(name)
    }

    private static let instanceVariableMap = ConcurrentHashMap<TypeInfo, HashMap<String, InstanceVariableInfo>>()
    private static func getInstanceVariableMap(typeInfo: TypeInfo): Map<String, InstanceVariableInfo> {
        match (instanceVariableMap.get(typeInfo)) {
            case Some(map) => map
            case _ => match (typeInfo) {
                case x: StructTypeInfo =>
                    let map = HashMap<String, InstanceVariableInfo>()
                    for (v in x.instanceVariables) {
                        map[v.name] = v
                    }
                    instanceVariableMap[typeInfo] = map
                    map
                case x: ClassTypeInfo =>
                    let map = HashMap<String, InstanceVariableInfo>()
                    var cti = Some(x)
                    while(let Some(c) <- cti && c != ClassTypeInfo.of<Object>()){
                        for (v in x.instanceVariables) {
                            map[v.name] = v
                        }
                        cti = c.superClass
                    }
                    instanceVariableMap[typeInfo] = map
                    map
                case _ => EmptyMap<String, InstanceVariableInfo>.INSTANCE()
            }
        }
    }
    public static func instanceVariables<T>(): Collection<InstanceVariableInfo> {
        instanceVariables(TypeInfo.of<T>())
    }
    public static func instanceVariables(typeInfo: TypeInfo): Collection<InstanceVariableInfo> {
        getInstanceVariableMap(typeInfo).values()
    }
    public static func instanceVariable<T>(name: String): ?InstanceVariableInfo {
        instanceVariable(TypeInfo.of<T>(), name)
    }
    public static func instanceVariable(typeInfo: TypeInfo, name: String): ?InstanceVariableInfo {
        getInstanceVariableMap(typeInfo).get(name)
    }
}

class FuncMeta <: Hashable & Equatable<FuncMeta> {
    private let hash: Int64
    FuncMeta(private let name: String, private let param: Array<TypeInfo>) {
        hash = HashBuilder().append(name).append(param).build()
    }
    public operator func ==(other: FuncMeta) {
        refEq(this, other) || (hash == other.hash && name == other.name && param == other.param)
    }
    public func hashCode(): Int64 {
        hash
    }
}