fixed loosing watches expansion after a step
authorEgor.Ushakov <egor.ushakov@jetbrains.com>
Thu, 17 Mar 2016 09:59:30 +0000 (12:59 +0300)
committerEgor.Ushakov <egor.ushakov@jetbrains.com>
Thu, 17 Mar 2016 10:45:26 +0000 (13:45 +0300)
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java

index 857bd9fc3f06749d6de4d38f28b01117d498c296..0f1eb9c4e077db712c74a52656280a6f550c9ed8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -32,7 +32,7 @@ import com.intellij.xdebugger.XSourcePosition;
 import com.intellij.xdebugger.frame.XStackFrame;
 import com.intellij.xdebugger.impl.XDebugSessionImpl;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
 import gnu.trove.THashMap;
 import org.jetbrains.annotations.NonNls;
@@ -45,8 +45,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
-import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createInfoMessage;
-
 /**
  * @author nik
  */
@@ -102,22 +100,27 @@ public class XVariablesView extends XVariablesViewBase implements DataProvider {
     tree.updateEditor();
   }
 
+  protected void addEmptyMessage(XValueContainerNode root) {
+    XDebugSession session = getSession(getPanel());
+    if (session != null) {
+      if (!session.isStopped() && session.isPaused()) {
+        root.setInfoMessage("Frame is not available", null);
+      }
+      else {
+        XDebugProcess debugProcess = session.getDebugProcess();
+        root.setInfoMessage(debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
+      }
+    }
+  }
+
   @Override
   protected void clear() {
     XDebuggerTree tree = getTree();
     tree.setSourcePosition(null);
     clearInlineData(tree);
 
-    XDebuggerTreeNode node;
-    XDebugSession session = getSession(getPanel());
-    if (session == null || (!session.isStopped() && session.isPaused())) {
-      node = createInfoMessage(tree, "Frame is not available");
-    }
-    else {
-      XDebugProcess debugProcess = session.getDebugProcess();
-      node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener());
-    }
-    tree.setRoot(node, true);
+    XValueContainerNode root = createNewRootNode(null);
+    addEmptyMessage(root);
     super.clear();
   }
 
index ef2390e44a16b26d9f38a5a58708b27690f6887d..8cae9395e2f5a33d1b5fe638b7e52104685e9a8c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -36,6 +36,7 @@ import com.intellij.xdebugger.evaluation.ExpressionInfo;
 import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
 import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValueContainer;
 import com.intellij.xdebugger.impl.actions.XDebuggerActions;
 import com.intellij.xdebugger.impl.evaluate.quick.XValueHint;
 import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
@@ -43,8 +44,8 @@ import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -73,7 +74,7 @@ public abstract class XVariablesViewBase extends XDebugView {
     XSourcePosition position = stackFrame.getSourcePosition();
     XDebuggerTree tree = getTree();
     tree.setSourcePosition(position);
-    tree.setRoot(buildRootNode(stackFrame), false);
+    createNewRootNode(stackFrame);
     final Project project = tree.getProject();
     project.putUserData(XVariablesView.DEBUG_VARIABLES, new XVariablesView.InlineVariablesInfo());
     project.putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new ObjectLongHashMap<VirtualFile>());
@@ -88,9 +89,16 @@ public abstract class XVariablesViewBase extends XDebugView {
     }
   }
 
