I try to override the functionality of CDT ResumeAtLine, MoveToLine, RunToLine. For this reason I created a custom SuspendResumeAdapterFactory but it isn't loaded but compiles and runs without error. Do I maybe need a custom adaptableType too?
Here is the content of my plugin.xml
.
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="my.package.CustomSuspendResumeAdapterFactory"
adaptableType="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
<adapter type="org.eclipse.debug.core.model.ISuspendResume"/>
</factory>
</extension>
And here my CustomSuspendResumeAdapterFactory
this class is reconstructed from memory not 100% sure if the syntax is correct, but I think it should be clear to see what I want to do.
package my.package;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.MoveToLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.ResumeAtLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
public class CustomSuspendResumeAdapterFactory implements IAdapterFactory {
static class SuspendResume implements ISuspendResume, IAdaptable {
private final CustomRunToLine fRunToLine;
private final CustomMoveToLine fMoveToLine;
private final CustomResumeAtLine fResumeAtLine;
SuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new CustomRunToLine(execCtx);
fMoveToLine = new CustomMoveToLine(execCtx);
fResumeAtLine = new CustomResumeAtLine(execCtx);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isInstance(RunToLine.class)) {
System.out.println("CUSTOM RUNTOLINE");
return (T)fRunToLine;
}
if (adapter.isInstance(MoveToLine.class)) {
System.out.println("CUSTOM MOVETOLINE");
return (T)fMoveToLine;
}
if (adapter.isInstance(ResumeToLine.class)) {
System.out.println("CUSTOM RESUMEATLINE");
return (T)fResumeAtLine;
}
return null;
}
@Override
public boolean canResume() { return false; }
@Override
public boolean canSuspend() { return false; }
// This must return true because the platform
// RunToLineActionDelegate will only enable the
// action if we are suspended
@Override
public boolean isSuspended() { return true; }
@Override
public void resume() throws DebugException {}
@Override
public void suspend() throws DebugException {}
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine, MoveToLine or
// ResumeAtLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return (T)new SuspendResume(execDmc);
}
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
}
You have provided a new adapter factory that converts object types that are already handled. i.e. your plugin.xml says you can convert IVMContext
to ISuspendResume
. But the DSF plug-in already provides such an adapter factory. If you have a new target type (like IMySpecialRunToLine) you could install a factory for that, it would take IVMContext
and convert it to a IMySpecialRunToLine
).
Although dated, the Eclipse Corner Article on Adapter Pattern may be useful if this is a new concept.
If you want to provide different implementation of Run To Line, you need to provide your own version of org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor)
. The org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine
class is simply glue to connect UI features (such as buttons/etc some provided directly, some by the core eclipse debug) to the DSF backend. i.e. if you look at what RunToLine
does, all it actually does is get the IRunControl2
service and call runToLine
on it.
The way to provider your own implementation of IRunControl2
is override org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession)
and provide your own GdbDebugServicesFactory
in your custom launch delegate by overriding org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String)
RunToLine
will be triggered when the user select Run To Line from the popup menu in the editor, as per this screenshot: