The problem I am trying to solve
Hello community, I use the PyDebugValue.getFrameAccessor().evaluate(...) method to evaluate new PyDebugValues.
I have a single-line code editor like the Evaluate Expression-editor in IntelliJ, where the user can enter an expression. In my editor I want to include a synthetic identifier for example _df which resolves to such a previous evaluated PyDebugValue. Or at least to an object of the same type, to have correct code completion for the properties/fields of the type.
The identifier _df should be available in my editor in the auto-completion popup AND correctly resolved.
Demo of the Problem
The problem I'm trying to solve can also be seen in the Evaluate Expression-editor in IntelliJ.
Here is a short example:
A string is evaluated, and the result is used to do further evaluations afterwards (in the second dialog).
The temporary identifier used to refer to the value is not resolved by the editor (marked by the red border) and also the auto-completion isn't possible. Nevertheless, it is a valid identifier, as the evaluation results of the statement in the second dialog shows.
Current way how I create the editor document
I create new Python documents when the user selects a Python variable in the debug view. Afterwards the document is assigned to a single line editor to let the user define a custom expression which is processed at a later point by my plugin.
The document is created with:
val document = PyDebuggerEditorsProvider().createDocument(
XDebuggerUtil.getInstance().createExpression("", PythonLanguage.INSTANCE, null, EvaluationMode.EXPRESSION), // empty expression
The psi-file mapped to the returned document is a com.jetbrains.python.psi.impl.PyExpressionCodeFragmentImpl with the psi-element, specified by the 3rd parameter provided to the createDocument call, as context. All identifier available in the context are correctly resolved when doing auto-complete or entering identifier manually into the editor.
Entering other identifier also results in a red border.
What I have tried so far
I implemented a com.intellij.codeInsight.completion.CompletionContributor and a com.intellij.psi.PsiReferenceContributor. With the CompletionContributor I was able to provide the identifier _df. But I couldn't find a way to create a PsiReferenceContributor which satisfies my needs. It seems that I can only contribute psi-references for string literals, at least I had no success using other element pattern.
I also tried to chain two PyExpressionCodeFragmentImpl instances, where the first one defines the synthetic identifier _df:
// snippet to create the identifier "_df"
val code = """
|from pandas import DataFrame
|_df = DataFrame()
// create document which defines "_df" and has as context the sourcePosition taken from the debugger
val firstDocument = PyDebuggerEditorsProvider().createDocument(
XDebuggerUtil.getInstance().createExpression(code, PythonLanguage.INSTANCE, null, EvaluationMode.CODE_FRAGMENT),
// calculate source-position for second document
val sourcePositionFromFirstFragment = XDebuggerUtil.getInstance().createPositionByElement(
// create document for the editor
val secondDocument = PyDebuggerEditorsProvider().createDocument(
XDebuggerUtil.getInstance().createExpression("", PythonLanguage.INSTANCE, null, EvaluationMode.EXPRESSION),
With this approach, the identifier _df is included in the auto-completion popup. But can't be resolved after completion. The same applies to all elements in the file to which XDebuggerManager.getInstance(project).currentSession?.currentPosition currently points.