Bug 333710 - [DOM] wrong JavaElement for recovered ITypeBinding
Summary: [DOM] wrong JavaElement for recovered ITypeBinding
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.7 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-06 18:36 EST by Qiangsheng Wang CLA
Modified: 2011-01-25 18:54 EST (History)
4 users (show)

See Also:


Attachments
Proposed fix + updated regression tests (6.18 KB, patch)
2011-01-07 10:10 EST, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Qiangsheng Wang CLA 2011-01-06 18:36:08 EST
Build Identifier: 3.6.0

java.lang.ClassCastException: org.eclipse.jdt.internal.core.CompilationUnit
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createStandardType(TypeEnvironment.java:338)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:192)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType.initialize(HierarchyType.java:42)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createStandardType(TypeEnvironment.java:338)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:192)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ParameterizedType.initialize(ParameterizedType.java:37)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createParameterizedType(TypeEnvironment.java:366)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:176)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType.initialize(HierarchyType.java:42)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ParameterizedType.initialize(ParameterizedType.java:31)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createParameterizedType(TypeEnvironment.java:366)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:176)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType.initialize(HierarchyType.java:42)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ParameterizedType.initialize(ParameterizedType.java:31)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createParameterizedType(TypeEnvironment.java:366)
	at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:176)
	at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsTCModel.createTType(InferTypeArgumentsTCModel.java:300)
	at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintCreator.doVisitMethodInvocationReturnType(InferTypeArgumentsConstraintCreator.java:546)
	at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintCreator.endVisit(InferTypeArgumentsConstraintCreator.java:475)
	at org.eclipse.jdt.core.dom.MethodInvocation.accept0(MethodInvocation.java:247)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2528)
	at org.eclipse.jdt.core.dom.VariableDeclarationFragment.accept0(VariableDeclarationFragment.java:225)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.VariableDeclarationStatement.accept0(VariableDeclarationStatement.java:273)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2529)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:504)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:484)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.CompilationUnit.accept0(CompilationUnit.java:219)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.internal.corext.fix.Java50Fix$AddTypeParametersOperation.rewriteAST(Java50Fix.java:122)
	at org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix.createChange(CompilationUnitRewriteOperationsFix.java:100)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal.createTextChange(FixCorrectionProposal.java:155)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal.createChange(CUCorrectionProposal.java:389)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeCorrectionProposal.getChange(ChangeCorrectionProposal.java:305)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.ChangeCorrectionProposal.performChange(ChangeCorrectionProposal.java:120)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal.performChange(CUCorrectionProposal.java:324)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal.apply(CUCorrectionProposal.java:301)
	at org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal.apply(FixCorrectionProposal.java:188)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.insertProposal(CompletionProposalPopup.java:928)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.insertSelectedProposalWithMask(CompletionProposalPopup.java:879)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.access$27(CompletionProposalPopup.java:875)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup$5.widgetDefaultSelected(CompletionProposalPopup.java:658)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:119)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3171)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:121)
	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:369)
	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:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1383)


Reproducible: Always

Steps to Reproduce:
1. Have following code.
List objects = P.getObjects(String content);
P.getObjects returns type is List<MyType>;
2. The warning bulb shows at left tool bar.
3. Click the bulb and select "Add type arguments to 'List'.
4. Exception happens.
Comment 1 Dani Megert CLA 2011-01-07 02:55:16 EST
I cannot reproduce this using 3.7 M4. Can you please provide a complete example to reproduce this?
Comment 2 Markus Keller CLA 2011-01-07 08:09:24 EST
The stacktrace reveals that this is a problem in ITypeBinding#getJavaElement(). To reproduce, try to apply the quick fix in Try#foo() here:

package xy;
import java.util.List;
public class Try {
    void foo() {
        List objects = P.getObjects("x");
        System.out.println(objects);
    }
}

package xy;
import java.util.List;
public class P {
    static List<MyType> getObjects(String content) {
        return null;
    }
}

package xy;
public class MyType extends Unknown {
}

The problem is that both implementations of ITypeBinding#getJavaElement() can return an ICompilationUnit, but they should only return an IType. The problem can be seen in the ASTView for class "P" with bindings recovery enabled. The superclass for MyType is a recovered ITypeBinding whose #getJavaElement() method returns an ICompilationUnit.
Comment 3 Olivier Thomann CLA 2011-01-07 09:29:56 EST
(In reply to comment #2)
> The problem is that both implementations of ITypeBinding#getJavaElement() can
> return an ICompilationUnit, but they should only return an IType. The problem
> can be seen in the ASTView for class "P" with bindings recovery enabled. The
> superclass for MyType is a recovered ITypeBinding whose #getJavaElement()
> method returns an ICompilationUnit.
For a recovered type binding, I would expect null to be returned.
Comment 4 Olivier Thomann CLA 2011-01-07 09:41:01 EST
The only other solution would be to return a IType that doesn't exist.

Markus, what do you prefer ?

The current javadoc of getJavaElement() doesn't say what to expect for recovered type binding. So both answers could be acceptable. I agree that an ICompilationUnit is wrong as this is a type.
Comment 5 Markus Keller CLA 2011-01-07 09:43:04 EST
Returning null would be an API change. The Javadoc has an explicit list of cases where null is to be expected, and recovered bindings are not mentioned.

I would appreciate an inexistent IType.
Comment 6 Olivier Thomann CLA 2011-01-07 10:10:00 EST
Created attachment 186280 [details]
Proposed fix + updated regression tests

This now returns an inexistent type. I updated some regression tests to check the expected type of the java element.
Comment 7 Olivier Thomann CLA 2011-01-07 10:10:56 EST
Released for 3.7M5.
Comment 8 Jay Arthanareeswaran CLA 2011-01-25 04:45:37 EST
Verified for 3.7M5 using build I20110124-1800.
Comment 9 Qiangsheng Wang CLA 2011-01-25 18:11:34 EST
Thanks guys. Verified and closing.
Comment 10 Olivier Thomann CLA 2011-01-25 18:54:22 EST
Please leave the bug in the VERIFIED state. Thanks.