3
* Created on Apr 21, 2004
4
* License: Common Public License v1.0
6
package org.python.pydev.debug.model;
8
import org.eclipse.core.resources.IResource;
9
import org.eclipse.core.runtime.Platform;
10
import org.eclipse.core.runtime.PlatformObject;
11
import org.eclipse.debug.core.DebugException;
12
import org.eclipse.debug.core.ILaunch;
13
import org.eclipse.debug.core.model.IBreakpoint;
14
import org.eclipse.debug.core.model.IDebugTarget;
15
import org.eclipse.debug.core.model.IStackFrame;
16
import org.eclipse.debug.core.model.IThread;
17
import org.eclipse.ui.views.properties.IPropertySource;
18
import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter;
19
import org.python.pydev.debug.model.remote.AbstractDebuggerCommand;
20
import org.python.pydev.debug.model.remote.AbstractRemoteDebugger;
21
import org.python.pydev.debug.model.remote.StepCommand;
22
import org.python.pydev.debug.model.remote.ThreadRunCommand;
23
import org.python.pydev.debug.model.remote.ThreadSuspendCommand;
24
import org.python.pydev.plugin.PydevPlugin;
27
* Represents python threads.
28
* Stack global variables are associated with threads.
30
public class PyThread extends PlatformObject implements IThread {
32
private AbstractDebugTarget target;
37
* true if this is a debugger thread, that can't be killed/suspended
39
private boolean isPydevThread;
41
private boolean isSuspended = false;
42
private boolean isStepping = false;
43
private IStackFrame[] stack;
45
public PyThread(AbstractDebugTarget target, String name, String id) {
49
isPydevThread = id.equals("-1"); // use a special id for pydev threads
53
* If a thread is entering a suspended state, pass in the stack
55
public void setSuspended(boolean state, IStackFrame[] stack) {
60
public String getName() throws DebugException {
64
public String getId() {
68
public boolean isPydevThread() {
72
public int getPriority() throws DebugException {
76
public String getModelIdentifier() {
77
return target.getModelIdentifier();
80
public IDebugTarget getDebugTarget() {
84
public ILaunch getLaunch() {
85
return target.getLaunch();
88
public boolean canTerminate() {
89
return !isPydevThread;
92
public boolean isTerminated() {
93
return target.isTerminated();
96
public void terminate() throws DebugException {
100
public boolean canResume() {
101
return !isPydevThread && isSuspended;
104
public boolean canSuspend() {
105
return !isPydevThread && !isSuspended;
108
public boolean isSuspended() {
112
public void resume() throws DebugException {
113
if (!isPydevThread) {
116
//RemoteDebugger d = target.getDebugger();
117
AbstractRemoteDebugger d = target.getDebugger();
119
d.postCommand(new ThreadRunCommand(d, id));
121
PydevPlugin.log("Terminating: No debugger in target when resuming.");
127
public void suspend() throws DebugException {
128
if (!isPydevThread) {
130
AbstractRemoteDebugger d = target.getDebugger();
131
d.postCommand(new ThreadSuspendCommand(d, id));
135
public boolean canStepInto() {
136
return !isPydevThread && isSuspended;
139
public boolean canStepOver() {
140
return !isPydevThread && isSuspended;
143
public boolean canStepReturn() {
144
return !isPydevThread && isSuspended;
147
public boolean isStepping() {
151
public void stepInto() throws DebugException {
152
if (!isPydevThread) {
154
AbstractRemoteDebugger d = target.getDebugger();
155
d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_INTO, id));
159
public void stepOver() throws DebugException {
160
if (!isPydevThread) {
162
AbstractRemoteDebugger d = target.getDebugger();
163
d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_OVER, id));
167
public void stepReturn() throws DebugException {
168
if (!isPydevThread) {
170
AbstractRemoteDebugger d = target.getDebugger();
171
d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_RETURN, id));
175
public IStackFrame[] getStackFrames() throws DebugException {
176
if(isSuspended && stack != null){
179
return new IStackFrame[0];
182
public boolean hasStackFrames() throws DebugException {
183
return (stack != null && stack.length > 0);
186
public IStackFrame getTopStackFrame() throws DebugException {
187
return stack == null ? null : stack[0];
190
public PyStackFrame findStackFrameByID(String id) {
193
for (int i=0; i<stack.length; i++){
195
if (id.equals(((PyStackFrame)stack[i]).getId())){
197
return (PyStackFrame)stack[i];
204
public IBreakpoint[] getBreakpoints() {
205
// should return breakpoint that caused this thread to suspend
206
// not implementing this seems to cause no harm
207
PyBreakpoint[] breaks = new PyBreakpoint[0];
211
public Object getAdapter(Class adapter) {
212
if (adapter.equals(ILaunch.class) ||
213
adapter.equals(IResource.class))
214
return target.getAdapter(adapter);
215
else if (adapter.equals(ITaskListResourceAdapter.class))
217
else if (adapter.equals(IPropertySource.class)
218
|| adapter.equals(ITaskListResourceAdapter.class)
219
|| adapter.equals(org.eclipse.debug.ui.actions.IToggleBreakpointsTarget.class)
220
|| adapter.equals(org.eclipse.debug.ui.actions.IRunToLineTarget.class)
221
|| adapter.equals(org.eclipse.ui.IContributorResourceAdapter.class)
222
|| adapter.equals(org.eclipse.ui.model.IWorkbenchAdapter.class)
223
|| adapter.equals(org.eclipse.ui.IActionFilter.class)
225
return super.getAdapter(adapter);
227
// System.err.println("PythonThread Need adapter " + adapter.toString());
228
Platform.getAdapterManager().getAdapter(this, adapter);
230
// ongoing, I do not fully understand all the interfaces they'd like me to support
231
return super.getAdapter(adapter);