mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bugzilla 196757
VariableLayoutNode.java - created VariableLocalsLayoutNode.java - deleted VariableSubExpressionsLayoutNode.java - deleted VariableVMProvider.java - changed to use VariableLayoutNode ExpressionVMProvider.java - changed to use VariableLayoutNode VMElementsUpdate.java - support -1 on data mining Bugzilla 196756 RegisterGroupLayoutNode.java - handle more events/cleanup RegisterLayoutNode.java - handle more events/cleanup
This commit is contained in:
parent
575d660c1b
commit
003f06ca0b
7 changed files with 234 additions and 465 deletions
|
@ -17,8 +17,7 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode;
|
|||
import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLocalsLayoutNode;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableSubExpressionsLayoutNode;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableLayoutNode;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
|
@ -87,11 +86,11 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache
|
|||
registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode });
|
||||
|
||||
/*
|
||||
* Create the local variables nodes next. They represent the first level shown in the view.
|
||||
* Create the support for the SubExpressions. Anything which is brought into the expressions
|
||||
* view comes in as a fully qualified expression so we go directly to the SubExpression layout
|
||||
* node.
|
||||
*/
|
||||
IExpressionLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), syncvarDataAccess);
|
||||
IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), syncvarDataAccess);
|
||||
localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
|
||||
IExpressionLayoutNode subExpressioNode = new VariableLayoutNode(this, this, getSession(), syncvarDataAccess);
|
||||
|
||||
/*
|
||||
* Tell the expression node which subnodes it will directly support. It is very important
|
||||
|
@ -104,7 +103,7 @@ public class ExpressionVMProvider extends AbstractDebugDMVMProviderWithCache
|
|||
* assume what it was passed was for it and the real node which wants to handle it would be
|
||||
* left out in the cold.
|
||||
*/
|
||||
expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, localsNode });
|
||||
expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode, subExpressioNode });
|
||||
|
||||
/*
|
||||
* Let the work know which is the top level node.
|
||||
|
|
|
@ -60,8 +60,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode<IRegis
|
|||
implements IElementEditor
|
||||
{
|
||||
|
||||
protected class RegisterGroupVMC extends DMVMContext
|
||||
implements IVariable
|
||||
protected class RegisterGroupVMC extends DMVMContext implements IVariable
|
||||
{
|
||||
private IExpression fExpression;
|
||||
public RegisterGroupVMC(IDMContext<?> dmc) {
|
||||
|
@ -123,8 +122,7 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode<IRegis
|
|||
RegisterGroupVMC registerVmc = ((RegisterGroupVMC)variable);
|
||||
|
||||
StringBuffer exprBuf = new StringBuffer();
|
||||
IRegisterGroupDMContext groupDmc =
|
||||
DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class);
|
||||
IRegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class);
|
||||
if (groupDmc != null) {
|
||||
exprBuf.append("$$\""); //$NON-NLS-1$
|
||||
exprBuf.append(groupDmc.getName());
|
||||
|
@ -282,9 +280,12 @@ public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode<IRegis
|
|||
@Override
|
||||
protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm)
|
||||
{
|
||||
if (event instanceof IRegisters.IRegistersChangedDMEvent) {
|
||||
parentDelta.addNode(element, IModelDelta.STATE);
|
||||
if (event instanceof IRegisters.IGroupsChangedDMEvent) {
|
||||
parentDelta.addNode(element, IModelDelta.CONTENT);
|
||||
}
|
||||
if (event instanceof IRegisters.IGroupChangedDMEvent) {
|
||||
parentDelta.addNode(element, IModelDelta.STATE);
|
||||
}
|
||||
|
||||
super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm);
|
||||
}
|
||||
|
|
|
@ -499,6 +499,10 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode<IRegisterDM
|
|||
parentDelta.addNode(element, IModelDelta.STATE);
|
||||
}
|
||||
|
||||
if (event instanceof IRegisters.IRegistersChangedDMEvent) {
|
||||
parentDelta.addNode(element, IModelDelta.STATE);
|
||||
}
|
||||
|
||||
super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -17,8 +18,8 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
|||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMService;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
||||
|
@ -28,7 +29,6 @@ import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
|||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData;
|
||||
|
@ -41,6 +41,7 @@ import org.eclipse.dd.dsf.service.DsfSession;
|
|||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
|
@ -61,16 +62,68 @@ import org.eclipse.jface.viewers.TextCellEditor;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
@SuppressWarnings({"restriction", "nls"})
|
||||
public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpressionDMData> implements IElementEditor {
|
||||
public class VariableLayoutNode extends AbstractExpressionLayoutNode<IExpressionDMData> implements IElementEditor {
|
||||
|
||||
/**
|
||||
* List of child nodes containing only a reference to this. This is what enables the view model
|
||||
* provider to know about the recursive nature of subexpression nodes.
|
||||
*/
|
||||
private final IVMLayoutNode[] fChildLayoutNodes = { this };
|
||||
|
||||
@Override
|
||||
public IVMLayoutNode[] getChildLayoutNodes() {
|
||||
return fChildLayoutNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaFlags(Object e) {
|
||||
/*
|
||||
* @see buildDelta()
|
||||
*/
|
||||
|
||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
|
||||
if ( e instanceof IExpressions.IExpressionChangedDMEvent) {
|
||||
return IModelDelta.STATE;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
|
||||
|
||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
||||
parentDelta.addFlags(IModelDelta.CONTENT);
|
||||
}
|
||||
else if ( event instanceof IExpressions.IExpressionChangedDMEvent) {
|
||||
/*
|
||||
* Flush the cache.
|
||||
*/
|
||||
VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext());
|
||||
|
||||
/*
|
||||
* Logically one would think that STATE should be specified here. But we specifiy CONTENT
|
||||
* as well so that if there sub expressions which are affected in some way ( such as with
|
||||
* an expanded union then they will show the changes also.
|
||||
*/
|
||||
parentDelta.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)event).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE );
|
||||
}
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
private final IFormattedValuePreferenceStore fFormattedPrefStore;
|
||||
|
||||
private final SyncVariableDataAccess fSyncVariableDataAccess;
|
||||
|
||||
protected class VariableLocalsVMC extends DMVMContext implements IFormattedValueVMContext, IVariable {
|
||||
protected class VariableExpressionVMC extends DMVMContext implements IFormattedValueVMContext, IVariable {
|
||||
|
||||
private IExpression fExpression;
|
||||
|
||||
public VariableLocalsVMC(IDMContext<?> dmc) {
|
||||
public VariableExpressionVMC(IDMContext<?> dmc) {
|
||||
super(dmc);
|
||||
}
|
||||
|
||||
|
@ -88,7 +141,7 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
|
||||
return fExpression;
|
||||
} else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) {
|
||||
return fVariableLocalsExpressionFactory;
|
||||
return fVariableExpressionFactory;
|
||||
} else {
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
@ -96,8 +149,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof VariableLocalsVMC && super.equals(other)) {
|
||||
VariableLocalsVMC otherGroup = (VariableLocalsVMC)other;
|
||||
if (other instanceof VariableExpressionVMC && super.equals(other)) {
|
||||
VariableExpressionVMC otherGroup = (VariableExpressionVMC)other;
|
||||
return (otherGroup.fExpression == null && fExpression == null) ||
|
||||
(otherGroup.fExpression != null && otherGroup.fExpression.equals(fExpression));
|
||||
}
|
||||
|
@ -123,29 +176,28 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; }
|
||||
}
|
||||
|
||||
protected class VariableLocalsExpressionFactory implements IWatchExpressionFactoryAdapterExtension {
|
||||
protected class VariableExpressionFactory implements IWatchExpressionFactoryAdapterExtension {
|
||||
|
||||
public boolean canCreateWatchExpression(IVariable variable) {
|
||||
return variable instanceof VariableLocalsVMC;
|
||||
return variable instanceof VariableExpressionVMC;
|
||||
}
|
||||
|
||||
public String createWatchExpression(IVariable variable) throws CoreException {
|
||||
|
||||
//VariableLocalsVMC registerVmc = ((VariableLocalsVMC)variable);
|
||||
VariableExpressionVMC exprVmc = (VariableExpressionVMC) variable;
|
||||
|
||||
IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(exprVmc.getDMC(), IExpressionDMContext.class);
|
||||
if (exprDmc != null) {
|
||||
return exprDmc.getQualifiedExpression();
|
||||
}
|
||||
|
||||
/*
|
||||
* This needs to be completed by filling in the fully qualified expression.
|
||||
* Currently the ExpressionDMC does not support that. This will be changed
|
||||
* shortly. For now I am creating a bugzilla about this not being complete
|
||||
* and checking this in.
|
||||
*/
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final protected VariableLocalsExpressionFactory fVariableLocalsExpressionFactory = new VariableLocalsExpressionFactory();
|
||||
final protected VariableExpressionFactory fVariableExpressionFactory = new VariableExpressionFactory();
|
||||
|
||||
public VariableLocalsLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider,
|
||||
public VariableLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider,
|
||||
DsfSession session, SyncVariableDataAccess syncVariableDataAccess) {
|
||||
super(provider, session, IExpressions.IExpressionDMContext.class);
|
||||
fFormattedPrefStore = prefStore;
|
||||
|
@ -154,7 +206,7 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
|
||||
@Override
|
||||
protected IVMContext createVMContext(IDMContext<IExpressionDMData> dmc) {
|
||||
return new VariableLocalsVMC(dmc);
|
||||
return new VariableExpressionVMC(dmc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,8 +291,6 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
{
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
/*
|
||||
* PREFPAGE : We are using a default format until the preference page is created
|
||||
*
|
||||
* First select the format to be used. This involves checking so see that the preference
|
||||
* page format is supported by the register service. If the format is not supported then
|
||||
* we will pick the first available format.
|
||||
|
@ -320,25 +370,156 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
|
||||
return new TextCellEditor(parent);
|
||||
}
|
||||
else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
|
||||
return new TextCellEditor(parent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
|
||||
return new VariableLayoutValueCellModifier(fFormattedPrefStore, fSyncVariableDataAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
|
||||
// ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they
|
||||
// should be in the parent chain of the IFrameDMContext object?
|
||||
public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) {
|
||||
|
||||
final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class);
|
||||
/*
|
||||
* Create a valid DMC for this entered expression.
|
||||
*/
|
||||
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
|
||||
IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionText);
|
||||
|
||||
/*
|
||||
* Now create the valid VMC which wrappers it.
|
||||
*/
|
||||
IVMContext vmc = createVMContext(expressionDMC);
|
||||
|
||||
/*
|
||||
* Associate this expression with the newly valid DMC and return this VMC back up the chain of command
|
||||
* so it will be used when displaying the value in the expression view.
|
||||
*/
|
||||
associateExpression(vmc, expression);
|
||||
update.setChild(vmc, 0);
|
||||
update.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associateExpression(Object element, IExpression expression) {
|
||||
if (element instanceof VariableExpressionVMC) {
|
||||
((VariableExpressionVMC)element).setExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDeltaFlagsForExpressionPart(Object event) {
|
||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void testContextForExpression(Object element, String expression, DataRequestMonitor<Boolean> rm) {
|
||||
/*
|
||||
* Since we are overriding "getElementForExpression" we do not need to do anything here. But
|
||||
* we are forced to supply this routine because it is abstract in the extending class.
|
||||
*/
|
||||
}
|
||||
|
||||
public int getExpressionLength(String expression) {
|
||||
/*
|
||||
* Since we are overriding "getElementForExpression" we do not need to do anything here.
|
||||
* We just assume the entire expression is for us.
|
||||
*/
|
||||
return expression.length() ;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
// Get the data model context object for the current node in the hierarchy.
|
||||
|
||||
final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class);
|
||||
|
||||
if ( expressionDMC != null ) {
|
||||
getSubexpressionsUpdateElementsInSessionThread( update );
|
||||
}
|
||||
else {
|
||||
getLocalsUpdateElementsInSessionThread( update );
|
||||
}
|
||||
}
|
||||
|
||||
private void getSubexpressionsUpdateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
|
||||
final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class);
|
||||
|
||||
if ( expressionDMC != null ) {
|
||||
|
||||
// Get the services we need to use.
|
||||
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
|
||||
if (expressionService == null) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
final DsfExecutor dsfExecutor = getSession().getExecutor();
|
||||
|
||||
// Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing
|
||||
// the sub-expressions of the expression represented by the current expression node.
|
||||
|
||||
final DataRequestMonitor<Iterable<IExpressionDMContext>> rm =
|
||||
new DataRequestMonitor<Iterable<IExpressionDMContext>>(dsfExecutor, null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill the update with the the IExpressionDMContext objects returned by
|
||||
// IExpressions.getSubExpressions().
|
||||
|
||||
List<IExpressionDMContext> subExpressionDMCList = (List<IExpressionDMContext>)getData();
|
||||
IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()];
|
||||
Iterator<IExpressionDMContext> iter = subExpressionDMCList.iterator();
|
||||
|
||||
int i = 0;
|
||||
while (iter.hasNext()) {
|
||||
subExpressionDMCArray[i++] = iter.next();
|
||||
}
|
||||
|
||||
fillUpdateWithVMCs(update, subExpressionDMCArray);
|
||||
update.done();
|
||||
}
|
||||
};
|
||||
|
||||
// Make the asynchronous call to IExpressions.getSubExpressions(). The results are processed in the
|
||||
// DataRequestMonitor.handleCompleted() above.
|
||||
|
||||
expressionService.getSubExpressions(expressionDMC, rm);
|
||||
}
|
||||
}
|
||||
|
||||
private void getLocalsUpdateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
|
||||
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
|
||||
//final ISymbolDMContext symbolDmc =
|
||||
// findDmcInPath(update.getElementPath(), ISymbolDMContext.class);
|
||||
|
||||
// Get the services we need to use.
|
||||
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
final IStack stackFrameService = getServicesTracker().getService(IStack.class);
|
||||
|
||||
if (execDmc == null || frameDmc == null || expressionService == null || stackFrameService == null) {
|
||||
if ( frameDmc == null || expressionService == null || stackFrameService == null) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
@ -430,8 +611,8 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
|
||||
mrm.add(rm);
|
||||
|
||||
VMCacheManager.getVMCacheManager().getCache(VariableLocalsLayoutNode.this.getVMProvider().getPresentationContext())
|
||||
.getModelData(stackFrameService, localDMC, rm, getExecutor());
|
||||
VMCacheManager.getVMCacheManager().getCache(VariableLayoutNode.this.getVMProvider().getPresentationContext())
|
||||
.getModelData(stackFrameService, localDMC, rm, getExecutor());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -441,96 +622,4 @@ public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpr
|
|||
|
||||
stackFrameService.getLocals(frameDmc, rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
|
||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent,
|
||||
int nodeOffset, RequestMonitor requestMonitor) {
|
||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
||||
// Create a delta that the whole register group has changed.
|
||||
parent.addFlags(IModelDelta.CONTENT);
|
||||
}
|
||||
|
||||
super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor);
|
||||
}
|
||||
|
||||
public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
|
||||
return new TextCellEditor(parent);
|
||||
}
|
||||
else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
|
||||
return new TextCellEditor(parent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
|
||||
return new VariableLayoutValueCellModifier(fFormattedPrefStore, fSyncVariableDataAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) {
|
||||
|
||||
/*
|
||||
* Create a valid DMC for this entered expression.
|
||||
*/
|
||||
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
|
||||
IExpressionDMContext expressionDMC = expressionService.createExpression(frameDmc, expressionText);
|
||||
|
||||
/*
|
||||
* Now create the valid VMC which wrappers it.
|
||||
*/
|
||||
IVMContext vmc = createVMContext(expressionDMC);
|
||||
|
||||
/*
|
||||
* Associate this expression with the newly valid DMC and return this VMC back up the chain of command
|
||||
* so it will be used when displaying the value in the expression view.
|
||||
*/
|
||||
associateExpression(vmc, expression);
|
||||
update.setChild(vmc, 0);
|
||||
update.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associateExpression(Object element, IExpression expression) {
|
||||
if (element instanceof VariableLocalsVMC) {
|
||||
((VariableLocalsVMC)element).setExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDeltaFlagsForExpressionPart(Object event) {
|
||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void testContextForExpression(Object element, String expression, DataRequestMonitor<Boolean> rm) {
|
||||
/*
|
||||
* Since we are overriding "getElementForExpression" we do not need to do anything here. But
|
||||
* we are forced to supply this routine because it is abstract in the extending class.
|
||||
*/
|
||||
}
|
||||
|
||||
public int getExpressionLength(String expression) {
|
||||
/*
|
||||
* Since we are overriding "getElementForExpression" we do not need to do anything here.
|
||||
* We just assume the entire expression is for us.
|
||||
*/
|
||||
return expression.length() ;
|
||||
}
|
||||
}
|
|
@ -1,318 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMService;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode<IExpressionDMData> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private SyncVariableDataAccess fSyncVariableDataAccess;
|
||||
|
||||
public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session, SyncVariableDataAccess syncVariableDataAccess) {
|
||||
super(provider, session, IExpressions.IExpressionDMContext.class);
|
||||
fSyncVariableDataAccess = syncVariableDataAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of child nodes containing only a reference to this. This is what enables the view model
|
||||
* provider to know about the recursive nature of subexpression nodes.
|
||||
*/
|
||||
private final IVMLayoutNode[] fChildLayoutNodes = { this };
|
||||
|
||||
@Override
|
||||
public IVMLayoutNode[] getChildLayoutNodes() {
|
||||
return fChildLayoutNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* We override this method because we now need to perform an extra level of data fetch to get the
|
||||
* formatted value of the expression.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@Override
|
||||
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
|
||||
for (final ILabelUpdate update : updates) {
|
||||
|
||||
final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class);
|
||||
|
||||
VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext())
|
||||
.getModelData((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter()),
|
||||
dmc,
|
||||
new DataRequestMonitor<IExpressionDMData>(getSession().getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
// Check that the request was evaluated and data is still valid. The request could
|
||||
// fail if the state of the service changed during the request, but the view model
|
||||
// has not been updated yet.
|
||||
|
||||
if (!getStatus().isOK() || !getData().isValid()) {
|
||||
assert getStatus().isOK() ||
|
||||
getStatus().getCode() != IDsfService.INTERNAL_ERROR ||
|
||||
getStatus().getCode() != IDsfService.NOT_SUPPORTED;
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
// If columns are configured, extract the selected values for each understood column.
|
||||
// First, we fill all of those columns which can be filled without extra data mining.
|
||||
// We also note if we do have to do extra data mining. Any columns need to set the
|
||||
// processing flag so we know we have further work to do. If there are more columns
|
||||
// which need data extraction they need to be added in both "for" loops.
|
||||
|
||||
String[] localColumns = update.getPresentationContext().getColumns();
|
||||
if (localColumns == null)
|
||||
localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
|
||||
|
||||
boolean weAreExtractingFormattedData = false;
|
||||
|
||||
for (int idx = 0; idx < localColumns.length; idx++) {
|
||||
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
|
||||
update.setLabel(getData().getName(), idx);
|
||||
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) {
|
||||
update.setLabel(getData().getTypeName(), idx);
|
||||
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
|
||||
weAreExtractingFormattedData = true;
|
||||
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
|
||||
update.setLabel("", idx); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! weAreExtractingFormattedData ) {
|
||||
update.done();
|
||||
} else {
|
||||
for (int idx = 0; idx < localColumns.length; idx++) {
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
|
||||
updateFormattedExpressionValue(update, idx, dmc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getExecutor()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private data access routine which performs the extra level of data access needed to
|
||||
* get the formatted data value for a specific register.
|
||||
*/
|
||||
private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex,
|
||||
final IExpressionDMContext dmc)
|
||||
{
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
/*
|
||||
* PREFPAGE : We are using a default format until the preference page is created
|
||||
*
|
||||
* First select the format to be used. This involves checking so see that the preference
|
||||
* page format is supported by the register service. If the format is not supported then
|
||||
* we will pick the first available format.
|
||||
*/
|
||||
|
||||
final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT;
|
||||
|
||||
expressionService.getAvailableFormattedValues(
|
||||
dmc,
|
||||
new DataRequestMonitor<String[]>(getSession().getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the desired format is supported.
|
||||
*/
|
||||
String[] formatIds = getData();
|
||||
String finalFormatId = IFormattedValues.NATURAL_FORMAT;
|
||||
boolean requestedFormatIsSupported = false;
|
||||
|
||||
for ( String fId : formatIds ) {
|
||||
if ( preferencePageFormatId.equals(fId) ) {
|
||||
// The desired format is supported.
|
||||
|
||||
finalFormatId = preferencePageFormatId;
|
||||
requestedFormatIsSupported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! requestedFormatIsSupported ) {
|
||||
/*
|
||||
* Desired format is not supported. If there are any formats supported
|
||||
* then use the first available.
|
||||
*/
|
||||
if ( formatIds.length != 0 ) {
|
||||
finalFormatId = formatIds[0];
|
||||
}
|
||||
else {
|
||||
// Expression service does not support any format.
|
||||
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format has been validated. Get the formatted value.
|
||||
*/
|
||||
FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId);
|
||||
|
||||
VMCacheManager.getVMCacheManager().getCache(update.getPresentationContext())
|
||||
.getModelData(expressionService,
|
||||
valueDmc,
|
||||
new DataRequestMonitor<FormattedValueDMData>(getSession().getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the label/column with the properly formatted data value.
|
||||
*/
|
||||
update.setLabel(getData().getFormattedValue(), labelIndex);
|
||||
update.done();
|
||||
}
|
||||
},
|
||||
getExecutor()
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
// Get the data model context object for the current node in the hierarchy.
|
||||
|
||||
final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class);
|
||||
|
||||
// ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they
|
||||
// should be in the parent chain of the IFrameDMContext object?
|
||||
|
||||
final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class);
|
||||
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
|
||||
//final ISymbolDMContext symbolDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class);
|
||||
|
||||
// Get the services we need to use.
|
||||
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
|
||||
if (execDmc == null || frameDmc == null || expressionService == null) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
final DsfExecutor dsfExecutor = getSession().getExecutor();
|
||||
|
||||
// Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing
|
||||
// the sub-expressions of the expression represented by the current expression node.
|
||||
|
||||
final DataRequestMonitor<Iterable<IExpressionDMContext>> rm =
|
||||
new DataRequestMonitor<Iterable<IExpressionDMContext>>(dsfExecutor, null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!getStatus().isOK()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill the update with the the IExpressionDMContext objects returned by
|
||||
// IExpressions.getSubExpressions().
|
||||
|
||||
List<IExpressionDMContext> subExpressionDMCList = (List<IExpressionDMContext>)getData();
|
||||
IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()];
|
||||
Iterator<IExpressionDMContext> iter = subExpressionDMCList.iterator();
|
||||
|
||||
int i = 0;
|
||||
while (iter.hasNext()) {
|
||||
subExpressionDMCArray[i++] = iter.next();
|
||||
}
|
||||
|
||||
fillUpdateWithVMCs(update, subExpressionDMCArray);
|
||||
update.done();
|
||||
}
|
||||
};
|
||||
|
||||
// Make the asynchronous call to IExpressions.getSubExpressions(). The results are processed in the
|
||||
// DataRequestMonitor.handleCompleted() above.
|
||||
|
||||
expressionService.getSubExpressions(expressionDMC, rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
|
||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
else if (e instanceof IExpressions.IExpressionChangedDMEvent) {
|
||||
/*
|
||||
* Flush the cache.
|
||||
*/
|
||||
VMCacheManager.getVMCacheManager().flush(super.getVMProvider().getPresentationContext());
|
||||
|
||||
/*
|
||||
* Logically one would think that STATE should be specified here. But we specifiy CONTENT
|
||||
* as well so that if there sub expressions which are affected in some way ( such as with
|
||||
* an expanded union then they will show the changes also.
|
||||
*/
|
||||
return IModelDelta.CONTENT | IModelDelta.STATE;
|
||||
}
|
||||
|
||||
return IModelDelta.NO_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) {
|
||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
||||
// Create a delta that the whole register group has changed.
|
||||
parent.addFlags(IModelDelta.CONTENT);
|
||||
}
|
||||
else if (e instanceof IExpressions.IExpressionChangedDMEvent) {
|
||||
parent.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)e).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE );
|
||||
}
|
||||
|
||||
super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor);
|
||||
}
|
||||
}
|
|
@ -39,17 +39,11 @@ public class VariableVMProvider extends AbstractDebugDMVMProviderWithCache imple
|
|||
*/
|
||||
IVMRootLayoutNode debugViewSelection = new DMVMRootLayoutNode(this);
|
||||
|
||||
/*
|
||||
* Create the local variables nodes next. They represent the first level shown in the view.
|
||||
*/
|
||||
IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), varAccess);
|
||||
debugViewSelection.setChildNodes(new IVMLayoutNode[] { localsNode });
|
||||
|
||||
/*
|
||||
* Create the next level which represents members of structs/unions/enums and elements of arrays.
|
||||
*/
|
||||
IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), varAccess);
|
||||
localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
|
||||
IVMLayoutNode subExpressioNode = new VariableLayoutNode(this, this, getSession(), varAccess);
|
||||
debugViewSelection.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
|
||||
|
||||
/*
|
||||
* Now set this schema set as the layout set.
|
||||
|
|
|
@ -75,7 +75,7 @@ public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate
|
|||
public void done() {
|
||||
@SuppressWarnings("unchecked")
|
||||
DataRequestMonitor<List<Object>> rm = (DataRequestMonitor<List<Object>>)fRequestMonitor;
|
||||
if (fElements.size() == fLength) {
|
||||
if (fElements.size() == fLength || fLength == -1 ) {
|
||||
rm.setData(fElements);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$
|
||||
|
|
Loading…
Add table
Reference in a new issue