Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables view feature #297

Closed
wants to merge 8 commits into from
Closed

Conversation

nikolay-egorov
Copy link
Contributor

No description provided.

@nikolay-egorov nikolay-egorov requested a review from ileasile July 6, 2021 16:02
@nikolay-egorov nikolay-egorov self-assigned this Jul 6, 2021
@nikolay-egorov nikolay-egorov force-pushed the variables-view-feature branch 2 times, most recently from 922f348 to b2400c7 Compare July 7, 2021 14:05
data class VariableState(
val propertyKlass: KProperty1<Any, *>,
val scriptInstance: Any,
var stringValue: String
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be val, at least here, in API class. You may make an interface with val stringValue and then implement it in this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we basically would like to consider that VariableState is an immutable thing, hence, from the semantic perspective, changing stringValue gives us a new VariableState? Sure thing, I can have another var field in a implementation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, property class and script instance hold the exhaustive information about variable state. Other things may be obtained from these two. So I suggest something like this:

data class VariableState(
    private val propertyClass: KProperty1<Any, *>,
    private val scriptInstance: Any,
) {
    // caching, methods to get pure and stringified values go here
}

What do you think?

Copy link
Contributor Author

@nikolay-egorov nikolay-egorov Jul 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I did this way :

interface VarState {
    val propertyKlass: KProperty<*>
    val scriptInstance: Any?
    val stringValue: String?
}

data class VariableState(
    override val propertyKlass: KProperty1<Any, *>,
    override val scriptInstance: Any,
    var mutableStringValue: String?
) : VarState {
    override val stringValue: String?
        get() = mutableStringValue
}

But I like your approach more

/**
* Current state of visible variables
*/
val variablesMap: Map<String, VariableState>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call it variablesState

@nikolay-egorov nikolay-egorov force-pushed the variables-view-feature branch from 8ab2741 to 76f1d75 Compare July 12, 2021 16:11
@nikolay-egorov nikolay-egorov force-pushed the variables-view-feature branch 2 times, most recently from b203e86 to 58d0a74 Compare July 12, 2021 16:36
@nikolay-egorov nikolay-egorov requested a review from ileasile July 13, 2021 06:32
Copy link
Collaborator

@ileasile ileasile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost all is OK. The latest serious thing which I don't like is that stringified values are exposed as a part of Notebook API. They may be exposed, but at least with the corresponding raw values.

@@ -0,0 +1,29 @@
package org.jetbrains.kotlinx.jupyter.api
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename this class to VariableState.kt

import kotlin.reflect.jvm.isAccessible

interface VariableState {
val propertyKlass: KProperty<*>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about renaming it to property or kProperty? I don't see a reason for a word class

return buildString {
append(
"""
<table class="$varsTableStyleClass" style="width:80%;margin-left:auto;margin-right:auto;" align="center">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something happened with indentation here, I think that additional tab will make things better

if (isHtmlFormat) notebook.variablesReportAsHTML() else notebook.variablesReport()
)

// TODO: causes some tests to fail. perhaps, due to exhausting log calling
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What tests are failing? Let's do something with them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -395,7 +415,14 @@ class ReplForJupyterImpl(
updateClasspath()
} ?: emptyList()

EvalResult(rendered, EvaluatedSnippetMetadata(newClasspath, compiledData, newImports))
notebook.updateVariablesState(variablesState)
notebook.cellVariables = cellVariables
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create a Notebook method that will be called like notebook.updateVariablesState(internalEvaluator). It seems that we can make cellVariables a val property

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we cant make it val since we need to reasign it once it changed

assertEquals(res.metadata.evaluatedVariablesState, varsUpdate)
assertFalse(repl.notebook.variablesState.isEmpty())
val varsState = repl.notebook.variablesState
assertEquals("1", varsState["x"]!!.stringValue)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add extension method that will allow us to write varsState.getStringValue("x"). And also, varsState.getValue("x") for getting raw value

cell = notebook.addCell(internalId, codeToExecute, EvalData(jupyterId, code))
}
} finally {
compiledData = internalEvaluator.popAddedCompiledScripts()
newImports = importsCollector.popAddedImports()
}
val variablesState = internalEvaluator.variablesHolder
val cellVariables = internalEvaluator.cellVariables
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this variable needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah)

cell = notebook.addCell(internalId, codeToExecute, EvalData(jupyterId, code))
}
} finally {
compiledData = internalEvaluator.popAddedCompiledScripts()
newImports = importsCollector.popAddedImports()
}
val variablesState = internalEvaluator.variablesHolder
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable may be inlined

* Value: set of variable names.
* Useful <==> declarations + modifying references
*/
var cellVariables: Map<Int, Set<String>>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need it to be a var?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might create another field and make val in api. I think it might make sense since we do not want to allow change notebook.varsState from notebook

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do so then

Comment on lines 170 to 173
if (property is KMutableProperty1) {
variablesHolder.remove(property.name)
}

if (property !is KMutableProperty1) {
variablesHolder[property.name] = state
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if-else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand a bit more?

Comment on lines 62 to 69
protected fun Map<String, VariableState>.getStringValue(variableName: String): String? {
return get(variableName)?.stringValue
}

protected fun Map<String, VariableState>.getValue(variableName: String): Any? {
return get(variableName)?.value
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace these declarations to testUtil.kt, they may be useful in other tests as well

@nikolay-egorov nikolay-egorov force-pushed the variables-view-feature branch from b7fbc83 to 6ec1281 Compare July 13, 2021 16:02
@ileasile
Copy link
Collaborator

Thank you @nikolay-egorov! Merged manually as c6b1390

@ileasile ileasile closed this Jul 13, 2021
@ileasile ileasile deleted the variables-view-feature branch July 14, 2021 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants