-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: add Range token.Pos to RangeStmt #50429
Comments
I also ever encountered this problem: https://groups.google.com/g/golang-tools/c/PaJBT2WjEPQ/m/HegyRyhjAwAJ A related issue: #13590 There are two other similar cases:
Currently, I need some efforts to get their positions, and I'm not sure my implementation is bug free. |
To add some more context why a kludge with the manual token (described in the referenced thread + in this issue) discovery is hard: I'm also using a minified Go corpus that can be queried by structural patterns. But if #13590 is closed, I don't think anything has changed since then? |
I don't have an objection to this proposal. My only concern is that right now But you're just asking for 16 bytes, and I don't think my philosophical concerns should be blocking. |
Is that list comprehensive? I wonder how much it would take to have an invariant that "go/ast captures all the positions of semantically relevant tokens". |
I think the list is comprehensive. The three are all the ones I found in developing go101/Golds. |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
Change https://go.dev/cl/426091 mentions this issue: |
For #50429 Change-Id: Idb027244f901d9f482c894b5b979a054d0f07de5 Reviewed-on: https://go-review.googlesource.com/c/go/+/426091 Reviewed-by: Daniel Martí <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Robert Findley <[email protected]>
This was fixed by https://go.dev/cl/426091 . |
The current
RangeStmt
:Proposed changes:
RangeStmt struct { For token.Pos // position of "for" keyword + Range token.Pos // position of "range" keyword Key, Value Expr // Key, Value may be nil TokPos token.Pos // position of Tok; invalid if Key == nil Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE X Expr // value to range over Body *BlockStmt }
It will add extra 8 bytes to the size on 64-bit platforms. An unfortunate coincidence is that right now its size is 80 bytes, exactly as a size class. Making it 88 bytes will get it to the next size class, 96 bytes allocation (so we effectively add 16 bytes per range statement on 64-bit platforms).
Although I would assume that range statements are not that frequent as, say,
*ast.Ident
, so it might not be a big deal.Why I need this: when doing a partial code search/replacements, you may want to use some structural elements as anchors and then make a span of this range. For instance, gogrep now supports range patterns like
range $x
, which means it'll match*ast.RangeStmt
and capture only it's range expression. The bad part is that it's hard to figure out what's the starting pos of this partial syntax is.The only way to find
range
position right now is to takeTokPos
and walk the source text manually, hoping that there are no inline/**/
comments or some other things that may be floating between:=
andrange
. It's unusual to have anything between Tok and Range, but it's still possible even for gofmt'ed code.As a side note, it looks like gofmt does move comments there:
for _, x := /*ok*/ range xs {}
becomesfor _, x := range /*ok*/ xs {}
.If the rationale above is not convincing, I actually need this pattern matching of standalone
range
clauses in the rules engine (based on go-ruleguard) that is based on gogrep. Getting a precise location (pos range) is important to apply an automatic fix.This issue may meet the same fate as #44257 did, but I figured I'll still report the fact that there is an issue that a few people can get into while creating untrivial Go tools.
If this proposal is accepted, I would like to send a CL with implementation.
Kludge / workaround
If this proposal is never accepted, I'll embed a partial solution that may also show how awkward it is to find "range" pos right now.
The text was updated successfully, but these errors were encountered: