X-Git-Url: http://git.phpeclipse.com
diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugThread.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugThread.java
index 4581ee5..67aacaf 100644
--- a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugThread.java
+++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugThread.java
@@ -6,6 +6,14 @@
*/
package net.sourceforge.phpeclipse.xdebug.php.model;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Vector;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
+import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugResponse;
+
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
@@ -13,6 +21,10 @@ import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
* @author Axel
@@ -21,59 +33,292 @@ import org.eclipse.debug.core.model.IThread;
* Window - Preferences - Java - Code Style - Code Templates
*/
public class XDebugThread extends XDebugElement implements IThread, IDebugEventSetListener {
-
- /**
- * Breakpoints this thread is suspended at or null
- * if none.
- */
-
- private IStackFrame[] fStackFrames=null;
-
- private IBreakpoint[] fBreakpoints;
-
- /**
- * Whether this thread is stepping
- */
- private boolean fStepping = false;
-
+ private XDebugStackFrame[] fStackFrames;
+ private IBreakpoint[] fBreakpoints;
+
+ private boolean fStepping = false; // Whether this thread is stepping
+ private boolean fTerminated = false;
+
+ private int fStepCount = 0;
+ private int fCurrentStepCount = 0;
+
+ private Vector stackListOld = new Vector(); // The 'static' list of stack frames
+
/**
* Constructs a new thread for the given target
- *
+ *
* @param target VM
*/
public XDebugThread(XDebugTarget target) {
super(target);
DebugPlugin.getDefault().addDebugEventListener(this);
+ fStackFrames = null;
}
-
- /* (non-Javadoc)
- * @see org.eclipse.debug.core.model.IThread#getStackFrames()
+
+ /**
+ *
*/
- public IStackFrame[] getStackFrames() throws DebugException {
- if (isSuspended()) {
- if (fStackFrames==null)
- {
-// XDebugCorePlugin.log(IStatus.INFO,"vor getStackFrames");
- fStackFrames=((XDebugTarget) getDebugTarget()).getStackFrames();
-// XDebugCorePlugin.log(IStatus.INFO,"nach getStackFrames");
+ public void setStackFrames (XDebugStackFrame[] frames) {
+ this.fStackFrames = frames;
+ }
+
+ public void incrementStepCounter() {
+ fStepCount++;
+ }
+
+ /**
+ *
+ * @param arg0
+ * @return
+ */
+ public Object getAdapter (Class arg0) {
+ if (IWorkbenchAdapter.class.equals (arg0)) {
+ return new IWorkbenchAdapter() {
+ public Object[] getChildren(Object o) {
+ try {
+ return getStackFrames ();
+ } catch (DebugException x) {
+ PHPeclipsePlugin.log ("Unable to get stack frames.", x);
+ }
+
+ return new Object[0];
+ }
+
+ public ImageDescriptor getImageDescriptor(Object object) {
+ return null;
+ }
+
+ public String getLabel(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getParent(Object o) {
+ return getDebugTarget();
+ }
+ };
+ }
+ return super.getAdapter(arg0);
+ }
+
+ /**
+ * Reset the availability flag for all stackframes in the list.
+ *
+ * @param list The list of old stackframes
+ */
+ private void resetAvailability (Vector list) {
+ int i;
+
+ for (i = 0; i < list.size (); i++) {
+ ((XDebugStackFrame) list.get(i)).setAvailable (false); //
+ }
+ }
+
+ /**
+ * Check whether the new stackframe is in the list of old stackframes.
+ * Test for identical stackframe (identical means same description and same line number).
+ *
+ * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+ * @param list The list of old stackframes
+ * @return
+ * - true if we have found the identical stackframe within the list
+ * - false if we did not find the identical stackframe within the list
+ */
+ private boolean isStackFrameInList (XDebugStackFrame stackFrameNew, Vector list) {
+ int i;
+ XDebugStackFrame stackFrameOld;
+
+ for (i = 0; i < list.size (); i++) {
+ stackFrameOld = (XDebugStackFrame) list.get (i); //
+
+ if (stackFrameNew.getFullName ().equals (stackFrameOld.getFullName ()) &&
+ stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
+ stackFrameNew.getLineNumber () == stackFrameOld.getLineNumber ()) { // Did we find the sent stackframe within the list of old stackframes?
+ stackFrameOld.setAvailable (true); // We found the new stackframe in the list of old stack frames
+ stackFrameOld.setLevel (stackFrameNew.getLevel ());
+ stackFrameOld.setUpToDate (false); // Need to update the variables
+
+ return true; // The stackframe was found in the list
}
- return fStackFrames;
- } else {
+ }
+
+ return false;
+ }
+
+ /**
+ * Check whether the new stackframe is in the list of old stackframes.
+ * Test for exact stackframe (exact means same description and same line number).
+ *
+ * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+ * @param list The list of old stackframes
+ * @return
+ * - true if we have exactly this stackframe within the list
+ * - false if we did not find the exact stackframe within the list
+ */
+ private void markIdenticalStackFrames (Vector oldList, Vector newList) {
+ int i;
+ XDebugStackFrame stackFrameNew;
+
+ resetAvailability (oldList); // Reset the availability flag of the old stack frames
+ resetAvailability (newList); // Reset the availability flag of the old stack frames
+
+ for (i = 0; i < newList.size (); i++) { // For all stackList entries
+ stackFrameNew = (XDebugStackFrame) newList.get (i);
+
+ if (isStackFrameInList (stackFrameNew, oldList)) { // Is this stackframe in the list
+ stackFrameNew.setAvailable (true); //
+ //
+// break;
+ }
+ }
+ }
+
+ /**
+ *
+ * The stackList contains the currently read stackframes which were sent
+ * from DBG. The DBG interface holds a list of the active stack frames.
+ * This method replicates the 'static' stackframe list with the DBG stackframe list
+ * Replication is done in the following way:
+ *
null
* if none.
- *
+ *
* @param breakpoints the breakpoints this thread is suspended at, or null
* if none
*/
protected void setBreakpoints(IBreakpoint[] breakpoints) {
fBreakpoints = breakpoints;
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#canResume()
*/
public boolean canResume() {
return isSuspended();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
*/
public boolean canSuspend() {
- return !isSuspended();
+ return !isTerminated() && !isSuspended();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
*/
public boolean isSuspended() {
return getDebugTarget().isSuspended();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#resume()
*/
public void resume() throws DebugException {
- fStackFrames=null;
- fBreakpoints=null;
+ fBreakpoints = null;
getDebugTarget().resume();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#suspend()
*/
public void suspend() throws DebugException {
getDebugTarget().suspend();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#canStepInto()
*/
public boolean canStepInto() {
return isSuspended();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#canStepOver()
*/
public boolean canStepOver() {
return isSuspended();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#canStepReturn()
*/
public boolean canStepReturn() {
- if (fStackFrames!=null)
- return (fStackFrames.length>1);
- else
+ if (fStackFrames != null) {
+ return (fStackFrames.length > 1);
+ } else {
return false;
+ }
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#isStepping()
*/
public boolean isStepping() {
return fStepping;
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepInto()
*/
public void stepInto() throws DebugException {
- fStackFrames=null;
- fBreakpoints=null;
- ((XDebugTarget)getDebugTarget()).step_into();
+ fBreakpoints = null;
+ ((XDebugTarget) getDebugTarget()).step_into();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepOver()
*/
public void stepOver() throws DebugException {
- fStackFrames=null;
- fBreakpoints=null;
- ((XDebugTarget)getDebugTarget()).step_over();
+ fBreakpoints = null;
+ ((XDebugTarget) getDebugTarget()).step_over();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepReturn()
*/
public void stepReturn() throws DebugException {
- fStackFrames=null;
- fBreakpoints=null;
- ((XDebugTarget)getDebugTarget()).step_out();
-
+ fBreakpoints = null;
+ ((XDebugTarget) getDebugTarget()).step_out();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#canTerminate()
*/
public boolean canTerminate() {
return !isTerminated();
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#isTerminated()
*/
public boolean isTerminated() {
- return getDebugTarget().isTerminated();
+ return fTerminated;
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
public void terminate() throws DebugException {
- getDebugTarget().terminate();
+ ((XDebugTarget) getDebugTarget()).getDebugConnection().stop();
+ fTerminated = true;
+ }
+
+ public void terminated() throws DebugException {
+ fTerminated = true;
}
-
+
/**
* Sets whether this thread is stepping
- *
+ *
* @param stepping whether stepping
*/
protected void setStepping(boolean stepping) {
@@ -225,13 +487,31 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS
}
public void handleDebugEvents(DebugEvent[] events) {
- DebugEvent de=events[0];
+ DebugEvent de = events[0];
System.out.println(de.toString());
-
}
public void removeEventListeners() {
DebugPlugin.getDefault().removeDebugEventListener(this);
-
+ }
+
+ /**
+ * Fires a RESUME
event for this element with
+ * the given detail.
+ *
+ * @param detail event detail code
+ */
+ public void fireResumeEvent(int detail) {
+ fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail));
+ }
+
+ /**
+ * Fires a SUSPEND
event for this element with
+ * the given detail.
+ *
+ * @param detail event detail code
+ */
+ public void fireSuspendEvent (int detail) {
+ fireEvent (new DebugEvent (this, DebugEvent.SUSPEND, detail));
}
}