-  @NotNull
-  protected XDebuggerTreeNode buildRootNode(@NotNull XStackFrame stackFrame) {
-    return new XStackFrameNode(getTree(), stackFrame);
+  protected XValueContainerNode createNewRootNode(@Nullable XStackFrame stackFrame) {
+    XValueContainerNode root;
+    if (stackFrame == null) {
+      root = new XValueContainerNode<XValueContainer>(getTree(), null, new XValueContainer() {}) {};
+    }
+    else {
+      root = new XStackFrameNode(getTree(), stackFrame);
+    }
+    getTree().setRoot(root, false);
+    return root;
   }
 
   private void registerInlineEvaluator(final XStackFrame stackFrame,
index 1386f7750f936c2c4fb50ded5941d0b513d1721f..f9143bd16fdd305812cc9018f9cce27a92ddac7d 100644 (file)
@@ -49,10 +49,7 @@ import com.intellij.xdebugger.impl.ui.XDebugSessionData;
 import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
 import com.intellij.xdebugger.impl.ui.tree.actions.XWatchTransferable;
-import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import com.intellij.xdebugger.impl.ui.tree.nodes.*;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -82,7 +79,7 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget,
     ActionManager actionManager = ActionManager.getInstance();
 
     XDebuggerTree tree = getTree();
-    tree.setRoot(buildRootNode(null), false);
+    createNewRootNode(null);
     AnAction newWatchAction = actionManager.getAction(XDebuggerActions.XNEW_WATCH);
     AnAction removeWatchAction = actionManager.getAction(XDebuggerActions.XREMOVE_WATCH);
     AnAction copyAction = actionManager.getAction(XDebuggerActions.XCOPY_WATCH);
@@ -269,17 +266,6 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget,
     DnDManager.getInstance().unregisterTarget(this, getTree());
   }
 
-  @Override
-  protected void clear() {
-    XDebuggerTree tree = getTree();
-    XExpression[] expressions = getExpressions();
-    super.clear();
-    if (expressions.length > 0) {
-      myRootNode = new WatchesRootNode(tree, this, expressions, null);
-      tree.setRoot(myRootNode, false);
-    }
-  }
-
   private static boolean isAboveSelectedItem(MouseEvent event, XDebuggerTree watchTree) {
     Rectangle bounds = watchTree.getRowBounds(watchTree.getLeadSelectionRow());
     if (bounds != null) {
@@ -304,7 +290,7 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget,
   @Override
   public void addWatchExpression(@NotNull XExpression expression, int index, final boolean navigateToWatchNode) {
     XDebugSession session = getSession(getTree());
-    myRootNode.addWatchExpression(session != null ? session.getDebugProcess().getEvaluator() : null, expression, index, navigateToWatchNode);
+    myRootNode.addWatchExpression(session != null ? session.getCurrentStackFrame() : null, expression, index, navigateToWatchNode);
     updateSessionData();
     if (navigateToWatchNode && session != null) {
       showWatchesTab((XDebugSessionImpl)session);
@@ -344,14 +330,21 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget,
     super.processSessionEvent(event);
   }
 
-  @NotNull
   @Override
-  protected XDebuggerTreeNode buildRootNode(@Nullable XStackFrame stackFrame) {
+  protected XValueContainerNode createNewRootNode(@Nullable XStackFrame stackFrame) {
     WatchesRootNode node = new WatchesRootNode(getTree(), this, getExpressions(), stackFrame);
     myRootNode = node;
+    getTree().setRoot(node, false);
     return node;
   }
 
+  @Override
+  protected void addEmptyMessage(XValueContainerNode root) {
+    if (Registry.is("debugger.watches.in.variables")) {
+      super.addEmptyMessage(root);
+    }
+  }
+
   @NotNull
   private XExpression[] getExpressions() {
     XDebuggerTree tree = getTree();
index af43106354d9f02382f84c2e2624293d7af3a7ce..0273c045c5c2cb79d8f7d619ee0e4a19ffa5d8f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
 package com.intellij.xdebugger.impl.ui.tree.nodes;
 
 import com.intellij.icons.AllIcons;
+import com.intellij.util.ThreeState;
+import com.intellij.xdebugger.Obsolescent;
 import com.intellij.xdebugger.XExpression;
-import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import com.intellij.xdebugger.evaluation.XInstanceEvaluator;
+import com.intellij.xdebugger.frame.*;
 import com.intellij.xdebugger.frame.presentation.XErrorValuePresentation;
+import com.intellij.xdebugger.frame.presentation.XValuePresentation;
 import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.concurrency.Promise;
 
 import javax.swing.*;
 
@@ -32,9 +38,11 @@ import javax.swing.*;
 public class WatchNodeImpl extends XValueNodeImpl implements WatchNode {
   private final XExpression myExpression;
 
-  public WatchNodeImpl(@NotNull XDebuggerTree tree, @NotNull WatchesRootNode parent,
-                       @NotNull XValue result, @NotNull XExpression expression) {
-    super(tree, parent, expression.getExpression(), result);
+  public WatchNodeImpl(@NotNull XDebuggerTree tree,
+                       @NotNull WatchesRootNode parent,
+                       @NotNull XExpression expression,
+                       @Nullable XStackFrame stackFrame) {
+    super(tree, parent, expression.getExpression(), new XWatchValue(expression, stackFrame));
     myExpression = expression;
   }
 
@@ -50,4 +58,134 @@ public class WatchNodeImpl extends XValueNodeImpl implements WatchNode {
   public XExpression getExpression() {
     return myExpression;
   }
+
+  private static class XWatchValue extends XNamedValue {
+    private final XExpression myExpression;
+    private final XStackFrame myStackFrame;
+    private volatile XValue myValue;
+
+    public XWatchValue(XExpression expression, XStackFrame stackFrame) {
+      super(expression.getExpression());
+      myExpression = expression;
+      myStackFrame = stackFrame;
+    }
+
+    @Override
+    public void computeChildren(@NotNull XCompositeNode node) {
+      if (myValue != null) {
+        myValue.computeChildren(node);
+      }
+    }
+
+    @Override
+    public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
+      if (myStackFrame != null) {
+        XDebuggerEvaluator evaluator = myStackFrame.getEvaluator();
+        if (evaluator != null) {
+          evaluator.evaluate(myExpression, new MyEvaluationCallback(node, place), myStackFrame.getSourcePosition());
+        }
+      }
+      else {
+        node.setPresentation(null, EMPTY_PRESENTATION, false);
+      }
+    }
+
+    private class MyEvaluationCallback extends XEvaluationCallbackBase implements Obsolescent {
+      @NotNull private final XValueNode myNode;
+      @NotNull private final XValuePlace myPlace;
+
+      public MyEvaluationCallback(@NotNull XValueNode node, @NotNull XValuePlace place) {
+        myNode = node;
+        myPlace = place;
+      }
+
+      @Override
+      public boolean isObsolete() {
+        return myNode.isObsolete();
+      }
+
+      @Override
+      public void evaluated(@NotNull XValue result) {
+        myValue = result;
+        result.computePresentation(myNode, myPlace);
+      }
+
+      @Override
+      public void errorOccurred(@NotNull String errorMessage) {
+        myNode.setPresentation(XDebuggerUIConstants.ERROR_MESSAGE_ICON, new XErrorValuePresentation(errorMessage), false);
+      }
+    }
+
+    private static final XValuePresentation EMPTY_PRESENTATION = new XValuePresentation() {
+      @NotNull
+      @Override
+      public String getSeparator() {
+        return "";
+      }
+
+      @Override
+      public void renderValue(@NotNull XValueTextRenderer renderer) {
+      }
+    };
+
+    @Override
+    @Nullable
+    public String getEvaluationExpression() {
+      return myValue != null ? myValue.getEvaluationExpression() : null;
+    }
+
+    @Override
+    @NotNull
+    public Promise<XExpression> calculateEvaluationExpression() {
+      return myValue != null ? myValue.calculateEvaluationExpression() : Promise.reject("Not evaluated yet");
+    }
+
+    @Override
+    @Nullable
+    public XInstanceEvaluator getInstanceEvaluator() {
+      return myValue != null ? myValue.getInstanceEvaluator() : null;
+    }
+
+    @Override
+    @Nullable
+    public XValueModifier getModifier() {
+      return myValue != null ? myValue.getModifier() : null;
+    }
+
+    @Override
+    public void computeSourcePosition(@NotNull XNavigatable navigatable) {
+      if (myValue != null) {
+        myValue.computeSourcePosition(navigatable);
+      }
+    }
+
+    @Override
+    @NotNull
+    public ThreeState computeInlineDebuggerData(@NotNull XInlineDebuggerDataCallback callback) {
+      return ThreeState.NO;
+    }
+
+    @Override
+    public boolean canNavigateToSource() {
+      return myValue != null && myValue.canNavigateToSource();
+    }
+
+    @Override
+    public boolean canNavigateToTypeSource() {
+      return myValue != null && myValue.canNavigateToTypeSource();
+    }
+
+    @Override
+    public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) {
+      if (myValue != null) {
+        myValue.computeTypeSourcePosition(navigatable);
+      }
+    }
+
+    @Override
+    @Nullable
+    public XReferrersProvider getReferrersProvider() {
+      return myValue != null ? myValue.getReferrersProvider() : null;
+    }
+  }
 }
\ No newline at end of file
index 7fc574dd6567e3ea969704d104274d48785235ca..b4d536eb1b9e98d793578f99ea6f0de29b569076 100644 (file)
  */
 package com.intellij.xdebugger.impl.ui.tree.nodes;
 
-import com.intellij.icons.AllIcons;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.tree.TreeUtil;
-import com.intellij.xdebugger.Obsolescent;
 import com.intellij.xdebugger.XDebugSession;
 import com.intellij.xdebugger.XExpression;
 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
-import com.intellij.xdebugger.frame.*;
-import com.intellij.xdebugger.frame.presentation.XErrorValuePresentation;
-import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.frame.XCompositeNode;
+import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValueChildrenList;
+import com.intellij.xdebugger.frame.XValueContainer;
 import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
 import com.intellij.xdebugger.impl.frame.WatchInplaceEditor;
 import com.intellij.xdebugger.impl.frame.XWatchesView;
-import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
-import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.tree.TreeNode;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 import static com.intellij.xdebugger.impl.frame.XDebugView.getSession;
@@ -69,24 +65,13 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
         else {
           node.addChildren(XValueChildrenList.EMPTY, true);
         }
-        XDebuggerEvaluator evaluator = stackFrame == null ? null : stackFrame.getEvaluator();
-        WatchesRootNode thisNode = (WatchesRootNode)node;
-        for (WatchNodeImpl child : thisNode.myChildren) {
-          MyEvaluationCallback callback = new MyEvaluationCallback(child);
-          if (evaluator != null) {
-            evaluator.evaluate(child.getExpression(), callback, stackFrame.getSourcePosition());
-          }
-          else {
-            callback.noSession();
-          }
-        }
       }
     });
     setLeaf(false);
     myWatchesView = watchesView;
     myChildren = ContainerUtil.newArrayList();
     for (XExpression watchExpression : expressions) {
-      myChildren.add(createEvaluatingNode(myTree, this, watchExpression));
+      myChildren.add(new WatchNodeImpl(myTree, this, watchExpression, stackFrame));
     }
   }
 
@@ -114,25 +99,22 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
     myChildren.clear();
   }
 
-  private void replaceNode(WatchNodeImpl oldNode, WatchNodeImpl newNode) {
-    int[] selectedRows = getTree().getSelectionRows();
-    for (int i = 0; i < myChildren.size(); i++) {
-      WatchNodeImpl child = myChildren.get(i);
-      if (child == oldNode) {
-        myChildren.set(i, newNode);
-        fireNodeStructureChanged(newNode);
-        myTree.childrenLoaded(this, Collections.singletonList((XValueContainerNode<?>)newNode), false);
-        getTree().setSelectionRows(selectedRows);
-        return;
-      }
-    }
+  /**
+   * @deprecated Use {@link #addWatchExpression(XStackFrame, XExpression, int, boolean)}
+   */
+  @Deprecated
+  public void addWatchExpression(@Nullable XDebuggerEvaluator evaluator,
+                                 @NotNull XExpression expression,
+                                 int index,
+                                 boolean navigateToWatchNode) {
+    addWatchExpression((XStackFrame)null, expression, index, navigateToWatchNode);
   }
 
-  public void addWatchExpression(final @Nullable XDebuggerEvaluator evaluator,
-                                 final @NotNull XExpression expression,
-                                 int index, final boolean navigateToWatchNode) {
-    WatchNodeImpl message = evaluator != null ? createEvaluatingNode(myTree, this, expression) :
-                            createMessageNode(myTree, this, expression);
+  public void addWatchExpression(@Nullable XStackFrame stackFrame,
+                                 @NotNull XExpression expression,
+                                 int index,
+                                 boolean navigateToWatchNode) {
+    WatchNodeImpl message = new WatchNodeImpl(myTree, this, expression, stackFrame);
     if (index == -1) {
       myChildren.add(message);
       index = myChildren.size() - 1;
@@ -145,9 +127,6 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
     if (navigateToWatchNode) {
       myTree.scrollPathToVisible(message.getPath());
     }
-    if (evaluator != null) {
-      evaluator.evaluate(expression, new MyEvaluationCallback(message), null);
-    }
   }
 
   private void fireNodeInserted(int index) {
@@ -204,7 +183,7 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
     if (index == -1) {
       int selectedIndex = myChildren.indexOf(ArrayUtil.getFirstElement(myTree.getSelectedNodes(WatchNodeImpl.class, null)));
       int targetIndex = selectedIndex == - 1 ? myChildren.size() : selectedIndex + 1;
-      messageNode = createMessageNode(myTree, this, XExpressionImpl.EMPTY_EXPRESSION);
+      messageNode = new WatchNodeImpl(myTree, this, XExpressionImpl.EMPTY_EXPRESSION, null);
       myChildren.add(targetIndex, messageNode);
       fireNodeInserted(targetIndex);
       getTree().setSelectionRows(ArrayUtil.EMPTY_INT_ARRAY);
@@ -215,77 +194,4 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
     XDebugSession session = getSession(myTree);
     new WatchInplaceEditor(this, session, myWatchesView, messageNode, "watch", node).show();
   }
-
-  private static class MyEvaluationCallback extends XEvaluationCallbackBase implements Obsolescent {
-    private final WatchNodeImpl myResultPlace;
-
-    public MyEvaluationCallback(@NotNull WatchNodeImpl resultPlace) {
-      myResultPlace = resultPlace;
-    }
-
-    @Override
-    public boolean isObsolete() {
-      return myResultPlace.isObsolete();
-    }
-
-    @Override
-    public void evaluated(@NotNull final XValue result) {
-      DebuggerUIUtil.invokeLater(() -> {
-        WatchesRootNode root = (WatchesRootNode)myResultPlace.getParent();
-        root.replaceNode(myResultPlace, new WatchNodeImpl(root.myTree, root, result, myResultPlace.getExpression()));
-      });
-    }
-
-    @Override
-    public void errorOccurred(@NotNull final String errorMessage) {
-      DebuggerUIUtil.invokeLater(() -> {
-        WatchesRootNode root = (WatchesRootNode)myResultPlace.getParent();
-        root.replaceNode(myResultPlace, createErrorNode(root.myTree, root, myResultPlace.getExpression(), errorMessage));
-      });
-    }
-
-    public void noSession() {
-      DebuggerUIUtil.invokeLater(() -> {
-        WatchesRootNode root = (WatchesRootNode)myResultPlace.getParent();
-        root.replaceNode(myResultPlace, createMessageNode(root.myTree, root, myResultPlace.getExpression()));
-      });
-    }
-  }
-
-  private static WatchNodeImpl createMessageNode(XDebuggerTree tree, WatchesRootNode parent, XExpression expression) {
-    return new WatchNodeImpl(tree, parent, new XValue() {
-      @Override
-      public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
-        node.setPresentation(AllIcons.Debugger.Watch, new XValuePresentation() {
-          @NotNull
-          @Override
-          public String getSeparator() {
-            return "";
-          }
-
-          @Override
-          public void renderValue(@NotNull XValueTextRenderer renderer) {
-          }
-        }, false);
-      }
-    }, expression);
-  }
-
-  private static WatchNodeImpl createEvaluatingNode(XDebuggerTree tree, WatchesRootNode parent, XExpression expression) {
-    return new WatchNodeImpl(tree, parent, new XValue() {
-      @Override
-      public void computePresentation(@NotNull XValueNode node1, @NotNull XValuePlace place) {
-      }
-    }, expression);
-  }
-
-  private static WatchNodeImpl createErrorNode(XDebuggerTree tree, WatchesRootNode parent,
-                                               @NotNull XExpression expression, @NotNull String errorMessage) {
-    return new WatchNodeImpl(tree, parent, new XValue() {
-      @Override
-      public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
-        node.setPresentation(XDebuggerUIConstants.ERROR_MESSAGE_ICON, new XErrorValuePresentation(errorMessage), false);
-      }
-    }, expression);
-  }
 }
index 7538e676065b9206feaf1014da889b4ef97ebeab..443959f89965fa19749f88dd4fcc260aa30142d3 100644 (file)
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import javax.swing.event.HyperlinkListener;
 import javax.swing.tree.TreeNode;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -175,10 +176,16 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
 
   @Override
   public void setMessage(@NotNull final String message,
-                         final Icon icon, @NotNull final SimpleTextAttributes attributes, @Nullable final XDebuggerTreeNodeHyperlink link) {
+                         final Icon icon,
+                         @NotNull final SimpleTextAttributes attributes,
+                         @Nullable final XDebuggerTreeNodeHyperlink link) {
     invokeNodeUpdate(() -> setMessageNodes(MessageTreeNode.createMessages(myTree, this, message, link, icon, attributes), false));
   }
 
+  public void setInfoMessage(@NotNull String message, @Nullable HyperlinkListener hyperlinkListener) {
+    invokeNodeUpdate(() -> setMessageNodes(Collections.singletonList(MessageTreeNode.createInfoMessage(myTree, message, hyperlinkListener)), false));
+  }
+
   private void setTemporaryMessageNode(final MessageTreeNode messageNode) {
     setMessageNodes(Collections.singletonList(messageNode), true);
   }
index 5812b1c1eaa34d1edb7c5d12c730aa2ba60c6472..ac6032161ce19178f67388c0beca66af0041b99a 100644 (file)
@@ -24,7 +24,6 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.ColoredTextContainer;
 import com.intellij.ui.SimpleTextAttributes;
 import com.intellij.util.ThreeState;
-import com.intellij.util.ui.tree.TreeUtil;
 import com.intellij.xdebugger.XDebugSession;
 import com.intellij.xdebugger.XSourcePosition;
 import com.intellij.xdebugger.frame.*;
@@ -99,8 +98,6 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
     // extra check for obsolete nodes - tree root was changed
     // too dangerous to put this into isObsolete - it is called from anywhere, not only EDT
     if (isObsolete()) return;
-    XDebuggerTreeNode root = getTree().getRoot();
-    if (root != null && !TreeUtil.isAncestor(root, this)) return;
 
     setIcon(icon);
     myValuePresentation = valuePresentation;