@@ -2,9 +2,6 @@ package org.jetbrains.kotlinx.jupyter.api
22
33import java.lang.reflect.Field
44import kotlin.reflect.KProperty
5- import kotlin.reflect.KProperty1
6- import kotlin.reflect.full.declaredMemberProperties
7- import kotlin.reflect.jvm.isAccessible
85
96interface VariableState {
107 val property: Field
@@ -32,6 +29,7 @@ data class VariableStateImpl(
3229) : VariableState {
3330 private var cachedValue: Result <Any ?> = Result .success(null )
3431 override var isRecursive: Boolean = false
32+ private var isLargeForString: Boolean = false
3533
3634 // use of Java 9 required
3735 @SuppressWarnings(" DEPRECATION" )
@@ -58,10 +56,28 @@ data class VariableStateImpl(
5856 if (cachedValue.getOrNull() == null ) {
5957 return @DependentLazyDelegate null
6058 }
61- handleIfRecursiveStructure()
59+ try {
60+ cachedValue.getOrNull().toString()
61+ isRecursive = false
62+ isLargeForString = false
63+ } catch (e: VirtualMachineError ) {
64+ when (e) {
65+ is StackOverflowError -> {
66+ isRecursive = true
67+ }
68+ is OutOfMemoryError -> {
69+ isLargeForString = true
70+ }
71+ else -> {
72+ return @DependentLazyDelegate null
73+ }
74+ }
75+ }
6276
6377 if (! isRecursive) {
6478 cachedValue.getOrNull().toString()
79+ } else if (isLargeForString) {
80+ " ${cachedValue.getOrNull()!! ::class .simpleName} : too large structure"
6581 } else {
6682 getRecursiveObjectName()
6783 }
@@ -72,46 +88,4 @@ data class VariableStateImpl(
7288
7389 override val value: Result <Any ?>
7490 get() = cachedValue
75-
76- private fun handleIfRecursiveStructure () {
77- if (cachedValue.getOrNull() == null ) return
78- traverseObject(cachedValue.getOrNull(), mutableSetOf ())
79- }
80-
81- private fun traverseObject (value : Any? , seenNodes : MutableSet <Any >) {
82- if (value == null ) return
83- val membersProperties = try {
84- value::class .declaredMemberProperties
85- } catch (ex: Throwable ) {
86- emptyList<Collection <KProperty1 <Any , * >>>()
87- }
88-
89- val receivedInstances: MutableList <Any ?> = mutableListOf ()
90- for (property in membersProperties) {
91- @Suppress(" UNCHECKED_CAST" )
92- property as KProperty1 <Any , * >
93- try {
94- val wasAccessible = property.isAccessible
95- property.isAccessible = true
96- val callInstance = property.get(value)
97- property.isAccessible = wasAccessible
98- val wasSeen = callInstance != null && ! seenNodes.add(callInstance)
99-
100- if (wasSeen) {
101- isRecursive = true
102- return
103- }
104- receivedInstances.add(callInstance)
105- } catch (ex: Throwable ) {
106- // there might be recursive elements inside the container
107- if (ex is StackOverflowError ) {
108- isRecursive = true
109- }
110- return
111- }
112- }
113- receivedInstances.forEach {
114- traverseObject(it, seenNodes)
115- }
116- }
11791}
0 commit comments