2009-11-18 28 views
52

Tôi đang thực hiện tái cấu trúc nhật thực mới. Điều này sẽ cho phép các nhà phát triển để kéo lên các báo cáo điều kiện tiên quyết từ một phương pháp con để các phương pháp cha mẹ.Lỗi trong bản xem trước của tùy chỉnh Eclipse refactoring

Tất cả đều hoạt động hoàn hảo khi tôi chọn "Hoàn tất" trong trình hướng dẫn tái cấu trúc, nhưng khi tôi chọn "Xem trước", tôi gặp lỗi "Không có chỉnh sửa đích được cung cấp". Điều này có vẻ là do sự cố trong số TextEdit được trả về từ ASTRewrite.rewriteAST(). Tuy nhiên tôi không thể hiểu tại sao.

Dấu vết ngăn xếp của ngoại lệ xảy ra sau khi mã Refactoring.createChange() của tôi được chạy và thay đổi được sử dụng để tạo bản xem trước.

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) 

Hiện nay mã mà thực hiện sự thay đổi trông như thế này:

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

Tôi biết rằng cách createMoveTarget được sử dụng không phải là cách nó được ghi chép lại, nhưng khi tôi làm theo các tài liệu như dưới đây, tuyên bố bị xóa khỏi nguồn nhưng không được chuyển đến đích và tôi vẫn gặp lỗi tương tự trong bản xem trước.

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

Dưới đây là ví dụ về việc tái cấu trúc đang được thực hiện.

Trước:

class A { 
    foo(int a) { 
     return a * 2; 
    } 
} 

class B { 
    foo(int a) { 
     JC.requires(a > 1); 

     return a * 3; 
    } 
} 

Sau:

class A { 
    foo(int a) { 
     JC.requires(a > 1); 

     return a * 2; 
    } 
} 

class B extends A { 
    foo(int a) {   
     return a * 3; 
    } 
} 
+1

Ví dụ về tái cấu trúc của bạn không thực sự tái cấu trúc vì nó thay đổi ngữ nghĩa nhưng điều đó tùy thuộc vào bạn. Thật khó để nói những gì sai với mã vì một phần của nguồn trong ngăn xếp không có sẵn. Có lẽ bạn nên theo dõi tại sao MoveSourceEdit.setTargetEdit không được gọi hoặc được gọi với đối số null. –

+1

Xin chào Petr, cảm ơn đề xuất của bạn. Tôi sẽ xem xét chi tiết hơn và so sánh việc tái cấu trúc nhật thực cho riêng tôi. Về sự thay đổi ngữ nghĩa khi các thông số kỹ thuật tái cấu trúc, điều đó rất thú vị vì nó lặp lại hầu hết công việc hàn lâm trong lĩnh vực này. Tuy nhiên định nghĩa của Fowler chỉ duy trì hành vi, ví dụ phương pháp kéo lên thay đổi ngữ nghĩa của hệ thống phân cấp lớp. Tôi có thể thêm một tùy chọn để bảo tồn ngữ nghĩa bằng cách thêm một mệnh đề mới vào câu lệnh. Dù sao tôi sẽ được quan tâm để thảo luận thêm về điều này với bạn nó như bạn muốn. – iain

Trả lời

2

tôi thấy bài viết eclipse.org hữu ích nhất để có được tôi bắt đầu.

Một nơi tốt để bắt đầu gỡ lỗi mã là đặt các điểm ngắt trên org.eclipse.jdt.core.dom.rewrite.ASTRewrite, đặc biệt là phương thức rewriteAST(), sau đó kích hoạt một số phép tái cấu trúc.

Dưới đây là một số ít bạn có thể thấy hữu ích. Bạn đang tìm kiếm bất cứ điều gì đặc biệt hay ý thức chung về cách xử lý AST?

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

Xin chào, Cảm ơn các mẹo và liên kết. Tôi đã nhìn thấy các liên kết ibm và vogella nhưng không nhìn thấy liên kết khác. Đó là một thời gian dài kể từ khi tôi làm việc trên mã này, nó là một phần của một luận văn thạc sĩ và chức năng đủ để sử dụng. Tôi sẽ tìm hiểu mã trong vài tuần tới và xem liệu tôi có thể giải quyết vấn đề này hay không. Tôi đã bị mất mỗi khi tôi gỡ lỗi jdt. Mức độ vô hướng là vô tận và các phép tái cấu trúc cổ phiếu được thực hiện với một lớp trừu tượng riêng khiến chúng khó giải mã. – iain

Các vấn đề liên quan