mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
[248606] Add support for toggling watchpoints in the variables and expressions views.
This commit is contained in:
parent
63934dce7a
commit
adde620eaf
14 changed files with 627 additions and 165 deletions
|
@ -16,7 +16,7 @@ Export-Package: org.eclipse.cdt.debug.core,
|
|||
org.eclipse.cdt.debug.core.executables,
|
||||
org.eclipse.cdt.debug.core.model,
|
||||
org.eclipse.cdt.debug.core.sourcelookup,
|
||||
org.eclipse.cdt.debug.internal.core;x-internal:=true,
|
||||
org.eclipse.cdt.debug.internal.core;x-friends:="org.eclipse.cdt.dsf.gdb.ui",
|
||||
org.eclipse.cdt.debug.internal.core.breakpoints;x-friends:="org.eclipse.cdt.debug.edc",
|
||||
org.eclipse.cdt.debug.internal.core.executables;x-internal:=true,
|
||||
org.eclipse.cdt.debug.internal.core.model;x-internal:=true,
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.debug.core.IRequest;
|
||||
|
||||
/**
|
||||
* Base class for request objects used in asynchronous calls in base CDT
|
||||
* (non-DSF). This is used in base features that delegate a task to a backend
|
||||
* that is either DSF or CDI. Since DSF is highly asynchronous, the base logic
|
||||
* has to use asynchronous APIs.
|
||||
*/
|
||||
public class CRequest implements IRequest {
|
||||
private IStatus fStatus;
|
||||
private boolean fCanceled;
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#cancel()
|
||||
*/
|
||||
public void cancel() {
|
||||
fCanceled= true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#done()
|
||||
*/
|
||||
public void done() {
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#getStatus()
|
||||
*/
|
||||
public IStatus getStatus() {
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#isCanceled()
|
||||
*/
|
||||
public boolean isCanceled() {
|
||||
return fCanceled;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#setStatus(org.eclipse.core.runtime.IStatus)
|
||||
*/
|
||||
public void setStatus(IStatus status) {
|
||||
fStatus= status;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Freescale Semiconductor and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import org.eclipse.debug.core.IRequest;
|
||||
|
||||
/**
|
||||
* View model types for which the "Add Watchpoint (C/C++)" action is applicable
|
||||
* should implement this interface. The action is a popupMenu/objectContribution
|
||||
* that targets this type.
|
||||
*
|
||||
* <p>
|
||||
* Note that the action is particular to CBreakpoint, and not all CDT debugger
|
||||
* solutions use CBreakpoint.
|
||||
*/
|
||||
public interface ICWatchpointTarget {
|
||||
|
||||
/** IRequest object used in the asynchronous method {@link ICWatchpointTarget#getSize()} */
|
||||
interface GetSizeRequest extends IRequest {
|
||||
int getSize();
|
||||
void setSize(int size);
|
||||
};
|
||||
|
||||
interface CanCreateWatchpointRequest extends IRequest {
|
||||
boolean getCanCreate();
|
||||
void setCanCreate(boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if a watchpoint can be set on the element. The result does not
|
||||
* guarantee an attempt to set such a watchpoint will succeed. This is
|
||||
* merely a way to find out whether it makes sense to even attempt it. For
|
||||
* example, an expression that's not an l-value should return false. The
|
||||
* implementation may choose to go even further and check that the target
|
||||
* supports watchpoints (at all or at that particular location).
|
||||
*/
|
||||
void canSetWatchpoint(CanCreateWatchpointRequest request);
|
||||
|
||||
/**
|
||||
* Get the expression or the name of the variable
|
||||
*/
|
||||
String getExpression();
|
||||
|
||||
/**
|
||||
* Asynchronous method to retrieve the size of the variable/expression, in
|
||||
* bytes.
|
||||
*
|
||||
* @param request
|
||||
* the async request object
|
||||
*/
|
||||
void getSize(GetSizeRequest request);
|
||||
}
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.debug.core.model.ICDebugElementStatus;
|
|||
import org.eclipse.cdt.debug.core.model.ICType;
|
||||
import org.eclipse.cdt.debug.core.model.ICValue;
|
||||
import org.eclipse.cdt.debug.internal.core.CSettingsManager;
|
||||
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugEvent;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
|
@ -72,7 +73,7 @@ class VariableEventListener implements ICDIEventListener {
|
|||
/**
|
||||
* Represents a variable in the CDI model.
|
||||
*/
|
||||
public abstract class CVariable extends AbstractCVariable implements ICDIEventListener {
|
||||
public abstract class CVariable extends AbstractCVariable implements ICDIEventListener, ICWatchpointTarget {
|
||||
|
||||
interface IInternalVariable {
|
||||
IInternalVariable createShadow( int start, int length ) throws DebugException;
|
||||
|
@ -878,4 +879,33 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
|
|||
// even if the initial setup fails, we still want the complete creation to be successful
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#getExpression()
|
||||
*/
|
||||
public String getExpression() {
|
||||
try {
|
||||
return getExpressionString();
|
||||
} catch (DebugException e) {
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#getSize()
|
||||
*/
|
||||
public void getSize(ICWatchpointTarget.GetSizeRequest request) {
|
||||
// CDI has synchronous APIs, so this is easy...
|
||||
request.setSize(sizeof());
|
||||
request.done();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#canCreateWatchpoint(org.eclipse.cdt.debug.internal.core.IWatchpointTarget.CanCreateWatchpointRequest)
|
||||
*/
|
||||
public void canSetWatchpoint(ICWatchpointTarget.CanCreateWatchpointRequest request) {
|
||||
// CDI has synchronous APIs, so this is easy...
|
||||
request.setCanCreate(sizeof() > 0);
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -723,6 +723,19 @@
|
|||
id="org.eclipse.cdt.debug.ui.actions.method.ToggleMethodBreakpointAction">
|
||||
</action>
|
||||
</objectContribution>
|
||||
<objectContribution
|
||||
objectClass="org.eclipse.cdt.debug.internal.core.ICWatchpointTarget"
|
||||
id="org.eclipse.cdt.debug.ui.WatchpointActions">
|
||||
<action
|
||||
class="org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointOnVariableActionDelegate"
|
||||
enablesFor="1"
|
||||
icon="icons/elcl16/watchpoint_co.gif"
|
||||
id="org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointOnVariableActionDelegate"
|
||||
label="%AddWatchpoint.label"
|
||||
menubarPath="additions"
|
||||
tooltip="%AddWatchpoint.tooltip">
|
||||
</action>
|
||||
</objectContribution>
|
||||
<objectContribution
|
||||
objectClass="org.eclipse.cdt.core.model.IVariable"
|
||||
id="org.eclipse.cdt.debug.ui.WatchpointActions">
|
||||
|
@ -808,20 +821,6 @@
|
|||
class="org.eclipse.cdt.debug.core.model.ICVariable">
|
||||
</selection>
|
||||
</action>
|
||||
<action
|
||||
class="org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointOnVariableActionDelegate"
|
||||
enablesFor="1"
|
||||
icon="icons/elcl16/watchpoint_co.gif"
|
||||
id="org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointOnVariableActionDelegate"
|
||||
label="%AddWatchpoint.label"
|
||||
menubarPath="additions"
|
||||
tooltip="%AddWatchpoint.tooltip">
|
||||
<enablement>
|
||||
<pluginState
|
||||
value="activated"
|
||||
id="org.eclipse.cdt.debug.ui"/>
|
||||
</enablement>
|
||||
</action>
|
||||
</viewerContribution>
|
||||
<viewerContribution
|
||||
targetID="org.eclipse.debug.ui.RegisterView"
|
||||
|
|
|
@ -11,84 +11,142 @@
|
|||
package org.eclipse.cdt.debug.internal.ui.actions;
|
||||
|
||||
|
||||
import org.eclipse.cdt.debug.internal.core.model.CVariable;
|
||||
import org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointDialog;
|
||||
import org.eclipse.cdt.debug.internal.core.CRequest;
|
||||
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
|
||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreeSelection;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.ui.IActionDelegate;
|
||||
import org.eclipse.ui.IObjectActionDelegate;
|
||||
import org.eclipse.ui.IWorkbenchPart;
|
||||
import org.eclipse.ui.progress.WorkbenchJob;
|
||||
|
||||
|
||||
public class AddWatchpointOnVariableActionDelegate extends AddWatchpointActionDelegate {
|
||||
/**
|
||||
* Invoked when user right clicks on an element in the Variables or Expressions
|
||||
* view and selects 'Add Watchpoint (C/C++)'
|
||||
*/
|
||||
public class AddWatchpointOnVariableActionDelegate extends AddWatchpointActionDelegate implements IObjectActionDelegate {
|
||||
|
||||
/**
|
||||
* Constructor for Action1.
|
||||
* The target variable/expression
|
||||
*/
|
||||
private ICWatchpointTarget fVar;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AddWatchpointOnVariableActionDelegate() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
|
||||
*/
|
||||
public void setActivePart(IAction action, IWorkbenchPart targetPart) {}
|
||||
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
|
||||
// Don't care. Our logic is agnostic to the view we're invoked from.
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IActionDelegate#run(IAction)
|
||||
private static class GetSizeRequest extends CRequest implements ICWatchpointTarget.GetSizeRequest {
|
||||
int fSize;
|
||||
public int getSize() {
|
||||
return fSize;
|
||||
}
|
||||
public void setSize(int size) {
|
||||
fSize = size;
|
||||
}
|
||||
};
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointActionDelegate#run(org.eclipse.jface.action.IAction)
|
||||
*/
|
||||
public void run(IAction action) {
|
||||
IStructuredSelection selection = getSelection();
|
||||
|
||||
if (selection == null || selection.isEmpty()) {
|
||||
if (fVar == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object obj = ((TreeSelection)selection).getFirstElement();
|
||||
if (obj != null && obj instanceof CVariable) {
|
||||
CVariable var = (CVariable)obj;
|
||||
|
||||
String expr = "";
|
||||
|
||||
try {
|
||||
expr = var.getExpressionString();
|
||||
} catch (DebugException e) {}
|
||||
|
||||
AddWatchpointDialog dlg = new AddWatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell(),
|
||||
getMemorySpaceManagement()); //$NON-NLS-1$
|
||||
dlg.setExpression(expr);
|
||||
dlg.initializeRange(false, Integer.toString(var.sizeof()));
|
||||
if (dlg.open() == Window.OK) {
|
||||
addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange());
|
||||
}
|
||||
final String expr = fVar.getExpression();
|
||||
if (expr == null) {
|
||||
assert false : "how are we getting an empty expression?"; //$NON-NLS-1$
|
||||
return;
|
||||
}
|
||||
|
||||
// Getting the size of the variable/expression is an asynchronous
|
||||
// operation...or at least the API is (the CDI implementation reacts
|
||||
// synchronously)
|
||||
final ICWatchpointTarget.GetSizeRequest request = new GetSizeRequest() {
|
||||
public void done() {
|
||||
// Now that we have the size, put up a dialog to create the watchpoint
|
||||
final int size = getSize();
|
||||
assert size > 0 : "unexpected variale/expression size"; //$NON-NLS-1$
|
||||
WorkbenchJob job = new WorkbenchJob("open watchpoint dialog") { //$NON-NLS-1$
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
AddWatchpointDialog dlg = new AddWatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell(),
|
||||
getMemorySpaceManagement());
|
||||
dlg.setExpression(expr);
|
||||
dlg.initializeRange(false, Integer.toString(size));
|
||||
if (dlg.open() == Window.OK) {
|
||||
addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange());
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
job.setSystem(true);
|
||||
job.schedule();
|
||||
}
|
||||
|
||||
};
|
||||
fVar.getSize(request);
|
||||
}
|
||||
|
||||
private class CanCreateWatchpointRequest extends CRequest implements ICWatchpointTarget.CanCreateWatchpointRequest {
|
||||
boolean fCanCreate;
|
||||
public boolean getCanCreate() {
|
||||
return fCanCreate;
|
||||
}
|
||||
public void setCanCreate(boolean value) {
|
||||
fCanCreate = value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see IActionDelegate#selectionChanged(IAction, ISelection)
|
||||
* Record the target variable/expression
|
||||
*
|
||||
* @see org.eclipse.ui.actions.ActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
|
||||
* org.eclipse.jface.viewers.ISelection)
|
||||
*/
|
||||
public void selectionChanged(IAction action, ISelection selection) {
|
||||
public void selectionChanged(final IAction action, ISelection selection) {
|
||||
if (selection == null || selection.isEmpty()) {
|
||||
action.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
if (selection instanceof TreeSelection) {
|
||||
Object obj = ((TreeSelection)selection).getFirstElement();
|
||||
if (obj != null && obj instanceof CVariable) {
|
||||
action.setEnabled(true);
|
||||
} else {
|
||||
action.setEnabled(false);
|
||||
fVar = (ICWatchpointTarget)DebugPlugin.getAdapter(obj, ICWatchpointTarget.class);
|
||||
if (fVar != null) {
|
||||
final ICWatchpointTarget.CanCreateWatchpointRequest request = new CanCreateWatchpointRequest() {
|
||||
public void done() {
|
||||
action.setEnabled(getCanCreate());
|
||||
}
|
||||
};
|
||||
fVar.canSetWatchpoint(request);
|
||||
return;
|
||||
}
|
||||
assert false : "action should not have been available for object " + obj; //$NON-NLS-1$
|
||||
}
|
||||
else if (selection instanceof StructuredSelection) {
|
||||
// Not sure why, but sometimes we get an extraneous empty StructuredSelection. Seems harmless enough
|
||||
assert ((StructuredSelection)selection).getFirstElement() == null : "action installed in unexpected type of view/part"; //$NON-NLS-1$
|
||||
}
|
||||
else {
|
||||
assert false : "action installed in unexpected type of view/part"; //$NON-NLS-1$
|
||||
}
|
||||
action.setEnabled(false);
|
||||
}
|
||||
|
||||
private IStructuredSelection getSelection() {
|
||||
return (IStructuredSelection)getView().getViewSite().getSelectionProvider().getSelection();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.cdt.debug.core.model.ICThread;
|
|||
import org.eclipse.cdt.debug.core.model.ICType;
|
||||
import org.eclipse.cdt.debug.core.model.ICValue;
|
||||
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
|
||||
import org.eclipse.cdt.debug.internal.core.CRequest;
|
||||
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
|
||||
import org.eclipse.cdt.debug.internal.core.model.CExpression;
|
||||
import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
|
||||
|
@ -179,6 +180,12 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
|||
fFrameLevel = 0;
|
||||
}
|
||||
|
||||
private class AddressRequest extends CRequest implements IDisassemblyRetrieval.AddressRequest {
|
||||
private BigInteger fAddress;
|
||||
public BigInteger getAddress() { return fAddress; }
|
||||
public void setAddress(BigInteger address) { fAddress = address; }
|
||||
};
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int)
|
||||
*/
|
||||
|
@ -190,7 +197,7 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
|||
return;
|
||||
}
|
||||
IStackFrame stackFrame= stackFrames[targetFrame];
|
||||
fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new IDisassemblyRetrieval.AddressRequest() {
|
||||
fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new AddressRequest() {
|
||||
@Override
|
||||
public void done() {
|
||||
fCallback.setUpdatePending(false);
|
||||
|
@ -238,6 +245,12 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
|||
return fTargetFrameContext.getFrameLineNumber();
|
||||
}
|
||||
|
||||
private class DisassemblyRequest extends CRequest implements IDisassemblyRetrieval.DisassemblyRequest {
|
||||
private IDisassemblyBlock fBlock;
|
||||
public IDisassemblyBlock getDisassemblyBlock() { return fBlock; }
|
||||
public void setDisassemblyBlock(IDisassemblyBlock block) { fBlock = block; }
|
||||
};
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, boolean, boolean, boolean, int, int, int)
|
||||
*/
|
||||
|
@ -253,7 +266,7 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
|||
endAddress= startAddress.add(addressLength);
|
||||
}
|
||||
final BigInteger finalEndAddress= endAddress;
|
||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
|
||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() {
|
||||
@Override
|
||||
public void done() {
|
||||
if (!isCanceled() && getDisassemblyBlock() != null) {
|
||||
|
@ -365,7 +378,7 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
|||
public void retrieveDisassembly(String file, int lines,
|
||||
BigInteger endAddress, final boolean mixed, final boolean showSymbols,
|
||||
final boolean showDisassembly) {
|
||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
|
||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() {
|
||||
@Override
|
||||
public void done() {
|
||||
if (!isCanceled() && getDisassemblyBlock() != null) {
|
||||
|
|
|
@ -14,89 +14,21 @@ package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
|
|||
import java.math.BigInteger;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.debug.core.IRequest;
|
||||
import org.eclipse.debug.core.model.IStackFrame;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface IDisassemblyRetrieval {
|
||||
/**
|
||||
*/
|
||||
public static class Request implements IRequest {
|
||||
private IStatus fStatus;
|
||||
private boolean fCanceled;
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#cancel()
|
||||
*/
|
||||
public void cancel() {
|
||||
fCanceled= true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#done()
|
||||
*/
|
||||
public void done() {
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#getStatus()
|
||||
*/
|
||||
public IStatus getStatus() {
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#isCanceled()
|
||||
*/
|
||||
public boolean isCanceled() {
|
||||
return fCanceled;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.core.IRequest#setStatus(org.eclipse.core.runtime.IStatus)
|
||||
*/
|
||||
public void setStatus(IStatus status) {
|
||||
fStatus= status;
|
||||
}
|
||||
|
||||
interface AddressRequest extends IRequest {
|
||||
BigInteger getAddress();
|
||||
void setAddress(BigInteger address);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public static class AddressRequest extends Request {
|
||||
private BigInteger fAddress;
|
||||
/**
|
||||
* @return the address
|
||||
*/
|
||||
public BigInteger getAddress() {
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address the address to set
|
||||
*/
|
||||
public void setAddress(BigInteger address) {
|
||||
fAddress= address;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DisassemblyRequest extends Request {
|
||||
IDisassemblyBlock fDisassemblyBlock;
|
||||
|
||||
/**
|
||||
* @return the disassemblyBlock
|
||||
*/
|
||||
public IDisassemblyBlock getDisassemblyBlock() {
|
||||
return fDisassemblyBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param disassemblyBlock the disassemblyBlock to set
|
||||
*/
|
||||
public void setDisassemblyBlock(IDisassemblyBlock disassemblyBlock) {
|
||||
fDisassemblyBlock= disassemblyBlock;
|
||||
}
|
||||
interface DisassemblyRequest extends IRequest {
|
||||
IDisassemblyBlock getDisassemblyBlock();
|
||||
void setDisassemblyBlock(IDisassemblyBlock disassemblyBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Freescale Semiconductor. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionManagerVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.SingleExpressionVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterBitFieldVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterGroupVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
|
||||
/**
|
||||
* A specialization of ExpressionVMProvider that uses a GDB-specific variable VM
|
||||
* node. To understand why this is necessary, see GdbVariableVMNode.
|
||||
*/
|
||||
public class GdbExpressionVMProvider extends ExpressionVMProvider {
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbExpressionVMProvider(AbstractVMAdapter adapter,
|
||||
IPresentationContext context, DsfSession session) {
|
||||
super(adapter, context, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* The only difference between this and our super implementation is that we
|
||||
* create a GdbVariableVMNode instead of a VariableVMNode.
|
||||
*
|
||||
* @see org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider#configureLayout()
|
||||
*/
|
||||
@Override
|
||||
protected void configureLayout() {
|
||||
|
||||
/*
|
||||
* Allocate the synchronous data providers.
|
||||
*/
|
||||
SyncRegisterDataAccess syncRegDataAccess = new SyncRegisterDataAccess(getSession());
|
||||
SyncVariableDataAccess syncvarDataAccess = new SyncVariableDataAccess(getSession()) ;
|
||||
|
||||
/*
|
||||
* Create the top level node which provides the anchor starting point.
|
||||
*/
|
||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
||||
|
||||
/*
|
||||
* Now the Over-arching management node.
|
||||
*/
|
||||
if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(getPresentationContext().getId())) {
|
||||
SingleExpressionVMNode expressionManagerNode = new SingleExpressionVMNode(this);
|
||||
addChildNodes(rootNode, new IVMNode[] { expressionManagerNode });
|
||||
} else {
|
||||
ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this);
|
||||
addChildNodes(rootNode, new IVMNode[] {expressionManagerNode});
|
||||
}
|
||||
|
||||
/*
|
||||
* The expression view wants to support fully all of the components of the register view.
|
||||
*/
|
||||
IExpressionVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), syncRegDataAccess);
|
||||
|
||||
IExpressionVMNode registerNode = new RegisterVMNode(this, getSession(), syncRegDataAccess);
|
||||
addChildNodes(registerGroupNode, new IExpressionVMNode[] {registerNode});
|
||||
|
||||
/*
|
||||
* Create the next level which is the bit-field level.
|
||||
*/
|
||||
IVMNode bitFieldNode = new RegisterBitFieldVMNode(this, getSession(), syncRegDataAccess);
|
||||
addChildNodes(registerNode, new IVMNode[] { bitFieldNode });
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
IExpressionVMNode variableNode = new GdbVariableVMNode(this, getSession(), syncvarDataAccess);
|
||||
addChildNodes(variableNode, new IExpressionVMNode[] {variableNode});
|
||||
|
||||
/*
|
||||
* Tell the expression node which sub-nodes it will directly support. It is very important
|
||||
* that the variables node be the last in this chain. The model assumes that there is some
|
||||
* 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.
|
||||
*/
|
||||
setExpressionNodes(new IExpressionVMNode[] {registerGroupNode, variableNode});
|
||||
|
||||
/*
|
||||
* Let the work know which is the top level node.
|
||||
*/
|
||||
setRootNode(rootNode);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Freescale Semiconductor. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
|
||||
/**
|
||||
* Specialization of DSF's VariableVMNode. See
|
||||
* {@link GdbVariableVMNode#createVMContext(IDMContext)} for why this is needed.
|
||||
*/
|
||||
public class GdbVariableVMNode extends VariableVMNode {
|
||||
|
||||
/**
|
||||
* Specialization of VariableVMNode.VariableExpressionVMC that participates
|
||||
* in the "Add Watchpoint" object contribution action.
|
||||
*/
|
||||
public class GdbVariableExpressionVMC extends VariableVMNode.VariableExpressionVMC implements ICWatchpointTarget {
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbVariableExpressionVMC(IDMContext dmc) {
|
||||
super(dmc);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#getExpression()
|
||||
*/
|
||||
public String getExpression() {
|
||||
final IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(getDMContext(), IExpressionDMContext.class);
|
||||
if (exprDmc != null) {
|
||||
return exprDmc.getExpression();
|
||||
}
|
||||
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#getSize()
|
||||
*/
|
||||
public void getSize(final ICWatchpointTarget.GetSizeRequest request) {
|
||||
final IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(getDMContext(), IExpressionDMContext.class);
|
||||
if (exprDmc != null) {
|
||||
getSession().getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
if (expressionService != null) {
|
||||
final DataRequestMonitor<IExpressionDMAddress> drm = new DataRequestMonitor<IExpressionDMAddress>(getSession().getExecutor(), null) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
request.setSize(getData().getSize());
|
||||
request.done();
|
||||
}
|
||||
};
|
||||
|
||||
expressionService.getExpressionAddressData(exprDmc, drm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
request.setSize(-1);
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.IWatchpointTarget#canCreateWatchpoint(org.eclipse.cdt.debug.internal.core.IWatchpointTarget.CanCreateWatchpointRequest)
|
||||
*/
|
||||
public void canSetWatchpoint(final ICWatchpointTarget.CanCreateWatchpointRequest request) {
|
||||
// If the expression is an l-value, then we say it supports a
|
||||
// watchpoint. The logic here is basically the same as what's in
|
||||
// getSize(), as the same DSF service method tells us (a) if it's an
|
||||
// lvalue, and (b) its size.
|
||||
final IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(getDMContext(), IExpressionDMContext.class);
|
||||
if (exprDmc != null) {
|
||||
getSession().getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
if (expressionService != null) {
|
||||
final DataRequestMonitor<IExpressionDMAddress> drm = new DataRequestMonitor<IExpressionDMAddress>(getSession().getExecutor(), null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
assert getData().getSize() > 0;
|
||||
request.setCanCreate(true);
|
||||
}
|
||||
else {
|
||||
request.setCanCreate(false);
|
||||
}
|
||||
request.done();
|
||||
}
|
||||
};
|
||||
|
||||
expressionService.getExpressionAddressData(exprDmc, drm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
request.setCanCreate(false);
|
||||
request.done();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbVariableVMNode(AbstractDMVMProvider provider, DsfSession session,
|
||||
SyncVariableDataAccess syncVariableDataAccess) {
|
||||
super(provider, session, syncVariableDataAccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* The primary reason for the specialization of VariableVMNode is to create
|
||||
* a GDB-specific VM context that implements ICWatchpointTarget, so that the
|
||||
* "Add Watchpoint" context menu appears for variables and expressions in
|
||||
* GDB-DSF sessions but not necessarily other DSF-based sessions [bugzilla
|
||||
* 248606]
|
||||
*
|
||||
* @see org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode#createVMContext(org.eclipse.cdt.dsf.datamodel.IDMContext)
|
||||
*/
|
||||
@Override
|
||||
protected IDMVMContext createVMContext(IDMContext dmc) {
|
||||
return new GdbVariableExpressionVMC(dmc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Freescale Semiconductor. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
|
||||
/**
|
||||
* A specialization of VariableVMProvider that uses a GDB-specific variable VM
|
||||
* node. To understand why this is necessary, see GdbVariableVMNode.
|
||||
*/
|
||||
public class GdbVariableVMProvider extends VariableVMProvider {
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbVariableVMProvider(AbstractVMAdapter adapter,
|
||||
IPresentationContext context, DsfSession session) {
|
||||
super(adapter, context, session);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider#configureLayout(org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess)
|
||||
*/
|
||||
@Override
|
||||
protected void configureLayout() {
|
||||
// Create the variable data access routines.
|
||||
SyncVariableDataAccess varAccess = new SyncVariableDataAccess(getSession()) ;
|
||||
|
||||
// Create the top level node to deal with the root selection.
|
||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
||||
setRootNode(rootNode);
|
||||
|
||||
// Create the next level which represents members of structs/unions/enums and elements of arrays.
|
||||
IVMNode subExpressioNode = new GdbVariableVMNode(this, getSession(), varAccess);
|
||||
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
|
||||
|
||||
// Configure the sub-expression node to be a child of itself. This way the content
|
||||
// provider will recursively drill-down the variable hierarchy.
|
||||
addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode });
|
||||
}
|
||||
}
|
|
@ -13,10 +13,8 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
|||
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.modules.ModulesVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.breakpoints.GdbBreakpointVMProvider;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
@ -47,11 +45,11 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
|||
if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
|
||||
return new LaunchVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
|
||||
return new VariableVMProvider(this, context, getSession());
|
||||
return new GdbVariableVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) {
|
||||
return new RegisterVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
|
||||
return new ExpressionVMProvider(this, context, getSession());
|
||||
return new GdbExpressionVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
|
||||
return new ModulesVMProvider(this, context, getSession());
|
||||
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
||||
|
|
|
@ -146,8 +146,8 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
fExpression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtype")
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
|
||||
return fExpression;
|
||||
|
@ -750,7 +750,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
|||
IExpressionDMContext expressionDMC = expressionService.createExpression(
|
||||
createCompositeDMVMContext(update),
|
||||
update.getExpression().getExpressionText());
|
||||
VariableExpressionVMC variableVmc = new VariableExpressionVMC(expressionDMC);
|
||||
VariableExpressionVMC variableVmc = (VariableExpressionVMC)createVMContext(expressionDMC);
|
||||
variableVmc.setExpression(update.getExpression());
|
||||
|
||||
update.setExpressionElement(variableVmc);
|
||||
|
|
|
@ -69,27 +69,8 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
|||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
|
||||
|
||||
/*
|
||||
* Create the variable data access routines.
|
||||
*/
|
||||
SyncVariableDataAccess varAccess = new SyncVariableDataAccess(session) ;
|
||||
|
||||
/*
|
||||
* Create the top level node to deal with the root selection.
|
||||
*/
|
||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
||||
setRootNode(rootNode);
|
||||
|
||||
/*
|
||||
* Create the next level which represents members of structs/unions/enums and elements of arrays.
|
||||
*/
|
||||
IVMNode subExpressioNode = new VariableVMNode(this, getSession(), varAccess);
|
||||
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
|
||||
|
||||
// Configure the sub-expression node to be a child of itself. This way the content
|
||||
// provider will recursively drill-down the variable hierarchy.
|
||||
addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode });
|
||||
}
|
||||
configureLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
@ -98,6 +79,30 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the nodes of this provider. This method may be over-ridden by
|
||||
* sub classes to create an alternate configuration in this provider.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected void configureLayout() {
|
||||
|
||||
// Create the variable data access routines.
|
||||
SyncVariableDataAccess varAccess = new SyncVariableDataAccess(getSession()) ;
|
||||
|
||||
// Create the top level node to deal with the root selection.
|
||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
||||
setRootNode(rootNode);
|
||||
|
||||
// Create the next level which represents members of structs/unions/enums and elements of arrays.
|
||||
IVMNode subExpressioNode = new VariableVMNode(this, getSession(), varAccess);
|
||||
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
|
||||
|
||||
// Configure the sub-expression node to be a child of itself. This way the content
|
||||
// provider will recursively drill-down the variable hierarchy.
|
||||
addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode });
|
||||
}
|
||||
|
||||
@Override
|
||||
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
|
||||
return new VariableColumnPresentation();
|
||||
|
|
Loading…
Add table
Reference in a new issue