vscode-java icon indicating copy to clipboard operation
vscode-java copied to clipboard

Code completion shortcut not working in if statement nested in for loop

Open hasen6 opened this issue 1 year ago • 14 comments

Environment
  • Operating System: MacOS 12.511
  • JDK version: 1.8.0_341
  • Visual Studio Code version: 1.71.0
  • Java extension version: 1.10.0
Steps To Reproduce

Capture d’écran 2022-09-13 à 12 22 24 PM finds the code completion shortcut no problem. Capture d’écran 2022-09-13 à 12 22 37 PM fails to find the shortcut.

The problem persists after restarting VScode.

hasen6 avatar Sep 13 '22 10:09 hasen6

not working in if statement nested in for loop

At least not due to this,

image

Eskibear avatar Sep 13 '22 10:09 Eskibear

At least not due to this,

Well how would you describe the situation I posted? Looks like a nested foreach loop to me. Please edit the title to what you believe it should be called.

hasen6 avatar Sep 14 '22 08:09 hasen6

@hasen6 Could you provide a project example reproducing the error?

snjeza avatar Sep 16 '22 14:09 snjeza

@hasen6 The exact project would be ideal. If not, would it be possible to activate the command palette (eg. ctrl+shift+p) and launch the Java: Open All Log Files command after you have reproduced the problem. I would post the .log file or at least any errors you see in there.

Snippet completions are one of the last collected so maybe something failed before and they never got collected ? Looking at https://github.com/eclipse/eclipse.jdt.ls/blob/dbd035c6aa036b6ee7dd7ea503de548f33fe641c/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandler.java#L162-L175 nothing stands out as obvious since I wouldn't think this is a cancellation issue.

rgrunber avatar Sep 16 '22 19:09 rgrunber

@rgrunber

The exact project would be ideal. If not, would it be possible to activate the command palette (eg. ctrl+shift+p) and launch the Java: Open All Log Files command after you have reproduced the problem. I would post the .log file or at least any errors you see in there.

I can't share the project unfortunately since it's a large multiple file game engine. I've actually since changed that method and the error no longer reproduces anywhere in the new version of that method. However I have a backup of how the code was previously and the error reproduces just as before inside that code, it seems the circumstances have to be quite specific for the error to occur. It's not as simple as an 'if statement in a for loop', but I don't know how else to describe it. Unfortunately the log files have nothing. I don't think vscode considers it to be an error but it reproduces every time in those conditions, it's not something failing as a one off.

I'm trying to put together some kind of simple project that would reproduce the error.

hasen6 avatar Sep 17 '22 08:09 hasen6

This is weird too, it's successful if there's an error above it:

Fails:

Capture d’écran 2022-09-17 à 10 50 32 AM

Succeeds

Capture d’écran 2022-09-17 à 10 50 43 AM

hasen6 avatar Sep 17 '22 08:09 hasen6

I think the moment you're able to reproduce, check the .log file as I described above. If there's a stacktrace, then maybe we can address it without a code snippet, or even work backwards to figure out what kind of snippets trigger this.

Another possibility is that something in here is just failing : https://github.com/eclipse/eclipse.jdt.ls/blob/dbd035c6aa036b6ee7dd7ea503de548f33fe641c/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SnippetCompletionProposal.java#L218-L239 .

rgrunber avatar Sep 19 '22 21:09 rgrunber

I think the moment you're able to reproduce, check the .log file as I described above. If there's a stacktrace, then maybe we can address it without a code snippet, or even work backwards to figure out what kind of snippets trigger this.

I opened vscode in terminal with code --log trace and after typing sout and seeing the error, as far as I can see there was nothing written to the main.log, it's really just not seeing it as any kind of error. But I do have a minimal project where I can recreate the error every single time. Let me know where I can send that to.

hasen6 avatar Sep 20 '22 12:09 hasen6

I opened vscode in terminal with code --log trace and after typing sout and seeing the error, as far as I can see there was nothing written to the main.log, it's really just not seeing it as any kind of error. But I do have a minimal project where I can recreate the error every single time. Let me know where I can send that to.

Not sure if the main.log would show these errors. They would only be logged to the language server's logs (The .log file from Java : Open All Log Files command). The Language Server For Java tab within the Output View might also have any errors.

Are you able to attach the project to a comment (drag & drop into reply box) ?

rgrunber avatar Sep 20 '22 13:09 rgrunber

Not sure if the main.log would show these errors. They would only be logged to the language server's logs (The .log file from Java : Open All Log Files command). The Language Server For Java tab within the Output View might also have any errors.

Ok I thought you were referring to the main.log when you said .log file. Anyway you can check the project yourself, it will be simpler.

Are you able to attach the project to a comment (drag & drop into reply box) ?

Ok I'll try, I thought it was only images that could be dropped but it looks like it's added. The project will show up with a lot of red underlined errors because everything is missing but I noticed it doesn't matter, you should be able to still run shortcut snippets like 'sout' for the System.out.println(); though. Check the TileDB.java file and type a snippet exactly where I was typing it in the screenshots.

spacerogue 2.zip

hasen6 avatar Sep 20 '22 17:09 hasen6

Thanks for the project. I'm able to reproduce with a much simpler example now :

Test.java

package org.example;

public class Test {

	private boolean removed;

	public void test(Object input) {
		if (true) {
                        sout|
			((Test)input).removed = true;
		}
	}
}

The problem happens at https://github.com/eclipse/eclipse.jdt.ls/blob/dbd035c6aa036b6ee7dd7ea503de548f33fe641c/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SnippetCompletionProposal.java#L231 . The tokenLocation is not recognized as a TL_STATEMENT_START (used to avoid suggesting snippets everywhere) but a TOKEN_KIND_UNKNOWN

Seems to me like a fix would belong in https://github.com/eclipse-jdt/eclipse.jdt.core/blob/fa7970e436a20d3526755326eafdb8bb6b8c6e01/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java#L1897

rgrunber avatar Sep 20 '22 19:09 rgrunber

@rgrunber indeed the bug can be reproduced in upstream Eclipse. Is there a bug report to point to?

fbricon avatar Sep 21 '22 09:09 fbricon

Thanks for the project. I'm able to reproduce with a much simpler example now

I'm glad you were able to reproduce it, it's certainly an elusive bug, if you change almost anything to my example project's function, the bug no longer occurs, it was quite a miracle I even came across it in the first place. I've been working on projects in java every day since I reported the bug and literally never came across it again even once. I guess it has to be fixed nonetheless though.

hasen6 avatar Sep 21 '22 12:09 hasen6

I don't think there's a bug for this upstream, but this seems to be in the category of the parser recovering tokens in an unexpected way. I think I see what's happening, and it makes this bug look not entirely wrong.

sout|
((Test)input).removed = true;

is parsed (recovered) as

sout((Test)input).removed = true;

In other words, sout : Test -> Test, so it could be interpreted as completion being triggered within a statement, and not at the start. I could still file this upstream and see if anything could be done.

rgrunber avatar Sep 22 '22 00:09 rgrunber

@rgrunber It's pretty rare to come across but I just came across it again in another situation so I guess it wasn't fixed.

hasen6 avatar Oct 11 '22 22:10 hasen6