This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch releases-0.12 in repository https://gitbox.apache.org/repos/asf/fory.git
commit 6f3d06b517ed5b149e190d6ab489e381ce2b4bd7 Author: chaokunyang <[email protected]> AuthorDate: Sat Sep 20 00:27:31 2025 +0800 fix nested generic type --- .../org/apache/fory/resolver/ClassResolver.java | 56 +++++++++++++++++++++- .../org/apache/fory/resolver/TypeResolver.java | 1 + .../main/java/org/apache/fory/type/TypeUtils.java | 34 ++++--------- 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java index 11c43233f..d266c1543 100644 --- a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java +++ b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java @@ -2064,13 +2064,65 @@ public class ClassResolver implements TypeResolver { public void resetWrite() {} + private static final GenericType OBJECT_GENERIC_TYPE = GenericType.build(Object.class); + @CodegenInvoke public GenericType getGenericTypeInStruct(Class<?> cls, String genericTypeStr) { Map<String, GenericType> map = - extRegistry.classGenericTypes.computeIfAbsent(cls, TypeUtils::buildGenericMap); - return map.get(genericTypeStr); + extRegistry.classGenericTypes.computeIfAbsent(cls, this::buildGenericMap); + return map.getOrDefault(genericTypeStr, OBJECT_GENERIC_TYPE); } + /** + * Build a map of nested generic type name to generic type for all fields in the class. + * + * @param cls the class to build the map of nested generic type name to generic type for all + * fields in the class + * @return a map of nested generic type name to generic type for all fields in the class + */ + protected Map<String, GenericType> buildGenericMap(Class<?> cls) { + Map<String, GenericType> map = new HashMap<>(); + Map<String, GenericType> map2 = new HashMap<>(); + for (Field field : ReflectionUtils.getFields(cls, true)) { + Type type = field.getGenericType(); + GenericType genericType = buildGenericType(type); + buildGenericMap(map, genericType); + TypeRef<?> typeRef = TypeRef.of(type); + buildGenericMap(map2, typeRef); + } + map.putAll(map2); + return map; + } + + private void buildGenericMap(Map<String, GenericType> map, TypeRef<?> typeRef) { + if (map.containsKey(typeRef.getType().getTypeName())) { + return; + } + map.put(typeRef.getType().getTypeName(), buildGenericType(typeRef)); + Class<?> rawType = typeRef.getRawType(); + if (TypeUtils.isMap(rawType)) { + Tuple2<TypeRef<?>, TypeRef<?>> kvTypes = TypeUtils.getMapKeyValueType(typeRef); + buildGenericMap(map, kvTypes.f0); + buildGenericMap(map, kvTypes.f1); + } else if (TypeUtils.isCollection(rawType)) { + TypeRef<?> elementType = TypeUtils.getElementType(typeRef); + buildGenericMap(map, elementType); + } else if (rawType.isArray()) { + TypeRef<?> arrayComponent = TypeUtils.getArrayComponent(typeRef); + buildGenericMap(map, arrayComponent); + } + } + + private void buildGenericMap(Map<String, GenericType> map, GenericType genericType) { + if (map.containsKey(genericType.getType().getTypeName())) { + return; + } + map.put(genericType.getType().getTypeName(), genericType); + for (GenericType t : genericType.getTypeParameters()) { + buildGenericMap(map, t); + } + } + @Override public GenericType buildGenericType(TypeRef<?> typeRef) { return GenericType.build( diff --git a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java index 92dbdb821..1113c7d5d 100644 --- a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java +++ b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java @@ -19,6 +19,7 @@ package org.apache.fory.resolver; +import java.lang.reflect.Field; import java.lang.reflect.Type; import org.apache.fory.Fory; import org.apache.fory.annotation.Internal; diff --git a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java index b47a45419..03fc675d7 100644 --- a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java +++ b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java @@ -414,6 +414,14 @@ public class TypeUtils { return type; } + public static TypeRef<?> getArrayComponent(TypeRef<?> type) { + if (type.getType() instanceof GenericArrayType) { + Type componentType = ((GenericArrayType) (type.getType())).getGenericComponentType(); + return TypeRef.of(componentType); + } + return TypeRef.of(getArrayComponentInfo(type.getRawType()).f0); + } + public static Class<?> getArrayComponent(Class<?> type) { return getArrayComponentInfo(type).f0; } @@ -909,30 +917,4 @@ public class TypeUtils { return false; }); } - - /** - * Build a map of nested generic type name to generic type for all fields in the class. - * - * @param cls the class to build the map of nested generic type name to generic type for all - * fields in the class - * @return a map of nested generic type name to generic type for all fields in the class - */ - public static Map<String, GenericType> buildGenericMap(Class<?> cls) { - Map<String, GenericType> map = new HashMap<>(); - for (Field field : ReflectionUtils.getFields(cls, true)) { - Type type = field.getGenericType(); - GenericType genericType = GenericType.build(type); - if (map.containsKey(type.getTypeName())) { - continue; - } - map.put(type.getTypeName(), genericType); - for (GenericType t : genericType.getTypeParameters()) { - if (map.containsKey(t.getType().getTypeName())) { - continue; - } - map.put(t.getType().getTypeName(), GenericType.build(t.getType())); - } - } - return map; - } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
