1) Made getVariables and evalBlock methods in PHPDBGInterface synchronized (At least...
authorrobekras <robekras>
Thu, 24 Aug 2006 18:31:14 +0000 (18:31 +0000)
committerrobekras <robekras>
Thu, 24 Aug 2006 18:31:14 +0000 (18:31 +0000)
2) getVariables method returns an empty vector if socket is closed (avoiding exception).
3) updateStackFrameList improved to avoid rebuild of variables view when stepping through the current php file.
4) getAdapter in PHPDebugTarget calls super.getAdapter (for eclipse 3.2 compatibility)
5) hasVariables in PHPStackFrame return always true (for eclipse 3.2 compatibility)
6) Removed second sending of RESUME event in stepInto and stepOver (in PHPStackFrame).
7) getStackFrames (in PHPThread) returns the stackframes only if in suspended state (for eclipse 3.2 compatibility).
8) PHPWatchExpressionDelegateCode beautifying.

net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java
net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java
net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDebugTarget.java
net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java
net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java
net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/watch/PHPWatchExpressionDelegate.java

index 89ef3a2..0ae3bc0 100644 (file)
@@ -179,7 +179,7 @@ public class PHPDBGInterface {
                PHPDBGFrame     DBGFrame2;
                PHPDBGFrame             DBGFrame3;
                int                     modNo;
-               
+
                DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
                DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
                DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
@@ -219,22 +219,21 @@ public class PHPDBGInterface {
                if (!condition.equals ("")) {                                                           // Do we have a condition for breakpoint
                        rawCounter++;                                                                                   // Set to new ID
                        DBGFrame1.addInt (rawCounter);                          // ID of condition
-                       
+
                        DBGFrame3.addInt (rawCounter);                                      // FRAME_RAWDATA ID
                        DBGFrame3.addInt (condition.length() + 1);                  // length of rawdata (+ null char)
                        DBGFrame3.addString (condition);                                        // The break condition
                        DBGFrame3.addChar ('\0');                                                   // null char
 
-                       DBGPacket.addFrame (DBGFrame3);                         // First add break condition            
+                       DBGPacket.addFrame (DBGFrame3);                         // First add break condition
                }
                else {
                        DBGFrame1.addInt (0);                                           // ID of condition is 0, because there is no condition
                }
 
-               
                DBGFrame1.addInt (bpno);                                            // breakpoint number
                DBGFrame1.addInt (isunderhit);                                  // is under hit
-               
+
                DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
 
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
@@ -419,7 +418,7 @@ public class PHPDBGInterface {
         * @param stack The stackframe for which we want the variables.
         * @return      The array of variables
         */
-       public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
+       public synchronized Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
                PHPDBGPacket            DBGPacket;
                PHPDBGFrame             DBGFrame1;
                PHPDBGEvalString        evalStr;
@@ -433,7 +432,7 @@ public class PHPDBGInterface {
                DBGPacket.addFrame (DBGFrame1);                             // Add command data
 
                if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-                       return null;                                                                                    //  No, then leave here
+                       return new Vector ();                                                                   // No, then leave here with an empty vector 
                }
 
                DBGPacket.sendPacket (os);                                  // Send the request to DBG
@@ -501,7 +500,7 @@ public class PHPDBGInterface {
                flushAllPackets();
        }
 
-       public PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException  {
+       public synchronized PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException  {
                PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
@@ -615,7 +614,7 @@ public class PHPDBGInterface {
                                                if ((int) framesInfo[nextFrame + 8 + toRead - 1] == 0) {                                // Is there a string termination at the end?
                                                        return String.copyValueOf (framesInfo, nextFrame + 8, toRead - 1);      // Then copy frame content to String without the \0 and return
                                                }
-                                               
+
                                                return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
                                        }
                                        break;
@@ -628,6 +627,75 @@ public class PHPDBGInterface {
        }
 
        /**
+        * 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++) {
+                       ((PHPStackFrame) 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 (PHPStackFrame stackFrameNew, Vector list) {
+               int             i;
+               PHPStackFrame   stackFrameOld;
+
+               for (i = 0; i < list.size (); i++) {
+                       stackFrameOld = (PHPStackFrame) list.get (i);                                           //
+
+                       if (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.setIndex (stackFrameNew.getIndex ());
+                               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;
+               PHPStackFrame   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 = (PHPStackFrame) 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.
@@ -637,10 +705,10 @@ public class PHPDBGInterface {
         * <li> It looks for new stackframes within the DBG stackframe list and
         *      adds them to the 'static' list.
         * <li> It looks for stackframes within the 'static' list, and removes them
-        *              from the 'static' list in case the do not appear within the DBG list.
+        *              from the 'static' list in case they do not appear within the DBG list.
         * <li> It looks for stackframes which are already existent and replicates the
         *              line number and the index number.
-        * <li> At the end the 'static' stackfram list has to be sorted by the stackframes
+        * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
         *              index numbers.
         * </ul>
         *
@@ -657,22 +725,32 @@ public class PHPDBGInterface {
                PHPStackFrame   stackFrameOld;
                PHPStackFrame[] newStackList;
 
+               markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
+                                                                                                                                                               // of old stack frames
+
                for (i = 0; i < stackList.size (); i++) {                                                               // For all stackList entries
                        stackFrameNew = (PHPStackFrame) stackList.get(i);
 
                        for (n = 0; n < stackListOld.size (); n++) {                                    // For all StackFrames in the StackFrame list
                                stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   //
 
-                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
-                                       stackFrameNew.getLineNumber() == stackFrameOld.getLineNumber()) {// Did we find the sent stackframe within the list of old stackframes?
+                               if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
+                                       continue;
+                               }
+
+                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) {// Did we find the sent stackframe within the list of old stackframes?
                                        stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
                                        stackFrameOld.setIndex (stackFrameNew.getIndex ());
 
+                                       stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
+                                       stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
+
                                        break;                                                                  //  Yes, then break;
                                }
                        }
 
-                       if (n == stackListOld.size ()) {                                    // Did not find the new stackframe within the list
+                       if (!stackFrameNew.isAvailable ()) {                                // Did not find the new stackframe within the list?
+                                stackFrameNew.setAvailable (true);                                                             // Mark the stack frame as available and
                                 stackListOld.add (stackFrameNew);                              //  then add the new stackframe
                        }
                }
@@ -682,13 +760,9 @@ public class PHPDBGInterface {
                for (n = 0; n < stackListOld.size (); n++) {                                            // For all StackFrames in the StackFrame list
                        stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
 
-                       for (i = 0; i < stackList.size (); i++) {                                                       // For all stackList entries
-                               stackFrameNew = (PHPStackFrame) stackList.get (i);
-
-                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
-                                       stackFrameNew.getLineNumber() == stackFrameOld.getLineNumber()) {// Did we find the sent stackframe within the list of old stackframes?
-                                       break;                                                                  //  Yes, then break;
-                               }
+                       i = 0;
+                       if (!stackFrameOld.isAvailable ()) {
+                               i = stackList.size ();
                        }
 
                        if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones
index 77d751e..5c5b26b 100644 (file)
@@ -176,6 +176,15 @@ public class PHPDBGProxy {
        }
 
        /**
+        * Get the DBG interface which is linked to this proxy
+        *
+        * @paran DBGInt The DGB interface which is linked with this proxy
+        */
+       public PHPDBGInterface getDBGInterface () {
+               return DBGInt;
+       }
+       
+       /**
         * Give back a buffered input stream for the socket which is
         * linked with this proxy
         */
@@ -417,7 +426,8 @@ public class PHPDBGProxy {
        }
 
        /**
-        *
+        * Is called by the DebuggerRunner
+        * 
         * @param debugTarget
         */
        public void setDebugTarget (PHPDebugTarget debugTarget) {
index 36d415b..afce149 100644 (file)
@@ -29,6 +29,7 @@ import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.IDebugTarget;
 import org.eclipse.debug.core.model.IMemoryBlock;
 import org.eclipse.debug.core.model.IProcess;
+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;
@@ -148,6 +149,10 @@ public class PHPDebugTarget extends PHPDebugElement implements IPHPDebugTarget,
                return PHPDebugCorePlugin.PLUGIN_ID;
        }
 
+       public IStackFrame[] getStackFrames () throws DebugException {
+               return (IStackFrame[]) this.phpDBGProxy.getDBGInterface ().getStackList ();
+       }
+
        public IDebugTarget getDebugTarget() {
                return this;
        }
@@ -239,12 +244,12 @@ public class PHPDebugTarget extends PHPDebugElement implements IPHPDebugTarget,
        public void breakpointChanged (IBreakpoint breakpoint, IMarkerDelta arg1) {
                PHPLineBreakpoint bp;
                bp = (PHPLineBreakpoint) breakpoint;
-               
+
                try {
-                       if (breakpoint.isEnabled ()     &&                                                                      // Check if breakpoint state changed from disabled to enabled 
+                       if (breakpoint.isEnabled ()     &&                                                                      // Check if breakpoint state changed from disabled to enabled
                                !arg1.getAttribute ("org.eclipse.debug.core.enabled", false)) {
                                this.getPHPDBGProxy().addBreakpoint(breakpoint);
-                       } 
+                       }
                        else if (!breakpoint.isEnabled () &&                                                    // Check if breakpoint state changed from enabled to disabled
                            arg1.getAttribute ("org.eclipse.debug.core.enabled", true)) {
                                this.getPHPDBGProxy().removeBreakpoint(breakpoint);
@@ -255,7 +260,7 @@ public class PHPDebugTarget extends PHPDebugElement implements IPHPDebugTarget,
                                        this.getPHPDBGProxy().addBreakpoint(breakpoint);                // and then we add again (else DBG would have two breakpoints!).
                                }
                                else {
-                                       this.getPHPDBGProxy().removeBreakpoint(breakpoint);             
+                                       this.getPHPDBGProxy().removeBreakpoint(breakpoint);
                                }
                        }
                        else {                                                                                                                  // All other cases will terminate the debugger
@@ -319,7 +324,13 @@ public class PHPDebugTarget extends PHPDebugElement implements IPHPDebugTarget,
                                }
                        };
                }
-               return null;
+               else {
+                   if (arg0 == PHPDebugElement.class) {
+                       return this;
+                   }
+
+                   return super.getAdapter(arg0);
+               }
        }
 
        public IProcess getProcess() {
index 1c5dcdd..dcd372e 100644 (file)
@@ -41,7 +41,10 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
        private PHPVariable[]   variables;          // The array of variables TODO: better introduce a vector?
        private Vector          varList  = new Vector ();
        private String                  description;        // The source file name with the full path on target/remote system
-       private boolean         fUpToDate;          //
+       private boolean         fUpToDate;          // Indicates whether the variable list within this stackframe is
+                                                                                               // up-to-date
+       private boolean         fAvailable;         // Needed when updating the stackframe list, shows whether the stackframe
+                                                                                               // is within the list which was received from dbg
 
        /**
         *
@@ -111,6 +114,32 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
 
        /**
         *
+        */
+       public void setAvailable (boolean available) {
+               fAvailable = available;
+       }
+
+       /**
+        *
+        */
+       public boolean isAvailable () {
+               return fAvailable;
+       }
+
+
+       /**
+        * @see IAdaptable#getAdapter(Class)
+        */
+       public Object getAdapter(Class adapter) {
+               if (adapter == PHPStackFrame.class) {
+                       return this;
+               }
+
+               return super.getAdapter(adapter);
+       }
+
+       /**
+        *
         *
         */
        private void resetHasChangedInfo (Vector varList) {
@@ -279,11 +308,6 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
         * @return The array of PHPVariables for this stackframe.
         */
        public IVariable[] getVariables() throws DebugException {
-               PHPVariable[] variablesNew;                                 // The intermediate storage of the variable array we get from DBG proxy
-
-               //variablesNew = this.getPHPDBGProxy ().readVariables (this); // Get the variable array from DBG proxy
-               //variables    = variablesNew;                                // Store the array the stackframes member variable
-
                if (!isUpToDate ()) {
                        resetHasChangedInfo (varList);
                        updateVariableList (varList, this.getPHPDBGProxy ().readVariables (this));
@@ -352,7 +376,8 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
         *
         */
        public boolean hasVariables () throws DebugException {
-               return (varList.size () > 0);
+               return true;
+               // return (varList.size () > 0);
        }
 
        public int getLineNumber() {
@@ -448,9 +473,16 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
 
                thread.prepareForResume (DebugEvent.STEP_INTO);             // Don't know why, but this is necessary
                this.getPHPDBGProxy ().readStepIntoEnd (PHPStackFrame.this);
-
-               ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_INTO);
-               DebugPlugin.getDefault().fireDebugEventSet (new DebugEvent[] { ev });
+               
+        // Commented out sending the RESUME event because it was already sent by prepareForResume.
+        // The second RESUME event leads only to a little flickering within the variables view.
+        // It is also not clear why this event was necessary in eclipse < 3.2
+        // Also sending a SUSPEND event here leads to a total rebuild of the variables view.
+        // (eclipse 3.2 has a build in timeout of 500 ms which leads to a auto suspend, with
+        // no flickering... but why???)
+        // 
+               //ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_INTO);
+               //DebugPlugin.getDefault().fireDebugEventSet (new DebugEvent[] { ev });
        }
 
        /**
@@ -464,8 +496,10 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Compa
                thread.prepareForResume (DebugEvent.STEP_OVER);
                this.getPHPDBGProxy ().readStepOverEnd (PHPStackFrame.this) ;
 
-               ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_OVER);
-               DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev });
+        // See comment within the previous stepInto method.
+        // 
+               //ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_OVER);
+               //DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev });
        }
 
        /**
index 49a432e..94feaf9 100644 (file)
@@ -94,7 +94,11 @@ public class PHPThread extends PHPDebugElement implements IThread {
         *
         */
        public IStackFrame[] getStackFrames () throws DebugException {
-               return frames;
+               if (isSuspended()) {
+                       return ((PHPDebugTarget)getDebugTarget()).getStackFrames();
+               } else {
+                       return new IStackFrame[0];
+               }
        }
 
        public int getStackFramesSize () {
@@ -166,7 +170,7 @@ public class PHPThread extends PHPDebugElement implements IThread {
                this.frames = null;                                         // Reset the stackframes
                ev          = new DebugEvent (this, DebugEvent.RESUME, de); // Create an event resume by stepping
 
-               DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev });  // Fire the event
+               DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev });  // Fire the event
        }
 
        /**
@@ -308,22 +312,13 @@ public class PHPThread extends PHPDebugElement implements IThread {
                if (IWorkbenchAdapter.class.equals (arg0)) {
                        return new IWorkbenchAdapter() {
                                public Object[] getChildren(Object o) {
-                                       Object[] children = null;
-
                                        try {
-                                               IStackFrame[] frames = getStackFrames();
-
-                                               if (null != frames) {
-                                                       children = new Object[frames.length];
-                                                       for (int i = 0; i < frames.length; ++i) {
-                                                               children[i] = frames[i];
-                                                       }
-                                               }
+                                               return getStackFrames ();
                                        } catch (DebugException x) {
                                                PHPeclipsePlugin.log ("Unable to get stack frames.", x);
                                        }
 
-                                       return children;
+                                       return new Object[0];
                                }
 
                                public ImageDescriptor getImageDescriptor(Object object) {
index 2c3964d..e37deff 100644 (file)
@@ -10,29 +10,41 @@ import org.eclipse.debug.core.model.IWatchExpressionDelegate;
 import org.eclipse.debug.core.model.IWatchExpressionListener;
 import org.eclipse.debug.core.model.IWatchExpressionResult;
 
+/**
+ *
+ */
 public class PHPWatchExpressionDelegate implements IWatchExpressionDelegate {
 
-       public void evaluateExpression(String expression, IDebugElement context,
-                       IWatchExpressionListener listener) {
-               IWatchExpressionResult x;
-               PHPDBGProxy dbg=((PHPDebugTarget)context.getDebugTarget()).getPHPDBGProxy();
-               PHPStackFrame s=null;
-               if(context instanceof PHPStackFrame)
-                       s=(PHPStackFrame)context;
-               try{
-               PHPVariable result[]=dbg.eval(s,expression);
-               if(result.length==0)
-                       x=new PHPWatchExpressionResult(expression,null,null);
-               else
-                       x=new PHPWatchExpressionResult(expression,result[0].getValue(),null);
-               }
-               catch(Exception e)
-               {
-                       String[] s1=new String[1];
-                       s1[0]=e.toString();
-               x=new PHPWatchExpressionResult(expression,null,s1);
-               }
-               listener.watchEvaluationFinished(x);
-       }
-
-}
\ No newline at end of file
+       public void evaluateExpression (String expression, IDebugElement context, IWatchExpressionListener listener) {
+       IWatchExpressionResult  x;
+               PHPDBGProxy                     dbg;
+               PHPStackFrame                   s;
+
+               dbg = ((PHPDebugTarget) context.getDebugTarget ()).getPHPDBGProxy ();
+               s   = null;
+
+               if (context instanceof PHPStackFrame) {
+                       s = (PHPStackFrame) context;
+               }
+
+               try {
+                       PHPVariable result[] = dbg.eval (s, expression);
+
+                       if (result.length == 0) {
+                               x = new PHPWatchExpressionResult (expression, null, null);
+                       }
+                       else {
+                               x = new PHPWatchExpressionResult (expression, result[0].getValue (), null);
+                       }
+               }
+               catch (Exception e) {
+                       String[] s1;
+
+                       s1    = new String[1];
+                       s1[0] = e.toString ();
+                       x     = new PHPWatchExpressionResult (expression, null, s1);
+               }
+
+               listener.watchEvaluationFinished (x);
+       }
+}