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;
}
/**
+ * 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
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
* @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;
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
}
/**
*
* 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) {
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;
}
}
}
+ 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;