[rd debugger] IDEA-377609 Move step out of code block to frontend

GitOrigin-RevId: 7dcc5bce46a36ce569f841cfd3292afb829b26ba
This commit is contained in:
Maksim Zuev
2025-08-15 11:22:36 +00:00
committed by intellij-monorepo-bot
parent b9f8a0ca1f
commit 6de58d6684
8 changed files with 59 additions and 43 deletions
@@ -1,17 +1,15 @@
// 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.backend
import com.intellij.debugger.actions.FreezeThreadAction
import com.intellij.debugger.actions.InterruptThreadAction
import com.intellij.debugger.actions.ThreadDumpAction
import com.intellij.debugger.actions.*
import com.intellij.debugger.engine.AsyncStacksUtils
import com.intellij.debugger.engine.JavaDebugProcess
import com.intellij.debugger.engine.JavaExecutionStack
import com.intellij.debugger.engine.executeOnDMT
import com.intellij.execution.filters.ExceptionFilters
import com.intellij.ide.ui.icons.rpcId
import com.intellij.debugger.actions.ResumeThreadAction
import com.intellij.java.debugger.impl.shared.rpc.*
import com.intellij.openapi.application.EDT
import com.intellij.platform.debugger.impl.rpc.toRpc
import com.intellij.unscramble.CompoundDumpItem
import com.intellij.unscramble.DumpItem
@@ -19,13 +17,10 @@ import com.intellij.xdebugger.impl.rpc.XDebugSessionId
import com.intellij.xdebugger.impl.rpc.XExecutionStackId
import com.intellij.xdebugger.impl.rpc.models.findValue
import fleet.util.channels.use
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.launch
internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
@OptIn(ExperimentalCoroutinesApi::class)
@@ -64,6 +59,13 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
AsyncStacksUtils.setAsyncStacksEnabled(session, state)
}
override suspend fun stepOutOfCodeBlock(sessionId: XDebugSessionId) {
val xSession = sessionId.findValue() ?: return
withContext(Dispatchers.EDT) {
StepOutOfBlockActionUtils.stepOutOfBlock(xSession)
}
}
override suspend fun resumeThread(executionStackId: XExecutionStackId) {
invokeThreadCommand(executionStackId, ThreadCommand.RESUME)
}
@@ -288,12 +288,6 @@
<add-to-group group-id="XDebugger.Frames.Tree.Popup.Frontend"/>
</action>
<action id="Debugger.StepOutOfBlock" class="com.intellij.debugger.actions.StepOutOfBlockAction"
icon="AllIcons.Actions.StepOutCodeBlock">
<add-to-group group-id="DebuggingActionsGroup" anchor="after" relative-to-action="StepOut"/>
<add-to-group group-id="XDebugger.ToolWindow.TopToolbar3.Extra" anchor="after" relative-to-action="SmartStepInto"/>
</action>
<action id="Debugger.CreateRenderer" class="com.intellij.debugger.actions.CreateRendererAction">
<add-to-group group-id="XDebugger.Watches.Inline.Popup" anchor="last"/>
<override-text place="XDebuggerTreePopup"/>
@@ -7,11 +7,8 @@ import com.intellij.debugger.engine.JavaDebugProcess;
import com.intellij.debugger.engine.MethodFilter;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiElement;
@@ -21,21 +18,13 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Range;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.sun.jdi.Location;
import com.sun.jdi.request.StepRequest;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
public class StepOutOfBlockAction extends DebuggerAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
XDebugSession session = DebuggerUIUtil.getSession(e);
if (session != null) {
doStepOutOfBlock(session);
}
}
@ApiStatus.Internal
public final class StepOutOfBlockActionUtils {
private static void doStepOutOfBlock(@NotNull XDebugSession xSession) {
XDebugProcess process = xSession.getDebugProcess();
@@ -65,23 +54,11 @@ public class StepOutOfBlockAction extends DebuggerAction implements DumbAware {
xSession.stepOut();
}
@TestOnly
@ApiStatus.Internal
public static void stepOutOfBlock(@NotNull XDebugSession xSession) {
doStepOutOfBlock(xSession);
}
@Override
public void update(@NotNull AnActionEvent e) {
XDebugSession session = DebuggerUIUtil.getSession(e);
e.getPresentation().setEnabledAndVisible(session != null && session.getDebugProcess() instanceof JavaDebugProcess &&
!((XDebugSessionImpl)session).isReadOnly() && session.isSuspended());
}
@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
private static final class BlockFilter implements MethodFilter {
private final Range<Integer> myLines;
@@ -22,6 +22,11 @@
<add-to-group group-id="DebuggingActionsGroup" anchor="last"/>
<add-to-group group-id="XDebugger.ToolWindow.TopToolbar3.Extra"/>
</action>
<action id="Debugger.StepOutOfBlock" class="com.intellij.java.debugger.impl.shared.actions.StepOutOfBlockAction"
icon="AllIcons.Actions.StepOutCodeBlock">
<add-to-group group-id="DebuggingActionsGroup" anchor="after" relative-to-action="StepOut"/>
<add-to-group group-id="XDebugger.ToolWindow.TopToolbar3.Extra" anchor="after" relative-to-action="SmartStepInto"/>
</action>
<action id="Debugger.XThreadsView.ResumeThread" class="com.intellij.java.debugger.impl.shared.actions.ResumeThreadAction">
<add-to-group group-id="XDebugger.Threads.View.Popup"/>
</action>
@@ -9,4 +9,5 @@ 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.InterruptThread.text=Interrupt
action.Debugger.XThreadsView.InterruptThread.text=Interrupt
action.Debugger.StepOutOfBlock.text=Step Out of Code Block
@@ -0,0 +1,36 @@
// 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.SharedJavaDebuggerManager
import com.intellij.java.debugger.impl.shared.rpc.JavaDebuggerSessionApi
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification
import com.intellij.openapi.project.DumbAware
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
import kotlinx.coroutines.launch
private class StepOutOfBlockAction : AnAction(), DumbAware, ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
override fun actionPerformed(e: AnActionEvent) {
val sessionProxy = DebuggerUIUtil.getSessionProxy(e) ?: return
sessionProxy.coroutineScope.launch {
JavaDebuggerSessionApi.getInstance().stepOutOfCodeBlock(sessionProxy.id)
}
}
override fun update(e: AnActionEvent) {
val sessionProxy = DebuggerUIUtil.getSessionProxy(e)
val project = e.project
if (sessionProxy == null || project == null) {
e.presentation.isEnabledAndVisible = false
return
}
val javaSession = SharedJavaDebuggerManager.getInstance(project).getJavaSession(sessionProxy.id)
e.presentation.isEnabledAndVisible = javaSession != null && !sessionProxy.isReadOnly && sessionProxy.isSuspended
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
@@ -32,6 +32,8 @@ interface JavaDebuggerSessionApi : RemoteApi<Unit> {
suspend fun interruptThread(executionStackId: XExecutionStackId)
suspend fun stepOutOfCodeBlock(sessionId: XDebugSessionId)
companion object {
@JvmStatic
suspend fun getInstance(): JavaDebuggerSessionApi {
@@ -314,7 +314,6 @@ action.Actions.ActionsPlugin.GenerateToString.description=Generate toString() me
action.Debugger.ShowRelatedStack.text=Show related stack\u2026
action.Debugger.ShowTypes.text=Show types
action.Debugger.AddSteppingFilter.text=Add Stepping Filter\u2026
action.Debugger.StepOutOfBlock.text=Step Out of Code Block
action.Debugger.CreateRenderer.text=Create\u2026
action.Debugger.CreateRenderer.XDebuggerTreePopup.text=Create Renderer
action.Debugger.XDebuggerTextPopup.ShowAsObject.text=Show as Object