cleanup
[idea/community.git] / platform / script-debugger / debugger-ui / src / org / jetbrains / debugger / frame / CallFrameView.java
1 package org.jetbrains.debugger.frame;
2
3 import com.intellij.icons.AllIcons;
4 import com.intellij.ui.ColoredTextContainer;
5 import com.intellij.ui.SimpleTextAttributes;
6 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
7 import com.intellij.xdebugger.frame.XCompositeNode;
8 import com.intellij.xdebugger.frame.XStackFrame;
9 import org.jetbrains.annotations.NotNull;
10 import org.jetbrains.annotations.Nullable;
11 import org.jetbrains.concurrency.Promise;
12 import org.jetbrains.debugger.*;
13
14 import java.util.List;
15
16 public final class CallFrameView extends XStackFrame implements VariableContext {
17   private final SourceInfo sourceInfo;
18   private final DebuggerViewSupport viewSupport;
19   private final CallFrame callFrame;
20
21   private final Script script;
22
23   private final boolean inLibraryContent;
24   private XDebuggerEvaluator evaluator;
25
26   public CallFrameView(@NotNull CallFrame callFrame, @NotNull DebuggerViewSupport viewSupport, @Nullable Script script) {
27     this(callFrame, viewSupport.getSourceInfo(script, callFrame), viewSupport, script);
28   }
29
30   public CallFrameView(@NotNull CallFrame callFrame,
31                        @Nullable SourceInfo sourceInfo,
32                        @NotNull DebuggerViewSupport viewSupport,
33                        @Nullable Script script) {
34     this.sourceInfo = sourceInfo;
35
36     this.viewSupport = viewSupport;
37     this.callFrame = callFrame;
38     this.script = script;
39
40     // isInLibraryContent call could be costly, so we compute it only once (our customizePresentation called on each repaint)
41     inLibraryContent = sourceInfo != null && viewSupport.isInLibraryContent(sourceInfo, script);
42   }
43
44   @Nullable
45   public Script getScript() {
46     return script;
47   }
48
49   @Override
50   public Object getEqualityObject() {
51     return callFrame.getEqualityObject();
52   }
53
54   @Override
55   public void computeChildren(@NotNull XCompositeNode node) {
56     node.setAlreadySorted(true);
57     ScopeVariablesGroup.createAndAddScopeList(node, callFrame.getVariableScopes(), this, callFrame);
58   }
59
60   @NotNull
61   public CallFrame getCallFrame() {
62     return callFrame;
63   }
64
65   @NotNull
66   @Override
67   public EvaluateContext getEvaluateContext() {
68     return callFrame.getEvaluateContext();
69   }
70
71   @Nullable
72   @Override
73   public String getName() {
74     return null;
75   }
76
77   @Nullable
78   @Override
79   public VariableContext getParent() {
80     return null;
81   }
82
83   @Override
84   public boolean watchableAsEvaluationExpression() {
85     return true;
86   }
87
88   @NotNull
89   @Override
90   public DebuggerViewSupport getViewSupport() {
91     return viewSupport;
92   }
93
94   @NotNull
95   @Override
96   public Promise<MemberFilter> getMemberFilter() {
97     return viewSupport.getMemberFilter(this);
98   }
99
100   @NotNull
101   public Promise<MemberFilter> getMemberFilter(@NotNull Scope scope) {
102     return ScopeVariablesGroup.createVariableContext(scope, this, callFrame).getMemberFilter();
103   }
104
105   @Nullable
106   @Override
107   public Scope getScope() {
108     return null;
109   }
110
111   @Override
112   public final XDebuggerEvaluator getEvaluator() {
113     if (evaluator == null) {
114       evaluator = viewSupport.createFrameEvaluator(this);
115     }
116     return evaluator;
117   }
118
119   @Override
120   @Nullable
121   public SourceInfo getSourcePosition() {
122     return sourceInfo;
123   }
124
125   @Override
126   public final void customizePresentation(@NotNull ColoredTextContainer component) {
127     if (sourceInfo == null) {
128       String scriptName = script == null ? "unknown" : script.getUrl().trimParameters().toDecodedForm();
129       int line = callFrame.getLine();
130       component.append(line != -1 ? scriptName + ':' + line : scriptName, SimpleTextAttributes.ERROR_ATTRIBUTES);
131       return;
132     }
133
134     String fileName = sourceInfo.getFile().getName();
135     int line = sourceInfo.getLine() + 1;
136
137     boolean isInLibraryContent = inLibraryContent;
138     SimpleTextAttributes textAttributes = isInLibraryContent ? SimpleTextAttributes.GRAYED_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
139
140     String functionName = sourceInfo.getFunctionName();
141     List<Scope> scopes = callFrame.getVariableScopes();
142     if (functionName == null || (functionName.isEmpty() && scopes.size() == 1 && scopes.get(0).isGlobal())) {
143       component.append(fileName + ":" + line, textAttributes);
144     }
145     else {
146       if (functionName.isEmpty()) {
147         component.append("anonymous", isInLibraryContent ? SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES);
148       }
149       else {
150         component.append(functionName, textAttributes);
151       }
152       component.append("(), " + fileName + ":" + line, textAttributes);
153     }
154     component.setIcon(AllIcons.Debugger.StackFrame);
155   }
156 }