From e6485e2535876cd83718bb5b1dcb146cb91679d8 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Wed, 21 Oct 2020 00:57:36 +0300 Subject: [PATCH] [memory-agent] IDEA-253276 Broken default behaviour of "Show referring objects" action in case of recursion GitOrigin-RevId: d4984649ad124923ab30a4a92c1e89db842f18c0 --- .../actions/JavaReferringObjectsValue.java | 8 +++++++- .../xdebugger/frame/XReferrersProvider.java | 7 +++++++ .../actions/ShowReferringObjectsAction.java | 20 +++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java index 8008fb819f23..3a2b9e08f2f9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java @@ -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 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()) { diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java index cb31a3be23b0..07ed26843044 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java @@ -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(); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java index e221e843b6a9..5a61de366211 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java @@ -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));