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 2e00970..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,11 @@ */ 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; @@ -16,6 +21,8 @@ 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; @@ -27,19 +34,19 @@ import org.w3c.dom.NodeList; */ public class XDebugThread extends XDebugElement implements IThread, IDebugEventSetListener { private XDebugStackFrame[] fStackFrames; - - private IBreakpoint[] fBreakpoints; - - /* Whether this thread is stepping */ - private boolean fStepping = false; - private boolean fTerminated = false; - - private int fStepCount = 0; - private int fCurrentStepCount = 0; - + 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) { @@ -47,88 +54,271 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS DebugPlugin.getDefault().addDebugEventListener(this); fStackFrames = null; } - + + /** + * + */ + 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 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 !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()
*/
@@ -197,28 +387,28 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS
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()
*/
@@ -282,14 +472,14 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS
((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) {
@@ -298,17 +488,17 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS
public void handleDebugEvents(DebugEvent[] events) {
DebugEvent de = events[0];
- System.out.println(de.toString());
+ 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) {
@@ -318,10 +508,10 @@ public class XDebugThread extends XDebugElement implements IThread, IDebugEventS
/**
* 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));
+ public void fireSuspendEvent (int detail) {
+ fireEvent (new DebugEvent (this, DebugEvent.SUSPEND, detail));
}
-}
\ No newline at end of file
+}