mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-03 23:25:26 +02:00
This is an udate that contains Fran Literrio's expression/variables view stuff along with my additions to make the expression view interact with the variables layout nodes. I do not have the bugzilla number offhand
This commit is contained in:
parent
1f71a2fac3
commit
eb5188e48f
7 changed files with 861 additions and 19 deletions
|
@ -16,6 +16,9 @@ import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePrefer
|
|||
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.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
|
||||
|
@ -58,16 +61,54 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
|
|||
}
|
||||
|
||||
protected void configureLayout() {
|
||||
SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess();
|
||||
|
||||
// Configure the layout nodes
|
||||
/*
|
||||
* Allocate the synchronous data providers.
|
||||
*/
|
||||
SyncRegisterDataAccess syncRegDataAccess = new SyncRegisterDataAccess();
|
||||
SyncVariableDataAccess syncvarDataAccess = new SyncVariableDataAccess() ;
|
||||
|
||||
/*
|
||||
* Create the top level node which provides the anchor starting point.
|
||||
*/
|
||||
IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this);
|
||||
|
||||
/*
|
||||
* Now the Overarching management node.
|
||||
*/
|
||||
ExpressionManagerLayoutNode expressionManagerNode = new ExpressionManagerLayoutNode(this);
|
||||
debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode});
|
||||
IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess);
|
||||
expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode });
|
||||
IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncDataAccess);
|
||||
|
||||
/*
|
||||
* The expression view wants to support fully all of the components of the register view.
|
||||
*/
|
||||
IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncRegDataAccess);
|
||||
IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncRegDataAccess);
|
||||
registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode });
|
||||
|
||||
/*
|
||||
* Create the local variables nodes next. They represent the first level shown in the view.
|
||||
*/
|
||||
IExpressionLayoutNode localsNode = new VariableLocalsLayoutNode(this, this, getSession(), syncvarDataAccess);
|
||||
IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), syncvarDataAccess);
|
||||
localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
|
||||
|
||||
/*
|
||||
* Tell the expression node which subnodes 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
|
||||
* form of metalanguage expression syntax which each of the nodes evaluates and decides if
|
||||
* they are dealing with it or not. The variables node assumes that the expression is fully
|
||||
* qualified and there is no analysis or subdivision of the expression it will parse. So it
|
||||
* it currently the case that the location of the nodes within the array being passed in is
|
||||
* the order of search/evaluation. Thus variables wants to be last. Otherwise it would just
|
||||
* 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 });
|
||||
|
||||
/*
|
||||
* Let the work know which is the top level node.
|
||||
*/
|
||||
setRootLayoutNode(debugViewSelectionNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* SyncVariableDataAccess.java
|
||||
* Created on May 22, 2007
|
||||
*
|
||||
* Copyright 2007 Wind River Systems Inc. All rights reserved.
|
||||
*/
|
||||
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||
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.IFormattedValues.IFormattedDataDMContext;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
@ThreadSafeAndProhibitedFromDsfExecutor("")
|
||||
public class SyncVariableDataAccess {
|
||||
|
||||
/**
|
||||
* Need to use the OSGi service tracker here (instead of DsfServiceTracker),
|
||||
* because we're accessing it in non-dispatch thread. DsfServiceTracker is
|
||||
* not thread-safe.
|
||||
*/
|
||||
private ServiceTracker fServiceTracker;
|
||||
|
||||
private synchronized IExpressions getService(String filter) {
|
||||
|
||||
if (fServiceTracker == null) {
|
||||
try {
|
||||
fServiceTracker = new ServiceTracker(DsfDebugUIPlugin
|
||||
.getBundleContext(), DsfDebugUIPlugin.getBundleContext()
|
||||
.createFilter(filter), null);
|
||||
fServiceTracker.open();
|
||||
} catch (InvalidSyntaxException e) {
|
||||
assert false : "Invalid filter in DMC: " + filter; //$NON-NLS-1$
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* All of the DMCs that this cell modifier is invoked for should
|
||||
* originate from the same service. This assertion checks this
|
||||
* assumption by comparing the service reference in the tracker to
|
||||
* the filter string in the DMC.
|
||||
*/
|
||||
try {
|
||||
assert DsfDebugUIPlugin.getBundleContext().createFilter(filter)
|
||||
.match(fServiceTracker.getServiceReference());
|
||||
} catch (InvalidSyntaxException e) {
|
||||
}
|
||||
}
|
||||
return (IExpressions) fServiceTracker.getService();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (fServiceTracker != null) {
|
||||
fServiceTracker.close();
|
||||
}
|
||||
}
|
||||
|
||||
public IExpressionDMContext getVariableDMC(Object element) {
|
||||
if (element instanceof IAdaptable) {
|
||||
return (IExpressionDMContext) ((IAdaptable) element).getAdapter(IExpressionDMContext.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public class GetVariableValueQuery extends Query<IExpressionDMData> {
|
||||
|
||||
private IExpressionDMContext fDmc;
|
||||
|
||||
public GetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc) {
|
||||
super(executor);
|
||||
fDmc = dmc;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<IExpressionDMData> rm) {
|
||||
/*
|
||||
* Guard agains the session being disposed. If session is disposed
|
||||
* it could mean that the executor is shut-down, which in turn could
|
||||
* mean that we can't complete the RequestMonitor argument. in that
|
||||
* case, cancel to notify waiting thread.
|
||||
*/
|
||||
final DsfSession session = DsfSession.getSession(fDmc.getSessionId());
|
||||
if (session == null) {
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
IExpressions service = getService(fDmc.getServiceFilter());
|
||||
if (service == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
service.getModelData(fDmc, new DataRequestMonitor<IExpressionDMData>(session.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard against
|
||||
* executor shutdown again.
|
||||
*/
|
||||
if (!DsfSession.isSessionActive(session.getId())) {
|
||||
GetVariableValueQuery.this.cancel(false);
|
||||
return;
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
/*
|
||||
* All good set return value.
|
||||
*/
|
||||
rm.setData(getData());
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public IExpressionDMContext getExpressionDMC(Object element) {
|
||||
if (element instanceof IAdaptable) {
|
||||
return (IExpressionDMContext) ((IAdaptable) element).getAdapter(IExpressionDMContext.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IExpressionDMData readVariable(Object element) {
|
||||
/*
|
||||
* Get the DMC and the session. If element is not an register DMC, or
|
||||
* session is stale, then bail out.
|
||||
*/
|
||||
IExpressionDMContext dmc = getExpressionDMC(element);
|
||||
if (dmc == null) return null;
|
||||
DsfSession session = DsfSession.getSession(dmc.getSessionId());
|
||||
if (session == null) return null;
|
||||
|
||||
/*
|
||||
* Create the query to request the value from service. Note: no need to
|
||||
* guard agains RejectedExecutionException, because
|
||||
* DsfSession.getSession() above would only return an active session.
|
||||
*/
|
||||
GetVariableValueQuery query = new GetVariableValueQuery(session.getExecutor(), dmc);
|
||||
session.getExecutor().execute(query);
|
||||
|
||||
/*
|
||||
* Now we have the data, go and get it. Since the call is completed now
|
||||
* the ".get()" will not suspend it will immediately return with the
|
||||
* data.
|
||||
*/
|
||||
try {
|
||||
return query.get();
|
||||
} catch (InterruptedException e) {
|
||||
assert false;
|
||||
return null;
|
||||
} catch (ExecutionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class SetVariableValueQuery extends Query<Object> {
|
||||
|
||||
private IExpressionDMContext fDmc;
|
||||
private String fValue;
|
||||
private String fFormatId;
|
||||
|
||||
public SetVariableValueQuery(DsfExecutor executor, IExpressionDMContext dmc, String value, String formatId) {
|
||||
super(executor);
|
||||
fDmc = dmc;
|
||||
fValue = value;
|
||||
fFormatId = formatId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<Object> rm) {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard against executor
|
||||
* shutdown again.
|
||||
*/
|
||||
final DsfSession session = DsfSession.getSession(fDmc.getSessionId());
|
||||
if (session == null) {
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guard against a disposed service
|
||||
*/
|
||||
IExpressions service = getService(fDmc.getServiceFilter());
|
||||
if (service == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the bit field using a string/format style.
|
||||
*/
|
||||
service.writeExpression(
|
||||
fDmc,
|
||||
fValue,
|
||||
fFormatId,
|
||||
new DataRequestMonitor<IExpressionDMData>(session.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard
|
||||
* against executor shutdown again.
|
||||
*/
|
||||
if (!DsfSession.isSessionActive(session.getId())) {
|
||||
SetVariableValueQuery.this.cancel(false);
|
||||
return;
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
/*
|
||||
* All good set return value.
|
||||
*/
|
||||
rm.setData(new Object());
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeVariable(Object element, String value, String formatId) {
|
||||
|
||||
/*
|
||||
* Get the DMC and the session. If element is not an register DMC, or
|
||||
* session is stale, then bail out.
|
||||
*/
|
||||
IExpressionDMContext dmc = getExpressionDMC(element);
|
||||
if (dmc == null) return;
|
||||
DsfSession session = DsfSession.getSession(dmc.getSessionId());
|
||||
if (session == null) return;
|
||||
|
||||
/*
|
||||
* Create the query to write the value to the service. Note: no need to
|
||||
* guard agains RejectedExecutionException, because
|
||||
* DsfSession.getSession() above would only return an active session.
|
||||
*/
|
||||
SetVariableValueQuery query = new SetVariableValueQuery(session.getExecutor(), dmc, value, formatId);
|
||||
session.getExecutor().execute(query);
|
||||
|
||||
/*
|
||||
* Now we have the data, go and get it. Since the call is completed now
|
||||
* the ".get()" will not suspend it will immediately return with the
|
||||
* data.
|
||||
*/
|
||||
try {
|
||||
/*
|
||||
* Return value is irrelevant, any error would come through with an
|
||||
* exception.
|
||||
*/
|
||||
query.get();
|
||||
} catch (InterruptedException e) {
|
||||
assert false;
|
||||
} catch (ExecutionException e) {
|
||||
/*
|
||||
* View must be shutting down, no need to show error dialog.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public IFormattedDataDMContext<?> getFormattedDMC(Object element) {
|
||||
if (element instanceof IAdaptable) {
|
||||
return (IFormattedDataDMContext<?>) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public class GetSupportFormatsValueQuery extends Query<Object> {
|
||||
|
||||
IFormattedDataDMContext<?> fDmc;
|
||||
|
||||
public GetSupportFormatsValueQuery(DsfExecutor executor, IFormattedDataDMContext<?> dmc) {
|
||||
super(executor);
|
||||
fDmc = dmc;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<Object> rm) {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard against executor
|
||||
* shutdown again.
|
||||
*/
|
||||
final DsfSession session = DsfSession.getSession(fDmc.getSessionId());
|
||||
if (session == null) {
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guard against a disposed service
|
||||
*/
|
||||
IExpressions service = getService(fDmc.getServiceFilter());
|
||||
if (service == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the bit field using a string/format style.
|
||||
*/
|
||||
service.getAvailableFormattedValues(
|
||||
fDmc,
|
||||
new DataRequestMonitor<String[]>(session.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
/*
|
||||
* We're in another dispatch, so we must
|
||||
* guard against executor shutdown again.
|
||||
*/
|
||||
if (!DsfSession.isSessionActive(session.getId())) {
|
||||
GetSupportFormatsValueQuery.this.cancel(false);
|
||||
return;
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
/*
|
||||
* All good set return value.
|
||||
*/
|
||||
rm.setData(new Object());
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getSupportedFormats(Object element) {
|
||||
|
||||
/*
|
||||
* Get the DMC and the session. If element is not an register DMC, or
|
||||
* session is stale, then bail out.
|
||||
*/
|
||||
IFormattedDataDMContext<?> dmc = getFormattedDMC(element);
|
||||
if (dmc == null) return null;
|
||||
DsfSession session = DsfSession.getSession(dmc.getSessionId());
|
||||
if (session == null) return null;
|
||||
|
||||
/*
|
||||
* Create the query to write the value to the service. Note: no need to
|
||||
* guard agains RejectedExecutionException, because
|
||||
* DsfSession.getSession() above would only return an active session.
|
||||
*/
|
||||
GetSupportFormatsValueQuery query = new GetSupportFormatsValueQuery(session.getExecutor(), dmc);
|
||||
session.getExecutor().execute(query);
|
||||
|
||||
/*
|
||||
* Now we have the data, go and get it. Since the call is completed now
|
||||
* the ".get()" will not suspend it will immediately return with the
|
||||
* data.
|
||||
*/
|
||||
try {
|
||||
return (String[]) query.get();
|
||||
} catch (InterruptedException e) {
|
||||
assert false;
|
||||
return null;
|
||||
} catch (ExecutionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class GetFormattedValueValueQuery extends Query<Object> {
|
||||
|
||||
private IFormattedDataDMContext<?> fDmc;
|
||||
private String fFormatId;
|
||||
|
||||
public GetFormattedValueValueQuery(DsfExecutor executor, IFormattedDataDMContext<?> dmc, String formatId) {
|
||||
super(executor);
|
||||
fDmc = dmc;
|
||||
fFormatId = formatId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<Object> rm) {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard against executor
|
||||
* shutdown again.
|
||||
*/
|
||||
final DsfSession session = DsfSession.getSession(fDmc.getSessionId());
|
||||
if (session == null) {
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guard against a disposed service
|
||||
*/
|
||||
IExpressions service = getService(fDmc.getServiceFilter());
|
||||
if (service == null) {
|
||||
rm .setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service unavailable", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to the proper formatting DMC then go get the formatted value.
|
||||
*/
|
||||
|
||||
FormattedValueDMContext formDmc = service.getFormattedValue(fDmc, fFormatId);
|
||||
|
||||
service.getModelData(formDmc, new DataRequestMonitor<FormattedValueDMData>(session.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
/*
|
||||
* We're in another dispatch, so we must guard against executor shutdown again.
|
||||
*/
|
||||
if (!DsfSession.isSessionActive(session.getId())) {
|
||||
GetFormattedValueValueQuery.this.cancel(false);
|
||||
return;
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
/*
|
||||
* All good set return value.
|
||||
*/
|
||||
rm.setData(getData().getFormattedValue());
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public String getFormattedValue(Object element, String formatId) {
|
||||
|
||||
/*
|
||||
* Get the DMC and the session. If element is not an register DMC, or
|
||||
* session is stale, then bail out.
|
||||
*/
|
||||
IFormattedDataDMContext<?> dmc = getFormattedDMC(element);
|
||||
if (dmc == null) return null;
|
||||
DsfSession session = DsfSession.getSession(dmc.getSessionId());
|
||||
if (session == null) return null;
|
||||
|
||||
/*
|
||||
* Create the query to write the value to the service. Note: no need to
|
||||
* guard agains RejectedExecutionException, because
|
||||
* DsfSession.getSession() above would only return an active session.
|
||||
*/
|
||||
GetFormattedValueValueQuery query = new GetFormattedValueValueQuery(session.getExecutor(), dmc, formatId);
|
||||
session.getExecutor().execute(query);
|
||||
|
||||
/*
|
||||
* Now we have the data, go and get it. Since the call is completed now
|
||||
* the ".get()" will not suspend it will immediately return with the
|
||||
* data.
|
||||
*/
|
||||
try {
|
||||
return (String) query.get();
|
||||
} catch (InterruptedException e) {
|
||||
assert false;
|
||||
return null;
|
||||
} catch (ExecutionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* VariableLayoutValueCellModifier.java
|
||||
* Created on May 22, 2007
|
||||
*
|
||||
* Copyright 2007 Wind River Systems Inc. All rights reserved.
|
||||
*/
|
||||
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore;
|
||||
|
||||
public class VariableLayoutValueCellModifier extends WatchExpressionCellModifier {
|
||||
|
||||
private SyncVariableDataAccess fDataAccess = null;
|
||||
private IFormattedValuePreferenceStore fFormattedValuePreferenceStore;
|
||||
|
||||
public VariableLayoutValueCellModifier(IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncVariableDataAccess access) {
|
||||
fDataAccess = access;
|
||||
fFormattedValuePreferenceStore = formattedValuePreferenceStore;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to make sure we are dealing with a valid variable.
|
||||
*/
|
||||
private IExpressionDMContext getVariableDMC(Object element) {
|
||||
if (element instanceof IAdaptable) {
|
||||
return (IExpressionDMContext)((IAdaptable)element).getAdapter(IExpressionDMContext.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModify(Object element, String property) {
|
||||
// If we're in the column value, modify the register data. Otherwise, call the super-class to edit
|
||||
// the watch expression.
|
||||
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) {
|
||||
// Make sure we are are dealing with a valid set of information.
|
||||
|
||||
if (getVariableDMC(element) == null)
|
||||
return false;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
return super.canModify(element, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(Object element, String property) {
|
||||
// If we're in the column value, modify the variable value. Otherwise, call the super-class to edit
|
||||
// the watch expression.
|
||||
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) {
|
||||
// Make sure we are working on the editable areas.
|
||||
|
||||
// Write the value in the currently requested format. Since they could
|
||||
// have freeformed typed in any format this is just a guess and may not
|
||||
// really accomplish anything.
|
||||
|
||||
String value = fDataAccess.getFormattedValue(element, fFormattedValuePreferenceStore.getDefaultFormatId());
|
||||
|
||||
if (value == null)
|
||||
return "..."; //$NON-NLS-1$
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return super.getValue(element, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(Object element, String property, Object value) {
|
||||
// If we're in the column value, modify the register data. Otherwise, call the super-class to edit
|
||||
// the watch expression.
|
||||
|
||||
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(property)) {
|
||||
if (value instanceof String) {
|
||||
// PREFPAGE : We are using a default format until the preference page is created.
|
||||
fDataAccess.writeVariable(element, (String) value, fFormattedValuePreferenceStore.getDefaultFormatId());
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.modify(element, property, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -12,10 +12,12 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
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.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMService;
|
||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||
|
@ -30,23 +32,130 @@ 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;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext;
|
||||
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.VMDelta;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.model.IDebugTarget;
|
||||
import org.eclipse.debug.core.model.IExpression;
|
||||
import org.eclipse.debug.core.model.IValue;
|
||||
import org.eclipse.debug.core.model.IVariable;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
|
||||
import org.eclipse.jface.viewers.CellEditor;
|
||||
import org.eclipse.jface.viewers.ICellModifier;
|
||||
import org.eclipse.jface.viewers.TextCellEditor;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
@SuppressWarnings({"restriction", "nls"})
|
||||
public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpressionDMData> {
|
||||
public class VariableLocalsLayoutNode extends AbstractExpressionLayoutNode<IExpressionDMData> implements IElementEditor {
|
||||
private final IFormattedValuePreferenceStore fFormattedPrefStore;
|
||||
|
||||
private final SyncVariableDataAccess fSyncVariableDataAccess;
|
||||
|
||||
protected class VariableLocalsVMC extends DMVMContext implements IFormattedValueVMContext, IVariable {
|
||||
|
||||
private IExpression fExpression;
|
||||
|
||||
public VariableLocalsVMC(IDMContext<?> dmc) {
|
||||
super(dmc);
|
||||
}
|
||||
|
||||
public VariableLocalsLayoutNode(AbstractVMProvider provider, DsfSession session) {
|
||||
super(provider, session, IExpressions.IExpressionDMContext.class);
|
||||
public IFormattedValuePreferenceStore getPreferenceStore() {
|
||||
return fFormattedPrefStore;
|
||||
}
|
||||
|
||||
public void setExpression(IExpression expression) {
|
||||
fExpression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
|
||||
return fExpression;
|
||||
} else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) {
|
||||
return fVariableLocalsExpressionFactory;
|
||||
} else {
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof VariableLocalsVMC && super.equals(other)) {
|
||||
VariableLocalsVMC otherGroup = (VariableLocalsVMC)other;
|
||||
return (otherGroup.fExpression == null && fExpression == null) ||
|
||||
(otherGroup.fExpression != null && otherGroup.fExpression.equals(fExpression));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0);
|
||||
}
|
||||
|
||||
public String getName() throws DebugException { return toString(); }
|
||||
public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$
|
||||
public IValue getValue() throws DebugException { return null; }
|
||||
public boolean hasValueChanged() throws DebugException { return false; }
|
||||
public void setValue(IValue value) throws DebugException {}
|
||||
public void setValue(String expression) throws DebugException {}
|
||||
public boolean supportsValueModification() { return false; }
|
||||
public boolean verifyValue(IValue value) throws DebugException { return false; }
|
||||
public boolean verifyValue(String expression) throws DebugException { return false; }
|
||||
public IDebugTarget getDebugTarget() { return null;}
|
||||
public ILaunch getLaunch() { return null; }
|
||||
public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; }
|
||||
}
|
||||
|
||||
protected class VariableLocalsExpressionFactory implements IWatchExpressionFactoryAdapterExtension {
|
||||
|
||||
public boolean canCreateWatchExpression(IVariable variable) {
|
||||
return variable instanceof VariableLocalsVMC;
|
||||
}
|
||||
|
||||
public String createWatchExpression(IVariable variable) throws CoreException {
|
||||
|
||||
//VariableLocalsVMC registerVmc = ((VariableLocalsVMC)variable);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
final protected VariableLocalsExpressionFactory fVariableLocalsExpressionFactory = new VariableLocalsExpressionFactory();
|
||||
|
||||
public VariableLocalsLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider,
|
||||
DsfSession session, SyncVariableDataAccess syncVariableDataAccess) {
|
||||
super(provider, session, IExpressions.IExpressionDMContext.class);
|
||||
fFormattedPrefStore = prefStore;
|
||||
fSyncVariableDataAccess = syncVariableDataAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IVMContext createVMContext(IDMContext<IExpressionDMData> dmc) {
|
||||
return new VariableLocalsVMC(dmc);
|
||||
}
|
||||
|
||||
/**
|
||||
* We override this method because we now need to perform an extra level of data fetch to get the
|
||||
* formatted value of the expression.
|
||||
|
@ -97,6 +206,8 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpression
|
|||
weAreExtractingFormattedData = true;
|
||||
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
|
||||
update.setLabel("", idx);
|
||||
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
|
||||
update.setLabel(getData().getName(), idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +243,7 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpression
|
|||
* we will pick the first available format.
|
||||
*/
|
||||
|
||||
final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT;
|
||||
final String preferencePageFormatId = fFormattedPrefStore.getDefaultFormatId();
|
||||
|
||||
expressionService.getAvailableFormattedValues(
|
||||
dmc,
|
||||
|
@ -212,10 +323,8 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpression
|
|||
// 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 IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class);
|
||||
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
|
||||
//final ISymbolDMContext symbolDmc =
|
||||
// findDmcInPath(update.getElementPath(), ISymbolDMContext.class);
|
||||
|
||||
|
@ -345,4 +454,76 @@ public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpression
|
|||
// }
|
||||
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() ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|||
|
||||
@SuppressWarnings("restriction")
|
||||
public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode<IExpressionDMData> {
|
||||
|
||||
private SyncVariableDataAccess fSyncVariableDataAccess;
|
||||
|
||||
public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session) {
|
||||
public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session, SyncVariableDataAccess syncVariableDataAccess) {
|
||||
super(provider, session, IExpressions.IExpressionDMContext.class);
|
||||
fSyncVariableDataAccess = syncVariableDataAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
*/
|
||||
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
|
||||
|
||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
|
||||
import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
|
||||
|
@ -20,11 +22,18 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont
|
|||
|
||||
@SuppressWarnings("restriction")
|
||||
public class VariableVMProvider extends AbstractDMVMProvider implements
|
||||
IColumnPresentationFactory {
|
||||
IColumnPresentationFactory, IFormattedValuePreferenceStore {
|
||||
|
||||
private String defaultFormatId = IFormattedValues.NATURAL_FORMAT;
|
||||
|
||||
public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
|
||||
super(adapter, context, session);
|
||||
|
||||
|
||||
/*
|
||||
* Create the variable data access routines.
|
||||
*/
|
||||
SyncVariableDataAccess varAccess = new SyncVariableDataAccess() ;
|
||||
|
||||
/*
|
||||
* Create the top level node to deal with the root selection.
|
||||
*/
|
||||
|
@ -33,13 +42,13 @@ public class VariableVMProvider extends AbstractDMVMProvider implements
|
|||
/*
|
||||
* Create the local variables nodes next. They represent the first level shown in the view.
|
||||
*/
|
||||
IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, getSession());
|
||||
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());
|
||||
IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession(), varAccess);
|
||||
localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
|
||||
|
||||
/*
|
||||
|
@ -57,4 +66,20 @@ public class VariableVMProvider extends AbstractDMVMProvider implements
|
|||
public String getColumnPresentationId(IPresentationContext context, Object element) {
|
||||
return VariableColumnPresentation.ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore#getDefaultFormatId()
|
||||
*/
|
||||
public String getDefaultFormatId() {
|
||||
return defaultFormatId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore#setDefaultFormatId(java.lang.String)
|
||||
*/
|
||||
public void setDefaultFormatId(String id) {
|
||||
defaultFormatId = id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.cdt.core.IAddress;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMData;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
|
@ -167,4 +168,17 @@ public interface IExpressions extends IDMService, IFormattedValues {
|
|||
* @param rm: Request completion monitor.
|
||||
*/
|
||||
void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm);
|
||||
|
||||
/**
|
||||
* This method supports the writing/modifying the value of the expression.
|
||||
*
|
||||
* @param expressionContext: The data model context representing an expression.
|
||||
*
|
||||
* @param expressionValue: The new value of the expression as a String.
|
||||
*
|
||||
* @param formatId: The format ID specifying the format of parameter <b>expressionValue</b>.
|
||||
*
|
||||
* @param rm: Request completion monitor.
|
||||
*/
|
||||
void writeExpression(IDMContext<?> expressionContext, String exressionValue, String formatId, RequestMonitor rm);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue