Bug 299167, turn the Variable View's Address column into a Location column.
authorryall
Tue, 12 Jan 2010 07:49:28 -0600
changeset 129 723898599d35
parent 127 b32168b846ac
child 130 51404ed29eed
Bug 299167, turn the Variable View's Address column into a Location column.
cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java	Tue Dec 15 14:25:31 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java	Tue Jan 12 07:49:28 2010 -0600
@@ -22,10 +22,10 @@
     public static String VariableColumnPresentation_name;
     public static String VariableColumnPresentation_type;
     public static String VariableColumnPresentation_value;
-    public static String VariableColumnPresentation_address;
+    public static String VariableColumnPresentation_location;
 
-    public static String VariableVMNode_Address_column__Error__text_format;
-    public static String VariableVMNode_Address_column__text_format;
+    public static String VariableVMNode_Location_column__Error__text_format;
+    public static String VariableVMNode_Location_column__text_format;
     public static String VariableVMNode_Description_column__text_format;
     public static String VariableVMNode_Expression_column__text_format;
     public static String VariableVMNode_Name_column__text_format;
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java	Tue Dec 15 14:25:31 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableColumnPresentation.java	Tue Jan 12 07:49:28 2010 -0600
@@ -42,7 +42,7 @@
         } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) {
             return MessagesForVariablesVM.VariableColumnPresentation_value;
         } else if (IDebugVMConstants.COLUMN_ID__ADDRESS.equals(id)) {
-        	return MessagesForVariablesVM.VariableColumnPresentation_address;
+        	return MessagesForVariablesVM.VariableColumnPresentation_location;
         } 
         return null;
     }
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java	Tue Dec 15 14:25:31 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java	Tue Jan 12 07:49:28 2010 -0600
@@ -17,7 +17,6 @@
 import java.util.Map;
 import java.util.concurrent.RejectedExecutionException;
 
-import org.eclipse.cdt.core.IAddress;
 import org.eclipse.cdt.debug.internal.ui.CDebugImages;
 import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
 import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
@@ -26,7 +25,6 @@
 import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
 import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
 import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
-import org.eclipse.cdt.dsf.concurrent.MultiRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
 import org.eclipse.cdt.dsf.datamodel.DMContexts;
 import org.eclipse.cdt.dsf.datamodel.IDMContext;
@@ -37,6 +35,7 @@
 import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
 import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
 import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMData;
+import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMLocation;
 import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
 import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
 import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
@@ -51,6 +50,7 @@
 import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext;
 import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
 import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
 import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
 import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
 import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
@@ -132,7 +132,7 @@
      *  
      * @since 2.0
      */    
