-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
go/ast: no way to distinguish some For statements, like for ;; {}
and for {}
#44257
Comments
for ;; {}
and for {}
cc @griesemer |
Marked for Go 1.17 but only so it's on the radar if we decide to address this. |
Moving this to 1.18 as it's not going to be addressed before the freeze. Note that adding information to the AST is not always a net win. For example, a significant fraction of gopls' memory use is devoted to AST, and adding fields can have a real (albeit incremental) impact on performance. While this change might have negligible impact, we have to draw the line somewhere, and for this there are some heuristics:
So with these considerations, I'm inclined to say that we shouldn't do this. However, I am very sympathetic to the underlying motivation. In gopls we've had various struggles writing refactoring tools, related to the fact that we can't compute the exact input from the AST. There is probably room for a higher-level library on top of go/{scanner,ast} that provides a better API for working with raw Go syntax. |
@findleyr This is in the Go1.18 milestone. Is it likely to happen for 1.18? Should it move to Backlog? Thanks. |
Yes, unfortunately this needs to go into the backlog. With everything else, parser improvements have had to take a back seat. Also unassigning myself, as I am not actively working on this. |
@mvdan Perhaps you're interested in picking this up? But again, this is not urgent in any way, as far as I can tell. |
I would guess that we can store This way, no new fields are added, so we'll pay extra memory in gopls only if the code actually had If Daniel is not interested enough, I can try rolling an implementation so we can see whether it's more involving than it looks right now or not. |
How often do Considering gofmt rewrites them into |
@ALTree, I would assume you have read my description above. But just to be clear: it appears in user-defined syntax patters when you want to find these kinds of structures. Or when you want to write a structural refactoring tool yourself, so you want to have as good AST as possible. I mentioned gogrep, but there is also go-ruleguard and I'm sure there are more tools like that in the wild. Most users are suffering without saying anything out loud (tools that inspect AST and use it as inputs for AST-related rewrites, etc; we don't even need a proper syntax tree, just an AST that misses less information, encoding I agree that we can't get 100% of what we want from the If such tools are out of scope, then we can close this issue. If not, I can bring some more related issues and open them as separate tickets (or we can extend this one if that looks better). |
@ALTree has a good point here. Unless there's a natural way to represent this with the |
@quasilyte Thanks for the clarification. I did read the thread before replying, and now I've also read your second reply, but I think my point still stands (or possibly I've misunderstood your argument). You pointed out that currently this: Of course if you're grepping over non-fmt'd code, for example for a tool that reports that I'm not saying that being able to tell them apart is a bad idea. I just wanted to say that -since the difference can only be apparent in non-go-fmt'd code- any solution to this issue should probably have ~0 impact on performance and memory usage of |
@ALTree, you're right, there is no big benefit in this since using this pattern is not very useful. I think I'll find some workaround in one way or another. The issue can be closed unless anyone has any reasons to keep it. It'll stay in history, so at least we'll have some context for the future. |
Closing issue per above discussion. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Parse
a
andb
: they produce the same AST. There is no way to distinguish them.Same for the cond-only for loops, we can't distinguish them:
With
SliceExpr
, we have a usefulSlice3
flag that helps to distinguish ambiguous cases.Maybe we can have something similar for the
ForStmt
? It can also be solved by adding semicolon positions to theForStmt
.I know that Go AST is (ahem) AST, not a parse tree, so some information can be lost there, but it seems like this would be useful for tools that analyze the Go source code style.
In particular, gogrep tool could benefit from that.
(It also looks like
go/printer
has the same difficulties, this is why we get identical printed forms above.)I'm also aware that after
gofmt
botha
andb
become identical; it's not always desirable to reformat the code being processed.Another gogrep-related thing.
for $*_ {}
could read as "any for loop" whilefor ; $*_; {}
should probably match only non-range loops. Right now it's hard to produce a different pattern for these as both of them generate identical AST.What did you expect to see?
A way to distinguish between 2 syntax forms.
What did you see instead?
No way to distinguish between 2 syntax forms.
The text was updated successfully, but these errors were encountered: