[memory-agent] IDEA-253276 Broken default behaviour of "Show referring objects" action in case of recursion

GitOrigin-RevId: d4984649ad124923ab30a4a92c1e89db842f18c0
This commit is contained in:
Vitaliy.Bibaev
2020-10-20 22:08:54 +00:00
committed by intellij-monorepo-bot
parent 5b5caf37a3
commit e6485e2535
3 changed files with 30 additions and 5 deletions
@@ -9,6 +9,7 @@ import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.memory.agent.MemoryAgentPathsToClosestGCRootsProvider;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.xdebugger.frame.*;
@@ -21,7 +22,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.Function;
public class JavaReferringObjectsValue extends JavaValue {
public class JavaReferringObjectsValue extends JavaValue implements XReferrersProvider.ShortestPathAware {
private static final long MAX_REFERRING = 100;
private final ReferringObjectsProvider myReferringObjectsProvider;
private final Function<? super XValueNode, ? extends XValueNode> myNodeConfigurator;
@@ -56,6 +57,11 @@ public class JavaReferringObjectsValue extends JavaValue {
};
}
@Override
public boolean isShortestPathAvailable() {
return myReferringObjectsProvider instanceof MemoryAgentPathsToClosestGCRootsProvider;
}
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
scheduleCommand(getEvaluationContext(), node, new SuspendContextCommandImpl(getEvaluationContext().getSuspendContext()) {
@@ -22,4 +22,11 @@ package com.intellij.xdebugger.frame;
*/
public abstract class XReferrersProvider {
public abstract XValue getReferringObjectsValue();
public interface ShortestPathAware {
/**
* @return true if first referrers lead to the closest GC root
*/
boolean isShortestPathAvailable();
}
}
@@ -2,18 +2,22 @@
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.frame.XReferrersProvider;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.TreeNode;
public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
private static final Logger LOG = Logger.getInstance(ShowReferringObjectsAction.class);
@Override
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return node.getValueContainer().getReferrersProvider() != null;
@@ -26,15 +30,23 @@ public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
XDebuggerTree tree = node.getTree();
XDebugSession session = XDebuggerManager.getInstance(tree.getProject()).getCurrentSession();
if (session != null) {
XValue referringObjectsRoot = referrersProvider.getReferringObjectsValue();
XInspectDialog dialog = new XInspectDialog(tree.getProject(),
tree.getEditorsProvider(),
tree.getSourcePosition(),
nodeName,
referrersProvider.getReferringObjectsValue(),
referringObjectsRoot,
tree.getValueMarkers(), session, false);
XDebuggerTree dialogTree = (XDebuggerTree)dialog.getPreferredFocusedComponent();
if (dialogTree != null) {
dialogTree.expandNodesOnLoad(treeNode -> isInTopSubTree(treeNode));
JComponent debuggerTree = dialog.getPreferredFocusedComponent();
if (debuggerTree instanceof XDebuggerTree) {
if (referringObjectsRoot instanceof XReferrersProvider.ShortestPathAware) {
if (((XReferrersProvider.ShortestPathAware)referringObjectsRoot).isShortestPathAvailable()) {
((XDebuggerTree)debuggerTree).expandNodesOnLoad(treeNode -> isInTopSubTree(treeNode));
}
}
}
else {
LOG.error("debugger tree unavailable");
}
dialog.setTitle(XDebuggerBundle.message("showReferring.dialog.title", nodeName));