Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 349405

Summary: [1.7][introduce indirection] Introduce indirection throws IAE
Product: [Eclipse Project] JDT Reporter: Raksha Vasisht <raksha.vasisht>
Component: UIAssignee: Raksha Vasisht <raksha.vasisht>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, deepakazad, markus.kell.r, satyam.kandula
Version: 3.7   
Target Milestone: 3.7.1   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Patch
none
Fix
none
Patch for tests none

Description Raksha Vasisht CLA 2011-06-15 03:37:25 EDT
BETA_JAVA7

class C1 {
}

interface I1 {
}

public class X1<T1 extends C1 & I1> {
	 <U extends C1 & I1> X1<U> getX() {
		return null;
	}

	X1<?> f2 = getX();
}

Introduce Indirection on getX gives ITE :

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.jdt.internal.ui.refactoring.IntroduceIndirectionInputPage.performFinish(IntroduceIndirectionInputPage.java:231)
	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.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754)
	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.startIntroduceIndirectionRefactoring(RefactoringExecutionStarter.java:359)
	at org.eclipse.jdt.ui.actions.IntroduceIndirectionAction.run(IntroduceIndirectionAction.java:155)
	at org.eclipse.jdt.ui.actions.IntroduceIndirectionAction.run(IntroduceIndirectionAction.java:149)
	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.ui.actions.RetargetAction.runWithEvent(RetargetAction.java:230)
	at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:234)
	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.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754)
	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:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:613)
	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)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
Caused by: java.lang.IllegalArgumentException
	at org.eclipse.jdt.core.dom.SimpleName.setIdentifier(SimpleName.java:198)
	at org.eclipse.jdt.core.dom.AST.newSimpleName(AST.java:2045)
	at org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.qualifyThisExpression(IntroduceIndirectionRefactoring.java:1068)
	at org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.updateMethodInvocation(IntroduceIndirectionRefactoring.java:981)
	at org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.updateReferences(IntroduceIndirectionRefactoring.java:680)
	at org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.checkFinalConditions(IntroduceIndirectionRefactoring.java:517)
	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 Deepak Azad CLA 2011-06-21 04:49:57 EDT
No diamonds here..
Comment 2 Deepak Azad CLA 2011-06-21 05:29:27 EDT
See bug 99931.
Comment 3 Raksha Vasisht CLA 2011-06-21 06:09:36 EDT
The problem seems to be here: 

org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.qualifyThisExpression(ThisExpression expr, MethodInvocation originalInvocation, IMember enclosing, CompilationUnitRewrite unitRewriter)

where it tries to set a qualifier with the type parameters, whereas it only needs to use 'this' qualifier. Need to check if the type binding is wrong(core) or the logic we use to compare the bindings and calculate the qualifier to be set(UI).
Comment 4 Raksha Vasisht CLA 2011-07-05 04:54:01 EDT
Created attachment 199100 [details]
Patch

(In reply to comment #3)
> The problem seems to be here: 
> 
> org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring.qualifyThisExpression(ThisExpression
> expr, MethodInvocation originalInvocation, IMember enclosing,
> CompilationUnitRewrite unitRewriter)
> 
The code here 

expr.setQualifier(unitRewriter.getAST().newSimpleName(currentTypeBinding.getName()));
			
currentTypeBinding.getName() gets the parameterized type name (HashMap<String, String>) and hence leads to an error. If it is parameterized it should simply use 'this' qualifier from the else block. 

I think we should fix this in BETA_JAVA7 in eventually in HEAD. Tests coming up.
Comment 5 Markus Keller CLA 2011-07-07 12:16:07 EDT
Created attachment 199270 [details]
Fix

First patch is not good. It e.g. breaks IntroduceIndirectionTests#test04() when you change "public class Foo" to "public class Foo<T>".

The problem is not that the type is parameterized, but that we compare it to typeOfCall, which is a declaration type binding. Normalizing the currentTypeBinding solves the problem.
Comment 6 Markus Keller CLA 2011-07-07 12:32:14 EDT
Released the fix to BETA_JAVA7.

Raksha, please add a test for your example, and a copy of test04() where Foo has a type parameter (attach a patch here, release to BETA_JAVA7, and close the bug).
Comment 7 Raksha Vasisht CLA 2011-07-12 02:38:33 EDT
Created attachment 199468 [details]
Patch for tests

(In reply to comment #6)
> Released the fix to BETA_JAVA7.
> 
> Raksha, please add a test for your example, and a copy of test04() where Foo
> has a type parameter (attach a patch here, release to BETA_JAVA7, and close the
> bug).

Added tests and committed to BETA_JAVA7.
Comment 8 Raksha Vasisht CLA 2011-07-12 02:38:53 EDT
.
Comment 9 Satyam Kandula CLA 2011-07-19 08:38:27 EDT
Verified using patch 1.0.0.v20110714-1400