diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IViewInMemory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IViewInMemory.java new file mode 100644 index 00000000000..8b16e10fb0c --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IViewInMemory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * Provides the ability to view a variable in the memory view. + * @since 7.4 + */ +public interface IViewInMemory extends IAdaptable { + + /** + * Returns whether this element can currently be viewed in the memory view. + * + * @return whether this element can currently be viewed in the memory view. + */ + boolean canViewInMemory(); + + /** + * Displays the element in the memory view. + */ + void viewInMemory(); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java index 3876ceed5b0..036826a4833 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Freescale Semiconductor. and others. + * Copyright (c) 2010, 2013 Freescale Semiconductor. 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 @@ -8,6 +8,7 @@ * Contributors: * Freescale Semiconductor - initial API and implementation * Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121) + * Marc Khouzam (Ericsson) - Add support disable "View Memory" action (bug 418710) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel; @@ -184,8 +185,50 @@ public class GdbVariableVMNode extends VariableVMNode { request.done(); } } + + @Override + public boolean canViewInMemory() { + String expr = getExpression(); + if (isConvenienceVariable(expr) || isRegisterExpression(expr)) { + return false; + } + return super.canViewInMemory(); + } }; + private static boolean isConvenienceVariable(String expr) { + // GDB convenience variables are variables that start with a $ followed + // by at least one digit. + // Note that registers also start with a $, so we need to make sure + // there is a digit immediately following the $. + // Also, the $ may not be at the start of the expression in cases + // where we are dealing with children of a convenience variable, + // such as ($1).myvar or ((class bar) $1).foo. + // So, we look for a $ followed by a number, anywhere in the expression. + // Convenience variables are used for return values of methods calls. + // see bug 341731 + if (expr.matches(".*" + "\\$\\d" + ".*")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return true; + } + + return false; + } + + private static boolean isRegisterExpression(String expr) { + // Registers expressions start with a $ followed by a non-digit. + // We must check for the non-digit because we need to make sure + // we are not dealing with a convenience variable. + // Also, the $ may not be at the start of the expression in cases + // where we are dealing with a casted register, or children of a register + // such as (int)($eax) + // So, we look for a $ followed by a non-digit, anywhere in the expression. + if (expr.matches(".*" + "\\$\\D" + ".*")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return true; + } + + return false; + } + /** * The special context representing more children to be available. * diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/DsfViewMemoryHandler.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/DsfViewMemoryHandler.java index e969df77347..57efdab36cd 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/DsfViewMemoryHandler.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/DsfViewMemoryHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Nokia and others. + * Copyright (c) 2010, 2013 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 @@ -7,6 +7,7 @@ * * Contributors: * Nokia - Initial API and implementation + * Marc Khouzam (Ericsson) - Allow to disable ViewMemory handler (bug 418710) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.actions; @@ -16,6 +17,7 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.RejectedExecutionException; +import org.eclipse.cdt.debug.core.model.IViewInMemory; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; @@ -32,6 +34,7 @@ import org.eclipse.cdt.dsf.service.DsfSession; 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.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -50,12 +53,11 @@ import org.eclipse.debug.ui.memory.IMemoryRendering; import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; import org.eclipse.debug.ui.memory.IMemoryRenderingSite; import org.eclipse.debug.ui.memory.IMemoryRenderingType; -import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.ISources; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; -import org.eclipse.ui.handlers.HandlerUtil; /** * DSF version of handler for viewing variable in memory view command. @@ -63,25 +65,58 @@ import org.eclipse.ui.handlers.HandlerUtil; */ public class DsfViewMemoryHandler extends AbstractHandler { + private VariableExpressionVMC[] fMemoryViewables = new VariableExpressionVMC[0]; + + protected VariableExpressionVMC[] getMemoryViewables() { + return fMemoryViewables; + } + + protected void setMemoryViewables(VariableExpressionVMC[] viewableMemoryITems) { + fMemoryViewables = viewableMemoryITems; + } + + @Override + public void setEnabled(Object evaluationContext) { + VariableExpressionVMC[] viewableMemoryITems = getMemoryViewables(evaluationContext); + setBaseEnabled(viewableMemoryITems.length > 0); + setMemoryViewables(viewableMemoryITems); + } + /* * (non-Javadoc) * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection instanceof IStructuredSelection) { - List list = new ArrayList(); - Iterator iter = ((IStructuredSelection)selection).iterator(); - while (iter.hasNext()) { - Object obj = iter.next(); - if (obj instanceof VariableExpressionVMC) { - list.add(obj); - } + if (getMemoryViewables() == null || getMemoryViewables().length == 0) { + return null; + } + + showInMemoryView(getMemoryViewables()); + + return null; + } + + private VariableExpressionVMC[] getMemoryViewables(Object evaluationContext) { + List viewableMemoryItems = new ArrayList(); + if (evaluationContext instanceof IEvaluationContext) { + Object s = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_MENU_SELECTION_NAME); + if (s instanceof IStructuredSelection) { + Iterator iter = ((IStructuredSelection)s).iterator(); + while(iter.hasNext()) { + Object obj = iter.next(); + if (obj instanceof VariableExpressionVMC) { + Object element = DebugPlugin.getAdapter(obj, IViewInMemory.class); + if (element != null) { + if (((IViewInMemory)element).canViewInMemory()) { + viewableMemoryItems.add((VariableExpressionVMC)obj); + } + } + } + } } - showInMemoryView(list.toArray(new VariableExpressionVMC[list.size()])); - } - return null; + } + return viewableMemoryItems.toArray(new VariableExpressionVMC[viewableMemoryItems.size()]); } private void addDefaultRenderings(IMemoryBlock memoryBlock, IMemoryRenderingSite memRendSite) { 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 9163bb86cc0..d6153a742a4 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2013 Wind River 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: * Wind River Systems - initial API and implementation + * Marc Khouzam (Ericsson) - Add support disable "View Memory" action (bug 418710) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.ui.viewmodel.variable; @@ -19,6 +20,7 @@ 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.core.model.IViewInMemory; import org.eclipse.cdt.debug.internal.ui.CDebugImages; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; @@ -157,7 +159,7 @@ public class VariableVMNode extends AbstractExpressionVMNode */ private final FormattedValueRetriever fFormattedValueRetriever; - public class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext { + public class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext, IViewInMemory { private IExpression fExpression; @@ -210,6 +212,16 @@ public class VariableVMNode extends AbstractExpressionVMNode public int hashCode() { return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); } + + @Override + public boolean canViewInMemory() { + return true; + } + + @Override + public void viewInMemory() { + assert false : "VariableExpressionVMC.viewInMemory() not implemented"; //$NON-NLS-1$ + } } protected class VariableExpressionFactory implements IWatchExpressionFactoryAdapter2 {