@@ -63,6 +63,8 @@ data class RuntimeObjectWrapper(
6363 val objectInstance : Any? ,
6464 val isRecursive : Boolean = false
6565) {
66+ val computerID: String = Integer .toHexString(hashCode())
67+
6668 override fun equals (other : Any? ): Boolean {
6769 if (other == null ) return objectInstance == null
6870 if (objectInstance == null ) return false
@@ -71,13 +73,12 @@ data class RuntimeObjectWrapper(
7173 }
7274
7375 override fun hashCode (): Int {
74- return if (isRecursive) Random .hashCode () else objectInstance?.hashCode() ? : 0
76+ return if (isRecursive) Random .nextInt () else objectInstance?.hashCode() ? : 0
7577 }
7678}
7779
7880fun Any?.toObjectWrapper (isRecursive : Boolean = false): RuntimeObjectWrapper = RuntimeObjectWrapper (this , isRecursive)
7981
80-
8182fun Any?.getToStringValue (isRecursive : Boolean = false): String {
8283 return if (isRecursive) {
8384 " ${this !! ::class .simpleName} : recursive structure"
@@ -90,6 +91,24 @@ fun Any?.getToStringValue(isRecursive: Boolean = false): String {
9091 }
9192}
9293
94+ fun Any?.getUniqueID (isRecursive : Boolean = false): String {
95+ return if (this != null ) {
96+ val hashCode = if (isRecursive) {
97+ Random .nextLong()
98+ } else {
99+ // ignore standard numerics
100+ if (this !is Number && this ::class .simpleName != " int" ) {
101+ this .hashCode()
102+ } else {
103+ Random .nextLong()
104+ }
105+ }
106+ Integer .toHexString(hashCode.toInt())
107+ } else {
108+ " "
109+ }
110+ }
111+
93112/* *
94113 * Provides contract for using threshold-based removal heuristic.
95114 * Every serialization-related info in [T] would be removed once [isShouldRemove] == true.
@@ -162,7 +181,13 @@ class VariablesSerializer(
162181 null
163182 }
164183 } catch (ex: Exception ) { null }
165- val serializedVersion = SerializedVariablesState (simpleTypeName, getProperString(value), true )
184+ val stringedValue = getProperString(value)
185+ val varID = if (value !is String ) {
186+ value.getUniqueID(stringedValue.contains(" : recursive structure" ))
187+ } else {
188+ " "
189+ }
190+ val serializedVersion = SerializedVariablesState (simpleTypeName, stringedValue, true , varID)
166191 val descriptors = serializedVersion.fieldDescriptor
167192
168193 // only for set case
@@ -180,6 +205,9 @@ class VariablesSerializer(
180205 if (isDescriptorsNeeded) {
181206 kProperties?.forEach { prop ->
182207 val name = prop.name
208+ if (name == " null" ) {
209+ return @forEach
210+ }
183211 val propValue = value?.let {
184212 try {
185213 prop as KProperty1 <Any , * >
@@ -188,7 +216,13 @@ class VariablesSerializer(
188216 if (prop.name == " size" ) {
189217 if (isArray(value)) {
190218 value as Array <* >
191- value.size
219+ // there might be size 10, but only one actual recursive value
220+ val runTimeSize = value.size
221+ if (runTimeSize > 5 && value[0 ] is List <* > && value[1 ] == null && value [2 ] == null ) {
222+ 1
223+ } else {
224+ runTimeSize
225+ }
192226 } else {
193227 value as Collection <* >
194228 value.size
@@ -405,17 +439,19 @@ class VariablesSerializer(
405439 if (! isSerializationActive || variableState == null || name == null ) return SerializedVariablesState ()
406440 // force recursive check
407441 variableState.stringValue
408- return serializeVariableState(cellId, name, variableState.property, variableState.value.getOrNull(), variableState.isRecursive, isOverride)
442+ return serializeVariableState(cellId, name, variableState.property, variableState.value.getOrNull(), variableState.isRecursive, isOverride)
409443 }
410444
411445 private fun serializeVariableState (cellId : Int , name : String , property : Field ? , value : Any? , isRecursive : Boolean , isOverride : Boolean = true): SerializedVariablesState {
412- val processedData = createSerializeVariableState(name, getSimpleTypeNameFrom(property, value), value)
413- return doActualSerialization(cellId, processedData, value.toObjectWrapper(isRecursive), isRecursive, isOverride)
446+ val wrapper = value.toObjectWrapper(isRecursive)
447+ val processedData = createSerializeVariableState(name, getSimpleTypeNameFrom(property, value), wrapper)
448+ return doActualSerialization(cellId, processedData, wrapper, isRecursive, isOverride)
414449 }
415450
416451 private fun serializeVariableState (cellId : Int , name : String , property : KProperty <* >, value : Any? , isRecursive : Boolean , isOverride : Boolean = true): SerializedVariablesState {
417- val processedData = createSerializeVariableState(name, getSimpleTypeNameFrom(property, value), value)
418- return doActualSerialization(cellId, processedData, value.toObjectWrapper(isRecursive), isRecursive, isOverride)
452+ val wrapper = value.toObjectWrapper(isRecursive)
453+ val processedData = createSerializeVariableState(name, getSimpleTypeNameFrom(property, value), wrapper)
454+ return doActualSerialization(cellId, processedData, wrapper, isRecursive, isOverride)
419455 }
420456
421457 private fun doActualSerialization (cellId : Int , processedData : ProcessedSerializedVarsState , value : RuntimeObjectWrapper , isRecursive : Boolean , isOverride : Boolean = true): SerializedVariablesState {
@@ -447,7 +483,7 @@ class VariablesSerializer(
447483 val type = processedData.propertiesType
448484 if (type == PropertiesType .KOTLIN ) {
449485 val kProperties = currentCellDescriptors.processedSerializedVarsToKTProperties[serializedVersion]
450- if (kProperties?.size == 1 && kProperties.first().name == " size" ) {
486+ if (kProperties?.size == 1 && kProperties.first().name == " size" ) {
451487 serializedVersion.fieldDescriptor.addDescriptor(value.objectInstance, " data" )
452488 }
453489 iterateThroughContainerMembers(cellId, value.objectInstance, serializedVersion.fieldDescriptor, isRecursive = isRecursive, kProperties = currentCellDescriptors.processedSerializedVarsToKTProperties[serializedVersion])
@@ -626,7 +662,6 @@ class VariablesSerializer(
626662// descriptor.putAll(descriptorsState?.fieldDescriptor ?: emptyMap())
627663// }
628664
629-
630665 if (seenObjectsPerCell?.containsKey(value) == false ) {
631666 if (descriptor[name] != null ) {
632667 seenObjectsPerCell[value] = descriptor[name]!!
@@ -642,7 +677,7 @@ class VariablesSerializer(
642677 if (value != null ) {
643678 value::class .simpleName
644679 } else {
645- value?.getToStringValue()
680+ value?.getToStringValue()
646681 }
647682 }
648683 }
@@ -666,10 +701,10 @@ class VariablesSerializer(
666701 }
667702
668703 private fun createSerializeVariableState (name : String , simpleTypeName : String? , value : RuntimeObjectWrapper ): ProcessedSerializedVarsState {
669- return doCreateSerializedVarsState(simpleTypeName, value.objectInstance)
704+ return doCreateSerializedVarsState(simpleTypeName, value.objectInstance, value.computerID )
670705 }
671706
672- private fun doCreateSerializedVarsState (simpleTypeName : String? , value : Any? ): ProcessedSerializedVarsState {
707+ private fun doCreateSerializedVarsState (simpleTypeName : String? , value : Any? , uniqueID : String? = null ): ProcessedSerializedVarsState {
673708 val javaClass = value?.javaClass
674709 val membersProperties = javaClass?.declaredFields?.filter {
675710 ! (it.name.startsWith(" script$" ) || it.name.startsWith(" serialVersionUID" ))
@@ -687,8 +722,15 @@ class VariablesSerializer(
687722 if (value != null && standardContainersUtilizer.isStandardType(type)) {
688723 return standardContainersUtilizer.serializeContainer(type, value)
689724 }
725+ val stringedValue = getProperString(value)
726+ val finalID = uniqueID
727+ ? : if (value !is String ) {
728+ value.getUniqueID(stringedValue.contains(" : recursive structure" ))
729+ } else {
730+ " "
731+ }
690732
691- val serializedVariablesState = SerializedVariablesState (type, getProperString(value), isContainer)
733+ val serializedVariablesState = SerializedVariablesState (type, getProperString(value), isContainer, ID = finalID )
692734
693735 return ProcessedSerializedVarsState (serializedVariablesState, membersProperties?.toTypedArray())
694736 }
0 commit comments