You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pubstructNodePath(Vec<NodeId>);implNodePath{pubfnroot(&self) -> NodeId;pubfnlast(&self) -> NodeId;pubfnkinds(&self,cst:&Cst) -> Vec<TreeKind>;pubfnlast_kind(&self,cst:&Cst) -> TreeKind;}impl std::ops::DerefforNodePath{typeTarget = [NodeId];}/// A token and the path to itpubstructTokenLocator{pubtoken:TokenId,pubpath:NodePath,}implTokenLocator{pubfnprev(&self,cst:&Cst) -> Option<TokenLocator>;pubfnnext(&self,cst:&Cst) -> Option<TokenLocator>;}pubenumLocator{Gap{path:NodePath},Token(TokenLocator),Boundary{left:TokenLocator,right:TokenLocator},}implLocator{pubfnpath(&self) -> &NodePath;pubfntoken(&self) -> Option<&TokenLocator>;pubfnspan(&self,cst:&Cst) -> Span;}implCst{pubfnlocate(&self,offset:u32) -> Locator;pubfncommon_ancestors(&self,range:Span) -> NodePath;}
How this works
3 states per cursor location is the Locator enum. A Token range has inclusive start/end. 2 tokens can share a Boundary. Gap keeps the enclosing node path which makes scoping simple.
common_ancestors is a way to figure out the deepest node which still contains a range
prev and next for peeking both directions to get context
Span::contains should be half-open so it matches the other
Why ?
These are genuinely useful API additions that we should have in the crate itself. They allow us to build more complex features in the LSP by abstracting away some of the spaghetti from Visitor implementations downstream, where we currently duplicate the behavior for each visitor. Being able to get a locator query like this means we can get rid of the workaround implementations in the LSP.
Span boundary bug
All 3 finders in the LSP have the same bug with descent where Span being inconsistent causes them to build the wrong node chain. Visitor doc says that exit_tree should run after children end, this also happens when a tree gets skipped. Stop is inconsistent because it does not call exit_tree on the node's open ancestors which causes scope stack corruption.
common_ancestors makes it possible to implement code actions, expansion and formatting for selections. It should also be possible to show a breadcrumb path composed from the returned NodePath.
Proposed API
How this works
3 states per cursor location is the
Locatorenum. A Token range has inclusive start/end. 2 tokens can share aBoundary.Gapkeeps the enclosing node path which makes scoping simple.common_ancestorsis a way to figure out the deepest node which still contains a rangeprevandnextfor peeking both directions to get contextSpan::containsshould be half-open so it matches the otherWhy ?
These are genuinely useful API additions that we should have in the crate itself. They allow us to build more complex features in the LSP by abstracting away some of the spaghetti from Visitor implementations downstream, where we currently duplicate the behavior for each visitor. Being able to get a locator query like this means we can get rid of the workaround implementations in the LSP.
Span boundary bug
All 3 finders in the LSP have the same bug with descent where
Spanbeing inconsistent causes them to build the wrong node chain.Visitordoc says thatexit_treeshould run after children end, this also happens when a tree gets skipped.Stopis inconsistent because it does not call exit_tree on the node's open ancestors which causes scope stack corruption.common_ancestorsmakes it possible to implement code actions, expansion and formatting for selections. It should also be possible to show a breadcrumb path composed from the returnedNodePath.