Community
Participate
Working Groups
What steps will reproduce the problem? 1. Create the following example: public class EclipseTest { private static interface InvokerIF{ public <T extends ArgIF> T invoke(T arg) throws Exception; } private static class Invoker implements InvokerIF{ public <T extends ArgIF> T invoke(T arg){ return arg; } } private static interface ArgIF{ } private static interface ArgIF2<C> extends ArgIF{ } private static class ArgImpl<C> implements ArgIF2<C>{ public ArgImpl() { super(); } } public static void main(String[] args) throws Exception { InvokerIF test = new Invoker(); test.invoke(new ArgImpl) } } 2. Place cursor after "new ArgImpl", before ")" 3. Call "Content Assist" by pressing Ctrl+space Note: if you change public <T extends ArgIF> T invoke(T arg) throws Exception; to public <T extends ArgIF> T invoke(T arg); "Content Assist" works as expected. -- Error Details -- Date: Sun Feb 06 15:12:48 MSK 2011 Message: org.eclipse.jdt.core.dom.MethodBinding cannot be cast to org.eclipse.jdt.core.dom.ITypeBinding Severity: Error Product: Eclipse 1.3.1.20100913-1228 (org.eclipse.epp.package.jee.product) Plugin: org.eclipse.ui Session Data: eclipse.buildId=M20100909-0800 java.version=1.6.0_20 java.vendor=Sun Microsystems Inc. BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=ru_RU Framework arguments: -product org.eclipse.epp.package.jee.product Command-line arguments: -os linux -ws gtk -arch x86_64 -product org.eclipse.epp.package.jee.product Exception Stack Trace: java.lang.ClassCastException: org.eclipse.jdt.core.dom.MethodBinding cannot be cast to org.eclipse.jdt.core.dom.ITypeBinding at org.eclipse.jdt.internal.ui.text.java.LazyGenericTypeProposal.getExpectedType(LazyGenericTypeProposal.java:612) at org.eclipse.jdt.internal.ui.text.java.LazyGenericTypeProposal.computeTypeArgumentProposals(LazyGenericTypeProposal.java:308) at org.eclipse.jdt.internal.ui.text.java.LazyGenericTypeProposal.apply(LazyGenericTypeProposal.java:205) at org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.apply(AbstractJavaCompletionProposal.java:317) at org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.apply(AbstractJavaCompletionProposal.java:332) at org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal.apply(JavaMethodCompletionProposal.java:55) at org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.apply(AbstractJavaCompletionProposal.java:477) at org.eclipse.jface.text.contentassist.CompletionProposalPopup.insertProposal(CompletionProposalPopup.java:928) at org.eclipse.jface.text.contentassist.CompletionProposalPopup.access$21(CompletionProposalPopup.java:892) at org.eclipse.jface.text.contentassist.CompletionProposalPopup$2.run(CompletionProposalPopup.java:495) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70) at org.eclipse.jface.text.contentassist.CompletionProposalPopup.showProposals(CompletionProposalPopup.java:482) at org.eclipse.jface.text.contentassist.ContentAssistant.showPossibleCompletions(ContentAssistant.java:1660) at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer.doOperation(CompilationUnitEditor.java:182) at org.eclipse.ui.texteditor.ContentAssistAction$1.run(ContentAssistAction.java:82) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70) at org.eclipse.ui.texteditor.ContentAssistAction.run(ContentAssistAction.java:80) at org.eclipse.jface.action.Action.runWithEvent(Action.java:498) at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:185) at org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:109) at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476) at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508) at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508) at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1524) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1257) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1282) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1267) at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1294) at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:730) at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:2841) at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:734) at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1743) at org.eclipse.swt.widgets.Control.windowProc(Control.java:4796) at org.eclipse.swt.widgets.Display.windowProc(Display.java:4360) at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method) at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8168) at org.eclipse.swt.widgets.Display.eventProc(Display.java:1238) at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method) at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2229) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3159) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438) at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115) 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:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:616) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574) at org.eclipse.equinox.launcher.Main.run(Main.java:1407) at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
Does this relate to JDT core?
(In reply to comment #1) > Does this relate to JDT core? I think so. I believe the underlying problem comes from JDT/Core. Ayushman, please investigate. Thanks.
This happens because of incorrect parsing of the binding key. org.eclipse.jdt.internal.core.util.BindingKeyParser.parseMethod() first parses the method signature and then parses the exceptions via the call to parseThrownExceptions(), and then the parsing of the type variables is done in org.eclipse.jdt.internal.core.util.BindingKeyParser.parse(boolean), line 647 after the parseMethod() has returned. Now the problem is that the parsing of the exceptions in parseThrownExceptions() is done by creating another parser but sharing the same scanner. So when the sub parser starts parsing, it finds the qualified name representing the signature and then when it tries to look for type variables, it also finds them since the signature looks like this: LEclipseTest$InvokerIF;.invoke<T::LEclipseTest$ArgIF;>(TT;)TT;|Ljava/lang/RuntimeException;:TT; The :TT; represents the type parameters and since they're immediately followed by the thrown exception, the parser moves the scanner ahead(though the type parameters are not relevant for this parser and it simply ignores it, the scanner cannot be reset back now). This way, when the control returns back to the original parser, and when it tries to look for the type variables of the method invoke(), it cannot find it since the scanner has already moved one place ahead. A possible fix is to make sure the parser does not look for type variable when parsing thrown exceptions, since exceptions cannot have type variables. I'm testing this fix.
Created attachment 195119 [details] proposed fix Patch passes all tests
Created attachment 195191 [details] proposed fix v1.0 + regression tests This patch simply makes sure that the scanner doesnt look for tyoe variables while parsing thrown exceptions
Olivier, can you please review? Thanks! A UI test will have to be added to check that content assist doesn't throw an exception here.
+1. The problem does come from the fact parsing the thrown exceptions also consuming the next type variable. The binding key resolver has lots of side-effects everywhere. Consuming the exception sets the type binding to be the exception type and the enclosing keybinding parser method binding is not remembered. So when scanning the type variable at the same time the exceptions are scanned, there is no match for the type variable binding name, because the type variable of the exception type are retrieved instead of the one from the method binding. So forcing to skip the type variable scanning while scanning the exception type seems to make sense. Once the exception is scanned, the binding key parser still needs to scan the type variable but in this case the method binding is there to return its type variables.
Thanks Olivier. Released in HEAD for 3.7RC1
> A UI test will have to be added to check that content assist doesn't throw an > exception here. Added test via bug 345363
Verified for 3.7RC1 using I20110511-0800