-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 inlay hints backend into the server #1549
Conversation
Do you have a more realistic sample? I fear this can be too distracting, there should probably be a preference for it. Also, how does it handle I'm not sure why RA didn't resolve |
Looks like RA does not resolve for cases when the structure is a method local one. Works fine with the regular structure.
Nice catch, it displays nothing. Should be easy to fix though. One more thing that needs improving is an already defined parameter.
Here you go, the analyzer itself:
Fully agree, the setting is good to have, but I'm more concerned about the API changes and the overall correctness of the implementation, so let's get over it first :) |
Notice another funny RA type inference artifact: This is another reason why it would be cool to have a way to get an actual type information, not just a string. |
Maybe hide the code lens by default when the type is obviously known to the programmer. struct SS {}
// the type of test is obviously SS.
let test = SS {};
// the type of num is obviously u8.
let num = 5u8;
// should we hide the type here? not everybody knows that this defaults to `i32`.
let num = 5; |
Nope alas I'm not that good with knowing about VS Code features. If we can display the way IntelliJ does it, it would be really awesome, but no idea if it's possible with the existing lenses. |
Hard to say, I find it hard to determine the rules of obviousness, especially in Rust. |
They seem to be normal decorations
If the expression on the right is a literal or a type constructor application (not sure how they are called), the type is more or less obvious -- that is, if you ignore inference for integral types, for example. If it's a function call, it's not. |
Sounds nice, but if I understand correctly, there's no way to do this with the current api provided by the |
It's not a lens, it's a decoration with |
This is most likely related to a hacky bit of the Chalk integration: We keep track of the name of a type parameter inside the type, but Chalk doesn't, so if the type parameter goes through Chalk, it loses the name. This needs refactoring to get rid of the name on our side as well, and instead find it out from the context when printing the type... Although in this function, there is no type parameter, so there might be something else going wrong... |
9987fce
to
50d9a8d
Compare
Hey, I actually did an implementation for this on the vscode-rls project, here's the PR I made :) I had also tried with lenses, but ended up finding out like you seem to have that fiddling with their range does little more than order them if the are on the same line. Decorators can be placed in line just fine, but they are completely client side. My implementation on vscode-rls is more of a hack if anything: it looks for stuff that looks like a declaration (let, for, closures...), and uses Hover requests to get the type names. Feel free to cherry pick the parts that seem useful to you. I would have given it a shot if ra-lsp had less cases of |
So the salient point here is that an inline text decoration can be inserted using the |
Excellent, we really should do this ❣️ Though, I expect we should do things slightly differently. First, on the back end, we should make this a custom request, as suggested by @SomeoneToIgnore . Something like type HintsResponse = Vec<Hint>
struct Hint {
text_range: TextRange,
label: String
} This should be added as a method to Second, on the front-end, I feel like we should explore @p-avital approach. This is maybe just me, but I find the whole idea of code-lenses, that shift code vertically, utterly horrendous. The IntelliJ solutions for this (icons in the gutter area) is so much more convenient. OTOH, I am not against having lenses as a rendering option, if it is behind a config flag. @SomeoneToIgnore let's perhaps star with just backed bit, which can be tested independently? |
Wow, nice work there @p-avital !
Any tips on the method name and semantics?
Ok. In the worst case, we can throw away the rendering part from the PR. |
I'd do the following:
I'd like to be open ended about semantics: we certainly should start with type hints, but it could be the case that we invent something else useful as well. IIRC, Kotlin shows inlay hints for lambda returns, for example: |
50d9a8d
to
201b344
Compare
One step closer, I hope: the new API added, along with a I have a small doubt about the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scaffold looks about right, though the cusom LSP request is missing.
To get the actual types, you'll need to use source_analyzer
. Take a look at syntax highlighting implemenation: it also uses this "walk the tree, get the types" approach
@@ -749,6 +750,29 @@ pub fn handle_code_lens( | |||
}), | |||
); | |||
|
|||
lenses.extend( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be moved eventually into a separate LSP requestion right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, removed now to avoid confusion.
I use it currently to do some sort of a final integration testing.
Oh, sorry, I haven't understood your idea fully before. |
Nice, now the resolution happens on the server.
Otherwise I've adjusted everything except the |
I think you can create one per each function and reuse it inside of it. There's a |
I see only https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide_api/src/syntax_highlighting.rs#L99 there and it creates the analyzer for every node, I think, due to |
Yeah, that's the one. |
Thanks for the tip, let's wait for @matklad first, it might be that I'm doing something wrong and have to change the code. |
Yeah, that's true,
yeah, it doesn't have access to stdlib (to make the test fast). You can mock out the relevant parts of stdlib though: struct Vec<T> {
fn new() -> Self {}
fn push(&mut self, x: T) {}
}
The problem is, there's not standard request for this. You could use lenses, but than you'll lose the nice UI. I still think that it makes sense to make this a fully-custom request, and not to piggyback it onto any existing one. |
Did not work for me alas.
and it did not give me any new resolutions. Since there are some types from iterators that won't be displayed anyway, I propose to leave the tests as is.
Ok, added one. Since there's no |
There's no
The best solutions here is probably to come up with a set of reusable stdlib stubs. Adding literal standard library will make tests much slower and brittle. We have one integration tests that checks that stdlib is hooked up appropriately, and that should be enough. |
Yeah, we intentionally maintain a strict separation between rust-analyzer types and language server protocol types, to make sure that rust-analyzer is usable without the LSP protocol bors r+ Thanks! |
1549: Show type lenses for the resolved let bindings r=matklad a=SomeoneToIgnore Types that are fully unresolved are not displayed: <img width="279" alt="image" src="https://user-images.githubusercontent.com/2690773/61518122-8e4ba980-aa11-11e9-9249-6d9f9b202e6a.png"> A few concerns that I have about the current implementation: * I've adjusted the `file_structure` API method to return the information about the `let` bindings. Although it works fine, I have a feeling that adding a new API method would be the better way. But this requires some prior discussion, so I've decided to go for an easy way with an MVP. Would be nice to hear your suggestions. * There's a hardcoded `{undersolved}` check that I was forced to use, since the method that resolves types returns a `String`. Is there a better typed API I can use? This will help, for instance, to add an action to the type lenses that will allow us to navigate to the type. Co-authored-by: Kirill Bulatov <[email protected]>
@SomeoneToIgnore do you have a screenshot at hand? Don't sweat over it if now. |
Ah, never mind. It looks like there's no UI yet. |
Nice, thanks for the review. Yes, there's no UI yet, I'll continue with that. |
Build succeeded |
1591: Make Analysis api cancellable r=matklad a=SomeoneToIgnore Based on the discussion from here: #1549 (comment) Co-authored-by: Kirill Bulatov <[email protected]>
1586: Add type decorators r=matklad a=SomeoneToIgnore A follow-up of #1549 Now the frontend shows inlay hints as VS Code Decorators: <img width="666" alt="image" src="https://user-images.githubusercontent.com/2690773/61802687-918fcc80-ae39-11e9-97b0-3195ab467393.png"> <img width="893" alt="image" src="https://user-images.githubusercontent.com/2690773/61802688-93599000-ae39-11e9-8bcb-4512e22aa3ed.png"> A few notes on the implementation: * I could not find a normal way to run and display the hints for the file that's already open in the VS Code when it starts. The updating code runs ok, but does not actually show anything. Seems like I miss some event that I could add a handler to. I've also experimented with `setTimeout` and it worked, but this is too ugly. The hints appear now when a new file is open or when some change is done in the existing file. * If there's a `dbg!` used in the lsp_server, the frontend starts receiving change events that contain the string from the `dbg!` output. It should not be the case in a real life, but I've decided to cover this case, just in case. * For bigger files, ~500 lines, the decorators start to blink, when updated, this does not seem to be very much of a problem for me at this particular stage of the feature development and can be optimized later. In the worst case, those decorators can be turned off in settings. * Cursor movement is rather non-intuitive on the right edge of the decorator. Seems like a thing to fix in the VS Code, not in the plugin. Co-authored-by: Kirill Bulatov <[email protected]>
Types that are fully unresolved are not displayed:
A few concerns that I have about the current implementation:
I've adjusted the
file_structure
API method to return the information about thelet
bindings.Although it works fine, I have a feeling that adding a new API method would be the better way.
But this requires some prior discussion, so I've decided to go for an easy way with an MVP.
Would be nice to hear your suggestions.
There's a hardcoded
{undersolved}
check that I was forced to use, since the method that resolves types returns aString
.Is there a better typed API I can use? This will help, for instance, to add an action to the type lenses that will allow us to navigate to the type.