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.executables,
|
||||||
org.eclipse.cdt.debug.core.model,
|
org.eclipse.cdt.debug.core.model,
|
||||||
org.eclipse.cdt.debug.core.sourcelookup,
|
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.breakpoints;x-friends:="org.eclipse.cdt.debug.edc",
|
||||||
org.eclipse.cdt.debug.internal.core.executables;x-internal:=true,
|
org.eclipse.cdt.debug.internal.core.executables;x-internal:=true,
|
||||||
org.eclipse.cdt.debug.internal.core.model;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.ICType;
|
||||||
import org.eclipse.cdt.debug.core.model.ICValue;
|
import org.eclipse.cdt.debug.core.model.ICValue;
|
||||||
import org.eclipse.cdt.debug.internal.core.CSettingsManager;
|
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.core.runtime.CoreException;
|
||||||
import org.eclipse.debug.core.DebugEvent;
|
import org.eclipse.debug.core.DebugEvent;
|
||||||
import org.eclipse.debug.core.DebugException;
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
@ -72,7 +73,7 @@ class VariableEventListener implements ICDIEventListener {
|
||||||
/**
|
/**
|
||||||
* Represents a variable in the CDI model.
|
* 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 {
|
interface IInternalVariable {
|
||||||
IInternalVariable createShadow( int start, int length ) throws DebugException;
|
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
|
// 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">
|
id="org.eclipse.cdt.debug.ui.actions.method.ToggleMethodBreakpointAction">
|
||||||
</action>
|
</action>
|
||||||
</objectContribution>
|
</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
|
<objectContribution
|
||||||
objectClass="org.eclipse.cdt.core.model.IVariable"
|
objectClass="org.eclipse.cdt.core.model.IVariable"
|
||||||
id="org.eclipse.cdt.debug.ui.WatchpointActions">
|
id="org.eclipse.cdt.debug.ui.WatchpointActions">
|
||||||
|
@ -808,20 +821,6 @@
|
||||||
class="org.eclipse.cdt.debug.core.model.ICVariable">
|
class="org.eclipse.cdt.debug.core.model.ICVariable">
|
||||||
</selection>
|
</selection>
|
||||||
</action>
|
</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>
|
||||||
<viewerContribution
|
<viewerContribution
|
||||||
targetID="org.eclipse.debug.ui.RegisterView"
|
targetID="org.eclipse.debug.ui.RegisterView"
|
||||||
|
|
|
@ -11,84 +11,142 @@
|
||||||
package org.eclipse.cdt.debug.internal.ui.actions;
|
package org.eclipse.cdt.debug.internal.ui.actions;
|
||||||
|
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.internal.core.model.CVariable;
|
import org.eclipse.cdt.debug.internal.core.CRequest;
|
||||||
import org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointDialog;
|
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
|
||||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
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.action.IAction;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
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.viewers.TreeSelection;
|
||||||
import org.eclipse.jface.window.Window;
|
import org.eclipse.jface.window.Window;
|
||||||
import org.eclipse.ui.IActionDelegate;
|
|
||||||
import org.eclipse.ui.IObjectActionDelegate;
|
import org.eclipse.ui.IObjectActionDelegate;
|
||||||
import org.eclipse.ui.IWorkbenchPart;
|
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() {
|
public AddWatchpointOnVariableActionDelegate() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* (non-Javadoc)
|
||||||
* @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
|
* @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.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
private static class GetSizeRequest extends CRequest implements ICWatchpointTarget.GetSizeRequest {
|
||||||
* @see IActionDelegate#run(IAction)
|
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) {
|
public void run(IAction action) {
|
||||||
IStructuredSelection selection = getSelection();
|
if (fVar == null) {
|
||||||
|
|
||||||
if (selection == null || selection.isEmpty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object obj = ((TreeSelection)selection).getFirstElement();
|
final String expr = fVar.getExpression();
|
||||||
if (obj != null && obj instanceof CVariable) {
|
if (expr == null) {
|
||||||
CVariable var = (CVariable)obj;
|
assert false : "how are we getting an empty expression?"; //$NON-NLS-1$
|
||||||
|
return;
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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()) {
|
if (selection == null || selection.isEmpty()) {
|
||||||
action.setEnabled(false);
|
action.setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (selection instanceof TreeSelection) {
|
if (selection instanceof TreeSelection) {
|
||||||
Object obj = ((TreeSelection)selection).getFirstElement();
|
Object obj = ((TreeSelection)selection).getFirstElement();
|
||||||
if (obj != null && obj instanceof CVariable) {
|
fVar = (ICWatchpointTarget)DebugPlugin.getAdapter(obj, ICWatchpointTarget.class);
|
||||||
action.setEnabled(true);
|
if (fVar != null) {
|
||||||
} else {
|
final ICWatchpointTarget.CanCreateWatchpointRequest request = new CanCreateWatchpointRequest() {
|
||||||
action.setEnabled(false);
|
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.ICType;
|
||||||
import org.eclipse.cdt.debug.core.model.ICValue;
|
import org.eclipse.cdt.debug.core.model.ICValue;
|
||||||
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
|
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.CDebugTarget;
|
||||||
import org.eclipse.cdt.debug.internal.core.model.CExpression;
|
import org.eclipse.cdt.debug.internal.core.model.CExpression;
|
||||||
import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
|
import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
|
||||||
|
@ -179,6 +180,12 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
||||||
fFrameLevel = 0;
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int)
|
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int)
|
||||||
*/
|
*/
|
||||||
|
@ -190,7 +197,7 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IStackFrame stackFrame= stackFrames[targetFrame];
|
IStackFrame stackFrame= stackFrames[targetFrame];
|
||||||
fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new IDisassemblyRetrieval.AddressRequest() {
|
fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new AddressRequest() {
|
||||||
@Override
|
@Override
|
||||||
public void done() {
|
public void done() {
|
||||||
fCallback.setUpdatePending(false);
|
fCallback.setUpdatePending(false);
|
||||||
|
@ -238,6 +245,12 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
||||||
return fTargetFrameContext.getFrameLineNumber();
|
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)
|
/* (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)
|
* @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);
|
endAddress= startAddress.add(addressLength);
|
||||||
}
|
}
|
||||||
final BigInteger finalEndAddress= endAddress;
|
final BigInteger finalEndAddress= endAddress;
|
||||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
|
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() {
|
||||||
@Override
|
@Override
|
||||||
public void done() {
|
public void done() {
|
||||||
if (!isCanceled() && getDisassemblyBlock() != null) {
|
if (!isCanceled() && getDisassemblyBlock() != null) {
|
||||||
|
@ -365,7 +378,7 @@ public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSe
|
||||||
public void retrieveDisassembly(String file, int lines,
|
public void retrieveDisassembly(String file, int lines,
|
||||||
BigInteger endAddress, final boolean mixed, final boolean showSymbols,
|
BigInteger endAddress, final boolean mixed, final boolean showSymbols,
|
||||||
final boolean showDisassembly) {
|
final boolean showDisassembly) {
|
||||||
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
|
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new DisassemblyRequest() {
|
||||||
@Override
|
@Override
|
||||||
public void done() {
|
public void done() {
|
||||||
if (!isCanceled() && getDisassemblyBlock() != null) {
|
if (!isCanceled() && getDisassemblyBlock() != null) {
|
||||||
|
|
|
@ -14,89 +14,21 @@ package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
|
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.IRequest;
|
||||||
import org.eclipse.debug.core.model.IStackFrame;
|
import org.eclipse.debug.core.model.IStackFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public interface IDisassemblyRetrieval {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
interface DisassemblyRequest extends IRequest {
|
||||||
*/
|
IDisassemblyBlock getDisassemblyBlock();
|
||||||
public static class AddressRequest extends Request {
|
void setDisassemblyBlock(IDisassemblyBlock disassemblyBlock);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.concurrent.ThreadSafe;
|
||||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
|
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.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.modules.ModulesVMProvider;
|
||||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
|
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.breakpoints.GdbBreakpointVMProvider;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
|
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
@ -47,11 +45,11 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
||||||
if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
|
if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
|
||||||
return new LaunchVMProvider(this, context, getSession());
|
return new LaunchVMProvider(this, context, getSession());
|
||||||
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
|
} 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()) ) {
|
} else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) {
|
||||||
return new RegisterVMProvider(this, context, getSession());
|
return new RegisterVMProvider(this, context, getSession());
|
||||||
} else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
|
} 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()) ) {
|
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
|
||||||
return new ModulesVMProvider(this, context, getSession());
|
return new ModulesVMProvider(this, context, getSession());
|
||||||
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
||||||
|
|
|
@ -146,8 +146,8 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
fExpression = expression;
|
fExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("rawtypes")
|
||||||
@SuppressWarnings("rawtype")
|
@Override
|
||||||
public Object getAdapter(Class adapter) {
|
public Object getAdapter(Class adapter) {
|
||||||
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
|
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
|
||||||
return fExpression;
|
return fExpression;
|
||||||
|
@ -750,7 +750,7 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
IExpressionDMContext expressionDMC = expressionService.createExpression(
|
IExpressionDMContext expressionDMC = expressionService.createExpression(
|
||||||
createCompositeDMVMContext(update),
|
createCompositeDMVMContext(update),
|
||||||
update.getExpression().getExpressionText());
|
update.getExpression().getExpressionText());
|
||||||
VariableExpressionVMC variableVmc = new VariableExpressionVMC(expressionDMC);
|
VariableExpressionVMC variableVmc = (VariableExpressionVMC)createVMContext(expressionDMC);
|
||||||
variableVmc.setExpression(update.getExpression());
|
variableVmc.setExpression(update.getExpression());
|
||||||
|
|
||||||
update.setExpressionElement(variableVmc);
|
update.setExpressionElement(variableVmc);
|
||||||
|
|
|
@ -69,27 +69,8 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
||||||
store.addPropertyChangeListener(fPreferencesListener);
|
store.addPropertyChangeListener(fPreferencesListener);
|
||||||
setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
|
setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
|
||||||
|
|
||||||
/*
|
configureLayout();
|
||||||
* 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 });
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
@ -97,6 +78,30 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
||||||
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
|
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
|
||||||
super.dispose();
|
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
|
@Override
|
||||||
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
|
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue