@@ -38,35 +38,39 @@ import net.minecraft.util.Identifier
3838import net.minecraft.util.math.BlockPos
3939import net.minecraft.util.math.ChunkPos
4040import org.apache.logging.log4j.Logger
41- import java.lang.reflect.Field
4241import java.lang.reflect.InaccessibleObjectException
4342import java.util.*
4443import kotlin.jvm.optionals.getOrDefault
44+ import kotlin.reflect.KClass
45+ import kotlin.reflect.KProperty1
46+ import kotlin.reflect.full.memberProperties
47+ import kotlin.reflect.jvm.javaField
48+ import kotlin.reflect.jvm.jvmErasure
4549
4650object DynamicReflectionSerializer : Loadable {
4751 // Classes that should not be recursively serialized
4852 private val skipables = setOf (
49- Codec ::class .java ,
50- Logger ::class .java ,
51- BlockPos ::class .java ,
52- BlockState ::class .java ,
53- ItemStack ::class .java ,
54- Identifier ::class .java ,
55- NbtCompound ::class .java ,
56- Map ::class .java ,
57- BitSet ::class .java ,
58- Collection ::class .java ,
59- RegistryEntry ::class .java ,
60- RegistryKey ::class .java ,
61- ScreenHandlerType ::class .java ,
62- TranslationStorage ::class .java ,
63- ChunkPos ::class .java ,
64- Text ::class .java ,
65- org.slf4j.Logger ::class .java ,
66- String ::class .java ,
53+ Codec ::class ,
54+ Logger ::class ,
55+ BlockPos ::class ,
56+ BlockState ::class ,
57+ ItemStack ::class ,
58+ Identifier ::class ,
59+ NbtCompound ::class ,
60+ Map ::class ,
61+ BitSet ::class ,
62+ Collection ::class ,
63+ RegistryEntry ::class ,
64+ RegistryKey ::class ,
65+ ScreenHandlerType ::class ,
66+ TranslationStorage ::class ,
67+ ChunkPos ::class ,
68+ Text ::class ,
69+ org.slf4j.Logger ::class ,
70+ String ::class ,
6771 )
6872 private val skipFields = setOf (
69- Codec ::class .java ,
73+ Codec ::class ,
7074 )
7175
7276 private const val INDENT = 2
@@ -104,9 +108,9 @@ object DynamicReflectionSerializer : Loadable {
104108
105109 val String .remappedName get() = mappings.getOrDefault(this , this )
106110
107- fun <T : Any > Class <T>.dynamicName (remap : Boolean ) =
108- if (remap) canonicalName .remappedName else simpleName
109- fun Field .dynamicName (remap : Boolean ) =
111+ fun <T : Any > KClass <T>.dynamicName (remap : Boolean ) =
112+ if (remap) qualifiedName? .remappedName else simpleName
113+ fun < T : Any > KProperty1 < T , * > .dynamicName (remap : Boolean ) =
110114 if (remap) name.remappedName else name
111115
112116 fun Any.dynamicString (
@@ -118,47 +122,46 @@ object DynamicReflectionSerializer : Loadable {
118122 remap : Boolean = !Lambda .isDebug,
119123 ): String {
120124 if (visitedObjects.contains(this )) {
121- builder.appendLine(" $indent${javaClass .dynamicName(remap)} (Circular Reference)" )
125+ builder.appendLine(" $indent${this :: class .dynamicName(remap)} (Circular Reference)" )
122126 return builder.toString()
123127 }
124128
125129 visitedObjects.add(this )
126- builder.appendLine(" $indent${javaClass .dynamicName(remap)} " )
130+ builder.appendLine(" $indent${this :: class .dynamicName(remap)} " )
127131
128- val fields = javaClass.declaredFields + javaClass.superclass?.declaredFields.orEmpty()
129- fields.forEach { field ->
130- processField(field, indent, builder, currentDepth, maxRecursionDepth, visitedObjects, remap)
131- }
132+ this ::class .memberProperties
133+ .forEach { processField(it, indent, builder, currentDepth, maxRecursionDepth, visitedObjects, remap) }
132134
133135 return builder.toString()
134136 }
135137
136- private fun Any.processField (
137- field : Field ,
138+ private fun < T : Any > T .processField (
139+ field : KProperty1 < out T , * > ,
138140 indent : String ,
139141 builder : StringBuilder ,
140142 currentDepth : Int ,
141143 maxRecursionDepth : Int ,
142144 visitedObjects : MutableSet <Any >,
143145 remap : Boolean ,
144146 ) {
145- if (skipFields.any { it.isAssignableFrom (field.type ) }) return
147+ if (skipFields.any { it.isInstance (field) }) return
146148
147149 try {
148- field.isAccessible = true
149- } catch (e : InaccessibleObjectException ) {
150+ field.javaField?. isAccessible = true
151+ } catch (_ : InaccessibleObjectException ) {
150152 return
151153 }
152- val fieldValue = field.get(this )
154+
155+ val fieldValue = field.javaField?.get(this )
153156 val fieldIndent = " $indent${" " .repeat(INDENT )} "
154157 builder.appendLine(" $fieldIndent${field.dynamicName(remap)} : ${fieldValue.formatFieldValue(remap)} " )
155158
156159 if (currentDepth < maxRecursionDepth
157160 && fieldValue != null
158- && ! field.type .isPrimitive
159- && ! field.type .isArray
160- && ! field.type .isEnum
161- && skipables.none { it.isAssignableFrom (field.type ) }
161+ && ! field.returnType.jvmErasure.java .isPrimitive
162+ && ! field.returnType.jvmErasure.java .isArray
163+ && ! field.returnType.jvmErasure.java .isEnum
164+ && skipables.none { it.isInstance (field.returnType.jvmErasure ) }
162165 ) {
163166 fieldValue.dynamicString(
164167 maxRecursionDepth,
@@ -186,10 +189,10 @@ object DynamicReflectionSerializer : Loadable {
186189 is Identifier -> " $namespace :$path "
187190 is NbtCompound -> asString().getOrDefault(" " )
188191 is RegistryEntry <* > -> " ${value()} "
192+ null -> " null"
189193 else -> {
190- if (this ?.javaClass?.canonicalName?.contains(" minecraft" ) == true )
191- " ${this .javaClass.dynamicName(remap)} @${Integer .toHexString(hashCode())} "
192- else this ?.toString() ? : " null"
194+ if (this ::class .qualifiedName?.contains(" minecraft" ) == true ) " ${this ::class .dynamicName(remap)} @${Integer .toHexString(hashCode())} "
195+ else this .toString()
193196 }
194197 }
195198
0 commit comments