Open atombender opened 4 years ago
Thank you for filing a gopls issue! Please take a look at the Troubleshooting guide, and make sure that you have provided all of the relevant information here.
Thanks for the report! /cc @muirdm
I think this is because incrementalAnalyzer{}
is a syntax error without extra parents around it. The composite literal curlies are parsed as the if
block curlies, so the AST is all messed up.
I'm not sure it would be easy to work around this type of syntax error. Maybe a code action to add in the missing parens?
@muirdm: No, that's not a syntax error.
Ah, I see what you're saying. It's not valid syntax in an if
statement without parens.
Looks like it generally happens in the presence of syntax errors. For example:
expectErr := proto.QueryParseError{Description: "No query"}) // <-- extra parenthesis
If you try to autocomplete expectErr
after this code snippet, the same thing happens.
Yup, syntax errors wreak all sorts of havoc. We try to work around "expected" syntax errors you get as you type code (e.g. as you type if fooBa
), but unexpected syntax errors will still prevent completion from working properly due to various reasons.
FWIW, GoLand does not have this issue.
There are two steps to improving this in gopls:
b := bytes.Buffer{}) // syntax error
b.Wr
To offer b.Write()
properly, we need to manually extract the selector expression b
and type check it (since it is not in the AST). It is easy in this case, but the left side of the selector can be an arbitrarily complex expression, so it is non-trivial to pick out out dependably. Out of curiosity, does GoLand handle selector expressions like this as well?
@muirdm An example from GoLand. Is the GIF relevant to your question?
I'm not sure if I'm understanding it correctly, but in GoLang, it does seem like
b := bytes.Buffer{}) // syntax error
is valid in a sense
b := bytes.Buffer{}
From what I can tell, GoLand's parser is more lenient, and will recover from such parsing errors. I'm not able to make it break on unexpected tokens. For example, if you do:
b := bytes.Buffer{}:=
b2 := bytes.Buffer{}
then doesn't understand the type of b
anymore, but it will happily continue to parse the rest of the file, and b2
will be autocompletable. Gopls just stops working.
Looking at how parser errors are phrased, it seems GoLand has its own parser, and doesn't reuse Go's.
Thanks. It makes sense that GoLand has its own parser since the standard library parser wasn't designed to work in the face of syntax errors.
It makes for any language server to have to its own parser. 😉 Editors aren't compilers, after all.
As an aside, this extends beyond just accidental syntax. Losing autocompletion occurs, of course, while just typing code. Here's an example where temporarily missing parantheses cause breakage:
That's unrelated to this bug, but it shows how the current parser is a problem.
Similar bug (the file has a syntax error some lines below the cursor):
Another example.
The first one (res.var
) was ok, and then the second one (res.err
) was messed up. This inconsistency makes the completion feature more confusing.
I'm experiencing the same issue when typing a comment for documenting a method/function. Typing the first few characters of the method/function name and pressing tab/enter afterwards used to autocomplete properly, but now it just appends the name to the already typed characters.
@kostaskoukouvis: That is https://github.com/golang/go/issues/39262.
@kostaskoukouvis: That is #39262.
Oops! My bad! :/
I'm experiencing the same issue here. The syntax error in my case was this statement:
if a, b _ = objobject.dosomething
When I removed the underscore, the autocorrect goes back to working as intended.
What did you do?
In VSCode, typed part of a word to autocomplete it, e.g.
cancel
, then selectedcancelCtx
.What did you expect to see?
I expected the current word to be
cancelCtx
.What did you see instead?
Current word became
canccancelCtx
.Build info
Also getting this behaviour with v0.4.0.
Go info
VSCode
VSCode-Go 0.14.1.
Log
gopls.log.gz