Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 347389 - [move member type] IllegalArgumentException on Refactor: Move Type to new File..
Summary: [move member type] IllegalArgumentException on Refactor: Move Type to new File..
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 4.3 M1   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-26 21:33 EDT by Miles Parker CLA
Modified: 2012-06-12 12:48 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Miles Parker CLA 2011-05-26 21:33:45 EDT
I don't think there was anything unusual happening when I tried this.

java.lang.reflect.InvocationTargetException
	at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:421)
	at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:331)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizard.internalPerformFinish(RefactoringWizard.java:605)
	at org.eclipse.ltk.ui.refactoring.UserInputWizardPage.performFinish(UserInputWizardPage.java:153)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizard.performFinish(RefactoringWizard.java:678)
	at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.okPressed(RefactoringWizardDialog2.java:455)
	at org.eclipse.jface.dialogs.Dialog.buttonPressed(Dialog.java:472)
	at org.eclipse.jface.dialogs.Dialog$2.widgetSelected(Dialog.java:624)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:240)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4123)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3969)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3608)
	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:181)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:193)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:116)
	at org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:38)
	at org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter.startMoveInnerRefactoring(RefactoringExecutionStarter.java:378)
	at org.eclipse.jdt.ui.actions.ConvertNestedToTopAction.run(ConvertNestedToTopAction.java:170)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:279)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:251)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	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$5.handleEvent(ActionContributionItem.java:411)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4123)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3969)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3608)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	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:344)
	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:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
Caused by: java.lang.IllegalArgumentException
	at org.eclipse.jdt.core.dom.SimpleName.setIdentifier(SimpleName.java:187)
	at org.eclipse.jdt.core.dom.AST.newSimpleName(AST.java:1303)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring$TypeReferenceQualifier.visit(MoveInnerToTopRefactoring.java:323)
	at org.eclipse.jdt.core.dom.ThisExpression.accept0(ThisExpression.java:137)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.SynchronizedStatement.accept0(SynchronizedStatement.java:164)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.IfStatement.accept0(IfStatement.java:190)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:504)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:484)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.createCompilationUnitRewrite(MoveInnerToTopRefactoring.java:912)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.createChangeManager(MoveInnerToTopRefactoring.java:842)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.checkFinalConditions(MoveInnerToTopRefactoring.java:736)
	at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:85)
	at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:121)
	at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:209)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2344)
	at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
	at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Root exception:
java.lang.IllegalArgumentException
	at org.eclipse.jdt.core.dom.SimpleName.setIdentifier(SimpleName.java:187)
	at org.eclipse.jdt.core.dom.AST.newSimpleName(AST.java:1303)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring$TypeReferenceQualifier.visit(MoveInnerToTopRefactoring.java:323)
	at org.eclipse.jdt.core.dom.ThisExpression.accept0(ThisExpression.java:137)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.SynchronizedStatement.accept0(SynchronizedStatement.java:164)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.IfStatement.accept0(IfStatement.java:190)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2530)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:504)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2553)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:484)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2482)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.createCompilationUnitRewrite(MoveInnerToTopRefactoring.java:912)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.createChangeManager(MoveInnerToTopRefactoring.java:842)
	at org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.checkFinalConditions(MoveInnerToTopRefactoring.java:736)
	at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:85)
	at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:121)
	at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:209)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2344)
	at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
	at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Comment 1 Miles Parker CLA 2011-05-26 21:35:22 EDT
There is a synchronized block in the code and I can see that in the AST. Here's the code:

	protected class SynchronizedCommandStack extends BasicCommandStack {
		public void execute(Command command) {
			if (command instanceof AbstractOverrideableCommand) {
				synchronized (SynchronizedCommandStack.this) {
					super.execute(command);
				}
			} else {
				super.execute(command);
			}
		}
	}
Comment 2 Miles Parker CLA 2011-05-26 21:37:59 EDT
Sure enough, commenting out those lines allowed the refactoring to suceed. This doesn't sound like UI, so I'm moving it to core.

	protected class SynchronizedCommandStack extends BasicCommandStack {
		public void execute(Command command) {
			if (command instanceof AbstractOverrideableCommand) {
				//synchronized (SynchronizedCommandStack.this) {
					super.execute(command);
				//}
			} else {
				super.execute(command);
			}
		}
	}
Comment 3 Olivier Thomann CLA 2011-05-26 21:43:33 EDT
Could you please provide complete steps to reproduce?
I'll take a look.
Comment 4 Miles Parker CLA 2011-05-26 22:21:27 EDT
Hi Oliver,

I can do better. Here's a simple test case that works consistently. Create the following:

public class TestClass {
    protected class SynchronizedSomething {
        public void execute() {
        	if (true) {
                synchronized (SynchronizedSomething.this) {
                    System.err.println();
                }
            }
        }
        
    }
}

Invoked the Refactor: Move Type to new File on SynchronizedSomething.
Comment 5 Markus Keller CLA 2011-05-27 09:38:40 EDT
Already happened in 3.6.2.

The bug is in the refactoring implementation (which is in the jdt.ui plug-in). 

Raksha, please have a look for 3.8. We must not pass "" to SimpleName#setIdentifier(String).
Comment 6 Raksha Vasisht CLA 2011-09-06 04:57:43 EDT
(In reply to comment #5)
> Already happened in 3.6.2.
> 
> The bug is in the refactoring implementation (which is in the jdt.ui plug-in). 
> 
> Raksha, please have a look for 3.8. We must not pass "" to
> SimpleName#setIdentifier(String).

Hmm after initial debugging I found that the analysis done in in the refactoring implementation(jdt.ui) to determine whether we need to provide a name for the enclosing instance field name optionally or mandatorily- depending on whether it contains any references to the enclosing type- is correct in   org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.isInstanceFieldCreationMandatory(). 
 In the example provided in comment#4 there is no reference to the enclosing type, hence we allow passing "" empty string in the name field. (See that if the example is changed to :
 
public class TestClass {
	protected class SynchronizedSomething {
		public void execute() {
			if (true) {
				synchronized (TestClass.this) { // changed here
					System.err.println();
				}
			}
		}
	}
the dialog asks for a non-optional string for enclosing field name, which is right)

Also, for the current example, if you try to provide any string (say 'i') as the enclosing instance field name, the refactoring completes without any error but results in wrong code in the end: 

class SynchronizedSomething {
    /**
	 * 
	 */
	private final TestClass i;

	/**
	 * @param testClass
	 */
	SynchronizedSomething(TestClass testClass) {
		i = testClass;
	}

	public void execute() {
        if (true) {
            synchronized (i) {  // WRONG HERE, should be 'this' 
                System.err.println();
            }
        }
    }
}

The code path from :

declaration.accept(new TypeReferenceQualifier(binding, null));

(line 912) in method:  
org.eclipse.jdt.internal.corext.refactoring.structure.MoveInnerToTopRefactoring.createCompilationUnitRewrite(...) 

is wrong and somewhere in the call stack below we replace SynchronizedSomething.this with instance of TestCase. 

Stack trace:

SimpleName.setIdentifier(String) line: 177	
AST.newSimpleName(String) line: 2036	
MoveInnerToTopRefactoring$TypeReferenceQualifier.visit(ThisExpression) line: 323	
ThisExpression.accept0(ASTVisitor) line: 137	
ThisExpression(ASTNode).accept(ASTVisitor) line: 2514	
SynchronizedStatement(ASTNode).acceptChild(ASTVisitor, ASTNode) line: 2562	
SynchronizedStatement.accept0(ASTVisitor) line: 164	
SynchronizedStatement(ASTNode).accept(ASTVisitor) line: 2514	
Block(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 2585	
Block.accept0(ASTVisitor) line: 136	
Block(ASTNode).accept(ASTVisitor) line: 2514	
IfStatement(ASTNode).acceptChild(ASTVisitor, ASTNode) line: 2562	
IfStatement.accept0(ASTVisitor) line: 190	
IfStatement(ASTNode).accept(ASTVisitor) line: 2514	
Block(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 2585	
Block.accept0(ASTVisitor) line: 136	
Block(ASTNode).accept(ASTVisitor) line: 2514	
MethodDeclaration(ASTNode).acceptChild(ASTVisitor, ASTNode) line: 2562	
MethodDeclaration.accept0(ASTVisitor) line: 504	
MethodDeclaration(ASTNode).accept(ASTVisitor) line: 2514	
TypeDeclaration(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 2585	
TypeDeclaration.accept0(ASTVisitor) line: 484	
TypeDeclaration(ASTNode).accept(ASTVisitor) line: 2514	
MoveInnerToTopRefactoring.createCompilationUnitRewrite(ITypeBinding[], CompilationUnitRewrite, Map<ICompilationUnit,SearchMatch[]>, Map<ICompilationUnit,SearchMatch[]>, boolean, ICompilationUnit, ICompilationUnit, boolean, RefactoringStatus, IProgressMonitor) line: 912