Conversation
tausbn
force-pushed
the
tausbn/unified-improve-node-locations
branch
3 times, most recently
from
September 17, 2026 15:37
3579163 to
ad29326
Compare
NB: This temporarily changes the test output for bulk imports, blocks, and things like synthesised Array and Option literals. Later commits will fix these up again.
The location 0..0 was being treated as "no useable location", which at the beginning of a file could cause problems. We now represent this as None instead, making Some(0..0) a valid empty location.
Adds two new macros, both variants of the existing `tree!` macro. First, `tree_at!` takes an extra argument, and sets the location of the root of the constructed tree to be that of the argument in question. Secondly, `tree_spanning!` does the same construction, but accepts an iterable of nodes instead. It then makes it so that the location of the root node of the constructed tree is the smallest span that contains all of the locations given by the iterable.
For such nodes, we assign them the zero-length location at the beginning of the matched input node.
Blocks are slightly awkward, since we destructure them (as codeBlock) in the query, and then reconstruct them (as `block`) in the rule body, meaning the location of the block is (by default) assigned to the wrong place by the heuristic. To get around this, I added a helper function that updates the location appropriately, including handling cases where we only optionally match a block. (Also, in some cases we can fix this by just not destructuring `codeBlock`s in the first place -- there's already a rule that maps `codeBlock` to `block`.)
Handles things like `try!` (which is represented as two separate tokens -- we explicitly union their ranges) and "let" binding modifiers (where we reuse the bindingSpecifier, getting its location and string value for free).
Build arguments, tuple-pattern elements, and tuple-type elements from their meaningful child ranges so separators remain owned by their parent nodes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep external child locations visible in AST dumps without treating non-containment as a fatal source-skeleton error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep inherited property metadata at its original source while limiting each accessor declaration to its own keyword and optional body. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tausbn
force-pushed
the
tausbn/unified-improve-node-locations
branch
from
September 18, 2026 14:31
ad29326 to
8b8e8f7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes the location-assigning heuristics to implement roughly the following principles:
middlein(outer foo: (middle bar: {baz}))), then it gets a location that spans all of its children (that is, all of the captures that have already been translated, that are assigned as descendants of this node).outerabove) gets the location of the entire node that matched that rule (unless that location has been assigned already, e.g. by recursive translation or explicit assignment).(identifier #{name}), wherenameis some captured node ID, then theidentifiernode gets the location of that capture, whereas the string value is what is actually interpolated.One consequence of the above rules is that if you have something like
then the location of the node emitted by the right hand side is not that of
foo, but rather whatever is assigned tobazwhen it is recursively translated.In cases where this heuristic is insufficient, newly added
tree_at!andtree_spanning!macros may be employed. These take a second argument that specifies the node (or iterable of nodes) from which to take the location of the tree being constructed.Should be reviewed commit-by-commit. I checked a bunch of the location changes in the last commit manually (and instructed Copilot to check the rest). In all cases, the locations are an improvement on what was there before (e.g. a call inside a tuple accidentally including the following
,in its range). This does produce a fair amount of churn, but I think it's somewhat unavoidable.