Conversation
In particular, introducing PEP 695 generics introduces a new scope
09e8222 to
b79964a
Compare
| let li = line_index(db.upcast(), file); | ||
|
|
||
| let text_size = li.offset( | ||
| // XXX bad |
There was a problem hiding this comment.
we hold usizes, LSP server holds u32s. Not sure what the resolution should be.
| }; | ||
|
|
||
| pub fn definition_at_location(file: File, location: Position, db: &dyn Db) -> Option<DefLocation> { | ||
| // XXX now this returns one or none. It could return an iterator of locations |
There was a problem hiding this comment.
Not clear to me if our current system could multiple locations but the LSP can handle multiple definition sites (I imagine in case of ambiguity)
|
Thanks for this contribution. This is a very cool feature. This is a feature we want long term but it isn't a short-term priority and there are a lot of things that we have to consider:
That's why I don't expect us to get around to reviewing and merging this feature in the short term. That doesn't mean you shouldn't work on it. I just want to avoid frustration if we won't be able to make progress on this feature short term. |
|
@MichaReiser yeah, understandable. I appreciate how quick you all are for reviews, and believe that's downstream of everyone doing these reviews seriously. So thank you for the expectation setting here. I'll try to avoid this branch becoming a thing people have to consider until the time is right. I wanted to open this draft PR to publicly state I had something working here (in case someone else was already tackling this), but I am comfortable just keeping this work on-branch until it looks like what people actually want. And if y'all come up with a totally different way to do this and just do it on a clean branch, no harm done (except to my pride 😆 ). I'll still be working through this branch just because I need this functionality for now. |
|
|
Thanks again for your work. I close this PR because it's unlikely that we start working on this feature anytime soon (or review it). But we will pick it back up once we're further along with Red Knot and your work will be a great source of inspiration for it. |
|
@MichaReiser understood! Looking forward to future work in this space |
Summary
This sets up "jump to definition" functionality in the
red_knotserver.Here are some challenges in doing this:
I tackled this with a custom trait,
CanLocate. We can ask implementations of theCanLocatetrait where their definition is, based on a cursor location. This combines "traverse the AST" with "do the lookup of the definition" because sometimes we'll need to just look up a name in a scope, but for attribute access in particular there's some interplay between types and definition that need to happen so thata.b.cis properly done as "find the definition ofcon the type ofa.b".In practice this trait means I can traverse an AST tree, zooming down until I find the smallest node that a cursor is located in.
From there, I have added a couple of methods to help go from an AST node to a
Definition.From a
Definitionto a location has proven to be tricky. I have a most definitely not the right answer helper that is simply looking through a hash table to try and find the definition's location based on its hash key (definition_range). It's most definitely wrong, and would appreciate some advice there.This currently implements "go to definition" based on just names and attribute access (not handling instance attributes just yet, though I believe MRO work is happening in another branch). Import traversal seems to magically work .
Still wanting to clean things up (in particular I think I can simplify some of the
CanLocateimplementations)Test Plan
First you need to set up the LSP server. In Emacs I did this with the following with
lsp-mode(please note I hardcoded thered_knotpath , you'll have to point to whatever you need)(in a project's
.dir-locals.el)I then was playing around with this file. Some "jump to definition" stuff works, some doesn't.