[ty] Change goto-def for class constructors to always go to class definition#23071
[ty] Change goto-def for class constructors to always go to class definition#23071BurntSushi merged 2 commits intomainfrom
Conversation
2cd98f1 to
55fc171
Compare
Typing conformance resultsNo changes detected ✅ |
|
55fc171 to
4caa0bf
Compare
| for node in covering_node | ||
| .parent() | ||
| .into_iter() | ||
| .chain(std::iter::once(node)) | ||
| { | ||
| return Some(GotoTarget::Call { | ||
| call, | ||
| callable: name.into(), | ||
| }); | ||
| if let AnyNodeRef::ExprCall(call) = node | ||
| && let ast::Expr::Name(ref name) = *call.func | ||
| { |
There was a problem hiding this comment.
I'm not really sure why do we need to loop over the two nodes here when only one of them is going to be a ExprCall unless I'm missing something? I don't mind this, just wanted to understand it.
There was a problem hiding this comment.
I added this to account for the case when the cursor is on (. Previously, we were assuming we were on a Name node, and thus the parent was the ExprCall. But if we're on the (, then the covering node we get back is directly the ExprCall. So we try the parent first, and if that fails, try the current node to find the right ExprCall.
| // Note that we specifically only look for a opening parenthesis | ||
| // here. Matching on a closing parenthesis seems ambiguous. e.g., | ||
| // what do you do in the case of `func(a<CURSOR>)`? Arguably the | ||
| // cursor is "inside" the function call. In any case, when AG tried | ||
| // to match on a closing parenthesis here, a bunch of tests failed | ||
| // in an undesirable way. |
There was a problem hiding this comment.
I think this is correct that we shouldn't try to match it against the closing parenthesis when inside the call and there are arguments because those should navigate as per the argument type, right?
There was a problem hiding this comment.
I'm honestly not sure. I think our current tests definitely assert that. And it seems reasonable to me. I think the most important thing is that we're consistent.
Specifically, consider foo(argument). If your cursor is "on" the ), then it looks like this: foo(argument<CURSOR>). In that case, the cursor isn't really "on" the argument. It's on the ). But visually (usually), the cursor is between argument and ), and so it seems like it could be confusing.
In any case, I think this is something we can iterate on in response to user feedback.
…inition Previously, we would include the class definition in addition to the `__init__` and `__new__` methods, if present. But it seems that this generally leads to unintuitive behavior from the perspective of users. It's also not what pyright does. This was also discussed a bit in the PR adding this functionality: #20014. Fixes astral-sh/ty#2218, Ref astral-sh/ty#2639
…es you too constructor method This commit builds on the previous by tweaking the behavior of goto-def on `(`. This lets users jump to the constructor method(s) directly instead of the class definition. Fixes astral-sh/ty#2218
4caa0bf to
539c739
Compare
|
I would have preferred to keep the behavior of getting both.. That way I'm immediately moved to the first location (line with Any chance that this could be made configurable? |
|
My sense is that more folks were surprised by the previous behavior. It's also not how pyright works. I'm not quite sure this is the kind of thing we want to offer a configuration knob for. |
|
I realized that, unless this is a standard behavior, users would probably not know that this difference exists. It might be worth documenting this somewhere, probably https://docs.astral.sh/ty/features/language-server/ ? It's not a priority but something that I've realized. |
|
@dhruvmanila Aye, I opened astral-sh/ty#2772 |
Previously, the ty LSP would also include
__init__and__new__targets along with the class definition. In some LSP clients (like VS
Code), this would bring up a prompt to ask the user to select one. It
seems like this is generally unexpected by users (and in particular,
deviates from pyright). This PR changes the ty LSP to behave more like
pyright here, and only include the class definition in the response.
This does also make the change to enable users to jump to the
constructor method directly by invoking goto-definition when the cursor
is on the parentheses of the call.
Reviewers might find reviewing commit-by-commit to be helpful here.
The first commit makes the change over to class definitions only.
The second commit adds special support for goto-definition when
the cursor is on a parenthesis.
Fixes astral-sh/ty#2218, Ref astral-sh/ty#2639