Skip to content

Commit

Permalink
Auto merge of #16117 - mustakimali:mo-order, r=Veykril
Browse files Browse the repository at this point in the history
feat: completion list suggests constructor like & builder methods first

When typing `MyType::` the completion items' order could be re-ordered based on how likely we want to select those:
* Constructors: `new` like functions to be able to create the type,
* Constructors that take args: Any other function that creates `Self`,
* Builder Methods: any builder methods available,
* Regular methods & associated functions (no change there)

![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/54593b91-07b3-455a-8a71-8d203d4eaf4a)

In this photo, the order is:
* `new` constructor is first
* `new_builder` second is a builder method
* `aaaanew` is a constructor that takes arguments, is third  and is irrespective of its alphabetical order among names.

---

Another Example using actix `HttpServer` shows preferring constructor without `self` arg first (the `new` method)

![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/938d3fb0-3d7a-4427-ae2f-ec02a834ccbe)

![image](https://github.com/rust-lang/rust-analyzer/assets/1546896/2c13860c-efd1-459d-b25e-df8adb61bbd0)

I've dropped my previous idea of highlighting these functions in the rustdoc (rust-lang/rust#107926)
  • Loading branch information
bors committed Feb 13, 2024
2 parents e944a27 + 2c76104 commit 3c4d642
Show file tree
Hide file tree
Showing 3 changed files with 438 additions and 4 deletions.
48 changes: 48 additions & 0 deletions crates/ide-completion/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ pub struct CompletionRelevance {
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
/// This is set for type inference results
pub is_definite: bool,
/// This is set for items that are function (associated or method)
pub function: Option<CompletionRelevanceFn>,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
Expand Down Expand Up @@ -207,6 +209,24 @@ pub enum CompletionRelevancePostfixMatch {
Exact,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct CompletionRelevanceFn {
pub has_params: bool,
pub has_self_param: bool,
pub return_type: CompletionRelevanceReturnType,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum CompletionRelevanceReturnType {
Other,
/// Returns the Self type of the impl/trait
DirectConstructor,
/// Returns something that indirectly constructs the `Self` type of the impl/trait e.g. `Result<Self, ()>`, `Option<Self>`
Constructor,
/// Returns a possible builder for the type
Builder,
}

impl CompletionRelevance {
/// Provides a relevance score. Higher values are more relevant.
///
Expand All @@ -231,6 +251,7 @@ impl CompletionRelevance {
postfix_match,
is_definite,
is_item_from_notable_trait,
function,
} = self;

// lower rank private things
Expand Down Expand Up @@ -275,6 +296,33 @@ impl CompletionRelevance {
if is_definite {
score += 10;
}

score += function
.map(|asf| {
let mut fn_score = match asf.return_type {
CompletionRelevanceReturnType::DirectConstructor => 15,
CompletionRelevanceReturnType::Builder => 10,
CompletionRelevanceReturnType::Constructor => 5,
CompletionRelevanceReturnType::Other => 0,
};

// When a fn is bumped due to return type:
// Bump Constructor or Builder methods with no arguments,
// over them tha with self arguments
if fn_score > 0 {
if !asf.has_params {
// bump associated functions
fn_score += 1;
} else if asf.has_self_param {
// downgrade methods (below Constructor)
fn_score = 1;
}
}

fn_score
})
.unwrap_or_default();

score
}

Expand Down
Loading

0 comments on commit 3c4d642

Please sign in to comment.