-    private IElementLabelProvider fLabelProvider;
+    private final IElementLabelProvider fLabelProvider;
 
     public class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext  {
         
@@ -375,9 +375,9 @@
             IDebugVMConstants.COLUMN_ID__ADDRESS,
             new LabelColumnInfo(new LabelAttribute[] { 
                 new LabelText(
-                    MessagesForVariablesVM.VariableVMNode_Address_column__text_format, 
+                    MessagesForVariablesVM.VariableVMNode_Location_column__text_format, 
                     new String[] { PROP_VARIABLE_ADDRESS }),
-                new LabelText(MessagesForVariablesVM.VariableVMNode_Address_column__Error__text_format, new String[] {}), 
+                new LabelText(MessagesForVariablesVM.VariableVMNode_Location_column__Error__text_format, new String[] {}), 
                 new LabelBackground(
                     DebugUITools.getPreferenceColor(IDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB()) 
                 {
@@ -706,16 +706,10 @@
     @ConfinedToDsfExecutor("getSession().getExecutor()")
     protected void fillAddressDataProperties(IPropertiesUpdate update, IExpressionDMAddress address)
     { 
-	    IExpressionDMAddress expression = address;
-	    Object expAddress = expression.getAddress();
-
-	    String addrString = ""; //$NON-NLS-1$
-	    if (expAddress instanceof IAddress)
-	    	addrString = "0x" + ((IAddress)expAddress).toString(16); //$NON-NLS-1$
-	    else if (expAddress instanceof String)
-	    	addrString = (String)expAddress;
-
-	    update.setProperty(PROP_VARIABLE_ADDRESS, addrString);
+    	if (address instanceof IExpressionDMLocation)
+    		update.setProperty(PROP_VARIABLE_ADDRESS, ((IExpressionDMLocation)address).getLocation());
+    	else
+    		update.setProperty(PROP_VARIABLE_ADDRESS, "0x" + address.getAddress().toString(16)); //$NON-NLS-1$
     }
     
     public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
@@ -898,36 +892,35 @@
                     
                     // Create the MultiRequestMonitor to handle completion of the set of getModelData() calls.
                     
-                    final MultiRequestMonitor<DataRequestMonitor<IVariableDMData>> mrm =
-                        new MultiRequestMonitor<DataRequestMonitor<IVariableDMData>>(dsfExecutor, null) {
-                            @Override
-                            public void handleCompleted() {
-                                // Now that all the calls to getModelData() are complete, we create an
-                                // IExpressionDMContext object for each local variable name, saving them all
-                                // in an array.
+                    final CountingRequestMonitor crm = new ViewerCountingRequestMonitor(dsfExecutor, update) {
+                        @Override
+                        public void handleCompleted() {
+                            // Now that all the calls to getModelData() are complete, we create an
+                            // IExpressionDMContext object for each local variable name, saving them all
+                            // in an array.
 
-                                if (!isSuccess()) {
-                                    handleFailedUpdate(update);
-                                    return;
-                                }
-         
-                                IExpressionDMContext[] expressionDMCs = new IExpressionDMContext[localsDMData.size()];
-                                
-                                int i = 0;
-                                
-                                for (IVariableDMData localDMData : localsDMData) {
-                                    expressionDMCs[i++] = expressionService.createExpression(frameDmc, localDMData.getName());
-                                }
+                            if (!isSuccess()) {
+                                handleFailedUpdate(update);
+                                return;
+                            }
+     
+                            IExpressionDMContext[] expressionDMCs = new IExpressionDMContext[localsDMData.size()];
+                            
+                            int i = 0;
+                            for (IVariableDMData localDMData : localsDMData) {
+                                expressionDMCs[i++] = expressionService.createExpression(frameDmc, localDMData.getName());
+                            }
 
-                                // Lastly, we fill the update from the array of view model context objects
-                                // that reference the ExpressionDMC objects for the local variables.  This is
-                                // the last code to run for a given call to updateElementsInSessionThread().
-                                // We can now leave anonymous-inner-class hell.
+                            // Lastly, we fill the update from the array of view model context objects
+                            // that reference the ExpressionDMC objects for the local variables.  This is
+                            // the last code to run for a given call to updateElementsInSessionThread().
+                            // We can now leave anonymous-inner-class hell.
 
-                                fillUpdateWithVMCs(update, expressionDMCs);
-                                update.done();
-                            }
+                            fillUpdateWithVMCs(update, expressionDMCs);
+                            update.done();
+                        }
                     };
+                    int countRM = 0;
                     
                     // Perform a set of getModelData() calls, one for each local variable's data model
                     // context object.  In the handleCompleted() method of the DataRequestMonitor, add the
@@ -935,18 +928,18 @@
                     
                     for (IVariableDMContext localDMC : localsDMCs) {
                         DataRequestMonitor<IVariableDMData> rm =
-                            new ViewerDataRequestMonitor<IVariableDMData>(dsfExecutor, update) {
+                            new DataRequestMonitor<IVariableDMData>(dsfExecutor, crm) {
                                 @Override
-                                public void handleCompleted() {
+                                public void handleSuccess() {
                                     localsDMData.add(getData());
-                                    mrm.requestMonitorDone(this);
+                                    crm.done();
                                 }
                         };
                         
-                        mrm.add(rm);
-                        
                         stackFrameService.getVariableData(localDMC, rm);
+                        countRM++;
                     }
+                    crm.setDoneCount(countRM);
                 }
         };
 
@@ -963,7 +956,6 @@
              (e instanceof PropertyChangeEvent &&
               ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) ) 
         {
-            // Create a delta that the whole register group has changed.
             return IModelDelta.CONTENT;
         } 
 
@@ -980,7 +972,6 @@
              (e instanceof PropertyChangeEvent &&
               ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) ) 
         {
-            // Create a delta that the whole register group has changed.
             parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
         } 
 
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java	Tue Dec 15 14:25:31 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java	Tue Jan 12 07:49:28 2010 -0600
@@ -11,8 +11,10 @@
  *******************************************************************************/
 package org.eclipse.cdt.dsf.debug.service;
 
+import java.math.BigInteger;
 import java.util.Map;
 
+import org.eclipse.cdt.core.IAddress;
 import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
 import org.eclipse.cdt.dsf.datamodel.IDMContext;
@@ -40,14 +42,61 @@
          */
         String getExpression();
     }
-    
+
+
     /**
      * The address and size of an expression.
      */
     public interface IExpressionDMAddress {
-    	Object getAddress();
+        
+        /**
+         * Returns the address of the expression.
+         */
+    	IAddress getAddress();
+    	
+    	/**
+    	 * Returns the size of the address.
+    	 */
     	int getSize();
     }
+ 
+    /**
+     * A representation of an expression location that does not correspond to 
+     * an address.  
+     * 
+     * @since 2.1
+     */
+    public interface IExpressionDMLocation extends IExpressionDMAddress {
+        
+        /**
+         * A constant that can be returned by {@link IExpressionDMAddress#getAddress()}
+         * to represent an invalid address.  Implementations of 
+         * <code>IExpressionDMLocation</code> can return this constant if no  
+         * valid address can be returned for a given expression location.  
+         */
+        public static final IAddress INVALID_ADDRESS = new IAddress() {
+            public IAddress add(BigInteger offset) { return this; }
+            public IAddress add(long offset) { return this; }
+            public BigInteger getMaxOffset() { return BigInteger.ZERO; }
+            public BigInteger distanceTo(IAddress other) { return BigInteger.ZERO; }
+            public BigInteger getValue() { return BigInteger.ZERO; }
+            public boolean isZero() { return false; }
+            public boolean isMax() { return false; }
+            public String toString(int radix) { return "INVALID"; }
+            public String toHexAddressString() { return toString(); }
+            public String toBinaryAddressString()  { return toString(); }
+            public int getCharsNum() { return 0; }
+            public int getSize() { return 0; }
+            public int compareTo(Object o) { return 0; }
+        };
+        
+        /**
+         * Returns a string representation of the expression location.
+         */
+    	public String getLocation();
+    }
+
+    
     
     /**
      * This is the model data interface that corresponds to IExpressionDMContext.
@@ -139,7 +188,9 @@
     /**
      * Retrieves the address and size of an expression given by the expression context(<tt>dmc</tt>).
      * Non-lvalues do not have an addresses (e.g., "x + 5").  When the expression
--    * has no address, the data request monitor will contain null.
+-    * has no address, the request monitor will have an error with code 
+     * <code>IDsfStatusConstants.REQUEST_FAILED</code> and the data request
+     * monitor will contain null.
      * 
      * @param dmc
      *            The ExpressionDMC for the expression
@@ -157,14 +208,18 @@
      *                
      * @param expression: The expression to evaluate.
      * 
-     * @return  An expression data model context object that must be passed to 
-     * getModelData() to obtain the value of the expression. 
+     * @return  An expression data model context object that must be passed to the appropriate
+     *          data retrieval routine to obtain the value of the expression.
      */
     IExpressionDMContext createExpression(IDMContext ctx, String expression);
 
     /**
      * Retrieves the sub-expressions of the given expression.  Sub-expressions are fields of a struct, union,
      * or class, the enumerators of an enumeration, and the element of an array.
+     * <br> 
+     * Note: Clients may call this method on any valid expression context, and before calling any other
+     * method to evaluate the expression value.  It is up to the implementation to internally evaluate the 
+     * expression if needed, in order to calculate sub expressions.    
      * 
      * @param exprCtx: The data model context representing an expression.
      * 
@@ -176,6 +231,10 @@
      * Retrieves a particular range of sub-expressions of the given expression.  
      * Sub-expressions are fields of a struct, union, or class, the enumerators 
      * of an enumeration, and the element of an array.
+     * <br> 
+     * Note: Clients may call this method on any valid expression context, and before calling any other
+     * method to evaluate the expression value.  It is up to the implementation to internally evaluate the 
+     * expression if needed, in order to calculate sub expressions.    
      * 
      * @param exprCtx: The data model context representing an expression.
      *        startIndex: Index of the first sub-expression to retrieve
@@ -190,6 +249,10 @@
     /**
      * Retrieves the number of sub-expressions of the given expression.  Sub-expressions are fields of a struct, union,
      * or class, the enumerators of an enumeration, and the element of an array.
+     * <br> 
+     * Note: Clients may call this method on any valid expression context, and before calling any other
+     * method to evaluate the expression value.  It is up to the implementation to internally evaluate the 
+     * expression if needed, in order to calculate sub expressions.    
      * 
      * @param exprCtx: The data model context representing an expression.
      * 
@@ -201,6 +264,10 @@
     /**
      * For object oriented languages, this method returns the expressions representing base types of
      * the given expression type.
+     * <br> 
+     * Note: Clients may call this method on any valid expression context, and before calling any other
+     * method to evaluate the expression value.  It is up to the implementation to internally evaluate the 
+     * expression if needed, in order to calculate sub expressions.    
      * 
      * @param exprContext: The data model context representing an expression.
      *