11package io.github.projectmapk.jackson.module.kogera
22
33import kotlinx.metadata.ClassName
4+ import kotlinx.metadata.ExperimentalContextReceivers
45import kotlinx.metadata.Flags
5- import kotlinx.metadata.KmClass
6+ import kotlinx.metadata.KmClassExtensionVisitor
7+ import kotlinx.metadata.KmClassVisitor
68import kotlinx.metadata.KmConstructor
9+ import kotlinx.metadata.KmConstructorVisitor
10+ import kotlinx.metadata.KmExtensionType
711import kotlinx.metadata.KmFunction
12+ import kotlinx.metadata.KmFunctionVisitor
813import kotlinx.metadata.KmProperty
9- import kotlinx.metadata.jvm.fieldSignature
14+ import kotlinx.metadata.KmPropertyVisitor
15+ import kotlinx.metadata.KmType
16+ import kotlinx.metadata.KmTypeAliasVisitor
17+ import kotlinx.metadata.KmTypeParameterVisitor
18+ import kotlinx.metadata.KmTypeVisitor
19+ import kotlinx.metadata.KmVariance
20+ import kotlinx.metadata.KmVersionRequirementVisitor
21+ import kotlinx.metadata.flagsOf
1022import kotlinx.metadata.jvm.getterSignature
1123import kotlinx.metadata.jvm.signature
1224import java.lang.reflect.Constructor
1325import java.lang.reflect.Field
1426import java.lang.reflect.Method
1527
28+ // KmClassVisitor with all processing disabled as much as possible to reduce load
29+ internal sealed class ReducedKmClassVisitor : KmClassVisitor () {
30+ final override val delegate: KmClassVisitor ? get() = null
31+
32+ // from KmDeclarationContainerVisitor
33+ override fun visitFunction (flags : Flags , name : String ): KmFunctionVisitor ? = null
34+ override fun visitProperty (
35+ flags : Flags ,
36+ name : String ,
37+ getterFlags : Flags ,
38+ setterFlags : Flags
39+ ): KmPropertyVisitor ? = null
40+ override fun visitTypeAlias (flags : Flags , name : String ): KmTypeAliasVisitor ? = null
41+ override fun visitExtensions (type : KmExtensionType ): KmClassExtensionVisitor ? = null
42+
43+ // from KmClassVisitor
44+ override fun visit (flags : Flags , name : ClassName ) {}
45+ override fun visitTypeParameter (
46+ flags : Flags ,
47+ name : String ,
48+ id : Int ,
49+ variance : KmVariance
50+ ): KmTypeParameterVisitor ? = null
51+ override fun visitSupertype (flags : Flags ): KmTypeVisitor ? = null
52+ override fun visitConstructor (flags : Flags ): KmConstructorVisitor ? = null
53+ override fun visitCompanionObject (name : String ) {}
54+ override fun visitNestedClass (name : String ) {}
55+ override fun visitEnumEntry (name : String ) {}
56+ override fun visitSealedSubclass (name : ClassName ) {}
57+ override fun visitInlineClassUnderlyingPropertyName (name : String ) {}
58+ override fun visitInlineClassUnderlyingType (flags : Flags ): KmTypeVisitor ? = null
59+
60+ @OptIn(ExperimentalContextReceivers ::class )
61+ override fun visitContextReceiverType (flags : Flags ): KmTypeVisitor ? = null
62+ override fun visitVersionRequirement (): KmVersionRequirementVisitor ? = null
63+ override fun visitEnd () {}
64+ }
65+
66+ internal class ReducedKmClass : ReducedKmClassVisitor () {
67+ var flags: Flags = flagsOf()
68+ val properties: MutableList <KmProperty > = ArrayList ()
69+ val constructors: MutableList <KmConstructor > = ArrayList (1 )
70+ var companionObject: String? = null
71+ val sealedSubclasses: MutableList <ClassName > = ArrayList (0 )
72+ var inlineClassUnderlyingType: KmType ? = null
73+
74+ override fun visit (flags : Flags , name : ClassName ) {
75+ this .flags = flags
76+ }
77+
78+ override fun visitProperty (flags : Flags , name : String , getterFlags : Flags , setterFlags : Flags ): KmPropertyVisitor =
79+ KmProperty (flags, name, getterFlags, setterFlags).apply { properties.add(this ) }
80+
81+ override fun visitConstructor (flags : Flags ): KmConstructorVisitor =
82+ KmConstructor (flags).apply { constructors.add(this ) }
83+
84+ override fun visitCompanionObject (name : String ) {
85+ this .companionObject = name
86+ }
87+
88+ override fun visitSealedSubclass (name : ClassName ) {
89+ sealedSubclasses.add(name)
90+ }
91+
92+ override fun visitInlineClassUnderlyingType (flags : Flags ): KmTypeVisitor =
93+ KmType (flags).also { inlineClassUnderlyingType = it }
94+ }
95+
1696// Jackson Metadata Class
1797internal class JmClass (
1898 clazz : Class <* >,
19- kmClass : KmClass ,
99+ kmClass : ReducedKmClass ,
20100 superJmClass : JmClass ? ,
21101 interfaceJmClasses : List <JmClass >
22102) {
@@ -40,10 +120,12 @@ internal class JmClass(
40120
41121 val flags: Flags = kmClass.flags
42122 val constructors: List <KmConstructor > = kmClass.constructors
123+ val propertyNameSet: Set <String > get() = allPropsMap.keys
43124 val properties: List <KmProperty > = allPropsMap.values.toList()
44125 val sealedSubclasses: List <ClassName > = kmClass.sealedSubclasses
45126 private val companionPropName: String? = kmClass.companionObject
46127 val companion : CompanionObject ? by lazy { companionPropName?.let { CompanionObject (clazz, it) } }
128+ val inlineClassUnderlyingType: KmType ? = kmClass.inlineClassUnderlyingType
47129
48130 fun findKmConstructor (constructor : Constructor <* >): KmConstructor ? {
49131 val descHead = constructor .parameterTypes.toDescBuilder()
@@ -67,21 +149,30 @@ internal class JmClass(
67149
68150 // Field name always matches property name
69151 fun findPropertyByField (field : Field ): KmProperty ? = allPropsMap[field.name]
70- ?.takeIf { it.fieldSignature?.desc == field.desc() }
71152
72153 fun findPropertyByGetter (getter : Method ): KmProperty ? {
73- val signature = getter.toSignature()
74- return properties.find { it.getterSignature == signature }
154+ val getterName = getter.name
155+ return properties.find { it.getterSignature?.name == getterName }
75156 }
76157
77- internal class CompanionObject (
78- declaringClass : Class <* >,
79- companionObject : String
80- ) {
158+ internal class CompanionObject (declaringClass : Class <* >, companionObject : String ) {
159+ private class ReducedCompanionVisitor : ReducedKmClassVisitor () {
160+ val functions: MutableList <KmFunction > = arrayListOf ()
161+
162+ override fun visitFunction (flags : Flags , name : String ): KmFunctionVisitor ? = KmFunction (flags, name)
163+ .apply { functions.add(this ) }
164+
165+ companion object {
166+ fun from (companionClass : Class <* >): ReducedCompanionVisitor = ReducedCompanionVisitor ().apply {
167+ companionClass.getAnnotation(Metadata ::class .java)!! .accept(this )
168+ }
169+ }
170+ }
171+
81172 private val companionField: Field = declaringClass.getDeclaredField(companionObject)
82173 val type: Class <* > = companionField.type
83174 val isAccessible: Boolean = companionField.isAccessible
84- private val functions by lazy { type.toKmClass() !! .functions }
175+ private val functions by lazy { ReducedCompanionVisitor .from(type) .functions }
85176 val instance: Any by lazy {
86177 // To prevent the call from failing, save the initial value and then rewrite the flag.
87178 if (! companionField.isAccessible) companionField.isAccessible = true
0 commit comments