From 89943cda17f6fec8f66d18b893116be2865960da Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 1 Aug 2017 20:40:53 +0300 Subject: [PATCH] allow to change the current frame and thread from the threads view --- .../actions/GotoFrameSourceAction.java | 40 ++++++++++++++----- .../debugger/engine/JavaExecutionStack.java | 9 +++-- .../debugger/engine/JavaStackFrame.java | 17 ++++++++ .../debugger/ui/impl/ThreadsPanel.java | 31 +++++--------- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java index e127596ec3b5..39a867bececd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,25 @@ */ package com.intellij.debugger.actions; -import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaExecutionStack; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.SuspendManagerUtil; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; /** * @author lex @@ -32,16 +44,26 @@ public abstract class GotoFrameSourceAction extends DebuggerAction{ doAction(dataContext); } - protected static void doAction(DataContext dataContext) { + public static void doAction(DataContext dataContext) { final Project project = CommonDataKeys.PROJECT.getData(dataContext); if(project == null) return; StackFrameDescriptorImpl stackFrameDescriptor = getStackFrameDescriptor(dataContext); - if(stackFrameDescriptor != null) { - //DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getFrameProxy()); - SourcePosition sourcePosition = stackFrameDescriptor.getSourcePosition(); - if (sourcePosition != null) { - sourcePosition.navigate(true); - } + XDebugSession session = XDebugSession.DATA_KEY.getData(dataContext); + if (stackFrameDescriptor != null && session != null) { + StackFrameProxyImpl frameProxy = stackFrameDescriptor.getFrameProxy(); + DebugProcessImpl process = (DebugProcessImpl)stackFrameDescriptor.getDebugProcess(); + process.getManagerThread().schedule(new SuspendContextCommandImpl((SuspendContextImpl)session.getSuspendContext()) { + @Override + public void contextAction(@NotNull SuspendContextImpl suspendContext) throws Exception { + ThreadReferenceProxyImpl threadProxy = frameProxy.threadProxy(); + SuspendContextImpl threadSuspendContext = SuspendManagerUtil.findContextByThread(process.getSuspendManager(), threadProxy); + JavaExecutionStack executionStack = + new JavaExecutionStack(threadProxy, process, Objects.equals(threadSuspendContext.getThread(), threadProxy)); + executionStack.initTopFrame(); + XStackFrame frame = executionStack.createStackFrame(frameProxy); + DebuggerUIUtil.invokeLater(() -> session.setCurrentStackFrame(executionStack, frame)); + } + }); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java index d5886c161605..61f2027fa1ae 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java @@ -88,7 +88,7 @@ public class JavaExecutionStack extends XExecutionStack { try { StackFrameProxyImpl frame = myThreadProxy.frame(0); if (frame != null) { - myTopFrame = createStackFrame(frame, myTracker); + myTopFrame = createStackFrame(frame); } } catch (EvaluateException e) { @@ -99,8 +99,9 @@ public class JavaExecutionStack extends XExecutionStack { } } - private static XStackFrame createStackFrame(@NotNull StackFrameProxyImpl stackFrameProxy, @NotNull MethodsTracker tracker) { - StackFrameDescriptorImpl descriptor = new StackFrameDescriptorImpl(stackFrameProxy, tracker); + @NotNull + public XStackFrame createStackFrame(@NotNull StackFrameProxyImpl stackFrameProxy) { + StackFrameDescriptorImpl descriptor = new StackFrameDescriptorImpl(stackFrameProxy, myTracker); DebugProcessImpl debugProcess = (DebugProcessImpl)descriptor.getDebugProcess(); Location location = descriptor.getLocation(); if (location != null) { @@ -193,7 +194,7 @@ public class JavaExecutionStack extends XExecutionStack { } else { frameProxy = myStackFramesIterator.next(); - frame = createStackFrame(frameProxy, myTracker); + frame = createStackFrame(frameProxy); if (first && !myTopFrameReady) { myTopFrame = frame; myTopFrameReady = true; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java index 83a110020e16..ac7883b227cb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -706,4 +706,21 @@ public class JavaStackFrame extends XStackFrame implements JVMStackFrameInfoProv public boolean isInLibraryContent() { return myDescriptor.isInLibraryContent(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JavaStackFrame frame = (JavaStackFrame)o; + + if (!myDescriptor.getFrameProxy().equals(frame.myDescriptor.getFrameProxy())) return false; + + return true; + } + + @Override + public int hashCode() { + return myDescriptor.getFrameProxy().hashCode(); + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java index b2ea6c8dc193..921123727c4f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,18 @@ package com.intellij.debugger.ui.impl; import com.intellij.debugger.actions.DebuggerAction; import com.intellij.debugger.actions.DebuggerActions; +import com.intellij.debugger.actions.GotoFrameSourceAction; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.events.DebuggerCommandImpl; -import com.intellij.debugger.impl.*; -import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerContextListener; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerStateManager; import com.intellij.debugger.ui.impl.watch.DebuggerTree; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; -import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; -import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionPopupMenu; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -57,13 +56,7 @@ public class ThreadsPanel extends DebuggerTreePanel{ @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER && getThreadsTree().getSelectionCount() == 1) { - DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)getThreadsTree().getLastSelectedPathComponent(); - if (node != null) { - NodeDescriptorImpl descriptor = node.getDescriptor(); - if (descriptor instanceof StackFrameDescriptorImpl) { - selectFrame(node); - } - } + GotoFrameSourceAction.doAction(DataManager.getInstance().getDataContext(getThreadsTree())); } } }); @@ -171,12 +164,6 @@ public class ThreadsPanel extends DebuggerTreePanel{ } return super.getData(dataId); } - - private void selectFrame(DebuggerTreeNodeImpl node) { - StackFrameProxyImpl frame = ((StackFrameDescriptorImpl)node.getDescriptor()).getFrameProxy(); - DebuggerContextUtil.setStackFrame(getContextManager(), frame); - } - public ThreadsDebuggerTree getThreadsTree() { return (ThreadsDebuggerTree) getTree(); }