Skip to content

Commit 2b19e48

Browse files
Use custom lazy delegate
1 parent 9e21a26 commit 2b19e48

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableState.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jetbrains.kotlinx.jupyter.api
22

33
import java.lang.reflect.Field
4+
import kotlin.reflect.KProperty
45
import kotlin.reflect.KProperty1
56
import kotlin.reflect.jvm.isAccessible
67

@@ -12,6 +13,18 @@ interface VariableState {
1213
val isRecursive: Boolean
1314
}
1415

16+
class DependentLazyDelegate<T>(val initializer: () -> T?) {
17+
private var cachedPropertyValue: T? = null
18+
var isChanged: Boolean = true
19+
20+
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
21+
if (isChanged) {
22+
cachedPropertyValue = initializer()
23+
}
24+
return cachedPropertyValue
25+
}
26+
}
27+
1528
data class VariableStateImpl(
1629
override val property: Field,
1730
override val scriptInstance: Any,
@@ -60,7 +73,15 @@ data class VariableStateImpl(
6073
val res = action(this)
6174
isAccessible = wasAccessible
6275
return res
76+
private val customDelegate = DependentLazyDelegate {
77+
fun getRecursiveObjectName(): String {
78+
val kClassName = cachedValue.getOrNull()!!::class.simpleName
79+
return "$kClassName: recursive structure"
80+
}
81+
if (cachedValue.getOrNull() == null) {
82+
return@DependentLazyDelegate null
6383
}
84+
handleIfRecursiveStructure()
6485
}
6586
}
6687

src/main/kotlin/org/jetbrains/kotlinx/jupyter/serializationUtils.kt

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ class VariablesSerializer(
175175
value::class.java.isArray
176176
} == true
177177
}
178+
fun getProperEntrySetRepresentation(value: Any?): String {
179+
value as Set<*>
180+
val size = value.size
181+
if (size == 0) return ""
182+
val firstProper = value.firstOrNull {
183+
it as Map.Entry<*, *>
184+
it.key != null && it.value != null
185+
} as Map.Entry<*, *> ?: return ""
186+
return "<${firstProper.key!!::class.simpleName}, ${firstProper.value!!::class.simpleName}>"
187+
}
178188

179189
val kProperties = try {
180190
if (value != null) value::class.declaredMemberProperties else {
@@ -183,7 +193,11 @@ class VariablesSerializer(
183193
} catch (ex: Exception) { null }
184194
val stringedValue = getProperString(value)
185195
val varID = if (value !is String) {
186-
value.getUniqueID(stringedValue.contains(": recursive structure"))
196+
val isRecursive = stringedValue.contains(": recursive structure")
197+
if (!isRecursive && simpleTypeName == "LinkedEntrySet") {
198+
getProperEntrySetRepresentation(value)
199+
} else
200+
value.getUniqueID(isRecursive)
187201
} else {
188202
""
189203
}
@@ -382,10 +396,12 @@ class VariablesSerializer(
382396
val wasRedeclared = !unchangedVariables.contains(it)
383397
if (wasRedeclared) {
384398
removedFromSightVariables.remove(it)
385-
} /*
386-
(unchangedVariables.contains(it) || serializedVariablesCache[it]?.value != variablesState[it]?.value?.getOrNull().toString()) &&
387-
!removedFromSightVariables.contains(it)*/
388-
(unchangedVariables.contains(it)) &&
399+
}
400+
// todo: might consider self-recursive elements always to recompute since it's non comparable via strings
401+
if (serializedVariablesCache.isEmpty()) {
402+
true
403+
} else
404+
(!unchangedVariables.contains(it) || serializedVariablesCache[it]?.value != variablesState[it]?.stringValue) &&
389405
!removedFromSightVariables.contains(it)
390406
}
391407
log.debug("Variables state as is: $variablesState")
@@ -645,28 +661,6 @@ class VariablesSerializer(
645661
instancesPerState[descriptor[name]!!] = value.objectInstance
646662
}
647663

648-
/* if (!seenObjectsPerCell!!.containsKey(value)) {
649-
val simpleType = if (elem is Field) getSimpleTypeNameFrom(elem, value.objectInstance) ?: "null"
650-
else {
651-
elem as KProperty1<Any, *>
652-
getSimpleTypeNameFrom(elem, value.objectInstance) ?: "null"
653-
}
654-
serializedIteration[name] = if (standardContainersUtilizer.isStandardType(simpleType)) {
655-
standardContainersUtilizer.serializeContainer(simpleType, value.objectInstance, true)
656-
} else {
657-
createSerializeVariableState(name, simpleType, value)
658-
}
659-
descriptor[name] = serializedIteration[name]!!.serializedVariablesState
660-
661-
if (descriptor[name] != null) {
662-
instancesPerState[descriptor[name]!!] = value.objectInstance
663-
}
664-
}*/
665-
// else {
666-
// val descriptorsState = seenObjectsPerCell[value]
667-
// descriptor.putAll(descriptorsState?.fieldDescriptor ?: emptyMap())
668-
// }
669-
670664
if (seenObjectsPerCell?.containsKey(value) == false) {
671665
if (descriptor[name] != null) {
672666
seenObjectsPerCell[value] = descriptor[name]!!
@@ -801,7 +795,7 @@ fun getProperString(value: Any?): String {
801795
if (index != containerSize - 1) {
802796
if (mapMode) {
803797
value as Map.Entry<*, *>
804-
builder.append(value.key, '=', value.value, "\n")
798+
builder.append(value.key, '=', value.value, ", ")
805799
} else {
806800
builder.append(value, ", ")
807801
}

0 commit comments

Comments
 (0)