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

IJPL-199588

GitOrigin-RevId: a9219adad73166727304b1179a5b2ad1159ba16d
This commit is contained in:
Maria Sokolova
2025-08-01 11:11:15 +00:00
committed by intellij-monorepo-bot
parent 314bc94f0f
commit e1f6355aab
6 changed files with 71 additions and 5 deletions
@@ -2,6 +2,7 @@
package com.intellij.java.debugger.impl.backend
import com.intellij.debugger.actions.FreezeThreadAction
import com.intellij.debugger.actions.InterruptThreadAction
import com.intellij.debugger.actions.ThreadDumpAction
import com.intellij.debugger.engine.AsyncStacksUtils
import com.intellij.debugger.engine.JavaDebugProcess
@@ -71,6 +72,10 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
invokeThreadCommand(executionStackId, ThreadCommand.FREEZE)
}
override suspend fun interruptThread(executionStackId: XExecutionStackId) {
invokeThreadCommand(executionStackId, ThreadCommand.INTERRUPT)
}
private fun invokeThreadCommand(executionStackId: XExecutionStackId, command: ThreadCommand) {
val executionStackModel = executionStackId.findValue() ?: return
val xSession = executionStackModel.session
@@ -90,11 +95,14 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
ThreadCommand.FREEZE -> {
FreezeThreadAction.freezeThread(threadProxy, debugProcess, managerThread)
}
ThreadCommand.INTERRUPT -> {
InterruptThreadAction.interruptThread(threadProxy, debugProcess, managerThread)
}
}
}
companion object {
private enum class ThreadCommand { FREEZE, RESUME }
private enum class ThreadCommand { FREEZE, RESUME, INTERRUPT }
}
}
@@ -12,9 +12,10 @@ import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.ui.MessageType
import com.intellij.xdebugger.impl.XDebuggerManagerImpl
import java.util.*
import org.jetbrains.annotations.ApiStatus
internal class InterruptThreadAction : DebuggerAction() {
@ApiStatus.Internal
class InterruptThreadAction : DebuggerAction() {
override fun actionPerformed(e: AnActionEvent) {
val nodes = getSelectedNodes(e.dataContext)
if (nodes == null) {
@@ -27,7 +27,10 @@
</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>
<action id="Debugger.XThreadsView.InterruptThread" class="com.intellij.java.debugger.impl.shared.actions.InterruptThreadAction">
<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"
@@ -8,4 +8,5 @@ action.Memory.CalculateRetainedSize.text=Calculate Retained Size\u2026
action.resume.thread.text=Resume
action.freeze.thread.text=Freeze
action.Debugger.XThreadsView.ResumeThread.text=Resume
action.Debugger.XThreadsView.FreezeThread.text=Freeze
action.Debugger.XThreadsView.FreezeThread.text=Freeze
action.Debugger.XThreadsView.InterruptThread.text=Interrupt
@@ -0,0 +1,51 @@
// 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 InterruptThreadAction : 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
if (!node.isSuspendedJavaThread()) {
sessionProxy.coroutineScope.launch {
val executionStack = node.executionStackOrNull ?: return@launch
XDebugManagerProxy.getInstance().withId(executionStack, sessionProxy) { xExecutionStackId ->
JavaDebuggerSessionApi.getInstance().interruptThread(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.Debugger.XThreadsView.InterruptThread.text")
isEnabledAndVisible = true
}
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
}
@@ -30,6 +30,8 @@ interface JavaDebuggerSessionApi : RemoteApi<Unit> {
suspend fun freezeThread(executionStackId: XExecutionStackId)
suspend fun interruptThread(executionStackId: XExecutionStackId)
companion object {
@JvmStatic
suspend fun getInstance(): JavaDebuggerSessionApi {