[rd debugger] New splitted FreezeThreadAction based on XDebuggerTree (RPC)

IJPL-199588

GitOrigin-RevId: efa58ccba991bb3eaced63acdd4786058f1dc5ec
This commit is contained in:
Maria Sokolova
2025-08-01 11:11:15 +00:00
committed by intellij-monorepo-bot
parent 5e7196bea7
commit 865332c873
7 changed files with 74 additions and 4 deletions
@@ -67,6 +67,10 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
invokeThreadCommand(executionStackId, ThreadCommand.RESUME)
}
override suspend fun freezeThread(executionStackId: XExecutionStackId) {
invokeThreadCommand(executionStackId, ThreadCommand.FREEZE)
}
private fun invokeThreadCommand(executionStackId: XExecutionStackId, command: ThreadCommand) {
val executionStackModel = executionStackId.findValue() ?: return
val xSession = executionStackModel.session
@@ -83,8 +87,12 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
ThreadCommand.RESUME -> {
ResumeThreadAction.resumeThread(threadProxy, debugProcess, managerThread)
}
ThreadCommand.FREEZE -> {
FreezeThreadAction.freezeThread(threadProxy, debugProcess, managerThread)
}
}
}
companion object {
private enum class ThreadCommand { FREEZE, RESUME }
}
@@ -37,7 +37,8 @@ button.drop.anyway=Do Not Execute
button.execute.finally=Execute Finally Blocks
drop.frame.error.no.information=Information about the frame is not available
progress.evaluating=Evaluating {0}
action.resume.thread.text.resume=Resume
action.resume.thread.text=Resume
action.freeze.thread.text=Freeze
action.interrupt.thread.text=Interrupt
title.set.value=Set Value
warning.recalculate=The value will be recalculated
@@ -25,6 +25,9 @@
<action id="Debugger.XThreadsView.ResumeThread" class="com.intellij.java.debugger.impl.shared.actions.ResumeThreadAction">
<add-to-group group-id="XDebugger.Threads.View.Popup"/>
</action>
<action id="Debugger.XThreadsView.FreezeThread" class="com.intellij.java.debugger.impl.shared.actions.FreezeThreadAction">
<add-to-group group-id="XDebugger.Threads.View.Popup"/>
</action>>
<action class="com.intellij.debugger.memory.action.ShowInstancesByClassAction"
id="MemoryView.ShowInstancesFromDebuggerTree">
<add-to-group group-id="XDebugger.ValueGroup" anchor="after"
@@ -6,4 +6,6 @@ action.show.objects.text=Show {0} Objects\u2026
action.MemoryView.ShowInstancesFromDebuggerTree.text=Show Instances
action.Memory.CalculateRetainedSize.text=Calculate Retained Size\u2026
action.resume.thread.text=Resume
action.Debugger.XThreadsView.ResumeThread.text=Resume
action.freeze.thread.text=Freeze
action.Debugger.XThreadsView.ResumeThread.text=Resume
action.Debugger.XThreadsView.FreezeThread.text=Freeze
@@ -0,0 +1,50 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.debugger.impl.shared.actions
import com.intellij.java.debugger.impl.shared.JavaDebuggerSharedBundle
import com.intellij.java.debugger.impl.shared.rpc.JavaDebuggerSessionApi
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification
import com.intellij.xdebugger.impl.frame.XDebugManagerProxy
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl
import kotlinx.coroutines.launch
private class FreezeThreadAction : XDebuggerTreeActionBase(), ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
override fun perform(node: XValueNodeImpl?, nodeName: String, e: AnActionEvent) {
if (node == null) return
val project = e.project
if (project == null) {
return
}
val sessionProxy = DebuggerUIUtil.getSessionProxy(e) ?: return
sessionProxy.coroutineScope.launch {
val executionStack = node.executionStackOrNull ?: return@launch
XDebugManagerProxy.getInstance().withId(executionStack, sessionProxy) { xExecutionStackId ->
JavaDebuggerSessionApi.getInstance().freezeThread(xExecutionStackId)
}
sessionProxy.rebuildViews()
}
}
override fun update(e: AnActionEvent) {
val selectedNodes = getSelectedNodes(e.dataContext)
e.presentation.apply {
isEnabledAndVisible = false
if (DebuggerUIUtil.getSessionProxy(e) == null) {
return
}
if (selectedNodes.isNotEmpty() && selectedNodes.all { it.isNotSuspendedJavaThread() }) {
text = JavaDebuggerSharedBundle.message("action.freeze.thread.text")
isEnabledAndVisible = true
}
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
}
@@ -28,6 +28,8 @@ interface JavaDebuggerSessionApi : RemoteApi<Unit> {
suspend fun resumeThread(executionStackId: XExecutionStackId)
suspend fun freezeThread(executionStackId: XExecutionStackId)
companion object {
@JvmStatic
suspend fun getInstance(): JavaDebuggerSessionApi {
@@ -3,6 +3,9 @@
<group id="XDebugger.Frames.Tree.Popup.Frontend">
<reference ref="Debugger.PopFrame"/>
</group>
<group id="XDebugger.Threads.View.Popup">
<reference ref="Debugger.PopFrame"/>
</group>
<group id="XDebugger.Inspect.Tree.Popup.Frontend">
<group id="XDebugger.Inspect.Tree.Popup.Top.Section.Frontend"/>
<separator/>
@@ -120,6 +123,7 @@
<synonym key="action.Debugger.ThawSelectedThreads.synonym"/>
</action>
<action id="Debugger.ShowLibraryFrames" class="com.intellij.xdebugger.impl.actions.ShowLibraryFramesAction"/>
<action id="Debugger.CopyStack" class="com.intellij.xdebugger.impl.frame.XDebuggerFramesList$CopyStackAction" icon="AllIcons.Actions.Copy"/>
</group>
<group id="XDebugger.ToolWindow.TopToolbar">
@@ -195,9 +199,9 @@
<group id="XDebugger.Frames.Tree.Popup">
<reference ref="Debugger.PopFrame" />
<action id="Debugger.CopyStack" class="com.intellij.xdebugger.impl.frame.XDebuggerFramesList$CopyStackAction" icon="AllIcons.Actions.Copy">
<reference ref="Debugger.CopyStack">
<add-to-group group-id="XDebugger.Frames.Tree.Popup.Frontend"/>
</action>
</reference>
</group>
<group id="XDebugger.Frames.TopToolbar">