Skip to content
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

Add the ability to make a SyntaxNode which is offset by a certain amount from the source code #73

Open
RDambrosio016 opened this issue Aug 22, 2020 · 3 comments

Comments

@RDambrosio016
Copy link

Hello, i have been using rowan in my own project, it works absolutely great. However, when parsing something like a markdown file, i run into issues with text ranges because it assumes the root node starts at the start of the source. Which means i need to offset every single node, token, or element's range i make. It would be great if i could make a syntax node and tell rowan the range is actually offset by a certain amount, i tried to implement this myself but i ran into a good amount of issues, including:

  • A lot of things internally rely on range, this could probably be solved by making a raw_range internal method
  • There may be conflicts with how rowan uses the range to find stuff inside of green nodes, this could probably also be solved by the above.

Text would stay the same, as the green node will still have the right text, only text range of parent and children would be affected.

@CAD97
Copy link
Collaborator

CAD97 commented Aug 24, 2020

One possible way of kludging an offset together with the current API is to just put an extra green node in front with the desired offset length. Ofc, that requires a string of that length to back it, so it's not a great solution.

It in theory wouldn't be a difficult change to at a base offset to the syntax tree. In theory, "just:"

  • Change Kind::Root(GreenNode) to Kind::Root { node: GreenNode, offset: TextSize }
  • See if that changes the size of Kind. If so, investigate finagling the definition to re-add a niche to keep the size the same. (Idea: child index probably can be guaranteed to fit in u16.)
  • Update all the places matching Kind::Root(green) to Kind::Root { node: green, .. }, as well as the root constructor to take a root offset. (Or make a new constructor that takes an offset, and the existing one uses a zero offset.)
  • Update SyntaxNode::text_range to match the inner kind and read the root offset, rather than using the as_child helper. Probably add a SyntaxNode::offset(&self) -> TextSize helper.

That should be all that's necessary to add a root offset to the syntax tree. That also should make it possible to "reroot" syntax trees, pulling out a subtree so the rest can potentially be reclaimed, though I don't know how useful that'd be in practice.

@RDambrosio016
Copy link
Author

I briefly asked @matklad about this over zulip, he brought up a great point.

matklad: green nodes are offset-less by design

matklad: that way, you don't have to change every green node when you type a space at the start of the file

Which makes a ton of sense, only syntax nodes should carry an offset. This change should not affect green nodes at all

@CAD97
Copy link
Collaborator

CAD97 commented Aug 24, 2020

That's why the plan I outline is just adding an offset to the root of the syntax tree; it doesn't touch the green tree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants