代码之家  ›  专栏  ›  技术社区  ›  iain

自定义Eclipse重构预览时出错

  •  52
  • iain  · 技术社区  · 16 年前

    我正在实现一个新的eclipse重构。这将使开发人员能够将prerequisions语句从子方法拉到父方法。

    当我在重构向导中选择“Finish”时,这一切都能很好地工作,但是当我选择“Preview”时,我会得到一个错误“No target edit provided”。这似乎是由于 TextEdit 从返回 ASTRewrite.rewriteAST()

    异常的堆栈跟踪发生在 Refactoring.createChange() 运行代码,并使用更改生成预览。

    org.eclipse.text.edits.MalformedTreeException: No target edit provided.
    at org.eclipse.text.edits.MoveSourceEdit.performConsistencyCheck(MoveSourceEdit.java:208)
    at org.eclipse.text.edits.TextEdit.traverseConsistencyCheck(TextEdit.java:873)
    at org.eclipse.text.edits.MoveSourceEdit.traverseConsistencyCheck(MoveSourceEdit.java:183)
    at org.eclipse.text.edits.TextEdit.traverseConsistencyCheck(TextEdit.java:869)
    at org.eclipse.text.edits.TextEdit.traverseConsistencyCheck(TextEdit.java:869)
    at org.eclipse.text.edits.TextEditProcessor.checkIntegrityDo(TextEditProcessor.java:176)
    at org.eclipse.text.edits.TextEdit.dispatchCheckIntegrity(TextEdit.java:743)
    at org.eclipse.text.edits.TextEditProcessor.performEdits(TextEditProcessor.java:151)
    at org.eclipse.ltk.core.refactoring.TextChange.getPreviewDocument(TextChange.java:534)
    at org.eclipse.ltk.core.refactoring.TextChange.getPreviewDocument(TextChange.java:403)
    at org.eclipse.ltk.core.refactoring.TextChange.getPreviewContent(TextChange.java:411)
    at org.eclipse.ltk.internal.ui.refactoring.TextEditChangePreviewViewer.setInput(TextEditChangePreviewViewer.java:209)
    at org.eclipse.ltk.internal.ui.refactoring.AbstractChangeNode.feedInput(AbstractChangeNode.java:99)
    at org.eclipse.ltk.internal.ui.refactoring.PreviewWizardPage.showPreview(PreviewWizardPage.java:598)
    at org.eclipse.ltk.internal.ui.refactoring.PreviewWizardPage.access$6(PreviewWizardPage.java:583)
    at org.eclipse.ltk.internal.ui.refactoring.PreviewWizardPage$7.selectionChanged(PreviewWizardPage.java:574)
    at org.eclipse.jface.viewers.Viewer$2.run(Viewer.java:162)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.runtime.Platform.run(Platform.java:888)
    at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:48)
    at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
    at org.eclipse.jface.viewers.Viewer.fireSelectionChanged(Viewer.java:160)
    at org.eclipse.jface.viewers.StructuredViewer.updateSelection(StructuredViewer.java:2132)
    at org.eclipse.jface.viewers.StructuredViewer.setSelection(StructuredViewer.java:1669)
    at org.eclipse.jface.viewers.TreeViewer.setSelection(TreeViewer.java:1124)
    at org.eclipse.jface.viewers.Viewer.setSelection(Viewer.java:392)
    at org.eclipse.ltk.internal.ui.refactoring.PreviewWizardPage.setVisible(PreviewWizardPage.java:505)
    at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.makeVisible(RefactoringWizardDialog2.java:762)
    at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.showCurrentPage(RefactoringWizardDialog2.java:477)
    at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.nextOrPreviewPressed(RefactoringWizardDialog2.java:507)
    at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.access$2(RefactoringWizardDialog2.java:492)
    at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2$1.widgetSelected(RefactoringWizardDialog2.java:691)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:228)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
    at org.eclipse.jface.window.Window.runEventLoop(Window.java:825)
    at org.eclipse.jface.window.Window.open(Window.java:801)
    at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:143)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:155)
    at org.jmlspecs.eclipse.refactor.action.AbstractMethodActionDelegate.run(AbstractMethodActionDelegate.java:78)
    at org.jmlspecs.eclipse.refactor.action.AbstractMethodActionDelegate.run(AbstractMethodActionDelegate.java:67)
    at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:251)
    at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
    at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
    at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1287)
    

    当前执行更改的代码如下所示:

    CompilationUnit sourceNode = ...
    ASTRewrite sourceRewrite = ASTRewrite.create(sourceNode.getAST());
    
    Statement statement = ...
    sourceRewrite.createMoveTarget(statement);
    
    CompilationUnit destinationNode = ...
    MethodDeclaration destinationMethod = ...
    ASTRewrite destinationRewrite = ASTRewrite.create(destinationNode.getAST());
    
    ListRewrite lrw = destinationRewrite.getListRewrite(destinationMethod.getBody(),
        Block.STATEMENTS_PROPERTY);
    
    lrw.insertFirst(statement, null);
    

    我知道那条路 createMoveTarget 使用的不是它的文档记录方式,但是当我遵循下面的文档时,该语句从源代码中删除,但没有移动到目标,并且在预览中仍然得到相同的错误。

    CompilationUnit sourceNode = ...
    ASTRewrite sourceRewrite = ASTRewrite.create(sourceNode.getAST());
    
    Statement statement = ...
    Statement replacement = sourceRewrite.createMoveTarget(statement);
    sourceRewrite.remove(statement, null);
    
    CompilationUnit destinationNode = ...
    MethodDeclaration destinationMethod = ...
    ASTRewrite destinationRewrite = ASTRewrite.create(destinationNode.getAST());
    
    ListRewrite lrw = destinationRewrite.getListRewrite(destinationMethod.getBody(),
        Block.STATEMENTS_PROPERTY);
    
    lrw.insertFirst(replacement, null);
    

    之前:

    class A {
        foo(int a) {
            return a * 2;
        }
    }
    
    class B {
        foo(int a) {
            JC.requires(a > 1);
    
            return a * 3;
        }
    }
    

    之后:

    class A {
        foo(int a) {
            JC.requires(a > 1);
    
            return a * 2;
        }
    }
    
    class B extends A {
        foo(int a) {        
            return a * 3;
        }
    }
    
    1 回复  |  直到 16 年前
        1
  •  2
  •   mj-gholami    14 年前

    我找到了日蚀.org文章最有助于我开始。

    开始调试代码的一个好地方是在上设置断点org.eclipse.jdt网站.core.dom.rewrite文件.ASTRewrite,尤其是rewriteAST()方法,然后触发一些重构。

    这里有一些你可能会发现有用的。您是否在寻找任何关于如何处理AST的特定或一般意义的信息?

    http://www.ibm.com/developerworks/opensource/library/os-ast/  
    http://blog.sahits.ch/?p=228
    http://www.vogella.com/articles/EclipseJDT/article.html