Skip to content

Commit f3a3ce1

Browse files
Get unchangedVariables from notebook to reflect after execution state properly
1 parent e5fac02 commit f3a3ce1

File tree

3 files changed

+149
-2
lines changed

3 files changed

+149
-2
lines changed

src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/InternalEvaluatorImpl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ internal class InternalEvaluatorImpl(
5656
return variablesWatcher.findDeclarationAddress(variableName) ?: -1
5757
}
5858

59+
override fun getUnchangedVariables(): Set<String> {
60+
return variablesWatcher.getUnchangedVariables()
61+
}
62+
5963
override var writeCompiledClasses: Boolean
6064
get() = classWriter != null
6165
set(value) {

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class VariablesUsagesPerCellWatcher<K : Any, V : Any> {
9191
*/
9292
private val variablesDeclarationInfo: MutableMap<V, K> = mutableMapOf()
9393

94+
private val unchangedVariables: MutableSet<V> = mutableSetOf()
95+
// private val unchangedVariables: MutableSet<V> = mutableSetOf()
96+
9497
fun addDeclaration(address: K, variableRef: V) {
9598
ensureStorageCreation(address)
9699

@@ -99,21 +102,35 @@ class VariablesUsagesPerCellWatcher<K : Any, V : Any> {
99102
val oldCellId = variablesDeclarationInfo[variableRef]
100103
if (oldCellId != address) {
101104
cellVariables[oldCellId]?.remove(variableRef)
105+
unchangedVariables.remove(variableRef)
102106
}
107+
} else {
108+
unchangedVariables.add(variableRef)
103109
}
104110
variablesDeclarationInfo[variableRef] = address
105111
cellVariables[address]?.add(variableRef)
106112
}
107113

108-
fun addUsage(address: K, variableRef: V) = cellVariables[address]?.add(variableRef)
114+
fun addUsage(address: K, variableRef: V) {
115+
cellVariables[address]?.add(variableRef)
116+
if (variablesDeclarationInfo[variableRef] != address) {
117+
unchangedVariables.remove(variableRef)
118+
}
119+
}
109120

110121
fun removeOldUsages(newAddress: K) {
111122
// remove known modifying usages in this cell
112123
cellVariables[newAddress]?.removeIf {
113-
variablesDeclarationInfo[it] != newAddress
124+
val predicate = variablesDeclarationInfo[it] != newAddress
125+
if (predicate) {
126+
unchangedVariables.add(it)
127+
}
128+
predicate
114129
}
115130
}
116131

132+
fun getUnchangedVariables(): Set<V> = unchangedVariables
133+
117134
fun findDeclarationAddress(variableRef: V) = variablesDeclarationInfo[variableRef]
118135

119136
fun ensureStorageCreation(address: K) = cellVariables.putIfAbsent(address, mutableSetOf())

src/test/kotlin/org/jetbrains/kotlinx/jupyter/test/repl/ReplTests.kt

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,93 @@ class ReplVarsTest : AbstractSingleReplTest() {
709709
fun testOutVarRendering() {
710710
eval("Out").resultValue.shouldNotBeNull()
711711
}
712+
713+
714+
@Test
715+
fun testSeparatePrivateDefsUsage() {
716+
eval(
717+
"""
718+
private val x = "abcd"
719+
private var f = 47
720+
""".trimIndent(),
721+
jupyterId = 1
722+
)
723+
val state = repl.notebook.cellVariables
724+
assertTrue(state[0]!!.contains("x"))
725+
726+
eval(
727+
"""
728+
val x = 341
729+
private var f = "abcd"
730+
""".trimIndent(),
731+
jupyterId = 2
732+
)
733+
assertTrue(state.isNotEmpty())
734+
assertTrue(state[0]!!.isEmpty())
735+
assertTrue(state[1]!!.contains("x"))
736+
737+
val setOfPrevCell = setOf<String>()
738+
val setOfNextCell = setOf("x", "f")
739+
assertEquals(state[0], setOfPrevCell)
740+
assertEquals(state[1], setOfNextCell)
741+
}
742+
743+
@Test
744+
fun testRecursiveVarsState() {
745+
eval(
746+
"""
747+
val l = mutableListOf<Any>()
748+
l.add(listOf(l))
749+
750+
val m = mapOf(1 to l)
751+
752+
val z = setOf(1, 2, 4)
753+
""".trimIndent(),
754+
jupyterId = 1
755+
)
756+
val state = repl.notebook.variablesState
757+
assertTrue(state.contains("l"))
758+
assertTrue(state.contains("m"))
759+
assertTrue(state.contains("z"))
760+
761+
assertEquals("ArrayList: recursive structure", state["l"]!!.stringValue)
762+
assertTrue(state["m"]!!.stringValue!!.contains(" recursive structure"))
763+
assertEquals("[1, 2, 4]", state["z"]!!.stringValue)
764+
}
765+
766+
@Test
767+
fun testSeparatePrivateCellsUsage() {
768+
eval(
769+
"""
770+
private val x = "abcd"
771+
var f = 47
772+
internal val z = 47
773+
""".trimIndent(),
774+
jupyterId = 1
775+
)
776+
val state = repl.notebook.cellVariables
777+
assertTrue(state[0]!!.contains("x"))
778+
assertTrue(state[0]!!.contains("z"))
779+
780+
eval(
781+
"""
782+
private val x = 341
783+
f += x
784+
protected val z = "abcd"
785+
""".trimIndent(),
786+
jupyterId = 2
787+
)
788+
assertTrue(state.isNotEmpty())
789+
assertTrue(state[0]!!.isNotEmpty())
790+
assertFalse(state[0]!!.contains("x"))
791+
assertFalse(state[0]!!.contains("z"))
792+
assertTrue(state[1]!!.contains("x"))
793+
794+
val setOfPrevCell = setOf("f")
795+
val setOfNextCell = setOf("x", "f", "z")
796+
assertEquals(state[0], setOfPrevCell)
797+
assertEquals(state[1], setOfNextCell)
798+
}
712799
}
713800

714801
class ReplVarsSerializationTest : AbstractSingleReplTest() {
@@ -946,4 +1033,43 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
9461033
}
9471034
}
9481035
}
1036+
1037+
1038+
@Test
1039+
fun testUnchangedVariables() {
1040+
eval(
1041+
"""
1042+
private val x = "abcd"
1043+
var f = 47
1044+
internal val z = 47
1045+
""".trimIndent(),
1046+
jupyterId = 1
1047+
)
1048+
val state = repl.notebook.unchangedVariables()
1049+
val setOfCell = setOf("x", "f", "z")
1050+
assertTrue(state.isNotEmpty())
1051+
assertEquals(setOfCell, state)
1052+
1053+
eval(
1054+
"""
1055+
private val x = 341
1056+
f += x
1057+
protected val z = "abcd"
1058+
""".trimIndent(),
1059+
jupyterId = 2
1060+
)
1061+
assertTrue(state.isEmpty())
1062+
val setOfPrevCell = setOf("f")
1063+
assertNotEquals(setOfCell, setOfPrevCell)
1064+
1065+
eval(
1066+
"""
1067+
private val x = 341
1068+
protected val z = "abcd"
1069+
""".trimIndent(),
1070+
jupyterId = 2
1071+
)
1072+
assertTrue(state.isNotEmpty())
1073+
assertEquals(state, setOfPrevCell)
1074+
}
9491075
}

0 commit comments

Comments
 (0)