【问题标题】:Eclipse CDT extend AdapterFactoryEclipse CDT 扩展 AdapterFactory
【发布时间】:2015-12-12 02:32:45
【问题描述】:

我尝试覆盖 CDT ResumeAtLine、MoveToLine、RunToLine 的功能。出于这个原因,我创建了一个自定义的 SuspendResumeAdapterFactory,但它没有加载但编译和运行没有错误。我是否也需要一个自定义的 adaptableType?

这是我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> 

这里我的CustomSuspendResumeAdapterFactory 这个类是从内存中重建的,不是 100% 确定语法是否正确,但我认为应该清楚地看到我想要做什么。

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 };
    }
}

【问题讨论】:

    标签: eclipse eclipse-plugin eclipse-cdt


    【解决方案1】:

    为什么你的代码没有运行

    您提供了一个新的适配器工厂,可以转换已处理的对象类型。即您的 plugin.xml 表示您可以将 IVMContext 转换为 ISuspendResume。但是DSF插件已经提供了这样一个适配器工厂。如果您有一个新的目标类型(例如 IMySpecialRunToLine),您可以为此安装一个工厂,它将采用 IVMContext 并将其转换为 IMySpecialRunToLine)。

    虽然已经过时,但如果这是一个新概念,Eclipse Corner Article on Adapter Pattern 可能会很有用。

    如何进行自定义 Run To Line 实现

    如果您想提供不同的Run To Line 实现,您需要提供您自己的org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor) 版本。 org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine 类只是将 UI 功能(例如按钮/等,一些直接提供,一些由核心 Eclipse 调试)连接到 DSF 后端。也就是说,如果您查看 RunToLine 所做的事情,它实际上所做的只是获取 IRunControl2 服务并在其上调用 runToLine

    提供您自己的IRunControl2 实现的方法是覆盖org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession) 并通过覆盖org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String) 在您的自定义启动委托中提供您自己的GdbDebugServicesFactory

    RunToLine 将在用户从编辑器的弹出菜单中选择 Run To Line 时触发,如下图所示:

    【讨论】:

    • 何时触发“runToLine”?设法创建 CustomGDBRunControl 扩展了 GDBRunControl,但既没有调用通常的 MIRunControl.runToLine,也没有调用我的自定义:-/ 我认为它会在“进入”命令后触发?
    • step into 和 run to line 是两个不同的东西,step into 由 org.eclipse.cdt.dsf.debug.service.IRunControl.step(IExecutionDMContext, StepType, RequestMonitor) 处理,step 类型为 STEP_INTO
    • 但是在 IRunControl.step 中无法确定指令的行号?
    • 我希望单击 step-into 会跳过带有行号的行。所以我定义了一些行号exp。 1,2,3,4 并且每一步都会导致行号 1,2,3,4 将被替换为跨步。
    • 注意,您在这里描述的内容听起来有点像步进过滤(JDT 有)。 GDB 确实支持它,但我认为没有人在 Eclipse 中编写过对 GDB 功能的支持:sourceware.org/gdb/onlinedocs/gdb/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多