Include elided tokens in yeast AST node locations - #22531
Conversation
Co-authored-by: aschackmull <28296824+aschackmull@users.noreply.github.com>
Co-authored-by: aschackmull <28296824+aschackmull@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The implementation matches the stated behavior and includes focused regression coverage.
Pull request overview
Extends Yeast synthesized-node locations to include elided portions of matched source nodes.
Changes:
- Unions child-derived and inherited match ranges.
- Adds regression coverage for elided tokens.
File summaries
| File | Description |
|---|---|
shared/yeast/src/lib.rs |
Implements source-range unioning. |
shared/yeast/tests/test.rs |
Verifies the full matched call range is retained. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
tausbn
left a comment
There was a problem hiding this comment.
Looks good to me! 👍
While I'm not sure if this is the solution we want to use long term, I think this a perfectly good solution right now, especially if it unblocks other work.
|
On second thought, looking at the test failure: --- expected
+++ actual
@@ -1,6 +1,6 @@
nameExpr
| name_expr.swift:1:9:1:9 | NameExpr | y |
-| test.swift:1:8:1:17 | NameExpr | Foundation |
+| test.swift:1:1:1:17 | NameExpr | Foundation |
| test.swift:8:9:8:13 | NameExpr | items |
| test.swift:8:22:8:25 | NameExpr | item |
| test.swift:12:16:12:20 | NameExpr | items |
Error: [7/10 comp 2.6s eval 44ms] FAILED(RESULT) /home/runner/work/semmle-code/semmle-code/ql/unified/ql/test/library-tests/BasicTest/test.qlThe code in question is |
That's certainly true - I've no idea why that happens. I'll dig a bit. |
|
I think we need something that treats the matched "top-level" node of a rule specially. So, something like:
I'm not quite sure what to do about childless synthesised nodes (if we have any). Perhaps these should just inherit the range surrounding them. |
Co-authored-by: aschackmull <28296824+aschackmull@users.noreply.github.com>
|
Copilot claims to have fixed it now. I admit I don't have a good enough overview of the code to have complete confidence, but testing locally it appears to work. |
|
I had a look at the fix, and it looks okay, if a bit hacky. Unfortunately, there are other issues introduced by the changes in this PR that make some locations worse than before. For example, a generic type expression like C<Foo>becomes a Similarly, in switch x { case a, b: c }the locations of the At this point, I'm inclined to just wave this through, however. It (presumably) improves locations for the bits that you care about, and I can sit down and implement a better solution after we merge this. What do you think? |
I agree that those do sound like regressions, but I'm out of my depth re. actually properly fixing them. I'd need to invest a lot more time to get to know this codebase. And it doesn't make much sense for me to just act as meat-proxy between you and copilot - that's bound to just lead to worse code. So if you're happy with taking on the followup, then I'll humbly accept. |
tausbn
left a comment
There was a problem hiding this comment.
Let's get it in. I'll handle the follow-up.
Yeast rewrites can elide matched tokens when producing the target AST, causing synthesized node locations to shrink to only their retained children. For cases like
return x, this made the rewrittenreturn_exprspan onlyxinstead of the full return statement.Location synthesis
Regression coverage
Example:
The synthesized
callnow keeps the source range of the full matchedfoo.bar()expression, not just the retainedbarchild.