**********************************************************************/
package net.sourceforge.phpdt.internal.debug.core.model;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Vector;
import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy;
+import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugEvent;
/**
*
- * TODO Remove the variables array and use only the varList vector
- * Have also to change hasVariables
*/
public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Comparable {
private PHPThread thread; // The thread to which this stackframe belongs
- private String file; // The file name???
+ private String file; // The file name???
private int lineNumber;
private int index;
private int modno;
+ private PHPVariable[] variables; //
private int scope_id; // scope id
- //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 Vector varList; // Variables list
+ private String description; // The source file name with the full path on target/remote system
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
+ private boolean fDebug = true;
/**
*
* @param modno
* @param scope_id
*/
- public PHPStackFrame(PHPThread thread, String file, int line, int index,
- String desc, int modno, int scope_id) {
- super(null);
-
- this.lineNumber = line;
- this.index = index;
- this.file = file;
- this.thread = thread;
+ public PHPStackFrame (PHPThread thread, String file, int line, int index,
+ String desc, int modno, int scope_id) {
+ super (null);
+
+ this.lineNumber = line;
+ this.index = index;
+ this.file = file;
+ this.thread = thread;
this.description = desc;
- this.modno = modno;
- this.scope_id = scope_id;
- this.fUpToDate = false;
- }
+ this.modno = modno;
+ this.scope_id = scope_id;
+ this.varList = new Vector();
+ this.fUpToDate = false;
+ }
+
+// /**
+// *
+// * @param thread
+// * @param file
+// * @param line
+// * @param index
+// */
+// public PHPStackFrame(PHPThread thread, String file, int line, int index) {
+// super(null);
+//
+// this.lineNumber = line;
+// this.index = index;
+// this.file = file;
+// this.thread = thread;
+// this.fUpToDate = false;
+// }
/**
*
- * @param thread
- * @param file
- * @param line
- * @param index
- */
- public PHPStackFrame(PHPThread thread, String file, int line, int index) {
- super(null);
-
- this.lineNumber = line;
- this.index = index;
- this.file = file;
- this.thread = thread;
- this.fUpToDate = false;
- }
-
- /**
- *
* @return scope id
*/
public int getScopeID() {
}
/**
- *
+ *
*/
public void setScopeID(int scope_id) {
this.scope_id = scope_id;
- setUpToDate(false);
+ fUpToDate = false;
}
/**
this.thread = thread;
}
- /**
- *
- */
- private void setUpToDate(boolean upToDate) {
- fUpToDate = upToDate;
- }
+// /**
+// *
+// */
+// private void setUpToDate(boolean upToDate) {
+// fUpToDate = upToDate;
+// }
- /**
- *
- */
- private boolean isUpToDate() {
- return fUpToDate;
- }
+// /**
+// *
+// */
+// private boolean isUpToDate() {
+// return fUpToDate;
+// }
/**
*
* TODO Check where this recursion can come from.
* Whether this back reference is legal or a bug.
*
+ * Typically $GLOBALS contains $GLOBALS
+ *
* @param var
* @return
* <ul>
* <li> true if the PHPValue is
* </ul>
*/
- private boolean hasRecursion(PHPVariable var) {
+ private boolean hasRecursion (PHPVariable var) {
PHPVariable parentVar;
PHPValue val;
- val = (PHPValue) var.getValue(); // Get the PHPValue from the current PHPVariable
+ 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
+ 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
+ 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
}
* @param varListOld The 'static' list of variables which are to be updated.
* @param varListNew The new list of (current) variables from DBG.
*/
- private void updateVariableList(Vector varListOld, Vector varListNew) {
+ private void updateVariableList (Vector varListOld, Vector varListNew) {
PHPVariable varOld; // The variable from the 'static' list
PHPVariable varNew; // The variable from the DBG list
PHPValue valOld; // The value of the current variable from 'static' list
varOld = (PHPVariable) varListOld.get(o); // Get the static variable
if (varNew.getName().equals(varOld.getName())) { // Did we found the variable within the 'static' list?
- valOld = (PHPValue) varOld.getValue(); // Get the value from 'static'
- valNew = (PHPValue) varNew.getValue(); // Get the value from DBG
+ valOld = (PHPValue) varOld.getValue (); // Get the value from 'static'
+ 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
- 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());
+ 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
- varOld.setValueChanged(true); // and set the 'has changed' flag, so that the variable view
+ }
+
+ if (!valOld.getValueString ().equals (
+ valNew.getValueString ())) { // Has the value changed?
+ valOld.setValueString (valNew.getValueString ()); // Yes, set the 'static' value (variable) to the new value
+ varOld.setValueChanged (true); // and set the 'has changed' flag, so that the variable view
// could show the user the changed status with a different
// color
}
- //else {
- // varOld.setValueChanged (false); // Reset the 'has changed' flag
- //}
} catch (DebugException e) { // That's, because of the hasVariables method
}
}
if (n == varListNew.size()) { // Did not find the 'static' list variable within the 'DBG' list?
- varListOld.remove(o); // then remove the 'static' list variable from list
- o -= 1; // Adjust the 'static' list index
+ varListOld.remove(o--); // then remove the 'static' list variable from list
}
}
}
* A PHPVariable with the same name but with different object ID is
* handled as a new variable.
*
- * TODO Remove the intermediate storage array
- *
* @return The array of PHPVariables for this stackframe.
*/
public IVariable[] getVariables() throws DebugException {
- if (!isUpToDate()) {
- resetHasChangedInfo(varList);
- updateVariableList(varList, this.getPHPDBGProxy().readVariables(this));
- setUpToDate(true);
- Collections.sort(varList, new PHPVariableComparator());
- //variables = (PHPVariable[]) varList.toArray(new PHPVariable[varList.size()]);
- //Arrays.sort(variables, new PHPVariableComparator());
+ if (!fUpToDate) {
+ resetHasChangedInfo (varList);
+ updateVariableList (varList, this.getPHPDBGProxy ().readVariables (this));
+ fUpToDate = true;
+
+ variables = (PHPVariable[]) varList.toArray (new PHPVariable[varList.size ()]);
+ Arrays.sort (variables, new PHPVariableComparator ());
+/*
+ Collections.sort (varList, new PHPVariableComparator ());
+ */
}
- //return variables; // Give the array back to user interface
- return (PHPVariable[]) varList.toArray(new PHPVariable[varList.size()]);
+// return (PHPVariable[]) varList.toArray (new PHPVariable[varList.size ()]);
+
+ return variables; // Give the array back to user interface
}
/**
int i;
for (i = 0; i < varList.size(); i++) { // For all variables
- variable = (PHPVariable) varList.get(i); // Get the variable
- value = (PHPValue) variable.getValue(); // Get the value of the variable
+ variable = (PHPVariable) varList.get (i); // Get the variable
+ value = (PHPValue) variable.getValue (); // Get the value of the variable
try {
- if (value.hasVariables()) { // Does the variable/value have children
- if (!hasRecursion(variable)) { // Don't follow recursive variable/values
- variable = findVariable(value.getChildVariables(),
- varname);
+ if (value.hasVariables ()) { // Does the variable/value have children
+ if (!hasRecursion (variable)) { // Don't follow recursive variable/values
+ PHPVariable var = findVariable (value.getChildVariables(), varname);
- if (variable != null) {
- return variable;
+ if (var != null) {
+ return var;
}
}
- } else if ((variable.getName()).equals(varname)) { //
- return variable; //
+ }
+
+ if (variable.getName().equals (varname)) {
+ return variable;
}
} catch (DebugException e) { // That's, because of the hasVariables method
}
* @return
*/
public IVariable findVariable(String s) throws DebugException {
- if (!isUpToDate()) {
- //resetHasChangedInfo(varList);
- //updateVariableList(varList, this.getPHPDBGProxy().readVariables(this));
- //setUpToDate(true);
- //variables = (PHPVariable[]) varList.toArray(new PHPVariable[varList.size()]);
+ if (!fUpToDate) {
getVariables();
}
*
*/
public boolean hasVariables() throws DebugException {
- return true;
- // return (varList.size () > 0);
+ if (!fUpToDate) {
+ getVariables();
+ }
+
+ return (varList.size() > 0);
}
public int getLineNumber() {
StringBuffer name = new StringBuffer();
if (!this.getDescription().equals("")) {
- name.append(this.getDescription());
+ name.append (this.getDescription());
} else {
- name.append(this.getFileName());
+ name.append (this.getFileName());
}
- name.append(" [line ");
- name.append(this.getLineNumber());
- name.append("]");
+ name.append (" [line ");
+ name.append (this.getLineNumber());
+ name.append ("]");
+
+ if (fDebug) {
+ System.out.println ("PHPStackFrame getName: " + name.toString ());
+ }
return name.toString();
}
*
*/
public void stepInto() throws DebugException {
- DebugEvent ev;
-
- setUpToDate(false);
+ fUpToDate = false;
thread.prepareForResume(DebugEvent.STEP_INTO); // Don't know why, but this is necessary
this.getPHPDBGProxy().readStepIntoEnd(PHPStackFrame.this);
-
+
// 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 });
}
*
*/
public void stepOver() throws DebugException {
- DebugEvent ev;
-
- setUpToDate(false);
+ fUpToDate = false;
thread.prepareForResume(DebugEvent.STEP_OVER);
this.getPHPDBGProxy().readStepOverEnd(PHPStackFrame.this);
// See comment within the previous stepInto method.
- //
+ //
//ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_OVER);
//DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev });
}
*
*/
public void stepReturn() throws DebugException {
- DebugEvent ev;
-
- setUpToDate(false);
+ fUpToDate = false;
thread.prepareForResume(DebugEvent.STEP_RETURN);
this.getPHPDBGProxy().readStepReturnEnd(PHPStackFrame.this);
}
public void resume() throws DebugException {
- setUpToDate(false);
+ fUpToDate = false;
+
this.getThread().resume();
}
public void setFile(String file) {
this.file = file;
+
+ final String COMPILED_EVAL = "eval()'d code";
+ final String COMPILED_LAMBDA = "runtime-created function";
+
+ int i = 0;
+ if (file.endsWith(COMPILED_EVAL)) {
+ i = file.length() - COMPILED_EVAL.length();
+ } else if (file.endsWith(COMPILED_LAMBDA)) {
+ i = file.length() - COMPILED_LAMBDA.length();
+ }
+ if (i > 0) {
+ // assume COMPILED_STRING_DESCRIPTION_FORMAT
+ // "filename(linenumber) : string"
+ int j = i;
+ while (--i > 0) {
+ switch (file.charAt(i)) {
+ case ')':
+ j = i;
+ break;
+ case '(':
+ this.file = file.substring(0, i);
+ try {
+ lineNumber = Integer.parseInt(file.substring(i + 1, j));
+ } catch (NumberFormatException e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ return;
+ }
+ }
+ }
}
public int getModNo() {
* @return
* <ul>
* <li> -1 if the index of this stackframe is less.
- * <li> 0 if the index of both stackfream is equal (should no happen).
- * <li> 1 if the index of this stackfram is greater.
+ * <li> 0 if the index of both stackframes are equal (should no happen).
+ * <li> 1 if the index of this stackframe is greater.
* </ul>
*/
- public int compareTo(Object obj) {
- //if (index < ((PHPStackFrame) obj).getIndex()) {
- // return -1;
- //} else if (index > ((PHPStackFrame) obj).getIndex()) {
- // return 1;
- //}
-
- //return 0;
- return Integer.signum(index - ((PHPStackFrame) obj).getIndex());
+ public int compareTo (Object obj) {
+ if (!(obj instanceof PHPStackFrame)) {
+ throw new IllegalArgumentException ("A PHPStackFrame can only be compared with another PHPStackFrame");
+ }
+
+ int frameIndex = ((PHPStackFrame) obj).getIndex();
+
+ if (index < frameIndex) {
+ return -1;
+ } else if (index > frameIndex) {
+ return 1;
+ }
+
+ return 0;
}
}