Fix running activities with debugger values on a Debugger Thread

Pass ExecutionContextImpl separately from DebuggerCommandLauncher

GitOrigin-RevId: 9ba082242727f7335b05b799ff427853ee724d10
This commit is contained in:
Alexey Korovin
2025-04-09 16:09:41 +00:00
committed by intellij-monorepo-bot
parent 34d0fff9e3
commit 8a3be01c0c
18 changed files with 117 additions and 72 deletions
@@ -29,7 +29,14 @@ import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.TextRange
import com.intellij.platform.ide.progress.withBackgroundProgress
import com.intellij.xdebugger.XDebugSession
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.yield
import org.jetbrains.annotations.Nls
import java.util.stream.Stream
import kotlin.coroutines.CoroutineContext
@@ -151,26 +158,29 @@ class TraceStreamRunner(val cs: CoroutineScope) {
val expressionBuilder = provider.getExpressionBuilder(project)
val resultInterpreter = TraceResultInterpreterImpl(provider.getLibrarySupport().interpreterFactory)
val xValueInterpreter = provider.getXValueInterpreter(project)
val debuggerLauncher = provider.getDebuggerCommandLauncher(session)
val tracer: StreamTracer = EvaluateExpressionTracer(session, expressionBuilder, resultInterpreter, xValueInterpreter)
val result = tracer.trace(chain)
when (result) {
is StreamTracer.Result.Evaluated -> {
val resolvedTrace = result.result.resolve(provider.getLibrarySupport().resolverFactory)
withContext(Dispatchers.EDT) {
window.setTrace(resolvedTrace, result.debuggerCommandLauncher, provider.getCollectionTreeBuilder(result.debuggerCommandLauncher.project))
debuggerLauncher.launchDebuggerCommand {
val result = tracer.trace(chain)
when (result) {
is StreamTracer.Result.Evaluated -> {
val resolvedTrace = result.result.resolve(provider.getLibrarySupport().resolverFactory)
withContext(Dispatchers.EDT) {
window.setTrace(resolvedTrace, debuggerLauncher, result.evaluationContext, provider.getCollectionTreeBuilder(project))
}
}
is StreamTracer.Result.EvaluationFailed -> {
showError(result.message)
throw TraceEvaluationException(result.message, result.traceExpression)
}
is StreamTracer.Result.CompilationFailed -> {
showError(result.message)
throw TraceCompilationException(result.message, result.traceExpression)
}
StreamTracer.Result.Unknown -> {
LOG.error("Unknown result")
}
}
is StreamTracer.Result.EvaluationFailed -> {
showError(result.message)
throw TraceEvaluationException(result.message, result.traceExpression)
}
is StreamTracer.Result.CompilationFailed -> {
showError(result.message)
throw TraceCompilationException(result.message, result.traceExpression)
}
StreamTracer.Result.Unknown -> {
LOG.error("Unknown result")
}
}
}
@@ -2,11 +2,13 @@
package com.intellij.debugger.streams.core.lib;
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder;
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher;
import com.intellij.debugger.streams.core.trace.TraceExpressionBuilder;
import com.intellij.debugger.streams.core.trace.XValueInterpreter;
import com.intellij.debugger.streams.core.wrapper.StreamChainBuilder;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugSession;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -39,4 +41,7 @@ public interface LibrarySupportProvider {
@NotNull
LibrarySupport getLibrarySupport();
@NotNull
DebuggerCommandLauncher getDebuggerCommandLauncher(@NotNull XDebugSession session);
}
@@ -8,7 +8,7 @@ import com.intellij.xdebugger.frame.XValueContainer
interface CollectionTreeBuilder {
fun isSupported(container: XValueContainer): Boolean
fun createXNamedValue(value: Value?, debuggerCommandLauncher: DebuggerCommandLauncher): XNamedValue
fun createXNamedValue(value: Value?, evaluationContext: GenericEvaluationContext): XNamedValue
/**
* Is called under `com.intellij.debugger.streams.trace.EvaluationContextWrapper.launchDebuggerCommand`
@@ -1,9 +1,7 @@
package com.intellij.debugger.streams.core.trace
import com.intellij.openapi.project.Project
import kotlinx.coroutines.CoroutineScope
interface DebuggerCommandLauncher {
val project : Project
fun launchDebuggerCommand(command: suspend CoroutineScope.() -> Unit)
}
@@ -25,7 +25,7 @@ class EvaluateExpressionTracer(
) : StreamTracer {
override suspend fun trace(chain: StreamChain) : StreamTracer.Result {
val streamTraceExpression = myExpressionBuilder.createTraceExpression(chain)
val streamTraceExpression = withContext(Dispatchers.Default) { myExpressionBuilder.createTraceExpression(chain) }
val stackFrame = mySession.getCurrentStackFrame()
val evaluator = mySession.getDebugProcess().getEvaluator()
@@ -47,7 +47,7 @@ class EvaluateExpressionTracer(
return StreamTracer.Result.EvaluationFailed(streamTraceExpression,
StreamDebuggerBundle.message("stream.debugger.evaluation.failed.cannot.interpret.result", t.message!!))
}
return StreamTracer.Result.Evaluated(interpretedResult, result.debuggerCommandLauncher)
return StreamTracer.Result.Evaluated(interpretedResult, result.evaluationContext)
}
is XValueInterpreter.Result.Error -> {
return StreamTracer.Result.EvaluationFailed(streamTraceExpression, result.message)
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nls
*/
interface StreamTracer {
sealed class Result {
data class Evaluated(val result: TracingResult, val debuggerCommandLauncher: DebuggerCommandLauncher) : Result()
data class Evaluated(val result: TracingResult, val evaluationContext: GenericEvaluationContext) : Result()
data class EvaluationFailed(val traceExpression: String, val message: @Nls String) : Result()
data class CompilationFailed(val traceExpression: String, val message: @Nls String) : Result()
object Unknown : Result()
@@ -1,13 +1,18 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.streams.core.trace
import com.intellij.openapi.project.Project
import com.intellij.xdebugger.XDebugSession
import com.intellij.xdebugger.frame.XValue
import org.jetbrains.annotations.Nls
interface GenericEvaluationContext {
val project: Project
}
interface XValueInterpreter {
sealed class Result {
data class Array(val arrayReference: ArrayReference, val hasInnerExceptions: Boolean, val debuggerCommandLauncher: DebuggerCommandLauncher) : Result()
data class Array(val arrayReference: ArrayReference, val hasInnerExceptions: Boolean, val evaluationContext: GenericEvaluationContext) : Result()
data class Error(@Nls val message: String) : Result()
object Unknown : Result()
}
@@ -1,10 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.streams.core.ui.impl;
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder;
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher;
import com.intellij.debugger.streams.core.trace.TraceElement;
import com.intellij.debugger.streams.core.trace.Value;
import com.intellij.debugger.streams.core.trace.*;
import com.intellij.debugger.streams.core.ui.PaintingListener;
import com.intellij.debugger.streams.core.ui.TraceContainer;
import com.intellij.debugger.streams.core.ui.ValuesSelectionListener;
@@ -18,8 +15,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.List;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.*;
import java.util.stream.Collectors;
@@ -45,10 +43,10 @@ public abstract class CollectionTree extends XDebuggerTree implements TraceConta
private boolean myIgnoreExternalSelectionEvents = false;
protected CollectionTree(@NotNull List<TraceElement> traceElements,
@NotNull DebuggerCommandLauncher launcher,
@NotNull GenericEvaluationContext context,
@NotNull CollectionTreeBuilder collectionTreeBuilder,
@NotNull String debugName) {
super(launcher.getProject(), collectionTreeBuilder.getEditorsProvider(), null, XDebuggerActions.INSPECT_TREE_POPUP_GROUP, null);
super(context.getProject(), collectionTreeBuilder.getEditorsProvider(), null, XDebuggerActions.INSPECT_TREE_POPUP_GROUP, null);
myDebugName = debugName;
@@ -73,13 +71,14 @@ public abstract class CollectionTree extends XDebuggerTree implements TraceConta
public static CollectionTree create(@Nullable Value streamResult,
@NotNull List<TraceElement> traceElements,
@NotNull DebuggerCommandLauncher debuggerCommandLauncher,
@NotNull GenericEvaluationContext evaluationContext,
@NotNull CollectionTreeBuilder collectionTreeBuilder,
@NotNull String debugName) {
if (streamResult == null) {
return new IntermediateTree(traceElements, debuggerCommandLauncher, collectionTreeBuilder, debugName);
return new IntermediateTree(traceElements, evaluationContext, collectionTreeBuilder, debugName);
}
else {
return new TerminationTree(streamResult, traceElements, debuggerCommandLauncher, collectionTreeBuilder, debugName);
return new TerminationTree(streamResult, traceElements, debuggerCommandLauncher, evaluationContext, collectionTreeBuilder, debugName);
}
}
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
@@ -99,7 +99,7 @@ public class EvaluationAwareTraceWindow extends DialogWrapper {
return "#com.intellij.debugger.streams.ui.EvaluationAwareTraceWindow";
}
public void setTrace(@NotNull ResolvedTracingResult resolvedTrace, @NotNull DebuggerCommandLauncher launcher,
public void setTrace(@NotNull ResolvedTracingResult resolvedTrace, @NotNull DebuggerCommandLauncher launcher, @NotNull GenericEvaluationContext context,
@NotNull CollectionTreeBuilder builder) {
if (Disposer.isDisposed(myDisposable)) {
return;
@@ -112,7 +112,7 @@ public class EvaluationAwareTraceWindow extends DialogWrapper {
if (controllers.isEmpty()) return;
final List<TraceElement> trace = controllers.get(0).getTrace();
final CollectionTree tree = CollectionTree.create(controllers.get(0).getStreamResult(), trace, launcher, builder, "setTrace#Tree#0#");
final CollectionTree tree = CollectionTree.create(controllers.get(0).getStreamResult(), trace, launcher, context, builder, "setTrace#Tree#0#");
final CollectionView sourceView = new CollectionView(tree);
controllers.get(0).register(sourceView);
myTabContents.get(0).setContent(sourceView, BorderLayout.CENTER);
@@ -129,7 +129,7 @@ public class EvaluationAwareTraceWindow extends DialogWrapper {
final TraceController current = controllers.get(i);
final StreamTracesMappingView
view = new StreamTracesMappingView(launcher, previous, current, builder, "setTrace#MappingView#" + i + "#");
view = new StreamTracesMappingView(launcher, context, previous, current, builder, "setTrace#MappingView#" + i + "#");
tab.setContent(view, BorderLayout.CENTER);
}
@@ -140,7 +140,7 @@ public class EvaluationAwareTraceWindow extends DialogWrapper {
JBLabel label = new JBLabel(StreamDebuggerBundle.message("tab.content.exception.thrown"), SwingConstants.CENTER);
resultTab.setContent(label, BorderLayout.CENTER);
setTitle(StreamDebuggerBundle.message("stream.debugger.dialog.with.exception.title"));
final ExceptionView exceptionView = new ExceptionView(launcher, result, builder);
final ExceptionView exceptionView = new ExceptionView(launcher, context, result, builder);
Disposer.register(myDisposable, exceptionView);
myTabsPane.insertTab(StreamDebuggerBundle.message("exception.tab.name"), AllIcons.Nodes.ErrorIntroduction, exceptionView, "", 0);
myTabsPane.setSelectedIndex(0);
@@ -150,7 +150,7 @@ public class EvaluationAwareTraceWindow extends DialogWrapper {
resultTab.setContent(label, BorderLayout.CENTER);
}
final FlatView flatView = new FlatView(controllers, launcher, builder, "setTrace#FlatView#");
final FlatView flatView = new FlatView(controllers, launcher, context, builder, "setTrace#FlatView#");
myFlatContent.setContent(flatView, BorderLayout.CENTER);
myCenterPane.revalidate();
myCenterPane.repaint();
@@ -4,6 +4,7 @@ package com.intellij.debugger.streams.core.ui.impl
import com.intellij.debugger.streams.core.StreamDebuggerBundle
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.TraceElement
import com.intellij.icons.AllIcons
import com.intellij.ui.components.JBLabel
@@ -12,9 +13,9 @@ import javax.swing.JTree
/**
* @author Vitaliy.Bibaev
*/
class ExceptionView(launcher: DebuggerCommandLauncher, ex: TraceElement, builder: CollectionTreeBuilder)
class ExceptionView(launcher: DebuggerCommandLauncher, context: GenericEvaluationContext, ex: TraceElement, builder: CollectionTreeBuilder)
: CollectionView(JBLabel(StreamDebuggerBundle.message("exception.label")),
TerminationTree(ex.value!!, listOf(ex), launcher, builder, "ExceptionView")) {
TerminationTree(ex.value!!, listOf(ex), launcher, context, builder, "ExceptionView")) {
init {
instancesTree.cellRenderer = object : TraceTreeCellRenderer() {
override fun customizeCellRenderer(tree: JTree,
@@ -3,6 +3,7 @@ package com.intellij.debugger.streams.core.ui.impl
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.TraceElement
import com.intellij.debugger.streams.core.ui.LinkedValuesMapping
import com.intellij.debugger.streams.core.ui.TraceController
@@ -15,7 +16,7 @@ import javax.swing.JPanel
/**
* @author Vitaliy.Bibaev
*/
open class FlatView(controllers: List<TraceController>, launcher: DebuggerCommandLauncher, builder: CollectionTreeBuilder,
open class FlatView(controllers: List<TraceController>, launcher: DebuggerCommandLauncher, context: GenericEvaluationContext, builder: CollectionTreeBuilder,
debugName: String)
: JPanel(GridLayout(1, 2 * controllers.size - 1)) {
private val myPool = mutableMapOf<TraceElement, ValueWithPositionImpl>()
@@ -29,7 +30,7 @@ open class FlatView(controllers: List<TraceController>, launcher: DebuggerComman
val nextCall = controller.nextCall ?: error("intermediate state should know about next call")
val mappingPane = MappingPane(nextCall.tabTitle, nextCall.tabTooltip, valuesBefore, mapping, controller)
val tree = CollectionTree.create(controller.getStreamResult(), valuesBefore.map { it.traceElement }, launcher, builder, "${debugName}FlatView#controller#${index}")
val tree = CollectionTree.create(controller.getStreamResult(), valuesBefore.map { it.traceElement }, launcher, context, builder, "${debugName}FlatView#controller#${index}")
val view = PositionsAwareCollectionView(tree, valuesBefore)
controller.register(view)
view.addValuesPositionsListener(object : ValuesPositionsListener {
@@ -60,7 +61,7 @@ open class FlatView(controllers: List<TraceController>, launcher: DebuggerComman
lastValues?.let {
val lastController = controllers.last()
val tree = CollectionTree.create(lastController.getStreamResult(), it.map { it.traceElement }, launcher, builder, "${debugName}FlatView#lastValues#CollectionTree")
val tree = CollectionTree.create(lastController.getStreamResult(), it.map { it.traceElement }, launcher, context, builder, "${debugName}FlatView#lastValues#CollectionTree")
val view = PositionsAwareCollectionView(tree, it)
lastController.register(view)
view.addValuesPositionsListener(object : ValuesPositionsListener {
@@ -76,7 +77,7 @@ open class FlatView(controllers: List<TraceController>, launcher: DebuggerComman
if (controllers.size == 1) {
val controller = controllers[0]
val tree = CollectionTree.create(controller.getStreamResult(), controller.trace, launcher, builder, "FlatView#singleController")
val tree = CollectionTree.create(controller.getStreamResult(), controller.trace, launcher, context, builder, "FlatView#singleController")
val view = CollectionView(tree)
add(view)
controller.register(view)
@@ -1,10 +1,15 @@
package com.intellij.debugger.streams.core.ui.impl
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.TraceElement
import com.intellij.openapi.application.ApplicationManager
import com.intellij.xdebugger.frame.*
import com.intellij.xdebugger.frame.XCompositeNode
import com.intellij.xdebugger.frame.XValue
import com.intellij.xdebugger.frame.XValueChildrenList
import com.intellij.xdebugger.frame.XValueContainer
import com.intellij.xdebugger.frame.XValueNode
import com.intellij.xdebugger.frame.XValuePlace
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeListener
import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode
@@ -12,16 +17,16 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl
class IntermediateTree(
traceElements: List<TraceElement>,
launcher: DebuggerCommandLauncher,
context: GenericEvaluationContext,
private val myBuilder: CollectionTreeBuilder,
debugName: String,
) : CollectionTree(traceElements, launcher, myBuilder, debugName) {
) : CollectionTree(traceElements, context, myBuilder, debugName) {
private val myXValue2TraceElement: MutableMap<XValueContainer, TraceElement> = HashMap()
private val itemsCount : Int = traceElements.size
init {
val root = XValueNodeImpl(this, null, "root", MyTraceElementsRoot(traceElements, launcher))
val root = XValueNodeImpl(this, null, "root", MyTraceElementsRoot(traceElements, context))
setRoot(root, false)
root.isLeaf = false
@@ -51,12 +56,12 @@ class IntermediateTree(
private inner class MyTraceElementsRoot(
private val myTraceElements: List<TraceElement>,
private val myDebuggerCommandLauncher: DebuggerCommandLauncher,
private val myEvaluationContext: GenericEvaluationContext,
) : XValue() {
override fun computeChildren(node: XCompositeNode) {
val children = XValueChildrenList()
for (value in myTraceElements) {
val namedValue = myBuilder.createXNamedValue(value.value, myDebuggerCommandLauncher)
val namedValue = myBuilder.createXNamedValue(value.value, myEvaluationContext)
myXValue2TraceElement[namedValue] = value
children.add(namedValue)
}
@@ -3,6 +3,7 @@ package com.intellij.debugger.streams.core.ui.impl
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.ui.TraceController
/**
@@ -10,8 +11,9 @@ import com.intellij.debugger.streams.core.ui.TraceController
*/
class StreamTracesMappingView(
launcher: DebuggerCommandLauncher,
context: GenericEvaluationContext,
prevController: TraceController,
nextController: TraceController,
builder: CollectionTreeBuilder,
debugName: String
) : FlatView(listOf(prevController, nextController), launcher, builder, debugName)
) : FlatView(listOf(prevController, nextController), launcher, context, builder, debugName)
@@ -2,12 +2,17 @@ package com.intellij.debugger.streams.core.ui.impl
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.TraceElement
import com.intellij.debugger.streams.core.trace.Value
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.EDT
import com.intellij.util.ObjectUtils
import com.intellij.xdebugger.frame.*
import com.intellij.xdebugger.frame.XCompositeNode
import com.intellij.xdebugger.frame.XValue
import com.intellij.xdebugger.frame.XValueChildrenList
import com.intellij.xdebugger.frame.XValueNode
import com.intellij.xdebugger.frame.XValuePlace
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeListener
import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode
@@ -20,14 +25,15 @@ class TerminationTree(
streamResult : Value,
traceElements: List<TraceElement>,
launcher: DebuggerCommandLauncher,
context: GenericEvaluationContext,
private val myBuilder: CollectionTreeBuilder,
@Suppress("CanBeParameter") private val debugName: String,
) : CollectionTree(traceElements, launcher, myBuilder, debugName) {
) : CollectionTree(traceElements, context, myBuilder, debugName) {
private val NULL_MARKER: Any = ObjectUtils.sentinel("CollectionTree.NULL_MARKER")
init {
val root = XValueNodeImpl(this, null, "root", MyValueRoot(streamResult, launcher))
val root = XValueNodeImpl(this, null, "root", MyValueRoot(streamResult, context))
setRoot(root, false)
root.isLeaf = false
@@ -76,10 +82,10 @@ class TerminationTree(
})
}
private inner class MyValueRoot(private val myValue: Value, private val myDebuggerCommandLauncher: DebuggerCommandLauncher) : XValue() {
private inner class MyValueRoot(private val myValue: Value, private val myContext: GenericEvaluationContext) : XValue() {
override fun computeChildren(node: XCompositeNode) {
val children = XValueChildrenList()
children.add(myBuilder.createXNamedValue(myValue, myDebuggerCommandLauncher))
children.add(myBuilder.createXNamedValue(myValue, myContext))
node.addChildren(children, true)
}
@@ -3,10 +3,13 @@ package com.intellij.debugger.streams.lib.impl
import com.intellij.debugger.streams.core.lib.LibrarySupportProvider
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.XValueInterpreter
import com.intellij.debugger.streams.trace.impl.JavaDebuggerCommandLauncher
import com.intellij.debugger.streams.trace.impl.JavaValueInterpreter
import com.intellij.debugger.streams.ui.impl.JavaCollectionTreeBuilder
import com.intellij.openapi.project.Project
import com.intellij.xdebugger.XDebugSession
abstract class JvmLibrarySupportProvider : LibrarySupportProvider {
companion object {
@@ -16,4 +19,8 @@ abstract class JvmLibrarySupportProvider : LibrarySupportProvider {
override fun getXValueInterpreter(project: Project): XValueInterpreter = interpreter
override fun getCollectionTreeBuilder(project: Project): CollectionTreeBuilder = JavaCollectionTreeBuilder(project)
override fun getDebuggerCommandLauncher(session: XDebugSession): DebuggerCommandLauncher {
return JavaDebuggerCommandLauncher(session)
}
}
@@ -1,18 +1,16 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.streams.trace.impl
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.engine.JavaDebugProcess
import com.intellij.debugger.engine.executeOnDMT
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.openapi.project.Project
import com.intellij.xdebugger.XDebugSession
import kotlinx.coroutines.CoroutineScope
class JavaDebuggerCommandLauncher(val context: EvaluationContextImpl) : DebuggerCommandLauncher {
override val project: Project
get() = context.project
class JavaDebuggerCommandLauncher(val session: XDebugSession) : DebuggerCommandLauncher {
override fun launchDebuggerCommand(command: suspend CoroutineScope.() -> Unit) {
// runs in debugger manager thread only while SuspendContext is not resumed
executeOnDMT(context.suspendContext, block = command)
val debuggerContext = (session.debugProcess as JavaDebugProcess).debuggerSession.contextManager.context
executeOnDMT(debuggerContext, block = command)
}
}
@@ -3,18 +3,26 @@ package com.intellij.debugger.streams.trace.impl
import com.intellij.debugger.engine.DebuggerUtils
import com.intellij.debugger.engine.JavaValue
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.streams.core.StreamDebuggerBundle
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.XValueInterpreter
import com.intellij.openapi.project.Project
import com.intellij.psi.CommonClassNames
import com.intellij.xdebugger.XDebugSession
import com.intellij.xdebugger.frame.XValue
class JavaEvaluationContext(val context: EvaluationContextImpl) : GenericEvaluationContext {
override val project: Project
get() = context.project
}
class JavaValueInterpreter : XValueInterpreter {
override suspend fun extract(session: XDebugSession, result: XValue): XValueInterpreter.Result {
if (result is JavaValue) {
val reference = result.descriptor.getValue()
if (reference is com.sun.jdi.ArrayReference) {
return XValueInterpreter.Result.Array(JvmArrayReference(reference), hasInnerExceptions(reference), JavaDebuggerCommandLauncher(result.evaluationContext))
return XValueInterpreter.Result.Array(JvmArrayReference(reference), hasInnerExceptions(reference), JavaEvaluationContext(result.evaluationContext))
} else if (reference is com.sun.jdi.ObjectReference) {
val type = reference.referenceType()
var classType = type as? com.sun.jdi.ClassType
@@ -5,10 +5,10 @@ import com.intellij.debugger.engine.JavaValue
import com.intellij.debugger.engine.evaluation.EvaluationContext
import com.intellij.debugger.memory.utils.InstanceJavaValue
import com.intellij.debugger.streams.core.trace.CollectionTreeBuilder
import com.intellij.debugger.streams.core.trace.DebuggerCommandLauncher
import com.intellij.debugger.streams.core.trace.GenericEvaluationContext
import com.intellij.debugger.streams.core.trace.TraceElement
import com.intellij.debugger.streams.core.trace.Value
import com.intellij.debugger.streams.trace.impl.JavaDebuggerCommandLauncher
import com.intellij.debugger.streams.trace.impl.JavaEvaluationContext
import com.intellij.debugger.streams.trace.impl.JvmValue
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl
import com.intellij.debugger.ui.impl.watch.MessageDescriptor
@@ -37,10 +37,10 @@ class JavaCollectionTreeBuilder(val project: Project) : CollectionTreeBuilder {
}
}
override fun createXNamedValue(value: Value?, launcher: DebuggerCommandLauncher): XNamedValue {
override fun createXNamedValue(value: Value?, evaluationContext: GenericEvaluationContext): XNamedValue {
val jvmValue : com.sun.jdi.Value? = (value as? JvmValue)?.value
val valueDescriptor = PrimitiveValueDescriptor(project, jvmValue)
return InstanceJavaValue(valueDescriptor, (launcher as JavaDebuggerCommandLauncher).context, nodeManager)
return InstanceJavaValue(valueDescriptor, (evaluationContext as JavaEvaluationContext).context, nodeManager)
}
override fun getKey(container: XValueContainer, nullMarker: Any): Any {