Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code assist not working in annotation when one attribute is already specified #761

Closed
mauromol opened this issue Nov 7, 2018 · 9 comments
Assignees
Labels
Milestone

Comments

@mauromol
Copy link

mauromol commented Nov 7, 2018

Assume you have this dependency:
compile "org.springframework:spring-tx:4.3.18.RELEASE"

Then consider the following class:

package test39
import org.springframework.transaction.annotation.Transactional
class Test39 {
	@Transactional(readOnly=false|)
	void test() {}
}

Put the cursor at "|": the following exception is produced:

eclipse.buildId=4.8.0.I20180611-0500
java.version=1.8.0_191
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=it_IT
Command-line arguments:  -os win32 -ws win32 -arch x86_64 -data file:/D:/ws/my-project/

org.eclipse.jdt.ui
Warning
Wed Nov 07 10:05:41 CET 2018
The 'Groovy Code Completions' proposal computer from the 'org.codehaus.groovy.eclipse.codeassist.completion' plug-in did not complete normally. The extension has thrown a runtime exception.

java.lang.RuntimeException: No visit() method implemented for class: org.codehaus.groovy.ast.AnnotationNode
	at org.codehaus.groovy.ast.ASTNode.visit(ASTNode.java:62)
	at org.codehaus.groovy.eclipse.codeassist.processors.ConstructorCompletionProcessor.findCtorCallContext(ConstructorCompletionProcessor.java:169)
	at org.codehaus.groovy.eclipse.codeassist.processors.ConstructorCompletionProcessor.generateProposals(ConstructorCompletionProcessor.java:82)
	at org.codehaus.groovy.eclipse.codeassist.requestor.GroovyCompletionProposalComputer.computeCompletionProposals(GroovyCompletionProposalComputer.java:216)
	at org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerDescriptor.computeCompletionProposals(CompletionProposalComputerDescriptor.java:333)
	at org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategory.computeCompletionProposals(CompletionProposalCategory.java:337)
	at org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor.collectProposals(ContentAssistProcessor.java:331)
	at org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor.computeCompletionProposals(ContentAssistProcessor.java:288)
	at org.eclipse.jface.text.contentassist.ContentAssistant$3.lambda$0(ContentAssistant.java:2016)
	at java.util.Collections$SingletonSet.forEach(Unknown Source)
	at org.eclipse.jface.text.contentassist.ContentAssistant$3.run(ContentAssistant.java:2015)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.jface.text.contentassist.ContentAssistant.computeCompletionProposals(ContentAssistant.java:2012)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.computeProposals(CompletionProposalPopup.java:561)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup$2.run(CompletionProposalPopup.java:490)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:71)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.showProposals(CompletionProposalPopup.java:483)
	at org.eclipse.jface.text.contentassist.ContentAssistant.showPossibleCompletions(ContentAssistant.java:1829)
	at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer.doOperation(CompilationUnitEditor.java:186)
	at org.eclipse.ui.texteditor.ContentAssistAction$1.run(ContentAssistAction.java:84)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:71)
	at org.eclipse.ui.texteditor.ContentAssistAction.run(ContentAssistAction.java:81)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:473)
	at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:118)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:93)
	at sun.reflect.GeneratedMethodAccessor169.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:318)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:252)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:161)
	at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:152)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:494)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:487)
	at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:204)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.executeCommand(KeyBindingDispatcher.java:305)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.press(KeyBindingDispatcher.java:579)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.processKeyEvent(KeyBindingDispatcher.java:648)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.filterKeySequenceBindings(KeyBindingDispatcher.java:438)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.access$2(KeyBindingDispatcher.java:381)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher$KeyDownFilter.handleEvent(KeyBindingDispatcher.java:93)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86)
	at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1190)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1051)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1076)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1103)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1099)
	at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1486)
	at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:4884)
	at org.eclipse.swt.widgets.Canvas.WM_CHAR(Canvas.java:350)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:4765)
	at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:345)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4757)
	at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2303)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3532)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1170)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1059)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:667)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:597)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:656)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:592)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1498)

Then, try this alternative scenario:

	@Transactional(readOnly=false, |)
	void test() {
		
	}

Hit ctrl+space at "|" because you need to add another attribute (like "rollbackFor"): no proper code assist is given. Neither in this case:

	@Transactional(readOnly=false, roll|)
	void test() {
		
	}
@eric-milles eric-milles added the bug label Nov 7, 2018
@eric-milles eric-milles self-assigned this Nov 7, 2018
@eric-milles
Copy link
Member

This should not error out any more:

@Anno(abc=false|)
void meth() {}

These cases will not produce proposals without some change to parser recovery:

@Anno(abc=false, |)
void meth() {}
@Anno(abc=false, xyz|)
void meth() {}

@mauromol
Copy link
Author

mauromol commented Nov 8, 2018

I confirm the exception is gone in the first case, although content assist now gives suggestions that produce errors:

immagine

Any of those options are not applicable, because they return void, and, in any case, the annotation attribute value must be a constant expression:

immagine

immagine

@eric-milles
Copy link
Member

All tests for annotation attributes were done on type annotations. Due to the parser design, this does not translate well to other annotations. I'm going to try another approach and see if I can come up with something better.

Also, the proposals for the constant expression "false" are from substring matches. I didn't see those in my testing. At the moment, there is no filtering within annotation attribute value completion for only constant expressions.

@eric-milles eric-milles added this to the v3.2.0 milestone Nov 9, 2018
eric-milles added a commit that referenced this issue Nov 9, 2018
- grammar allows trailing comma in annotation body, which will be error
for groovyc but not eclipse compiler (maybe this can be fixed in future)
@eric-milles
Copy link
Member

Ready to test

@mauromol
Copy link
Author

Hi Eric, sorry for the delay. I just tested with 3.2.0.xx-201811182243-e48: completion of attributes when no characters are typed works, but this case does not work yet:

@Transactional(readOnly=false, roll|)
	void test() {
		
	}

See screenshot:

immagine

@eric-milles
Copy link
Member

Ready to test

@mauromol
Copy link
Author

With 3.2.0.xx-201811200031-e48 it works better: now with roll| I get completions for rollbackFor and rollbackForClassName annotation attributes. Though, substring suggestions are not given (like noRollbackFor), while they are if you start code assist before starting to write any letter and then you start typing roll.
Also, while invoking code assist when no letter is given only brings meaningful suggestions (i.e.: the annotation attributes), when you invoke it at roll| you still get those class suggestions (like RolloverButtonBorder or @Rollback) which are not meaningful in that context. There are many similar examples and this is an area where I think there could still be a lot of space for improvement for Greclipse.

@eric-milles
Copy link
Member

I'll take a look at substring matches. There is likely a startsWith that needs to be replaced.

As for relevant suggestions only in a given context, can you open a separate issue for that? Annotation proposals are not as evolved as statement or expression proposals.

@mauromol
Copy link
Author

I confirm substring matching works with 3.2.0.xx-201811202025-e48, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants