mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Moved generic packages out of the org.eclipse.dd.dsf.mi.* plugins and into the org.eclipse.dd.dsf.debug.* plugins as appropriate, in preparation for the memory view work (bug 160047).
This commit is contained in:
parent
434c29ab17
commit
51452d7e2c
16 changed files with 1801 additions and 3 deletions
|
@ -12,6 +12,8 @@ Require-Bundle: org.eclipse.ui,
|
|||
org.eclipse.debug.core,
|
||||
org.eclipse.debug.ui,
|
||||
org.eclipse.ui.ide,
|
||||
org.eclipse.jface.text,
|
||||
org.eclipse.ui.workbench.texteditor,
|
||||
org.eclipse.dd.dsf,
|
||||
org.eclipse.dd.dsf.ui,
|
||||
org.eclipse.dd.dsf.debug,
|
||||
|
@ -24,5 +26,7 @@ Export-Package:
|
|||
org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport,
|
||||
org.eclipse.dd.dsf.debug.ui.viewmodel.launch,
|
||||
org.eclipse.dd.dsf.debug.ui.viewmodel.register,
|
||||
org.eclipse.dd.dsf.debug.ui.viewmodel.variable
|
||||
org.eclipse.dd.dsf.debug.ui.viewmodel.variable,
|
||||
org.eclipse.dd.dsf.debug.ui.sourcelookup,
|
||||
org.eclipse.dd.dsf.debug.ui.actions
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -7,4 +7,50 @@
|
|||
delegateClass="org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionDelegate"/>
|
||||
</extension>
|
||||
|
||||
<extension point="org.eclipse.ui.editors.annotationTypes">
|
||||
<type
|
||||
name="org.eclipse.dd.debug.currentIP">
|
||||
</type>
|
||||
<type
|
||||
name="org.eclipse.dd.debug.secondaryIP">
|
||||
</type>
|
||||
</extension>
|
||||
|
||||
<extension point="org.eclipse.ui.editors.markerAnnotationSpecification">
|
||||
<specification
|
||||
annotationImageProvider="org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerImageProvider"
|
||||
annotationType="org.eclipse.dd.debug.currentIP"
|
||||
colorPreferenceKey="currentIPColor"
|
||||
colorPreferenceValue="198,219,174"
|
||||
highlightPreferenceKey="currentIPHighlight"
|
||||
highlightPreferenceValue="true"
|
||||
label="%debugCurrentInstructionPointer"
|
||||
overviewRulerPreferenceKey="currentIPOverviewRuler"
|
||||
overviewRulerPreferenceValue="true"
|
||||
presentationLayer="6"
|
||||
textPreferenceKey="currentIPIndication"
|
||||
textPreferenceValue="false"
|
||||
verticalRulerPreferenceKey="currentIPVerticalRuler"
|
||||
verticalRulerPreferenceValue="true">
|
||||
</specification>
|
||||
<specification
|
||||
annotationImageProvider="org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerImageProvider"
|
||||
annotationType="org.eclipse.dd.debug.secondaryIP"
|
||||
colorPreferenceKey="secondaryIPColor"
|
||||
colorPreferenceValue="219,235,204"
|
||||
highlightPreferenceKey="secondaryIPHighlight"
|
||||
highlightPreferenceValue="true"
|
||||
label="%debugCallStack"
|
||||
overviewRulerPreferenceKey="secondaryIPOverviewRuler"
|
||||
overviewRulerPreferenceValue="true"
|
||||
presentationLayer="6"
|
||||
textPreferenceKey="secondaryIPIndication"
|
||||
textPreferenceValue="false"
|
||||
verticalRulerPreferenceKey="secondaryIPVerticalRuler"
|
||||
verticalRulerPreferenceValue="true">
|
||||
</specification>
|
||||
</extension>
|
||||
|
||||
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.INativeProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Immutable
|
||||
public abstract class DsfCommandRunnable extends DsfRunnable {
|
||||
private final IExecutionDMContext fContext;
|
||||
private final DsfServicesTracker fTracker;
|
||||
private final IDebugCommandRequest fRequest;
|
||||
|
||||
public IExecutionDMContext getContext() { return fContext; }
|
||||
public IRunControl getRunControl() {
|
||||
return fTracker.getService(IRunControl.class);
|
||||
}
|
||||
public IStepQueueManager getStepQueueMgr() {
|
||||
return fTracker.getService(IStepQueueManager.class);
|
||||
}
|
||||
|
||||
public INativeProcesses getProcesses() {
|
||||
return fTracker.getService(INativeProcesses.class);
|
||||
}
|
||||
|
||||
public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) {
|
||||
fTracker = servicesTracker;
|
||||
if (element instanceof DMVMContext) {
|
||||
// Javac doesn't like the cast to "(AbstractDMVMLayoutNode<?>.DMVMContext)" need to use the
|
||||
// construct below and suppress warnings.
|
||||
@SuppressWarnings("unchecked")
|
||||
AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)element;
|
||||
fContext = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class);
|
||||
} else {
|
||||
fContext = null;
|
||||
}
|
||||
|
||||
fRequest = request;
|
||||
}
|
||||
|
||||
public final void run() {
|
||||
if (fRequest.isCanceled()) return;
|
||||
if (getContext() == null) {
|
||||
fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$
|
||||
} else if (getRunControl() == null) {
|
||||
fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$
|
||||
} else {
|
||||
doExecute();
|
||||
}
|
||||
fRequest.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform the actual work. It should not call monitor.done(), because
|
||||
* it will be called in the super-class.
|
||||
*/
|
||||
protected abstract void doExecute();
|
||||
|
||||
protected IStatus makeError(String message, Throwable e) {
|
||||
return new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, message, e);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.IResumeHandler;
|
||||
|
||||
@Immutable
|
||||
public class DsfResumeCommand implements IResumeHandler {
|
||||
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfResumeCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
request.setEnabled(getRunControl().canResume(getContext()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getRunControl().resume(getContext(), new RequestMonitor(fExecutor, null));
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.IStepIntoHandler;
|
||||
|
||||
@Immutable
|
||||
public class DsfStepIntoCommand implements IStepIntoHandler {
|
||||
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfStepIntoCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_INTO);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.IStepIntoHandler;
|
||||
|
||||
@Immutable
|
||||
public class DsfStepOverCommand implements IStepIntoHandler {
|
||||
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfStepOverCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_OVER);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.IStepIntoHandler;
|
||||
|
||||
@Immutable
|
||||
public class DsfStepReturnCommand implements IStepIntoHandler {
|
||||
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfStepReturnCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_RETURN);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.ISuspendHandler;
|
||||
|
||||
@Immutable
|
||||
public class DsfSuspendCommand implements ISuspendHandler {
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfSuspendCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
request.setEnabled(getRunControl().canSuspend(getContext()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getRunControl().suspend(getContext(), new RequestMonitor(fExecutor, null));
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.actions;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.INativeProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
|
||||
import org.eclipse.debug.core.commands.IDebugCommandRequest;
|
||||
import org.eclipse.debug.core.commands.IEnabledStateRequest;
|
||||
import org.eclipse.debug.core.commands.ITerminateHandler;
|
||||
|
||||
public class DsfTerminateCommand implements ITerminateHandler {
|
||||
private final DsfExecutor fExecutor;
|
||||
private final DsfServicesTracker fTracker;
|
||||
|
||||
public DsfTerminateCommand(DsfSession session) {
|
||||
fExecutor = session.getExecutor();
|
||||
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fTracker.dispose();
|
||||
}
|
||||
|
||||
// Run control may not be avilable after a connection is terminated and shut down.
|
||||
public void canExecute(final IEnabledStateRequest request) {
|
||||
if (request.getElements().length != 1 ||
|
||||
!(request.getElements()[0] instanceof DMVMContext) )
|
||||
{
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Javac doesn't like the cast to "(AbstractDMVMLayoutNode<?>.DMVMContext)" need to use the
|
||||
// construct below and suppress warnings.
|
||||
@SuppressWarnings("unchecked")
|
||||
AbstractDMVMLayoutNode<?>.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0];
|
||||
final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class);
|
||||
if (dmc == null) {
|
||||
request.setEnabled(false);
|
||||
request.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fExecutor.execute(
|
||||
new DsfRunnable() {
|
||||
public void run() {
|
||||
// Get the processes service and the exec context.
|
||||
INativeProcesses processes = fTracker.getService(INativeProcesses.class);
|
||||
if (processes == null || dmc == null) {
|
||||
// Context or service already invalid.
|
||||
request.done();
|
||||
} else {
|
||||
// Check the teriminate.
|
||||
processes.canTerminate(
|
||||
processes.getThreadForExecutionContext(dmc),
|
||||
new DataRequestMonitor<Boolean>(fExecutor, null) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
request.setEnabled(getData());
|
||||
request.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean execute(final IDebugCommandRequest request) {
|
||||
if (request.getElements().length != 1) {
|
||||
request.done();
|
||||
return false;
|
||||
}
|
||||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getProcesses().terminate(
|
||||
getProcesses().getThreadForExecutionContext(getContext()), new RequestMonitor(fExecutor, null));
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 IBM Corporation 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.dd.dsf.debug.ui.sourcelookup;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerManager.IPAnnotation;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.jface.text.source.Annotation;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.ui.texteditor.IAnnotationImageProvider;
|
||||
|
||||
@ThreadSafe
|
||||
public class InstructionPointerImageProvider implements IAnnotationImageProvider {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation)
|
||||
*/
|
||||
public Image getManagedImage(Annotation annotation) {
|
||||
return ((IPAnnotation)annotation).getImage();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation)
|
||||
*/
|
||||
public String getImageDescriptorId(Annotation annotation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptor(java.lang.String)
|
||||
*/
|
||||
public ImageDescriptor getImageDescriptor(String imageDescritporId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2006 IBM Corporation 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Wind River Systems - Adapter to use with DSF
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.sourcelookup;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.jface.text.Position;
|
||||
import org.eclipse.jface.text.source.Annotation;
|
||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.ui.IEditorInput;
|
||||
import org.eclipse.ui.texteditor.IDocumentProvider;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
/**
|
||||
* This class tracks instruction pointer contexts for a single DSF session.
|
||||
*/
|
||||
@ThreadSafe
|
||||
class InstructionPointerManager {
|
||||
|
||||
/**
|
||||
* Editor annotation object for instruction pointers.
|
||||
*/
|
||||
static class IPAnnotation extends Annotation {
|
||||
|
||||
/** The image for this annotation. */
|
||||
private Image fImage;
|
||||
|
||||
/** Frame DMC that this IP is for **/
|
||||
private IStack.IFrameDMContext fFrame;
|
||||
|
||||
/**
|
||||
* Constructs an instruction pointer image.
|
||||
*
|
||||
* @param frame stack frame the instruction pointer is associated with
|
||||
* @param annotationType the type of annotation to display (annotation identifier)
|
||||
* @param text the message to display with the annotation as hover help
|
||||
* @param image the image used to display the annotation
|
||||
*/
|
||||
IPAnnotation(IStack.IFrameDMContext frame, String annotationType, String text, Image image) {
|
||||
super(annotationType, false, text);
|
||||
fFrame = frame;
|
||||
fImage = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this annotation's image.
|
||||
*
|
||||
* @return image
|
||||
*/
|
||||
protected Image getImage() {
|
||||
return fImage;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof IPAnnotation) {
|
||||
return fFrame.equals(((IPAnnotation)other).fFrame);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fFrame.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the context for a single instruction pointer. This is a convenience class
|
||||
* used to store the three objects that comprise an instruction pointer 'context' so it
|
||||
* can be stored in collections.
|
||||
*/
|
||||
static class AnnotationWrapper {
|
||||
|
||||
/** The text editor for this context. */
|
||||
private ITextEditor fTextEditor;
|
||||
|
||||
/** Stack frame that this annotation is for */
|
||||
private IStack.IFrameDMContext fFrameDmc;
|
||||
|
||||
/** The vertical ruler annotation for this context. */
|
||||
private Annotation fAnnotation;
|
||||
|
||||
AnnotationWrapper(ITextEditor textEditor, Annotation annotation, IStack.IFrameDMContext frameDmc) {
|
||||
fTextEditor = textEditor;
|
||||
fAnnotation = annotation;
|
||||
fFrameDmc = frameDmc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof AnnotationWrapper) {
|
||||
AnnotationWrapper otherContext = (AnnotationWrapper) other;
|
||||
return getAnnotation().equals(otherContext.getAnnotation());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getAnnotation().hashCode();
|
||||
}
|
||||
|
||||
ITextEditor getTextEditor() { return fTextEditor; }
|
||||
Annotation getAnnotation() { return fAnnotation; }
|
||||
IStack.IFrameDMContext getFrameDMC() { return fFrameDmc; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of IDebugTarget objects to (mappings of IThread objects to lists of instruction
|
||||
* pointer contexts).
|
||||
*/
|
||||
private List<AnnotationWrapper> fAnnotationWrappers;
|
||||
|
||||
/**
|
||||
* Clients must not instantiate this class.
|
||||
*/
|
||||
public InstructionPointerManager() {
|
||||
fAnnotationWrappers = Collections.synchronizedList(new LinkedList<AnnotationWrapper>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an instruction pointer annotation in the specified editor for the
|
||||
* specified stack frame.
|
||||
*/
|
||||
public void addAnnotation(ITextEditor textEditor, IStack.IFrameDMContext frame, Position position, boolean isTopFrame) {
|
||||
|
||||
IDocumentProvider docProvider = textEditor.getDocumentProvider();
|
||||
IEditorInput editorInput = textEditor.getEditorInput();
|
||||
// If there is no annotation model, there's nothing more to do
|
||||
IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput);
|
||||
if (annModel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String id;
|
||||
String text;
|
||||
Image image;
|
||||
if (isTopFrame) {
|
||||
id = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
|
||||
text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
|
||||
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
|
||||
} else {
|
||||
id = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
|
||||
text = "Debug Call Stack"; //$NON-NLS-1$
|
||||
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
|
||||
}
|
||||
|
||||
Annotation annotation = new IPAnnotation(frame, id, text, image);
|
||||
|
||||
// Add the annotation at the position to the editor's annotation model.
|
||||
annModel.removeAnnotation(annotation);
|
||||
annModel.addAnnotation(annotation, position);
|
||||
|
||||
// Add to list of existing wrappers
|
||||
fAnnotationWrappers.add(new AnnotationWrapper(textEditor, annotation, frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all annotations associated with the specified debug target that this class
|
||||
* is tracking.
|
||||
*/
|
||||
public void removeAnnotations(IRunControl.IExecutionDMContext execDmc) {
|
||||
// Retrieve the mapping of threads to context lists
|
||||
synchronized(fAnnotationWrappers) {
|
||||
for (Iterator<AnnotationWrapper> wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) {
|
||||
AnnotationWrapper wrapper = wrapperItr.next();
|
||||
if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc)) {
|
||||
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
|
||||
wrapperItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all annotations tracked by this manager */
|
||||
public void removeAllAnnotations() {
|
||||
synchronized(fAnnotationWrappers) {
|
||||
for (AnnotationWrapper wrapper : fAnnotationWrappers) {
|
||||
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
|
||||
}
|
||||
fAnnotationWrappers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified annotation from the specified text editor.
|
||||
*/
|
||||
private void removeAnnotation(ITextEditor textEditor, Annotation annotation) {
|
||||
IDocumentProvider docProvider = textEditor.getDocumentProvider();
|
||||
if (docProvider != null) {
|
||||
IAnnotationModel annotationModel = docProvider.getAnnotationModel(textEditor.getEditorInput());
|
||||
if (annotationModel != null) {
|
||||
annotationModel.removeAnnotation(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,552 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.sourcelookup;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
||||
import org.eclipse.dd.dsf.debug.sourcelookup.DsfMISourceLookupParticipant;
|
||||
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput;
|
||||
import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.Position;
|
||||
import org.eclipse.swt.custom.BusyIndicator;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.IEditorDescriptor;
|
||||
import org.eclipse.ui.IEditorInput;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IEditorRegistry;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.part.FileEditorInput;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
import org.eclipse.ui.texteditor.IDocumentProvider;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
/**
|
||||
* Source display adapter that performs the source lookup, opens the editor,
|
||||
* and paints the IP for the given object.
|
||||
* <p>
|
||||
* The implementation relies on three types of jobs to perform the operations.<br>
|
||||
* - The first kind, "lookup job" performs the source lookup operation. <br>
|
||||
* - The second "display job" positions and annotates the editor. <br>
|
||||
* - The third clears the old IP annotations when a thread or process has resumed
|
||||
* or exited.
|
||||
* <p>
|
||||
* The the lookup jobs can run in parallel with the display or the clearing job,
|
||||
* but the clearing job and the display job must not run at the same time.
|
||||
* Hence there is some involved logic which ensures that the jobs are run in
|
||||
* proper order. To avoid race conditions, this logic uses the session's
|
||||
* dispatch thread to synchronize access to the state data of the running jobs.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("restriction")
|
||||
public class MISourceDisplayAdapter implements ISourceDisplay
|
||||
{
|
||||
/**
|
||||
* A job to perform source lookup on the given DMC.
|
||||
*/
|
||||
class LookupJob extends Job {
|
||||
|
||||
private IDMContext<?> fDmc;
|
||||
private IWorkbenchPage fPage;
|
||||
|
||||
/**
|
||||
* Constructs a new source lookup job.
|
||||
*/
|
||||
public LookupJob(IDMContext<?> dmc, IWorkbenchPage page) {
|
||||
super("DSF Source Lookup"); //$NON-NLS-1$
|
||||
setPriority(Job.INTERACTIVE);
|
||||
setSystem(true);
|
||||
fDmc = dmc;
|
||||
fPage = page;
|
||||
}
|
||||
|
||||
IDMContext<?> getDmc() { return fDmc; }
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
protected IStatus run(final IProgressMonitor monitor) {
|
||||
if (monitor.isCanceled()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
|
||||
final SourceLookupResult result = performLookup();
|
||||
executeFromJob(new DsfRunnable() { public void run() {
|
||||
if (!monitor.isCanceled()) {
|
||||
fPrevResult = result;
|
||||
fPrevModelContext = fDmc;
|
||||
fRunningLookupJob = null;
|
||||
startDisplayJob(fPrevResult, fPage);
|
||||
}
|
||||
}});
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
private SourceLookupResult performLookup() {
|
||||
SourceLookupResult result = new SourceLookupResult(fDmc, null, null, null);
|
||||
String editorId = null;
|
||||
IEditorInput editorInput = null;
|
||||
Object sourceElement = fSourceLookup.getSourceElement(fDmc);
|
||||
|
||||
if (sourceElement == null) {
|
||||
editorInput = new CommonSourceNotFoundEditorInput(fDmc);
|
||||
editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
|
||||
} else if (sourceElement instanceof IFile) {
|
||||
editorId = getEditorIdForFilename(((IFile)sourceElement).getName());
|
||||
editorInput = new FileEditorInput((IFile)sourceElement);
|
||||
}
|
||||
result.setEditorInput(editorInput);
|
||||
result.setEditorId(editorId);
|
||||
result.setSourceElement(sourceElement);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getEditorIdForFilename(String filename) {
|
||||
IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
|
||||
IEditorDescriptor descriptor = registry.getDefaultEditor(filename);
|
||||
if (descriptor == null) {
|
||||
return "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return descriptor.getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Job that positions the editor and paints the IP Annotation for given DMC.
|
||||
*/
|
||||
class DisplayJob extends UIJob {
|
||||
private SourceLookupResult fResult;
|
||||
private IWorkbenchPage fPage;
|
||||
|
||||
IDMContext<?> getDmc() { return fResult.getDmc(); }
|
||||
|
||||
/**
|
||||
* Constructs a new source display job
|
||||
*/
|
||||
public DisplayJob(SourceLookupResult result, IWorkbenchPage page) {
|
||||
super("Debug Source Display"); //$NON-NLS-1$
|
||||
setSystem(true);
|
||||
setPriority(Job.INTERACTIVE);
|
||||
fResult = result;
|
||||
fPage = page;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(final IProgressMonitor monitor) {
|
||||
DsfRunnable displayJobFinishedRunnable = new DsfRunnable() {
|
||||
public void run() {
|
||||
// If the current display job does not match up with "this", it means that this job got cancelled
|
||||
// after it already completed and after this runnable was queued into the dispatch thread.
|
||||
if (fRunningDisplayJob == DisplayJob.this) {
|
||||
fRunningDisplayJob = null;
|
||||
serviceDisplayAndClearingJobs();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
executeFromJob(displayJobFinishedRunnable);
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
|
||||
IEditorPart editor = openEditor(fResult, fPage);
|
||||
if (editor == null) {
|
||||
executeFromJob(displayJobFinishedRunnable);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
ITextEditor textEditor = null;
|
||||
if (editor instanceof ITextEditor) {
|
||||
textEditor = (ITextEditor)editor;
|
||||
} else {
|
||||
textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
|
||||
}
|
||||
if (textEditor != null) {
|
||||
positionEditor(textEditor, fResult.getDmc());
|
||||
}
|
||||
|
||||
executeFromJob(displayJobFinishedRunnable);
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the editor used to display the source for an element selected in
|
||||
* this view and returns the editor that was opened or <code>null</code> if
|
||||
* no editor could be opened.
|
||||
*/
|
||||
private IEditorPart openEditor(SourceLookupResult result, IWorkbenchPage page) {
|
||||
IEditorInput input= result.getEditorInput();
|
||||
String id= result.getEditorId();
|
||||
if (input == null || id == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return openEditor(page, input, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an editor in the workbench and returns the editor that was opened
|
||||
* or <code>null</code> if an error occurred while attempting to open the
|
||||
* editor.
|
||||
*/
|
||||
private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) {
|
||||
final IEditorPart[] editor = new IEditorPart[] {null};
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
if (!page.getWorkbenchWindow().getWorkbench().isClosing()) {
|
||||
try {
|
||||
editor[0] = page.openEditor(input, id, false);
|
||||
} catch (PartInitException e) {}
|
||||
}
|
||||
}
|
||||
};
|
||||
BusyIndicator.showWhile(Display.getDefault(), r);
|
||||
return editor[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Positions the text editor for the given stack frame
|
||||
*/
|
||||
private void positionEditor(ITextEditor editor, final IDMContext<?> dmc) {
|
||||
if (!(dmc instanceof IFrameDMContext)) return;
|
||||
final IFrameDMContext frameDmc = (IFrameDMContext)dmc;
|
||||
|
||||
// We need to retrieve the frame level and line number from the service.
|
||||
// Normally we could just get the needed information from IFrameDMData, but
|
||||
// IFrameDMData, which derives from IModelData can only be accessed on the
|
||||
// dispatch thread, so we need to copy over relevant information from
|
||||
// IFrameDMData into this structure so we can read it in the job thread.
|
||||
class FramePositioningData {
|
||||
int fLine;
|
||||
int fLevel;
|
||||
}
|
||||
|
||||
// Query the service for frame data. We are calling from a job thread,
|
||||
// so we use the Query.get() method, which will block until the
|
||||
// query is completed.
|
||||
Query<FramePositioningData> query = new Query<FramePositioningData>(fExecutor) {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<FramePositioningData> rm) {
|
||||
IStack stackService = fServicesTracker.getService(IStack.class);
|
||||
if (stackService == null) {
|
||||
doneException(new CoreException(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, "Stack data not available", null))); //$NON-NLS-1$
|
||||
return;
|
||||
}
|
||||
stackService.getModelData(
|
||||
frameDmc,
|
||||
new DataRequestMonitor<IFrameDMData>(fExecutor, rm) {
|
||||
@Override
|
||||
public void handleOK() {
|
||||
FramePositioningData clientData = new FramePositioningData();
|
||||
clientData.fLevel = getData().getLevel();
|
||||
// Document line numbers are 0-based. While debugger line numbers are 1-based.
|
||||
clientData.fLine = getData().getLine() - 1;
|
||||
rm.setData(clientData);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
try {
|
||||
fExecutor.execute(query);
|
||||
FramePositioningData framePositioningData = query.get();
|
||||
// If the frame data is not available, or the line number is not
|
||||
// known, give up.
|
||||
if (framePositioningData == null || framePositioningData.fLevel < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Position and annotate the editor.
|
||||
IRegion region= getLineInformation(editor, framePositioningData.fLine);
|
||||
if (region != null) {
|
||||
editor.selectAndReveal(region.getOffset(), 0);
|
||||
fIPManager.addAnnotation(
|
||||
editor, frameDmc, new Position(region.getOffset(), region.getLength()),
|
||||
framePositioningData.fLevel == 0);
|
||||
}
|
||||
} catch (InterruptedException e) { assert false : "Interrupted exception in DSF thread"; //$NON-NLS-1$
|
||||
} catch (ExecutionException e) { // Ignore
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line information for the given line in the given editor
|
||||
*/
|
||||
private IRegion getLineInformation(ITextEditor editor, int lineNumber) {
|
||||
IDocumentProvider provider= editor.getDocumentProvider();
|
||||
IEditorInput input= editor.getEditorInput();
|
||||
try {
|
||||
provider.connect(input);
|
||||
} catch (CoreException e) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
IDocument document= provider.getDocument(input);
|
||||
if (document != null)
|
||||
return document.getLineInformation(lineNumber);
|
||||
} catch (BadLocationException e) {
|
||||
} finally {
|
||||
provider.disconnect(input);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Job that removes the old IP Annotations associated with given execution
|
||||
* context.
|
||||
*/
|
||||
class ClearingJob extends UIJob {
|
||||
List<IRunControl.IExecutionDMContext> fDmcsToClear;
|
||||
|
||||
public ClearingJob(List<IRunControl.IExecutionDMContext> dmcs) {
|
||||
super("Debug Source Display"); //$NON-NLS-1$
|
||||
setSystem(true);
|
||||
setPriority(Job.INTERACTIVE);
|
||||
fDmcsToClear = dmcs;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
DsfRunnable clearingJobFinishedRunnable = new DsfRunnable() { public void run() {
|
||||
assert fRunningClearingJob == ClearingJob.this;
|
||||
fRunningClearingJob = null;
|
||||
serviceDisplayAndClearingJobs();
|
||||
}};
|
||||
|
||||
if (monitor.isCanceled()) {
|
||||
executeFromJob(clearingJobFinishedRunnable);
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
|
||||
for (IRunControl.IExecutionDMContext dmc : fDmcsToClear) {
|
||||
fIPManager.removeAnnotations(dmc);
|
||||
}
|
||||
|
||||
executeFromJob(clearingJobFinishedRunnable);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
private DsfSession fSession;
|
||||
private DsfExecutor fExecutor;
|
||||
private DsfServicesTracker fServicesTracker;
|
||||
private IDMContext<?> fPrevModelContext;
|
||||
private SourceLookupResult fPrevResult;
|
||||
private ISourceLookupDirector fSourceLookup;
|
||||
private DsfMISourceLookupParticipant fSourceLookupParticipant;
|
||||
private InstructionPointerManager fIPManager;
|
||||
|
||||
private LookupJob fRunningLookupJob;
|
||||
private DisplayJob fRunningDisplayJob;
|
||||
private DisplayJob fPendingDisplayJob;
|
||||
private ClearingJob fRunningClearingJob;
|
||||
private List<IRunControl.IExecutionDMContext> fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
|
||||
|
||||
public MISourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) {
|
||||
fSession = session;
|
||||
fExecutor = session.getExecutor();
|
||||
fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
fSourceLookup = sourceLocator;
|
||||
fSourceLookupParticipant = new DsfMISourceLookupParticipant(session);
|
||||
fSourceLookup.addParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant} );
|
||||
|
||||
fIPManager = new InstructionPointerManager();
|
||||
|
||||
fSession.addServiceEventListener(this, null);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
fSession.removeServiceEventListener(this);
|
||||
fServicesTracker.dispose();
|
||||
fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant});
|
||||
|
||||
// fSourceLookupParticipant is disposed by teh source lookup director
|
||||
|
||||
// Need to remove annotations in UI thread.
|
||||
//fIPManager.removeAllAnnotations();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java.lang.Object, org.eclipse.ui.IWorkbenchPage, boolean)
|
||||
*/
|
||||
public void displaySource(Object context, final IWorkbenchPage page, final boolean force) {
|
||||
if (!(context instanceof DMVMContext)) return;
|
||||
// Correct cast: (AbstractDMVMLayoutNode<?>.DMVMContext) breaks the javac compiler
|
||||
@SuppressWarnings("unchecked")
|
||||
final IDMContext<?> dmc = ((DMVMContext)context).getDMC();
|
||||
|
||||
// Quick test. DMC is checked again in source lookup participant, but
|
||||
// it's much quicker to test here.
|
||||
if (!(dmc instanceof IFrameDMContext)) return;
|
||||
|
||||
// Re-dispatch to executor thread before accessing job lists.
|
||||
fExecutor.execute(new DsfRunnable() { public void run() {
|
||||
if (!force && dmc.equals(fPrevModelContext)) {
|
||||
fPrevResult.updateArtifact(dmc);
|
||||
startDisplayJob(fPrevResult, page);
|
||||
} else {
|
||||
startLookupJob(dmc, page);
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
private void executeFromJob(Runnable runnable) {
|
||||
try {
|
||||
fExecutor.execute(runnable);
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Session disposed, ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void startLookupJob(final IDMContext<?> dmc, final IWorkbenchPage page) {
|
||||
// If there is a previous lookup job running, cancel it.
|
||||
if (fRunningLookupJob != null) {
|
||||
fRunningLookupJob.cancel();
|
||||
}
|
||||
|
||||
fRunningLookupJob = new LookupJob(dmc, page);
|
||||
fRunningLookupJob.schedule();
|
||||
}
|
||||
|
||||
// To be called only on dispatch thread.
|
||||
private void startDisplayJob(SourceLookupResult lookupResult, IWorkbenchPage page) {
|
||||
DisplayJob nextDisplayJob = new DisplayJob(lookupResult, page);
|
||||
if (fRunningDisplayJob != null) {
|
||||
// There is a display job currently running. Cancel it, and set
|
||||
// the next display job to be run.
|
||||
if (false && fRunningDisplayJob.cancel()) {
|
||||
fPendingDisplayJob = nextDisplayJob;
|
||||
fRunningDisplayJob = null;
|
||||
serviceDisplayAndClearingJobs();
|
||||
} else {
|
||||
// The job already started, so we need to wait until
|
||||
// serviceDisplayAndClearingJobs() is called by the job itself.
|
||||
fPendingDisplayJob = nextDisplayJob;
|
||||
}
|
||||
} else if (fRunningClearingJob != null) {
|
||||
// Wait for the clearing job to finish, instead, set the
|
||||
// display job as pending.
|
||||
fPendingDisplayJob = nextDisplayJob;
|
||||
} else {
|
||||
fRunningDisplayJob = nextDisplayJob;
|
||||
fRunningDisplayJob.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void serviceDisplayAndClearingJobs() {
|
||||
if (!fPendingExecDmcsToClear.isEmpty()) {
|
||||
// There are annotations to be cleared, run the job first
|
||||
fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear);
|
||||
fRunningClearingJob.schedule();
|
||||
fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
|
||||
} else if (fPendingDisplayJob != null) {
|
||||
fRunningDisplayJob = fPendingDisplayJob;
|
||||
fRunningDisplayJob.schedule();
|
||||
fPendingDisplayJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void startAnnotationClearingJob(IRunControl.IExecutionDMContext execDmc) {
|
||||
// Make sure to add the dmc to the list.
|
||||
fPendingExecDmcsToClear.add(execDmc);
|
||||
|
||||
// If lookup job is running, check it agains the exec context,
|
||||
// and cancel it if matches.
|
||||
if (fRunningLookupJob != null) {
|
||||
if (DMContexts.isAncestorOf(fRunningLookupJob.getDmc(), execDmc)) {
|
||||
fRunningLookupJob.cancel();
|
||||
fRunningLookupJob = null;
|
||||
}
|
||||
}
|
||||
// If there is a pending displahy job, make sure it doesn't get
|
||||
// pre-empted by this event. If so, just cancel the pending
|
||||
// display job.
|
||||
if (fPendingDisplayJob != null) {
|
||||
if (DMContexts.isAncestorOf(fPendingDisplayJob.getDmc(), execDmc)) {
|
||||
fPendingDisplayJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
// If no display or clearing jobs are running, schedule the clearing job.
|
||||
if (fRunningClearingJob == null && fRunningDisplayJob == null) {
|
||||
fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear);
|
||||
fRunningClearingJob.schedule();
|
||||
fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
|
||||
}
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IRunControl.IResumedDMEvent e) {
|
||||
if (e.getReason() != StateChangeReason.STEP) {
|
||||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IRunControl.IExitedDMEvent e) {
|
||||
startAnnotationClearingJob(e.getExecutionContext());
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IStepQueueManager.ISteppingTimedOutEvent e) {
|
||||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.ui.sourcelookup;
|
||||
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.ui.IEditorInput;
|
||||
|
||||
/**
|
||||
* The result of a source lookup contains the source element, editor id, and
|
||||
* editor input resolved for a debug artifact.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class SourceLookupResult {
|
||||
|
||||
/**
|
||||
* Element that source was resolved for.
|
||||
*/
|
||||
private IDMContext<?> fDmc;
|
||||
/**
|
||||
* Corresponding source element, or <code>null</code>
|
||||
* if unknown.
|
||||
*/
|
||||
private Object fSourceElement;
|
||||
/**
|
||||
* Associated editor id, used to display the source element,
|
||||
* or <code>null</code> if unknown.
|
||||
*/
|
||||
private String fEditorId;
|
||||
/**
|
||||
* Associatd editor input, used to display the source element,
|
||||
* or <code>null</code> if unknown.
|
||||
*/
|
||||
private IEditorInput fEditorInput;
|
||||
|
||||
/**
|
||||
* Creates a source lookup result on the given artifact, source element,
|
||||
* editor id, and editor input.
|
||||
*/
|
||||
public SourceLookupResult(IDMContext<?> dmc, Object sourceElement, String editorId, IEditorInput editorInput) {
|
||||
fDmc = dmc;
|
||||
setSourceElement(sourceElement);
|
||||
setEditorId(editorId);
|
||||
setEditorInput(editorInput);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getArtifact()
|
||||
*/
|
||||
public IDMContext<?> getDmc() {
|
||||
return fDmc;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getSourceElement()
|
||||
*/
|
||||
public Object getSourceElement() {
|
||||
return fSourceElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source element resolved for the artifact that source
|
||||
* lookup was performed for, or <code>null</code> if a source element
|
||||
* was not resolved.
|
||||
*
|
||||
* @param element resolved source element or <code>null</code> if unknown
|
||||
*/
|
||||
protected void setSourceElement(Object element) {
|
||||
fSourceElement = element;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorId()
|
||||
*/
|
||||
public String getEditorId() {
|
||||
return fEditorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier of the editor used to display this source
|
||||
* lookup result's source element, or <code>null</code> if unknown.
|
||||
*
|
||||
* @param id the identifier of the editor used to display this source
|
||||
* lookup result's source element, or <code>null</code> if unknown
|
||||
*/
|
||||
protected void setEditorId(String id) {
|
||||
fEditorId = id;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorInput()
|
||||
*/
|
||||
public IEditorInput getEditorInput() {
|
||||
return fEditorInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the editor input used to display this source lookup
|
||||
* result's source element, or <code>null</code> if unknown.
|
||||
*
|
||||
* @param input the editor input used to display this source lookup
|
||||
* result's source element, or <code>null</code> if unknown
|
||||
*/
|
||||
protected void setEditorInput(IEditorInput input) {
|
||||
fEditorInput = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the artifact to refer to the given artifact
|
||||
* if equal. For example, when a source lookup result is resued
|
||||
* for the same stack frame, we still need to update in case
|
||||
* the stack frame is not identical.
|
||||
*
|
||||
* @param artifact new artifact state
|
||||
*/
|
||||
public void updateArtifact(IDMContext<?> dmc) {
|
||||
if (fDmc.equals(dmc)) {
|
||||
fDmc = dmc;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.dd.dsf,
|
||||
org.eclipse.cdt.core
|
||||
Eclipse-LazyStart: true
|
||||
Export-Package: org.eclipse.dd.dsf.debug.service,
|
||||
org.eclipse.dd.dsf.debug.service.command
|
||||
Export-Package: org.eclipse.dd.dsf.debug.model,
|
||||
org.eclipse.dd.dsf.debug.service,
|
||||
org.eclipse.dd.dsf.debug.service.command,
|
||||
org.eclipse.dd.dsf.debug.sourcelookup
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.model;
|
||||
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IMemory;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.IMemoryBlock;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DsfMemoryBlockRetrieval implements IMemoryBlockRetrieval {
|
||||
|
||||
private final IDMContext<?> fContext;
|
||||
private final ServiceTracker fServiceTracker;
|
||||
|
||||
public DsfMemoryBlockRetrieval(IDMContext<?> dmc) {
|
||||
fContext = dmc;
|
||||
String memoryServiceFilter =
|
||||
"(&" +
|
||||
"(OBJECTCLASS=" + IMemory.class.getName() + ")" +
|
||||
"(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" +
|
||||
")";
|
||||
fServiceTracker = new ServiceTracker(DsfDebugPlugin.getBundleContext(), memoryServiceFilter, null);
|
||||
fServiceTracker.open();
|
||||
}
|
||||
|
||||
public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsStorageRetrieval() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.sourcelookup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.MultiStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
|
||||
|
||||
/**
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class DsfMISourceLookupParticipant implements ISourceLookupParticipant {
|
||||
protected static final Object[] EMPTY = new Object[0];
|
||||
|
||||
private DsfExecutor fExecutor;
|
||||
private String fSessionId;
|
||||
private DsfServicesTracker fServicesTracker;
|
||||
private ISourceLookupDirector fDirector;
|
||||
private Map<String, List<Object>> fLookupCache = Collections.synchronizedMap(new HashMap<String, List<Object>>());
|
||||
|
||||
public DsfMISourceLookupParticipant(DsfSession session) {
|
||||
fSessionId = session.getId();
|
||||
fExecutor = DsfSession.getSession(fSessionId).getExecutor();
|
||||
fServicesTracker = new DsfServicesTracker(DsfDebugPlugin.getBundleContext(), fSessionId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#init(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector)
|
||||
*/
|
||||
public void init(ISourceLookupDirector director) {
|
||||
fDirector = director;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
fServicesTracker.dispose();
|
||||
fDirector = null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object)
|
||||
*/
|
||||
public Object[] findSourceElements(Object object) throws CoreException {
|
||||
CoreException single = null;
|
||||
MultiStatus multiStatus = null;
|
||||
List<Object> results = null;
|
||||
|
||||
String name = getSourceName(object);
|
||||
if (name != null) {
|
||||
results = fLookupCache.get(name);
|
||||
if (results != null) {
|
||||
return results.toArray();
|
||||
} else {
|
||||
results = new ArrayList<Object>();
|
||||
}
|
||||
ISourceContainer[] containers = getSourceContainers();
|
||||
for (int i = 0; i < containers.length; i++) {
|
||||
try {
|
||||
ISourceContainer container = containers[i];
|
||||
if (container != null) {
|
||||
Object[] objects = container.findSourceElements(name);
|
||||
if (objects.length > 0) {
|
||||
if (isFindDuplicates()) {
|
||||
results.addAll(Arrays.asList(objects));
|
||||
} else {
|
||||
results.add(objects[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
if (single == null) {
|
||||
single = e;
|
||||
} else if (multiStatus == null) {
|
||||
multiStatus = new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, new IStatus[]{single.getStatus()}, "Source Lookup error", null); //$NON-NLS-1$
|
||||
multiStatus.add(e.getStatus());
|
||||
} else {
|
||||
multiStatus.add(e.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!results.isEmpty()) {
|
||||
synchronized(fLookupCache) {
|
||||
if (!fLookupCache.containsKey(name)) {
|
||||
fLookupCache.put(name, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (results == null || results.isEmpty()) {
|
||||
if (multiStatus != null) {
|
||||
throw new CoreException(multiStatus);
|
||||
} else if (single != null) {
|
||||
throw single;
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
return results.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this participant's source lookup director is configured
|
||||
* to search for duplicate source elements.
|
||||
*
|
||||
* @return whether this participant's source lookup director is configured
|
||||
* to search for duplicate source elements
|
||||
*/
|
||||
protected boolean isFindDuplicates() {
|
||||
ISourceLookupDirector director = fDirector;
|
||||
if (director != null) {
|
||||
return director.isFindDuplicates();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source containers currently registered with this participant's
|
||||
* source lookup director.
|
||||
*
|
||||
* @return the source containers currently registered with this participant's
|
||||
* source lookup director
|
||||
*/
|
||||
protected ISourceContainer[] getSourceContainers() {
|
||||
ISourceLookupDirector director = fDirector;
|
||||
if (director != null) {
|
||||
return director.getSourceContainers();
|
||||
}
|
||||
return new ISourceContainer[0];
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#sourceContainersChanged(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector)
|
||||
*/
|
||||
public void sourceContainersChanged(ISourceLookupDirector director) {
|
||||
fLookupCache.clear();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object)
|
||||
*/
|
||||
public String getSourceName(Object object) throws CoreException {
|
||||
if ( !(object instanceof IDMContext<?>) ||
|
||||
!((IDMContext<?>)object).getSessionId().equals(fSessionId) )
|
||||
{
|
||||
throw new CoreException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, -1, "Invalid object", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
final IDMContext<?> dmc = (IDMContext<?>)object;
|
||||
Query<String> query = new Query<String>(fExecutor) {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<String> rm) {
|
||||
getSourceNameOnDispatchThread(dmc, rm);
|
||||
}};
|
||||
fExecutor.execute(query);
|
||||
try {
|
||||
return query.get();
|
||||
} catch (InterruptedException e) { assert false : "Interrupted exception in DSF executor"; //$NON-NLS-1$
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof CoreException) {
|
||||
throw (CoreException)e.getCause();
|
||||
}
|
||||
assert false : "Unexptected exception"; //$NON-NLS-1$
|
||||
}
|
||||
return null; // Should never get here.
|
||||
}
|
||||
|
||||
@ConfinedToDsfExecutor("fExecutor")
|
||||
private void getSourceNameOnDispatchThread(IDMContext<?> dmc, final DataRequestMonitor<String> rm) {
|
||||
if (!(dmc instanceof IStack.IFrameDMContext)) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
IFrameDMContext frameDmc = (IFrameDMContext)dmc;
|
||||
|
||||
IStack stackService = fServicesTracker.getService(IStack.class);
|
||||
if (stackService == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stack data not available", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
stackService.getModelData(
|
||||
frameDmc,
|
||||
new DataRequestMonitor<IFrameDMData>(fExecutor, rm) { @Override
|
||||
public void handleOK() {
|
||||
rm.setData(getData().getFile());
|
||||
rm.done();
|
||||
}});
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue