Modified: 1764120 - Variables View doesn't show global vars in class context
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 0ae3bc0..79a9ae5 100644 (file)
@@ -14,13 +14,14 @@ package net.sourceforge.phpdt.internal.debug.core;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Vector;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.Vector;
 
 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
-import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
@@ -31,28 +32,31 @@ import org.eclipse.debug.core.DebugException;
  *
  */
 public class PHPDBGInterface {
-       public boolean                  sessionEnded = false;
-       public int                              sessType         = -1;
-       public int                              BPUnderHit       = 0;
-       public String                   sessID           = new String ();
-
-       private int[]                   LastBPRead   = new int[10];
-       private Vector                  DBGBPList    = new Vector ();
-       private Vector          DBGVarList   = new Vector ();
-       private PHPStackFrame[] DBGStackList;
-       private Vector                  DBGMods          = new Vector ();                       // The module names and their numbers
-       private Vector          stackListOld = new Vector ();
+       public boolean                  sessionEnded = false;
+       public int                              sessType = -1;
+       public int                              BPUnderHit = 0;
+       public String                           sessID = new String();
+
+       private int[]                           LastBPRead = new int[10];
+       private Vector                  DBGBPList = new Vector();
+       private Vector                  DBGVarList = new Vector();
+       private PHPStackFrame[]         DBGStackList = new PHPStackFrame[0];
+       private Vector                  DBGMods = new Vector();                         // The module names and their numbers
+       private Vector                  stackListOld = new Vector();
        private BufferedReader  in;
-       private OutputStream    os;                                                                             // The stream which goes to DBG
-       private boolean                 shouldStop       = false;
-       private String                  evalRet          = new String ("");
-       private String                  serGlobals       = new String ("");
-       private int                     rawCounter       = 1000;                                        // An rawData frame ID counter
-       private PHPDBGProxy     proxy            = null;
-       private int                     lastCmd          = -1;
-       private int                     sid                      = 0;
-       private boolean                 stopOnError      = false;
-       private char[]                  lastCommand      = new char[4];
+       private OutputStream            os;                                                             // The stream which goes to DBG
+       private boolean                         shouldStop = false;
+       private String                  evalRet = new String("");
+       //private String                        serGlobals = new String("");
+       private int                             rawCounter = 1000;                                      // An rawData frame ID counter
+       private PHPDBGProxy             proxy = null;
+       private int                             lastCmd = -1;
+       private int                             sid = 0;
+       private boolean                         stopOnError = false;
+       private char[]                  lastCommand = new char[4];
+
+       private static final String GlobalVariablesTitle = PHPDebugCorePlugin
+                       .getResourceString("VariablesView.GlobalVariables.title");
 
        /**
         * @param in    The input stream (communication from DBG).
@@ -418,52 +422,121 @@ public class PHPDBGInterface {
         * @param stack The stackframe for which we want the variables.
         * @return      The array of variables
         */
-       public synchronized Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
+       public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
                PHPDBGPacket            DBGPacket;
-               PHPDBGFrame             DBGFrame1;
+               PHPDBGFrame             DBGFrame1;
                PHPDBGEvalString        evalStr;
 
-               DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     //
-           DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL);        //
-
-               DBGFrame1.addInt (0);                                                                           // istr = raw data ID
-               DBGFrame1.addInt (1);                                                                           // scope_id = -1 means current location, 0 never used, +1 first depth
-
-               DBGPacket.addFrame (DBGFrame1);                             // Add command data
-
-               if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-                       return new Vector ();                                                                   // No, then leave here with an empty vector 
+               Vector globalList = new Vector();
+               // IStackFrame[] stacks = stack.getThread().getStackFrames();
+               // ( PHPStackFrame.getThread().getStackFrames() returns DBGStackList )
+               if (DBGStackList.length > 1) {
+                       // get global variables (and assign them to 'main()' stackframe)
+                       globalList = getVariables(DBGStackList[DBGStackList.length - 1], PHPDBGBase.GLOBAL_SCOPE_ID);
+                       if (!globalList.isEmpty()) {
+                               // remove unexpected '$this=?' variable
+                               PHPVariable var = (PHPVariable) globalList.get(0);
+                               PHPValue val = (PHPValue) var.getValue();
+                               Vector workList = val.getChildVariables();
+                               for (int i = 0; i < workList.size(); i++) {
+                                       if (((PHPVariable) workList.get(i)).getName().equals("$this")) {
+                                               workList.remove(i);
+                                               break;
+                                       }
+                               }
+                               var.setName(GlobalVariablesTitle);
+                               var.setModifiable(false);
+                       }
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
-
-               waitResponse (1000);                                        // Wait for the DBG response (1 second)
-               flushAllPackets ();                                         // Read and process the response from DBG
-
-               evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
-               DBGVarList      = evalStr.getVariables ();
+//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     //
+//         DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL);        //
+//
+//             DBGFrame1.addInt (0);                                                                           // istr = raw data ID
+//             DBGFrame1.addInt (1);                                                                           // scope_id = -1 means current location, 0 never used, +1 first depth
+//
+//             DBGPacket.addFrame (DBGFrame1);                             // Add command data
+//
+//             if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
+//                     return new Vector ();                                                                   // No, then leave here with an empty vector 
+//             }
+//
+//             serGlobals = "";
+//             DBGPacket.sendPacket (os);                                  // Send the request to DBG
+//
+//             waitResponse (1000);                                        // Wait for the DBG response (1 second)
+//             flushAllPackets ();                                         // Read and process the response from DBG
+//
+//             evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
+//             DBGVarList      = evalStr.getVariables ();
+
+               int scopeID = stack.getScopeID(); 
+               if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
+                       // current stackframe
+                       DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
+               } else if ((scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1) && !globalList.isEmpty()) {
+                       // 'main()' stackframe
+                       PHPVariable var = (PHPVariable) globalList.get(0);
+                       PHPValue val = (PHPValue) var.getValue();
+                       DBGVarList = val.getChildVariables();
+                       return DBGVarList;
+               } else {
+                       // back-trace stackframe
+                       // Never: DBGVarList = getVariables(stack, scopeID);
+                       // DBG 2.15.5 causes Application Error (on win32) in some cases
+                       DBGVarList.clear();
+               }
 
-               if (DBGVarList.size () > 0) {                                                           // Did we get back variables?
-                       PHPVariable var = (PHPVariable) DBGVarList.get (0);             // Yes, then get the first PHPVariable
-                       PHPValue    val = (PHPValue) var.getValue ();           // Get the value
+               if (DBGVarList.size() > 0) {                                                            // Did we get back variables?
+                       PHPVariable var = (PHPVariable) DBGVarList.get(0);              // Yes, then get the first PHPVariable
+                       PHPValue    val = (PHPValue) var.getValue();                    // Get the value
 
-                       if (var.getName ().equals ("")) {                                               // Is the root node an empty node (usually it is)
-                               DBGVarList = val.getChildVariables ();              // Then remove the empty node.
+                       if (var.getName().equals("")) {                                                 // Is the root node an empty node (usually it is)
+                               DBGVarList = val.getChildVariables();                           // Then remove the empty node.
                                                                                                                                        // With removing the empty root node, it wouldn't be necessary to
                                                                                                                                        // set the name to an empty string. So the code below is just for
                                                                                                                                        // info or in case the users want to have the empty root node.
 
                                                                                                                                        // The eclipse variable view cannot handle Variables which have an empty name
                                                                                                                                        // when it comes to variable tree restore operation. Without a name, no restore!
-                               var.setName (" ");                                                              // Give a name to the variable root node. Even if it is only a space :-)
+                               //var.setName (" ");                                                            // Give a name to the variable root node. Even if it is only a space :-)
                        }                                                                                                               // TODO the best would be to remove the empty root node, but this would
                                                                                                                                        // require a understanding and reworking of the PHPDBGEvalstring class.
                }
 
+               if (!globalList.isEmpty()) {
+                       DBGVarList.add(globalList.get(0));
+               }
+
                return DBGVarList;                                                                                      // Return the variables as list
        }
 
        /**
+        * 
+        * @throws IOException 
+        */
+       private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
+               PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+               PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
+
+               DBGFrame1.addInt(0);
+               DBGFrame1.addInt(scope_id);
+
+               DBGPacket.addFrame(DBGFrame1);
+               evalRet = "";
+
+               if (proxy.getSocket().isClosed()) {
+                       return new Vector();
+               }
+               DBGPacket.sendPacket(os);
+               waitResponse(1000);
+               flushAllPackets();
+
+               PHPDBGEvalString evalStr = new PHPDBGEvalString(stack, evalRet);
+               return evalStr.getVariables();
+       }
+
+       /**
         *
         * @param logString
         */
@@ -500,14 +573,15 @@ public class PHPDBGInterface {
                flushAllPackets();
        }
 
-       public synchronized 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);
 
                rawCounter++;
                DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
-               DBGFrame1.addInt(1);                                            // scope_id = -1 means current location, 0 never used, +1 first depth
+               //DBGFrame1.addInt(1);                                          // scope_id = -1 means current location, 0 never used, +1 first depth
+               DBGFrame1.addInt(stack.getScopeID());
 
                DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
                DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
@@ -519,8 +593,8 @@ public class PHPDBGInterface {
                // Add command data
                DBGPacket.addFrame(DBGFrame1);
 
-               if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-                       return null;                                                                                    //  No, then leave here
+               if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
+                       return null;                                                    //  No, then leave here
                }
                DBGPacket.sendPacket(os);
 
@@ -530,7 +604,6 @@ public class PHPDBGInterface {
                PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
 
                return evalStr.getVars();
-
        }
 
        /**
@@ -660,6 +733,7 @@ public class PHPDBGInterface {
                                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 ());
+                stackFrameOld.setScopeID(stackFrameNew.getScopeID());
                                return true;                                                            // The stackframe was found in the list
                        }
                }
@@ -741,6 +815,7 @@ public class PHPDBGInterface {
                                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.setScopeID(stackFrameNew.getScopeID());
 
                                        stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
                                        stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
@@ -859,7 +934,8 @@ public class PHPDBGInterface {
                                                                                                                  stackIndex,
                                                                                                                  getRawFrameData (entirePack,          // Get the string from this packet
                                                                                                                                   dbg_stack_new[3]),   // The frame ID for which we want the string
-                                                                                                                 dbg_stack_new[1]);                                    // The module number
+                                                                                                                 dbg_stack_new[1],                                     // The module number
+                                                                                                                 dbg_stack_new[2]);
                                                        stackList.add (newStack);
                                                }
 
@@ -959,7 +1035,7 @@ public class PHPDBGInterface {
 
                                                evalRet                 = getRawFrameData (entirePack, dbg_eval_tmp[1]);                //
                                                evalString              = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
-                                               serGlobals              = evalRet;                                                      //
+                                               //serGlobals            = evalRet;                                                      //
                                                break;
 
                                        case PHPDBGBase.FRAME_BPS:                                                          //