Community
Participate
Working Groups
N20050722-0010 BindingKey#internalToSignature() returns an invalid signature for a local type. package xy; import java.util.ArrayList; public class LocalTest { void m() { class Local { Local fSelf; } new ArrayList().add(new Local().fSelf); } } Calling BindingKey#internalToSignature() for the binding key of type Local "Lxy/LocalTest$98;" gives signature "Lxy.LocalTest$98;". Note the wrong name '98' of the type in the signature. This leads to two known problems: - The hover for fSelf is "98 xy.LocalTest.m().Local.fSelf" - The 'Infer Generic Type Arguments' refactoring fails with this exception, since it tries to create a SimpleName with identifier "98": java.lang.reflect.InvocationTargetException at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:327) at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:293) at org.eclipse.ltk.ui.refactoring.RefactoringWizard.internalPerformFinish(RefactoringWizard.java:547) at org.eclipse.ltk.ui.refactoring.UserInputWizardPage.performFinish(UserInputWizardPage.java:153) at org.eclipse.ltk.ui.refactoring.RefactoringWizard.performFinish(RefactoringWizard.java:613) at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.okPressed(RefactoringWizardDialog2.java:417) at org.eclipse.jface.dialogs.Dialog.buttonPressed(Dialog.java:409) at org.eclipse.jface.dialogs.Dialog$2.widgetSelected(Dialog.java:556) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:90) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:852) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3137) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2765) at org.eclipse.jface.window.Window.runEventLoop(Window.java:809) at org.eclipse.jface.window.Window.open(Window.java:787) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:125) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69) at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:138) at org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:40) at org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter.startInferTypeArgumentsRefactoring(RefactoringExecutionStarter.java:225) at org.eclipse.jdt.ui.actions.InferTypeArgumentsAction.run(InferTypeArgumentsAction.java:132) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:226) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:198) at org.eclipse.jface.action.Action.runWithEvent(Action.java:996) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:544) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:494) at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:401) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:852) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3137) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2765) at org.eclipse.jdt.internal.ui.actions.QuickMenuAction.run(QuickMenuAction.java:79) at org.eclipse.jface.action.Action.runWithEvent(Action.java:996) at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:182) at org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:108) at org.eclipse.core.commands.Command.execute(Command.java:311) at org.eclipse.core.commands.ParameterizedCommand.execute(ParameterizedCommand.java:396) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:459) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:781) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:828) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:550) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:493) at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:117) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) at org.eclipse.swt.widgets.Display.filterEvent(Display.java:920) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:851) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:876) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:861) at org.eclipse.swt.widgets.Control.traverse(Control.java:2777) at org.eclipse.swt.widgets.Control.translateMnemonic(Control.java:2618) at org.eclipse.swt.widgets.Composite.translateMnemonic(Composite.java:844) at org.eclipse.swt.widgets.Control.translateMnemonic(Control.java:2636) at org.eclipse.swt.widgets.Display.translateMnemonic(Display.java:3571) at org.eclipse.swt.widgets.Display.filterMessage(Display.java:934) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2761) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1699) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1663) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:367) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143) at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:103) at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163) 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:324) at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334) at org.eclipse.core.launcher.Main.basicRun(Main.java:278) at org.eclipse.core.launcher.Main.run(Main.java:973) at org.eclipse.core.launcher.Main.main(Main.java:948) Caused by: java.lang.IllegalArgumentException at org.eclipse.jdt.core.dom.SimpleName.setIdentifier(SimpleName.java:193) at org.eclipse.jdt.core.dom.AST.newSimpleName(AST.java:1248) at org.eclipse.jdt.core.dom.AST.newName(AST.java:1368) at org.eclipse.jdt.internal.corext.dom.ASTNodeFactory.newName(ASTNodeFactory.java:71) at org.eclipse.jdt.internal.corext.codemanipulation.ImportsStructure.addImportFromSignature(ImportsStructure.java:533) at org.eclipse.jdt.internal.corext.codemanipulation.ImportRewrite.addImportFromSignature(ImportRewrite.java:174) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.getTypeArguments(InferTypeArgumentsRefactoring.java:374) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteTypeVariable(InferTypeArgumentsRefactoring.java:342) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteConstraintVariable(InferTypeArgumentsRefactoring.java:323) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteDeclarations(InferTypeArgumentsRefactoring.java:302) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.checkFinalConditions(InferTypeArgumentsRefactoring.java:229) at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:84) at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:114) at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:189) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719) at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86) at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113) Root exception: java.lang.IllegalArgumentException at org.eclipse.jdt.core.dom.SimpleName.setIdentifier(SimpleName.java:193) at org.eclipse.jdt.core.dom.AST.newSimpleName(AST.java:1248) at org.eclipse.jdt.core.dom.AST.newName(AST.java:1368) at org.eclipse.jdt.internal.corext.dom.ASTNodeFactory.newName(ASTNodeFactory.java:71) at org.eclipse.jdt.internal.corext.codemanipulation.ImportsStructure.addImportFromSignature(ImportsStructure.java:533) at org.eclipse.jdt.internal.corext.codemanipulation.ImportRewrite.addImportFromSignature(ImportRewrite.java:174) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.getTypeArguments(InferTypeArgumentsRefactoring.java:374) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteTypeVariable(InferTypeArgumentsRefactoring.java:342) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteConstraintVariable(InferTypeArgumentsRefactoring.java:323) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.rewriteDeclarations(InferTypeArgumentsRefactoring.java:302) at org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring.checkFinalConditions(InferTypeArgumentsRefactoring.java:229) at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:84) at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:114) at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:189) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719) at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86) at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
What makes you believe that the key can be used to get the class name? This might be true for members, but not for locals where the position is used instead of the name.
I see that the format of the signature does not explicitly specify how a type name is encoded in the "Indentifier" part of a signature. Would it be possible to include the local type's name in the identifier? If not, it would be very complicated for JDT/UI to handle such signatures correctly in import rewrites and hovers (we would basically have to assume that the number is a position in the source file and then we would have to resolve the element at that position, etc.)
Changed the binding key for local types to include the local type's simple name (e.g. "Lxy/LocalTest$98$Local;"). Thus when asking the resulting signature for the simple name, it now returns "Local". Added regression test ASTConverter15Test#test0196() and updated other AST tests to reflect this change.
Reopen. The refactoring 'Infer Generic Type Arguments' on the submitted test case generates a code that doesn't compile. I get: package xy; import java.util.ArrayList; import xy.LocalTest.98.Local; public class LocalTest { void m() { class Local { Local fSelf; } new ArrayList<Local>().add(new Local().fSelf); } } So the fix might not be good enough or the import statement should be removed by the UI. This might expose a UI bug.
Olivier, please open another bug against JDT UI. The particular problem described in this bug (invalid signature) is fixed.
Open bug 110390. Closing as VERIFIED.