Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 303698 - [ccp] ReorgPolicies' canEnable() methods return true too often
Summary: [ccp] ReorgPolicies' canEnable() methods return true too often
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.6   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.6 M6   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-23 16:22 EST by Carsten Pfeiffer CLA
Modified: 2010-03-08 06:04 EST (History)
1 user (show)

See Also:


Attachments
Fixes the buggy canEnable() methods (1.94 KB, patch)
2010-02-23 16:24 EST, Carsten Pfeiffer CLA
markus.kell.r: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Carsten Pfeiffer CLA 2010-02-23 16:22:04 EST
Build Identifier: M20090917-0800

Have a look at ReorgPolicy.canEnable():

public boolean canEnable() throws JavaModelException {
	IResource[] resources= getResources();
	for (int i= 0; i < resources.length; i++) {
		IResource resource= resources[i];
		if (!resource.exists() || resource.isPhantom() || !resource.isAccessible())
			return false;
	}

	IJavaElement[] javaElements= getJavaElements();
	for (int i= 0; i < javaElements.length; i++) {
		IJavaElement element= javaElements[i];
		if (!element.exists())
			return false;
	}
	return true;
}

The last "return true" is wrong, as it would enable the policy even if the resources and javaElements arrays are empty. The same problem occurs in many other ReorgPolicy classes.

We experience this bug when using an own IQueryParticipant that creates non-IJavaElement matches.

I'll attach a patch against HEAD.

Reproducible: Always
Comment 1 Carsten Pfeiffer CLA 2010-02-23 16:24:13 EST
Created attachment 159997 [details]
Fixes the buggy canEnable() methods
Comment 2 Carsten Pfeiffer CLA 2010-02-23 16:36:04 EST
BTW, the result of the erroneous canEnable() returns is an ArrayIndexOutOfBoundsException later on, e.g. see this stacktrace:

java.lang.ArrayIndexOutOfBoundsException: 0
	at org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory$SubCuElementReorgPolicy.getSourceCu(ReorgPolicyFactory.java:3741)
	at org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory$MoveSubCuElementsPolicy.canEnable(ReorgPolicyFactory.java:2077)
	at org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester.isMoveAvailable(RefactoringAvailabilityTester.java:791)
	at org.eclipse.jdt.internal.ui.refactoring.reorg.ReorgMoveAction.selectionChanged(ReorgMoveAction.java:62)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchSelectionChanged(SelectionDispatchAction.java:262)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.selectionChanged(SelectionDispatchAction.java:257)
	at org.eclipse.jdt.ui.actions.MoveAction.selectionChanged(MoveAction.java:116)
	at org.eclipse.ui.part.PageBookView$5.run(PageBookView.java:256)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.runtime.Platform.run(Platform.java:888)
	at org.eclipse.ui.part.PageBookView$SelectionManager.selectionChanged(PageBookView.java:254)
	at org.eclipse.ui.part.PageBookView$SelectionProvider.selectionChanged(PageBookView.java:320)
	at org.eclipse.ui.part.PageBookView.pageSelectionChanged(PageBookView.java:897)
	at org.eclipse.ui.part.PageBookView.access$2(PageBookView.java:892)
	at org.eclipse.ui.part.PageBookView$2.selectionChanged(PageBookView.java:164)
	at org.eclipse.search.ui.text.AbstractTextSearchViewPage$SelectionProviderAdapter.selectionChanged(AbstractTextSearchViewPage.java:192)
	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.search2.internal.ui.basic.views.TreeViewerNavigator.internalSetSelection(TreeViewerNavigator.java:194)
	at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.navigateNext(TreeViewerNavigator.java:46)
	at org.eclipse.search.ui.text.AbstractTextSearchViewPage.navigateNext(AbstractTextSearchViewPage.java:946)
	at org.eclipse.search.ui.text.AbstractTextSearchViewPage.access$10(AbstractTextSearchViewPage.java:939)
	at org.eclipse.search.ui.text.AbstractTextSearchViewPage$UpdateUIJob.runInUIThread(AbstractTextSearchViewPage.java:151)
	at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:95)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3468)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3115)
	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(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	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)


This is due to

// we checked before that the array in not null and not empty
return getEnclosingCompilationUnit(fJavaElements[0]);

in getSourceCu().
Comment 3 Carsten Pfeiffer CLA 2010-03-08 03:57:54 EST
Any comments? This is quite a simple fix.
Comment 4 Markus Keller CLA 2010-03-08 05:01:04 EST
Makes sense, released to HEAD.
Comment 5 Carsten Pfeiffer CLA 2010-03-08 06:04:03 EST
Thanks a bunch, Markus!