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

Feat/inlay hints #2525

Closed
wants to merge 31 commits into from
Closed

Conversation

omprakaash
Copy link
Contributor

@omprakaash omprakaash commented Jan 5, 2024

Adds basic support for inlay-hints and annotation insertion for types.

@omprakaash omprakaash marked this pull request as draft January 5, 2024 19:46
@lpil
Copy link
Member

lpil commented Jan 30, 2024

Hi @omprakaash are you working on this?

@omprakaash
Copy link
Contributor Author

omprakaash commented Jan 30, 2024

Hi, Yes. Sorry, progress has been slow for a while due to college. I believe, I am close to putting this up for review by this week.

@omprakaash omprakaash marked this pull request as ready for review February 1, 2024 17:02
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a separate lsp_printer. I feel that this pretty similar to the pretty_printer so used an instance of one as a field here. Not sure if this is a good design decision.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea 👍

@lpil
Copy link
Member

lpil commented Mar 6, 2024

Hello! Are you currently working on this?

@omprakaash
Copy link
Contributor Author

Hey yes. Wanted to get this reviewed before potentially going further. Felt like this was getting too large for a single PR.

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a quick look through and it looks great so far! I can do a thorough review when you feel it's more ready 🙏

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea 👍

pretty::{break_, concat, nil, Document, Documentable},
};

use super::{pretty::Printer, Type, TypeVar};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just append to a string as inline hints don't need to be wrapped onto multiple lines. Would make it simpler and faster

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah gotcha ! Will change this.

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I've left a bunch of notes inline.

This is a very large PR and it is proving hard to merge. Would you like it if we split it into a series of smaller and easier PRs? For example, the annotation printer first, then a code action for annotate assignment, then module constant, etc etc.


#[serde(default = "InlayHintsConfig::default_variable_assignments")]
pub variable_assignments: bool,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you document in detail what these do please 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, will do

true
}
fn default_variable_assignments() -> bool {
true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we want this one off by default

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, was just testing this. Will switch it back to false when complete

Comment on lines +262 to +263
let type_qualifiers = get_type_qualifiers(module);
let module_qualifiers = get_module_qualifiers(module);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are only used in the code action function so let's move these function calls in there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

Comment on lines +515 to +517
if let Some((AssignName::Variable(v), _)) = &import.as_name {
let _ = module_qualifiers.insert(import.module.clone(), v.clone());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not import.used_name() here?


/// Response handler for the `workspace/configuration` request
fn configuration_update_received(&mut self, result: Json) {
if result.is_array() && !result.get(0).is_some_and(|config| config.is_null()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come we're not using serde here?

Type::Named {
name, args, module, ..
} => {
let key = module.clone() + "." + name.clone();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use (&str, &str) as the key to avoid the 3 allocations here.

Comment on lines +48 to +49
// Ignoring module names for in-built gleam types like Int
name.to_string()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could produce incorrect results when the prelude types have been shadowed locally.

} => {
let key = module.clone() + "." + name.clone();
let res = self.type_qualifiers.get(&key).unwrap_or(&key).to_string();
if args.is_empty() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're gunna want to have the correct qualifier even when there are args, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep !

position,
kind: Some(InlayHintKind::TYPE),
tooltip: None,
padding_left: text.starts_with(' ').then_some(true),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean?

}
}

pub fn extract_type_parameters_from_fn(function: &TypedFunction) -> HashMap<u64, TypeAst> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh we do this to make a note of all user given type-parameter names anywhere in the function. We call this function before we process a function definition to generate inlay-hints.
eg:
fn equals(a: value, b) { a == b } // In this case b's type would also be annotated as (value)

@omprakaash
Copy link
Contributor Author

Hey, yes I think it is better if we split this up into separate PRs. What order do you think works best? I think the order you mentioned is good(LSP Printer, variable assignment, module constant etc. ).

@lpil
Copy link
Member

lpil commented Apr 7, 2024

Sounds good to me! Whichever is easiest

@lpil
Copy link
Member

lpil commented May 20, 2024

Closing due to inactivity. Please feel free to reopen! Thank you

@lpil lpil closed this May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants