1
0
Fork 0
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:
Randy Rohrbach 2007-07-17 00:11:09 +00:00
parent 575d660c1b
commit 003f06ca0b
7 changed files with 234 additions and 465 deletions

View file

@ -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.

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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() ;
}
}

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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$