033efead7dae2df758c130200a1eb447717c74ef
[idea/community.git] / platform / script-debugger / debugger-ui / src / org / jetbrains / debugger / frame / ExecutionStackImpl.java
1 package org.jetbrains.debugger.frame;
2
3 import com.intellij.xdebugger.frame.XExecutionStack;
4 import com.intellij.xdebugger.frame.XStackFrame;
5 import org.jetbrains.annotations.NotNull;
6 import org.jetbrains.annotations.Nullable;
7 import org.jetbrains.debugger.*;
8
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.List;
12
13 public class ExecutionStackImpl extends XExecutionStack {
14   private final SuspendContext suspendContext;
15   private final Script topFrameScript;
16   private CallFrameView topCallFrameView;
17   private final DebuggerViewSupport debugProcess;
18
19   public ExecutionStackImpl(@NotNull SuspendContext suspendContext, @NotNull DebuggerViewSupport debugProcess, @Nullable Script topFrameScript) {
20     super("");
21
22     this.debugProcess = debugProcess;
23     this.suspendContext = suspendContext;
24     this.topFrameScript = topFrameScript;
25   }
26
27   @Override
28   @Nullable
29   public CallFrameView getTopFrame() {
30     CallFrame topCallFrame = suspendContext.getTopFrame();
31     if (topCallFrameView == null || topCallFrameView.getCallFrame() != topCallFrame) {
32       topCallFrameView = topCallFrame == null ? null : new CallFrameView(topCallFrame, debugProcess, topFrameScript);
33     }
34     return topCallFrameView;
35   }
36
37   @Override
38   public void computeStackFrames(final int firstFrameIndex, final XStackFrameContainer container) {
39     SuspendContext suspendContext = debugProcess.getVm().getSuspendContextManager().getContext();
40     // WipSuspendContextManager set context to null on resume _before_ vm.getDebugListener().resumed() call() (in any case, XFramesView can queue event to EDT), so, IDE state could be outdated compare to VM (our) state
41     if (suspendContext == null) {
42       return;
43     }
44
45     suspendContext.getCallFrames().done(new ContextDependentAsyncResultConsumer<CallFrame[]>(suspendContext) {
46       @Override
47       protected void consume(CallFrame[] frames, @NotNull Vm vm) {
48         int count = frames.length - firstFrameIndex;
49         List<XStackFrame> result;
50         if (count < 1) {
51           result = Collections.emptyList();
52         }
53         else {
54           result = new ArrayList<XStackFrame>(count);
55           for (int i = firstFrameIndex; i < frames.length; i++) {
56             CallFrame frame = frames[i];
57             // if script is null, it is native function (Object.forEach for example), so, skip it
58             Script script = vm.getScriptManager().getScript(frame);
59             if (script != null) {
60               result.add(new CallFrameView(frame, debugProcess, script));
61             }
62           }
63         }
64         container.addStackFrames(result, true);
65       }
66     });
67   }
68 }