Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Swartz2010-03-24 20:32:55 +0000
committerEd Swartz2010-03-24 20:32:55 +0000
commit2cfb9a353a74ebc9e83512416b8f5f0cd264998a (patch)
tree3d53ba0635cbf4e314377232bdb6775c5d42b135
parent1ba8d3916d0eb69237907c90db11b341b635f04b (diff)
downloadorg.eclipse.cdt-2cfb9a353a74ebc9e83512416b8f5f0cd264998a.tar.gz
org.eclipse.cdt-2cfb9a353a74ebc9e83512416b8f5f0cd264998a.tar.xz
org.eclipse.cdt-2cfb9a353a74ebc9e83512416b8f5f0cd264998a.zip
Fix bug 306553 by generalizing Cast To Type / Display As Array UI so it can be implemented by adapters. In DSF, add IExpressions2 service to implement this support.
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.properties5
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.xml166
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionHandler.java (renamed from debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionDelegate.java)77
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionHandler.java (renamed from debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionDelegate.java)82
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionHandler.java (renamed from debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionDelegate.java)75
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/DsfCastToTypeSupport.java232
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java11
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java4
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java60
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java11
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/messages.properties1
-rw-r--r--dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java5
-rw-r--r--dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java179
13 files changed, 715 insertions, 193 deletions
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties
index 2f0b4e2344a..223dd8b463a 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties
@@ -243,4 +243,7 @@ SaveTraceData.name=Save Trace Data
viewMemory.label = View Memory
disassemblyViewMenu.label = disassemblyViewMenu
sourceNotFoundEditor.name = C/C++ Source Not Found Editor
-displayMode.name = displayMode \ No newline at end of file
+displayMode.name = displayMode
+CastingCategory.description = Set of commands for typecasting variables and expressions.
+CastingCategory.name = Cast to Type or ArrayCastingCategory.description = Set of commands for typecasting variables and expressions.
+CastingCategory.name = Cast to Type or Array \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml
index e1bc7677229..e3b544aaf97 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml
@@ -593,57 +593,6 @@
</action>
</objectContribution>
<objectContribution
- objectClass="org.eclipse.cdt.debug.core.model.ICastToType"
- id="org.eclipse.cdt.debug.ui.VariableActions">
- <action
- label="%RestoreDefaultTypeAction.label"
- helpContextId="restore_default_type_action_context"
- tooltip="%RestoreDefaultTypeAction.tooltip"
- class="org.eclipse.cdt.debug.internal.ui.actions.RestoreDefaultTypeActionDelegate"
- menubarPath="variableGroup"
- enablesFor="1"
- id="org.eclipse.cdt.debug.internal.ui.actions.RestoreDefaultTypeActionDelegate">
- <enablement>
- <pluginState
- value="activated"
- id="org.eclipse.cdt.debug.ui">
- </pluginState>
- </enablement>
- </action>
- <action
- label="%CastToTypeAction.label"
- icon="icons/elcl16/casttotype_co.gif"
- helpContextId="cast_to_type_action_context"
- tooltip="%CastToTypeAction.tooltip"
- class="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionDelegate"
- menubarPath="variableGroup"
- enablesFor="1"
- id="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionDelegate">
- <enablement>
- <pluginState
- value="activated"
- id="org.eclipse.cdt.debug.ui">
- </pluginState>
- </enablement>
- </action>
- <action
- label="%CastToArrayAction.label"
- icon="icons/elcl16/showasarray_co.gif"
- helpContextId="cast_to_array_action_context"
- tooltip="%CastToArrayAction.tooltip"
- class="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionDelegate"
- menubarPath="variableGroup"
- enablesFor="1"
- id="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionDelegate">
- <enablement>
- <pluginState
- value="activated"
- id="org.eclipse.cdt.debug.ui">
- </pluginState>
- </enablement>
- </action>
- </objectContribution>
- <objectContribution
objectClass="org.eclipse.cdt.core.model.IFunction"
id="org.eclipse.cdt.debug.ui.FunctionBreakpointActions">
<action
@@ -2360,4 +2309,119 @@
</action>
</viewerContribution>
</extension>
+
+ <!-- Cast to Type / Display as Array -->
+ <extension
+ point="org.eclipse.ui.commands">
+
+ <category
+ description="%CastingCategory.description"
+ id="org.eclipse.cdt.debug.ui.category.casting"
+ name="%CastingCategory.name">
+ </category>
+
+ <command id="org.eclipse.cdt.debug.ui.command.restoreDefaultType"
+ categoryId="org.eclipse.cdt.debug.ui.category.casting"
+ description="%BreakpointPropertiesCommand.description"
+ helpContextId="restore_default_type_action_context"
+ name="%RestoreDefaultTypeAction.label">
+ </command>
+
+ <command id="org.eclipse.cdt.debug.ui.command.castToType"
+ name="%CastToTypeAction.label"
+ categoryId="org.eclipse.cdt.debug.ui.category.casting"
+ helpContextId="cast_to_type_action_context"
+ >
+ </command>
+
+ <command id="org.eclipse.cdt.debug.ui.command.castToArray"
+ name="%CastToTypeAction.label"
+ categoryId="org.eclipse.cdt.debug.ui.category.casting"
+ helpContextId="cast_to_array_action_context"
+ >
+ </command>
+ </extension>
+
+ <extension point="org.eclipse.ui.menus">
+
+ <!-- items for variables view... -->
+ <menuContribution
+ locationURI="popup:org.eclipse.debug.ui.VariableView?after=variableGroup">
+ <command commandId="org.eclipse.cdt.debug.ui.command.castToType"
+ label="%CastToTypeAction.label"
+ icon="icons/elcl16/casttotype_co.gif"
+ helpContextId="cast_to_type_action_context"
+ tooltip="%CastToTypeAction.tooltip"
+ id="org.eclipse.cdt.debug.menu.command.castToType">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command commandId="org.eclipse.cdt.debug.ui.command.castToArray"
+ label="%CastToArrayAction.label"
+ icon="icons/elcl16/showasarray_co.gif"
+ helpContextId="cast_to_array_action_context"
+ tooltip="%CastToArrayAction.tooltip"
+ id="org.eclipse.cdt.debug.menu.command.castToArray">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.cdt.debug.ui.command.restoreDefaultType"
+ helpContextId="restore_default_type_action_context"
+ id="org.eclipse.cdt.debug.menu.restoreDefaultType"
+ label="%RestoreDefaultTypeAction.label"
+ tooltip="%RestoreDefaultTypeAction.tooltip">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ </menuContribution>
+
+ <!-- items for expressions view... -->
+ <menuContribution
+ locationURI="popup:org.eclipse.debug.ui.ExpressionView?after=additions">
+ <command commandId="org.eclipse.cdt.debug.ui.command.castToType"
+ label="%CastToTypeAction.label"
+ icon="icons/elcl16/casttotype_co.gif"
+ helpContextId="cast_to_type_action_context"
+ tooltip="%CastToTypeAction.tooltip"
+ id="org.eclipse.cdt.debug.menu.command.castToType">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command commandId="org.eclipse.cdt.debug.ui.command.castToArray"
+ label="%CastToArrayAction.label"
+ icon="icons/elcl16/showasarray_co.gif"
+ helpContextId="cast_to_array_action_context"
+ tooltip="%CastToArrayAction.tooltip"
+ id="org.eclipse.cdt.debug.menu.command.castToArray">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.cdt.debug.ui.command.restoreDefaultType"
+ helpContextId="restore_default_type_action_context"
+ id="org.eclipse.cdt.debug.menu.restoreDefaultType"
+ label="%RestoreDefaultTypeAction.label"
+ tooltip="%RestoreDefaultTypeAction.tooltip">
+ <visibleWhen checkEnabled="true">
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.cdt.debug.internal.ui.actions.RestoreDefaultTypeActionHandler"
+ commandId="org.eclipse.cdt.debug.ui.command.restoreDefaultType">
+ </handler>
+ <handler
+ class="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionHandler"
+ commandId="org.eclipse.cdt.debug.ui.command.castToType">
+ </handler>
+ <handler
+ class="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionHandler"
+ commandId="org.eclipse.cdt.debug.ui.command.castToArray">
+ </handler>
+ </extension>
</plugin>
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionHandler.java
index 1c84bcba07d..3e37a31b1f3 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionDelegate.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToArrayActionHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 QNX Software Systems and others.
+ * Copyright (c) 2004, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Nokia - adapt to new command framework
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions;
@@ -16,11 +17,10 @@ import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.ui.IDebugView;
-import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
@@ -38,15 +38,19 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
/**
* The delegate of the "Display As Array" action.
*/
-public class CastToArrayActionDelegate extends ActionDelegate implements IObjectActionDelegate {
+public class CastToArrayActionHandler extends AbstractHandler {
protected class CastToArrayDialog extends Dialog {
@@ -227,27 +231,15 @@ public class CastToArrayActionDelegate extends ActionDelegate implements IObject
private IWorkbenchPart fTargetPart = null;
- public CastToArrayActionDelegate() {
+ public CastToArrayActionHandler() {
super();
}
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- */
- public void setActivePart( IAction action, IWorkbenchPart targetPart ) {
- fTargetPart = targetPart;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- */
- public void run( IAction action ) {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ fTargetPart = HandlerUtil.getActivePartChecked(event);
if ( getCastToArray() == null )
- return;
+ return null;
+
BusyIndicator.showWhile( Display.getCurrent(), new Runnable() {
public void run() {
@@ -269,27 +261,28 @@ public class CastToArrayActionDelegate extends ActionDelegate implements IObject
CDebugUIPlugin.log( getStatus() );
}
}
+
+ return null;
}
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
- */
- public void selectionChanged( IAction action, ISelection selection ) {
- if ( selection instanceof IStructuredSelection ) {
- Object element = ((IStructuredSelection)selection).getFirstElement();
- if ( element instanceof ICastToArray ) {
- boolean enabled = ((ICastToArray)element).canCastToArray();
- action.setEnabled( enabled );
- if ( enabled ) {
- setCastToArray( (ICastToArray)element );
- return;
- }
- }
- }
- action.setEnabled( false );
- setCastToArray( null );
+ @Override
+ public void setEnabled(Object evaluationContext) {
+ ICastToArray castToArray = getCastToArray(evaluationContext);
+ setBaseEnabled( castToArray != null );
+ setCastToArray(castToArray);
+ }
+
+ private ICastToArray getCastToArray(Object evaluationContext) {
+ if (evaluationContext instanceof IEvaluationContext) {
+ Object s = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_MENU_SELECTION_NAME);
+ if (s instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)s;
+ if (!ss.isEmpty()) {
+ return (ICastToArray)DebugPlugin.getAdapter(ss.getFirstElement(), ICastToArray.class);
+ }
+ }
+ }
+ return null;
}
protected ICastToArray getCastToArray() {
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionHandler.java
index 4dd86418456..1494871faef 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionDelegate.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CastToTypeActionHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 QNX Software Systems and others.
+ * Copyright (c) 2004, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,19 +7,23 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Nokia - adapt to new command framework
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions;
import org.eclipse.cdt.debug.core.model.ICastToType;
import org.eclipse.cdt.debug.internal.ui.CDebugImages;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.ui.IDebugView;
-import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
@@ -27,15 +31,15 @@ import org.eclipse.jface.window.Window;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.handlers.HandlerUtil;
/**
* The delegate of the "Cast To Type" action.
*/
-public class CastToTypeActionDelegate extends ActionDelegate implements IObjectActionDelegate {
+public class CastToTypeActionHandler extends AbstractHandler {
static protected class CastToTypeInputValidator implements IInputValidator {
@@ -74,29 +78,18 @@ public class CastToTypeActionDelegate extends ActionDelegate implements IObjectA
private IStatus fStatus = null;
- private IWorkbenchPart fTargetPart = null;
+ private IWorkbenchPart fTargetPart;
- public CastToTypeActionDelegate() {
+ public CastToTypeActionHandler() {
super();
}
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- */
- public void setActivePart( IAction action, IWorkbenchPart targetPart ) {
- fTargetPart = targetPart;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- */
- public void run( IAction action ) {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ fTargetPart = HandlerUtil.getActivePartChecked(event);
+
if ( getCastToType() == null )
- return;
+ return null;
+
BusyIndicator.showWhile( Display.getCurrent(), new Runnable() {
public void run() {
@@ -118,27 +111,28 @@ public class CastToTypeActionDelegate extends ActionDelegate implements IObjectA
CDebugUIPlugin.log( getStatus() );
}
}
+
+ return null;
}
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
- */
- public void selectionChanged( IAction action, ISelection selection ) {
- if ( selection instanceof IStructuredSelection ) {
- Object element = ((IStructuredSelection)selection).getFirstElement();
- if ( element instanceof ICastToType ) {
- boolean enabled = ((ICastToType)element).canCast();
- action.setEnabled( enabled );
- if ( enabled ) {
- setCastToType( (ICastToType)element );
- return;
- }
- }
- }
- action.setEnabled( false );
- setCastToType( null );
+
+ @Override
+ public void setEnabled(Object evaluationContext) {
+ ICastToType castToType = getCastToType(evaluationContext);
+ setBaseEnabled( castToType != null );
+ setCastToType(castToType);
+ }
+
+ private ICastToType getCastToType(Object evaluationContext) {
+ if (evaluationContext instanceof IEvaluationContext) {
+ Object s = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_MENU_SELECTION_NAME);
+ if (s instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)s;
+ if (!ss.isEmpty()) {
+ return (ICastToType)DebugPlugin.getAdapter(ss.getFirstElement(), ICastToType.class);
+ }
+ }
+ }
+ return null;
}
protected ICastToType getCastToType() {
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionHandler.java
index 71b4ed9dd3c..2bfb645f1f4 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionDelegate.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/RestoreDefaultTypeActionHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 QNX Software Systems and others.
+ * Copyright (c) 2004, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,40 +7,34 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Nokia - port to command framework
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions;
import org.eclipse.cdt.debug.core.model.ICastToType;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugException;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionDelegate;
/**
* The delegate of the "Restore Default Type" action.
*/
-public class RestoreDefaultTypeActionDelegate extends ActionDelegate implements IObjectActionDelegate {
+public class RestoreDefaultTypeActionHandler extends AbstractHandler {
private ICastToType fCastToType = null;
private IStatus fStatus = null;
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- */
- public void setActivePart( IAction action, IWorkbenchPart targetPart ) {
- }
-
protected ICastToType getCastToType() {
return fCastToType;
}
@@ -49,14 +43,10 @@ public class RestoreDefaultTypeActionDelegate extends ActionDelegate implements
fCastToType = castToType;
}
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- */
- public void run( IAction action ) {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
if ( getCastToType() == null )
- return;
+ return null;
+
BusyIndicator.showWhile( Display.getCurrent(), new Runnable() {
public void run() {
@@ -78,29 +68,30 @@ public class RestoreDefaultTypeActionDelegate extends ActionDelegate implements
CDebugUIPlugin.log( getStatus() );
}
}
+
+ return null;
}
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
- */
- public void selectionChanged( IAction action, ISelection selection ) {
- if ( selection instanceof IStructuredSelection ) {
- Object element = ((IStructuredSelection)selection).getFirstElement();
- if ( element instanceof ICastToType ) {
- boolean enabled = ((ICastToType)element).isCasted();
- action.setEnabled( enabled );
- if ( enabled ) {
- setCastToType( (ICastToType)element );
- return;
- }
- }
- }
- action.setEnabled( false );
- setCastToType( null );
+ @Override
+ public void setEnabled(Object evaluationContext) {
+ ICastToType castToType = getCastToType(evaluationContext);
+ setBaseEnabled( castToType != null && castToType.isCasted() );
+ setCastToType(castToType);
}
-
+
+ private ICastToType getCastToType(Object evaluationContext) {
+ if (evaluationContext instanceof IEvaluationContext) {
+ Object s = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_MENU_SELECTION_NAME);
+ if (s instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)s;
+ if (!ss.isEmpty()) {
+ return (ICastToType)DebugPlugin.getAdapter(ss.getFirstElement(), ICastToType.class);
+ }
+ }
+ }
+ return null;
+ }
+
public IStatus getStatus() {
return fStatus;
}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/DsfCastToTypeSupport.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/DsfCastToTypeSupport.java
new file mode 100644
index 00000000000..a0b23a5566a
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/DsfCastToTypeSupport.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Nokia and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nokia - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.dsf.debug.internal.ui.viewmodel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.debug.core.model.ICastToArray;
+import org.eclipse.cdt.debug.core.model.ICastToType;
+import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
+import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
+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.IExpressions2;
+import org.eclipse.cdt.dsf.debug.service.IExpressions2.CastInfo;
+import org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.MessagesForVariablesVM;
+import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
+import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
+import org.eclipse.cdt.dsf.service.DsfServicesTracker;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+
+/**
+ * This provides {@link ICastToType} and {@link ICastToArray} support on
+ * expression nodes.
+ */
+public class DsfCastToTypeSupport {
+ private final DsfServicesTracker serviceTracker;
+ private final AbstractDMVMProvider dmvmProvider;
+ private final SyncVariableDataAccess fSyncVariableDataAccess;
+
+ /** expression memento to casting context (TODO: persist these; bug 228301)*/
+ private Map<String, CastInfo> fCastedExpressionStorage = new HashMap<String, CastInfo>();
+
+ public class CastImplementation extends PlatformObject implements ICastToArray {
+ private final IExpressionDMContext exprDMC;
+ private String memento;
+
+ public CastImplementation(IExpressionDMContext exprDMC) {
+ this.exprDMC = exprDMC;
+ this.memento = createCastedExpressionMemento(exprDMC);
+ }
+
+ private boolean isValid() {
+ return (serviceTracker.getService(IExpressions2.class) != null && exprDMC != null);
+ }
+
+ private void throwIfNotValid() throws DebugException {
+ if (!isValid())
+ throw new DebugException(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
+ MessagesForVariablesVM.VariableVMNode_CannotCastVariable, null));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToType#canCast()
+ */
+ public boolean canCast() {
+ return isValid();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToType#getCurrentType()
+ */
+ public String getCurrentType() {
+ // get expected casted type first, if possible (if there's an error in the type,
+ // the expression might not evaluate successfully)
+ CastInfo castDMC = fCastedExpressionStorage.get(memento);
+ if (castDMC != null && castDMC.getTypeString() != null)
+ return castDMC.getTypeString();
+
+ // else, get the actual type
+ IExpressionDMData data = fSyncVariableDataAccess.readVariable(exprDMC);
+ if (data != null)
+ return data.getTypeName();
+
+ return ""; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToType#cast(java.lang.String)
+ */
+ public void cast(String type) throws DebugException {
+ throwIfNotValid();
+
+ CastInfo currentContext = fCastedExpressionStorage.get(memento);
+
+ updateCastInformation(type,
+ currentContext != null ? currentContext.getArrayStartIndex() : 0,
+ currentContext != null ? currentContext.getArrayCount() : 0);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToType#restoreOriginal()
+ */
+ public void restoreOriginal() throws DebugException {
+ throwIfNotValid();
+ fCastedExpressionStorage.remove(memento);
+ fireExpressionChangedEvent(exprDMC);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToType#isCasted()
+ */
+ public boolean isCasted() {
+ if (isValid())
+ return fCastedExpressionStorage.containsKey(memento);
+ else
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToArray#canCastToArray()
+ */
+ public boolean canCastToArray() {
+ return isValid();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.model.ICastToArray#castToArray(int, int)
+ */
+ public void castToArray(int startIndex, int length)
+ throws DebugException {
+ throwIfNotValid();
+
+ CastInfo currentContext = fCastedExpressionStorage.get(memento);
+
+ updateCastInformation(currentContext != null ? currentContext.getTypeString() : null,
+ startIndex,
+ length);
+ }
+
+ private void updateCastInformation(
+ String type, int arrayStartIndex,
+ int arrayCount) {
+ final CastInfo info = new CastInfo(type, arrayStartIndex, arrayCount);
+ fCastedExpressionStorage.put(memento, info);
+ fireExpressionChangedEvent(exprDMC);
+ }
+
+ private class ExpressionChangedEvent extends AbstractDMEvent<IExpressionDMContext> implements IExpressionChangedDMEvent {
+ public ExpressionChangedEvent(IExpressionDMContext context) {
+ super(context);
+ }
+ }
+
+ private void fireExpressionChangedEvent(IExpressionDMContext exprDMC) {
+ ExpressionChangedEvent event = new ExpressionChangedEvent(exprDMC);
+ dmvmProvider.handleEvent(event);
+ dmvmProvider.refresh(); // this seems to be required, esp. for Expressions View
+ }
+ }
+
+ public DsfCastToTypeSupport(DsfSession session, AbstractDMVMProvider dmvmProvider, SyncVariableDataAccess fSyncVariableDataAccess) {
+ this.dmvmProvider = dmvmProvider;
+ this.fSyncVariableDataAccess = fSyncVariableDataAccess;
+ this.serviceTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.ICastSupportTarget#createCastedExpressionMemento(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext, java.lang.String)
+ */
+ public String createCastedExpressionMemento(IExpressionDMContext exprDMC) {
+ // go to the original variable first
+ if (exprDMC instanceof ICastedExpressionDMContext) {
+ IExpressionDMContext origExpr = DMContexts.getAncestorOfType(exprDMC.getParents()[0], IExpressionDMContext.class);
+ if (origExpr == null) {
+ assert false;
+ } else {
+ exprDMC = origExpr;
+ }
+ }
+
+ // TODO: the memento doesn't really strictly define the expression's context;
+ // we should fetch module name, function name, etc. to be more useful (but do that asynchronously)
+ String expression = exprDMC.getExpression();
+ String memento = exprDMC.getSessionId() + "." + expression; //$NON-NLS-1$
+ return memento;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.ICastSupportTarget#replaceWihCastedExpression(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext)
+ */
+ public IExpressionDMContext replaceWithCastedExpression(
+ IExpressionDMContext exprDMC) {
+ IExpressions2 expression2Service = serviceTracker.getService(IExpressions2.class);
+ if (expression2Service == null)
+ return exprDMC;
+
+ if (!fCastedExpressionStorage.isEmpty()) {
+ String memento = createCastedExpressionMemento(exprDMC);
+ CastInfo castInfo = fCastedExpressionStorage.get(memento);
+ if (castInfo != null) {
+ return expression2Service.createCastedExpression(exprDMC, castInfo);
+ }
+ }
+ return exprDMC;
+ }
+
+ /**
+ * Get the ICastToArray (and ICastToType) implementation for the expression.
+ * This does not necessarily return a unique object for each call.
+ * @param exprDMC
+ * @return {@link ICastToArray}
+ */
+ public ICastToArray getCastImpl(IExpressionDMContext exprDMC) {
+ return new CastImplementation(exprDMC);
+ }
+}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java
index 935fca4f2a9..f1ca08fdf86 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java
@@ -16,8 +16,10 @@ import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
+import org.eclipse.cdt.dsf.debug.service.IExpressions2;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
@@ -239,9 +241,16 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
* view comes in as a fully qualified expression so we go directly to the SubExpression layout
* node.
*/
- IExpressionVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess);
+ VariableVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess);
addChildNodes(variableNode, new IExpressionVMNode[] {variableNode});
+ /* Wire up the casting support if the IExpressions2 service is available. */
+ DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
+ IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
+ if (expressions2 != null) {
+ variableNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, syncvarDataAccess));
+ }
+
/*
* Tell the expression node which sub-nodes it will directly support. It is very important
* that the variables node be the last in this chain. The model assumes that there is some
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java
index 0b0ab78b489..59b48b7318c 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/MessagesForVariablesVM.java
@@ -24,7 +24,9 @@ public class MessagesForVariablesVM extends NLS {
public static String VariableColumnPresentation_value;
public static String VariableColumnPresentation_location;
- public static String VariableVMNode_Location_column__Error__text_format;
+ public static String VariableVMNode_CannotCastVariable;
+
+ 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;
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java
index 389ea2b8592..e4485736f87 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java
@@ -17,6 +17,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
+import org.eclipse.cdt.debug.core.model.ICastToArray;
+import org.eclipse.cdt.debug.core.model.ICastToType;
import org.eclipse.cdt.debug.internal.ui.CDebugImages;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
@@ -28,7 +30,9 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
+import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
+import org.eclipse.cdt.dsf.debug.service.IExpressions2;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
@@ -149,13 +153,17 @@ public class VariableVMNode extends AbstractExpressionVMNode
fExpression = expression;
}
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object getAdapter(Class adapter) {
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
return fExpression;
} else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) {
return fVariableExpressionFactory;
+ } else if (fCastToTypeSupport != null && getDMContext() instanceof IExpressionDMContext
+ && (adapter.isAssignableFrom(ICastToType.class)
+ || adapter.isAssignableFrom(ICastToArray.class))) {
+ return fCastToTypeSupport.getCastImpl((IExpressionDMContext) getDMContext());
} else {
return super.getAdapter(adapter);
}
@@ -198,6 +206,8 @@ public class VariableVMNode extends AbstractExpressionVMNode
final protected VariableExpressionFactory fVariableExpressionFactory = new VariableExpressionFactory();
+ protected DsfCastToTypeSupport fCastToTypeSupport;
+
public VariableVMNode(AbstractDMVMProvider provider, DsfSession session,
SyncVariableDataAccess syncVariableDataAccess)
{
@@ -207,6 +217,15 @@ public class VariableVMNode extends AbstractExpressionVMNode
}
/**
+ * Set the cast support target. This is only meaningful if the {@link IExpressions2}
+ * service is available.
+ * @param castToTypeSupport
+ */
+ public void setCastToTypeSupport(DsfCastToTypeSupport castToTypeSupport) {
+ this.fCastToTypeSupport = castToTypeSupport;
+ }
+
+ /**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
@@ -821,9 +840,10 @@ public class VariableVMNode extends AbstractExpressionVMNode
public void run() {
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
if (expressionService != null) {
- IExpressionDMContext expressionDMC = expressionService.createExpression(
- createCompositeDMVMContext(update),
- update.getExpression().getExpressionText());
+ IExpressionDMContext expressionDMC = createExpression(expressionService,
+ createCompositeDMVMContext(update),
+ update.getExpression().getExpressionText());
+
VariableExpressionVMC variableVmc = (VariableExpressionVMC)createVMContext(expressionDMC);
variableVmc.setExpression(update.getExpression());
@@ -965,10 +985,20 @@ public class VariableVMNode extends AbstractExpressionVMNode
handleFailedUpdate(update);
return;
}
- if (update.getOffset() < 0) {
- fillUpdateWithVMCs(update, getData());
+
+ IExpressionDMContext[] data = getData();
+
+ // If any of these expressions use casts, replace them.
+ if (fCastToTypeSupport != null) {
+ for (int i = 0; i < data.length; i++) {
+ data[i] = fCastToTypeSupport.replaceWithCastedExpression(data[i]);
+ }
+ }
+
+ if (update.getOffset() < 0) {
+ fillUpdateWithVMCs(update, data);
} else {
- fillUpdateWithVMCs(update, getData(), update.getOffset());
+ fillUpdateWithVMCs(update, data, update.getOffset());
}
update.done();
}
@@ -1058,7 +1088,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
int i = 0;
for (IVariableDMData localDMData : localsDMData) {
- expressionDMCs[i++] = expressionService.createExpression(frameDmc, localDMData.getName());
+ expressionDMCs[i++] = createExpression(expressionService, frameDmc, localDMData.getName());
}
// Lastly, we fill the update from the array of view model context objects
@@ -1099,7 +1129,19 @@ public class VariableVMNode extends AbstractExpressionVMNode
stackFrameService.getLocals(frameDmc, rm);
}
- public int getDeltaFlags(Object e) {
+
+ private IExpressionDMContext createExpression(
+ IExpressions expressionService,
+ final IDMContext dmc, final String expression) {
+ IExpressionDMContext exprDMC = expressionService.createExpression(dmc, expression);
+
+ if (fCastToTypeSupport != null) {
+ exprDMC = fCastToTypeSupport.replaceWithCastedExpression(exprDMC);
+ }
+ return exprDMC;
+ }
+
+ public int getDeltaFlags(Object e) {
if ( e instanceof ISuspendedDMEvent ||
e instanceof IMemoryChangedEvent ||
e instanceof IExpressionChangedDMEvent ||
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java
index 37b4ca11ba5..d80e7761dc1 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java
@@ -13,8 +13,10 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.variable;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
+import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
+import org.eclipse.cdt.dsf.debug.service.IExpressions2;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
@@ -95,8 +97,15 @@ public class VariableVMProvider extends AbstractDMVMProvider
setRootNode(rootNode);
// Create the next level which represents members of structs/unions/enums and elements of arrays.
- IVMNode subExpressioNode = new VariableVMNode(this, getSession(), varAccess);
+ VariableVMNode subExpressioNode = new VariableVMNode(this, getSession(), varAccess);
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
+
+ // Wire up the casting support if the IExpressions2 service is available.
+ DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
+ IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
+ if (expressions2 != null) {
+ subExpressioNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, varAccess));
+ }
// Configure the sub-expression node to be a child of itself. This way the content
// provider will recursively drill-down the variable hierarchy.
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/messages.properties b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/messages.properties
index ae1f44cfe5b..75901dfc26e 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/messages.properties
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/messages.properties
@@ -16,6 +16,7 @@ VariableColumnPresentation_type=Type
VariableColumnPresentation_value=Value
VariableColumnPresentation_location=Location
+VariableVMNode_CannotCastVariable=Cannot cast this variable
VariableVMNode_Location_column__Error__text_format=
VariableVMNode_Location_column__text_format={0}
VariableVMNode_Description_column__text_format=
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java
index 3ccb9a640e7..b98cdbe5a78 100644
--- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java
+++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java
@@ -43,7 +43,6 @@ public interface IExpressions extends IFormattedValues {
String getExpression();
}
-
/**
* The address and size of an expression.
*/
@@ -143,6 +142,9 @@ public interface IExpressions extends IFormattedValues {
* "int *", "mytypedef", "(int *)[]", "enum Bar". If the debugger backend cannot supply
* this information, this method returns "<UNKNOWN>" (the angle brackets are there just in
* case there is a type named "UNKNOWN" in the application).
+ * <p>
+ * If you implement {@link IExpressions2}, this should return the casted type name,
+ * if this expression was generated via {@link IExpressions2#createCastedExpression(IDMContext, String, IExpressions2.ICastedExpressionDMContext)}
*/
String getTypeName();
@@ -175,6 +177,7 @@ public interface IExpressions extends IFormattedValues {
*/
public interface IExpressionChangedDMEvent extends IDMEvent<IExpressionDMContext> {}
+
/**
* Retrieves the expression DM data object for the given expression context(<tt>dmc</tt>).
*
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java
new file mode 100644
index 00000000000..9af9e45da51
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Nokia and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nokia - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.dsf.debug.service;
+
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+
+/**
+ * This interface extends the expressions service with support for casting to type or
+ * array.
+ * @since 2.1
+ */
+public interface IExpressions2 extends IExpressions {
+
+ /**
+ * This class specifies how an expression should be
+ * typecast to another type and/or displayed as an array.
+ */
+ public static class CastInfo {
+ private final String typeString;
+ private final int arrayCount;
+ private final int arrayStart;
+
+ /**
+ * Create an instance of casting information
+ * @param typeString if not <code>null</code>, the C/C++ type to which to cast the expression (e.g. "char**")
+ * @param arrayStart if arrayCount > 0, the start index for viewing contents of the expression as an array
+ * @param arrayCount if > 0, indicates to show [arrayStart ... arrayStart+arrayCount) as child expressions
+ */
+ public CastInfo(String typeString, int arrayStart, int arrayCount) {
+ this.typeString = typeString;
+ this.arrayStart = arrayStart;
+ this.arrayCount = arrayCount;
+ }
+
+ /**
+ * Create an instance of casting information for casting to type (only)
+ * @param typeString must be non-<code>null</code>; the C/C++ type to which to cast the expression (e.g. "char**")
+ */
+ public CastInfo(String typeString) {
+ if (typeString == null)
+ throw new IllegalArgumentException();
+ this.typeString = typeString;
+ this.arrayStart = this.arrayCount = 0;
+ }
+
+
+ /**
+ * Create an instance of casting information for showing as an array (only)
+ * @param arrayStart the start index for viewing contents of the expression as an array
+ * @param arrayCount must be > 0; indicates to show [arrayStart ... arrayStart+arrayCount) as child expressions
+ */
+ public CastInfo(int arrayStart, int arrayCount) {
+ if (arrayCount <= 0)
+ throw new IllegalArgumentException();
+ this.typeString = null;
+ this.arrayStart = arrayStart;
+ this.arrayCount = arrayCount;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + arrayCount;
+ result = prime * result + arrayStart;
+ result = prime * result
+ + ((typeString == null) ? 0 : typeString.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CastInfo other = (CastInfo) obj;
+ if (arrayCount != other.arrayCount)
+ return false;
+ if (arrayStart != other.arrayStart)
+ return false;
+ if (typeString == null) {
+ if (other.typeString != null)
+ return false;
+ } else if (!typeString.equals(other.typeString))
+ return false;
+ return true;
+ }
+
+ /**
+ * Get the user-friendly type name. This may be a post-processed string
+ * but should be semantically equivalent to the type used to create the context.
+ * @return type string, or <code>null</code> if no type casting performed
+ */
+ public String getTypeString() {
+ return typeString;
+ }
+
+ /**
+ * Get the start index for viewing children as an array. (Only effective if #getCount() > 0)
+ * @return the index of the first element of the array. 0 means that
+ * the original element is the first member of the array. This may be negative, too.
+ */
+ public int getArrayStartIndex(){
+ return arrayStart;
+ }
+
+ /**
+ * Get the number of elements to show when viewing children as an array.
+ * @return the array size, or <= 0 if not viewing as an array
+ */
+ public int getArrayCount(){
+ return arrayCount;
+ }
+ }
+
+ /**
+ * This context identifies a casted expression. Its parent is the original
+ * {@link IExpressionDMContext}.
+ */
+ public interface ICastedExpressionDMContext extends IExpressionDMContext {
+ CastInfo getCastInfo();
+
+ }
+
+ /**
+ * Create a variant of the expression which is casted with the given casting info.
+ * <p>
+ * If {@link ICastInfo#getTypeString()} is not <code>null</code>, such an expression should
+ * report the casted type via {@link IExpressionDMData} and generate subexpressions accordingly.
+ * <p>
+ * Note that typically, a cast of a primitive type (int, double, etc.) to another
+ * primitive type is interpreted as "*(other_type*)&(expression)", not merely
+ * as casting the rvalue of "expression" to another type (which usually only
+ * truncates or extends the value without much benefit).
+ * <p>
+ * If {@link ICastInfo#getArrayCount()} is greater than <code>0</code>, the expression should
+ * yield that number of elements as subexpressions, as array elements, starting with index
+ * {@link ICastInfo#getArrayStartIndex()}. (This does not affect the address of the
+ * expression itself, only which children are returned.)
+ * <p>
+ * The expected semantics of an array cast ranging from J to K are to take a
+ * pointer-valued expression whose base type is size N, evaluate its value
+ * to A, and yield array elements of the pointer base type at locations
+ * <code>A + N*J</code>, <code>A + N*(J+1)</code>, ...,
+ * <code>A + N*(J+K-1)</code>. But the address of the expression is <b>not</b> modified
+ * when an array cast is applied.
+ * <p>An implementation may provide its own semantics for viewing other data as arrays, if so desired.
+ * @param context an existing expression
+ * @param castInfo the casting information
+ * @param rm request monitor returning a casted expression data model context object that must be passed to the appropriate
+ * data retrieval routine to obtain the value of the expression. The object must
+ * report the casted type (if any) via {@link #getExpressionData(IExpressionDMContext, DataRequestMonitor)}
+ * and report alternate children according to the array casting context via
+ * {@link #getSubExpressionCount(IExpressionDMContext, DataRequestMonitor)}
+ * and {@link #getSubExpressions}.
+ */
+ ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context,
+ CastInfo castInfo);
+
+
+}

Back to the top