@@ -38,6 +38,8 @@ public abstract class KotlinDetector {
3838
3939 private static final @ Nullable Class <? extends Annotation > KOTLIN_JVM_INLINE ;
4040
41+ private static final @ Nullable Class <? extends Annotation > KOTLIN_SERIALIZABLE ;
42+
4143 private static final @ Nullable Class <?> KOTLIN_COROUTINE_CONTINUATION ;
4244
4345 // For ConstantFieldFeature compliance, otherwise could be deduced from kotlinMetadata
@@ -49,6 +51,7 @@ public abstract class KotlinDetector {
4951 ClassLoader classLoader = KotlinDetector .class .getClassLoader ();
5052 Class <?> metadata = null ;
5153 Class <?> jvmInline = null ;
54+ Class <?> serializable = null ;
5255 Class <?> coroutineContinuation = null ;
5356 try {
5457 metadata = ClassUtils .forName ("kotlin.Metadata" , classLoader );
@@ -58,6 +61,12 @@ public abstract class KotlinDetector {
5861 catch (ClassNotFoundException ex ) {
5962 // JVM inline support not available
6063 }
64+ try {
65+ serializable = ClassUtils .forName ("kotlinx.serialization.Serializable" , classLoader );
66+ }
67+ catch (ClassNotFoundException ex ) {
68+ // Kotlin Serialization not available
69+ }
6170 try {
6271 coroutineContinuation = ClassUtils .forName ("kotlin.coroutines.Continuation" , classLoader );
6372 }
@@ -72,6 +81,7 @@ public abstract class KotlinDetector {
7281 KOTLIN_PRESENT = (KOTLIN_METADATA != null );
7382 KOTLIN_REFLECT_PRESENT = ClassUtils .isPresent ("kotlin.reflect.full.KClasses" , classLoader );
7483 KOTLIN_JVM_INLINE = (Class <? extends Annotation >) jvmInline ;
84+ KOTLIN_SERIALIZABLE = (Class <? extends Annotation >) serializable ;
7585 KOTLIN_COROUTINE_CONTINUATION = coroutineContinuation ;
7686 }
7787
@@ -125,4 +135,26 @@ public static boolean isInlineClass(Class<?> clazz) {
125135 return (KOTLIN_JVM_INLINE != null && clazz .getDeclaredAnnotation (KOTLIN_JVM_INLINE ) != null );
126136 }
127137
138+ /**
139+ * Determine whether the given {@code ResolvableType} is annotated with {@code @kotlinx.serialization.Serializable}
140+ * at type or generics level.
141+ * @since 7.0
142+ */
143+ public static boolean hasSerializableAnnotation (ResolvableType type ) {
144+ Class <?> resolvedClass = type .resolve ();
145+ if (KOTLIN_SERIALIZABLE == null || resolvedClass == null ) {
146+ return false ;
147+ }
148+ if (resolvedClass .isAnnotationPresent (KOTLIN_SERIALIZABLE )) {
149+ return true ;
150+ }
151+ @ Nullable Class <?>[] resolvedGenerics = type .resolveGenerics ();
152+ for (Class <?> resolvedGeneric : resolvedGenerics ) {
153+ if (resolvedGeneric != null && resolvedGeneric .isAnnotationPresent (KOTLIN_SERIALIZABLE )) {
154+ return true ;
155+ }
156+ }
157+ return false ;
158+ }
159+
128160}
0 commit comments