1) A temporary fix for the recursion problem with the $GLOBALS array.
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 957c86e..03a735f 100644 (file)
@@ -15,6 +15,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Vector;
+import java.util.Collections;
 
 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
@@ -393,6 +394,43 @@ public class PHPDBGInterface {
        }
 
        /**
+        * Go up the tree of PHPVariables
+        * look whether the PHPValue is a reference to a parent PHPValue
+        *
+        * TODO Check where this recursion can come from.
+        * Whether this back reference is legal or a bug.
+        *
+        * @param var
+        * @return
+        * <ul>
+        * <li> false if the PHPValue is not a child of itself
+        * <li> true if the PHPValue is
+        * </ul>
+        */
+
+       private boolean hasRecursion (PHPVariable var) {
+               PHPVariable parentVar;
+               PHPValue    val;
+
+               val = (PHPValue) var.getValue ();                                                       // Get the PHPValue from the current PHPVariable
+
+               while (var != null) {                                                                           // As long as we have PHPVariable
+                       parentVar = var.getParent ();                                                   // Get the parent PHPVariable
+
+                       if (parentVar != null) {                                // Is there a parent?
+                               if (parentVar.getValue ().equals (val)) {                       // Get the PHPValue for the parent PHPVariable and check
+                                                                                                                                       // whether it is the same
+                                       return true;                                                                    // Return, if we have recursion
+                               }
+                       }
+
+                       var = parentVar;
+               }
+
+               return false;                                                                                           // No recursion found
+       }
+
+       /**
         * This method updates the 'static' variables list.
         * It does a replication between the 'static' list (the variable list which
         * is a member of this DBG interface object) and the DBG variable list
@@ -435,10 +473,13 @@ public class PHPDBGInterface {
                                        valNew = (PHPValue) varNew.getValue ();         // Get the value from DBG
 
                                        try {
-                                               if (valOld.hasVariables () ||                                   // If the 'static' value has child variables
-                                                   valNew.hasVariables ()) {                                                   //  or if the DBG value has child variables
-                                                       updateVariableList (valOld.getChildVariables (),        // Update the variable list for the child variables
-                                                                                               valNew.getChildVariables ());
+                                               if (valOld.hasVariables () ||                           // If the 'static' value has child variables
+                                                   valNew.hasVariables ()) {                           //  or if the DBG value has child variables
+                                                       if (!hasRecursion (varOld) &&
+                                                           !hasRecursion (varNew)) {                   // Both branches should not have a recursion
+                                                               updateVariableList (valOld.getChildVariables (),        // Update the variable list for the child variables
+                                                                                                       valNew.getChildVariables ());
+                                                       }
                                                }
                                                else if (!valOld.getValueString ().equals (valNew.getValueString ())) { // Has the value changed?
                                                        valOld.setValueString (valNew.getValueString ());                   // Yes, set the 'static' value (variable) to the new value
@@ -491,7 +532,7 @@ public class PHPDBGInterface {
         * @param stack The stackframe for which we want the variables.
         * @return      The array of variables
         */
-       public PHPVariable[] getVariables (PHPStackFrame stack) throws IOException, DebugException  {
+       public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
                PHPDBGPacket            DBGPacket;
                PHPDBGFrame             DBGFrame1;
                PHPDBGEvalString        evalStr;
@@ -516,7 +557,7 @@ public class PHPDBGInterface {
                evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
                updateVariableList (DBGVarList, evalStr.getVariables ());       // Replicate the 'static' variable list and the via DBG received variable list
 
-               return (PHPVariable[]) DBGVarList.toArray (new PHPVariable[DBGVarList.size ()]);        // Convert the list to an array and return the array
+               return DBGVarList;                                                                                      // Return the variables as list
        }
 
        /**
@@ -677,10 +718,23 @@ public class PHPDBGInterface {
         *
         * 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 looks whether the sent stackframes are already in the list.
+        * This method replicates the 'static' stackframe list with the DBG stackframe list
+        * Replication is done in the following way:
+        * <ul>
+        * <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.
+        * <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
+        *              index numbers.
+        * </ul>
+        *
         * Removes the unused stackframes from the list, or adds stackframes which
         * are not yet in the list.
         *
+        *
         * @param stackList
         */
        private void updateStackFrameList (Vector stackList) {
@@ -697,7 +751,8 @@ public class PHPDBGInterface {
                                stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   // ---
 
                                if (stackFrameNew.getModNo () == stackFrameOld.getModNo ()) {   // Did we find the sent stackframe within the list of old stackframes?
-                                       stackFrameOld.setLineNumber (stackFrameNew.getLineNumber());
+                                       stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
+                                       stackFrameOld.setIndex (stackFrameNew.getIndex ());
 
                                        break;                                                                  //  Yes, then break;
                                }
@@ -727,6 +782,8 @@ public class PHPDBGInterface {
                        }
                }
 
+               Collections.sort (stackListOld);                                                                                // Sort the 'static' stackframe list by the stackframe index numbers.
+                                                                                                                                                               //
                newStackList = new PHPStackFrame[stackListOld.size ()];
                newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
                DBGStackList = newStackList;