IDEA-121775 XDebugger: merge Watches and Variables in one view - do not evaluate...
[idea/community.git] / platform / xdebugger-impl / src / com / intellij / xdebugger / impl / ui / tree / nodes / WatchNodeImpl.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.xdebugger.impl.ui.tree.nodes;
17
18 import com.intellij.icons.AllIcons;
19 import com.intellij.util.ThreeState;
20 import com.intellij.xdebugger.Obsolescent;
21 import com.intellij.xdebugger.XExpression;
22 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
23 import com.intellij.xdebugger.evaluation.XInstanceEvaluator;
24 import com.intellij.xdebugger.frame.*;
25 import com.intellij.xdebugger.frame.presentation.XErrorValuePresentation;
26 import com.intellij.xdebugger.frame.presentation.XValuePresentation;
27 import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
28 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31 import org.jetbrains.concurrency.Promise;
32
33 import javax.swing.*;
34
35 /**
36  * @author nik
37  */
38 public class WatchNodeImpl extends XValueNodeImpl implements WatchNode {
39   private final XExpression myExpression;
40
41   public WatchNodeImpl(@NotNull XDebuggerTree tree,
42                        @NotNull WatchesRootNode parent,
43                        @NotNull XExpression expression,
44                        @Nullable XStackFrame stackFrame) {
45     super(tree, parent, expression.getExpression(), new XWatchValue(expression, tree.isShowing() ? stackFrame : null));
46     myExpression = expression;
47   }
48
49   @Nullable
50   @Override
51   public Icon getIcon() {
52     return getValuePresentation() instanceof XErrorValuePresentation?
53            XDebuggerUIConstants.ERROR_MESSAGE_ICON : AllIcons.Debugger.Watch;
54   }
55
56   @Override
57   @NotNull
58   public XExpression getExpression() {
59     return myExpression;
60   }
61
62   private static class XWatchValue extends XNamedValue {
63     private final XExpression myExpression;
64     private final XStackFrame myStackFrame;
65     private volatile XValue myValue;
66
67     public XWatchValue(XExpression expression, XStackFrame stackFrame) {
68       super(expression.getExpression());
69       myExpression = expression;
70       myStackFrame = stackFrame;
71     }
72
73     @Override
74     public void computeChildren(@NotNull XCompositeNode node) {
75       if (myValue != null) {
76         myValue.computeChildren(node);
77       }
78     }
79
80     @Override
81     public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
82       if (myStackFrame != null) {
83         XDebuggerEvaluator evaluator = myStackFrame.getEvaluator();
84         if (evaluator != null) {
85           evaluator.evaluate(myExpression, new MyEvaluationCallback(node, place), myStackFrame.getSourcePosition());
86         }
87       }
88       else {
89         node.setPresentation(null, EMPTY_PRESENTATION, false);
90       }
91     }
92
93     private class MyEvaluationCallback extends XEvaluationCallbackBase implements Obsolescent {
94       @NotNull private final XValueNode myNode;
95       @NotNull private final XValuePlace myPlace;
96
97       public MyEvaluationCallback(@NotNull XValueNode node, @NotNull XValuePlace place) {
98         myNode = node;
99         myPlace = place;
100       }
101
102       @Override
103       public boolean isObsolete() {
104         return myNode.isObsolete();
105       }
106
107       @Override
108       public void evaluated(@NotNull XValue result) {
109         myValue = result;
110         result.computePresentation(myNode, myPlace);
111       }
112
113       @Override
114       public void errorOccurred(@NotNull String errorMessage) {
115         myNode.setPresentation(XDebuggerUIConstants.ERROR_MESSAGE_ICON, new XErrorValuePresentation(errorMessage), false);
116       }
117     }
118
119     private static final XValuePresentation EMPTY_PRESENTATION = new XValuePresentation() {
120       @NotNull
121       @Override
122       public String getSeparator() {
123         return "";
124       }
125
126       @Override
127       public void renderValue(@NotNull XValueTextRenderer renderer) {
128       }
129     };
130
131     @Override
132     @Nullable
133     public String getEvaluationExpression() {
134       return myValue != null ? myValue.getEvaluationExpression() : null;
135     }
136
137     @Override
138     @NotNull
139     public Promise<XExpression> calculateEvaluationExpression() {
140       return Promise.resolve(myExpression);
141     }
142
143     @Override
144     @Nullable
145     public XInstanceEvaluator getInstanceEvaluator() {
146       return myValue != null ? myValue.getInstanceEvaluator() : null;
147     }
148
149     @Override
150     @Nullable
151     public XValueModifier getModifier() {
152       return myValue != null ? myValue.getModifier() : null;
153     }
154
155     @Override
156     public void computeSourcePosition(@NotNull XNavigatable navigatable) {
157       if (myValue != null) {
158         myValue.computeSourcePosition(navigatable);
159       }
160     }
161
162     @Override
163     @NotNull
164     public ThreeState computeInlineDebuggerData(@NotNull XInlineDebuggerDataCallback callback) {
165       return ThreeState.NO;
166     }
167
168     @Override
169     public boolean canNavigateToSource() {
170       return myValue != null && myValue.canNavigateToSource();
171     }
172
173     @Override
174     public boolean canNavigateToTypeSource() {
175       return myValue != null && myValue.canNavigateToTypeSource();
176     }
177
178     @Override
179     public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) {
180       if (myValue != null) {
181         myValue.computeTypeSourcePosition(navigatable);
182       }
183     }
184
185     @Override
186     @Nullable
187     public XReferrersProvider getReferrersProvider() {
188       return myValue != null ? myValue.getReferrersProvider() : null;
189     }
190   }
191 }