Skip to content

Commit 17c6f3d

Browse files
committed
Add CompletionRelevanceConstructorType enum and implement compute_constructor_type function
1 parent b2fc0b2 commit 17c6f3d

File tree

3 files changed

+64
-31
lines changed

3 files changed

+64
-31
lines changed

crates/ide-completion/src/item.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ pub struct CompletionRelevance {
164164
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
165165
/// This is set for type inference results
166166
pub is_definite: bool,
167-
/// Any other bonuses we want to add,
168-
pub bonus_score: u32,
167+
/// This is set for items that are constructors for the type of the impl/trait
168+
pub constructor_type: Option<CompletionRelevanceConstructorType>,
169169
}
170170

171171
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -207,6 +207,17 @@ pub enum CompletionRelevancePostfixMatch {
207207
Exact,
208208
}
209209

210+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
211+
pub enum CompletionRelevanceConstructorType {
212+
/// Returns the Self type of the impl/trait
213+
DirectConstructor,
214+
DirectConstructorWithArgs,
215+
/// Returns something that indirectly constructs the `Self` type of the impl/trait e.g. `Result<Self, ()>`, `Option<Self>`
216+
Constructor,
217+
/// Returns a possible builder for the type
218+
Builder,
219+
}
220+
210221
impl CompletionRelevance {
211222
/// Provides a relevance score. Higher values are more relevant.
212223
///
@@ -230,7 +241,7 @@ impl CompletionRelevance {
230241
is_private_editable,
231242
postfix_match,
232243
is_definite,
233-
bonus_score,
244+
constructor_type,
234245
} = self;
235246

236247
// lower rank private things
@@ -273,7 +284,15 @@ impl CompletionRelevance {
273284
score += 10;
274285
}
275286

276-
score + bonus_score
287+
score += match constructor_type {
288+
Some(CompletionRelevanceConstructorType::DirectConstructor) => 3,
289+
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs) => 2,
290+
Some(CompletionRelevanceConstructorType::Builder) => 2,
291+
Some(CompletionRelevanceConstructorType::Constructor) => 2,
292+
None => 0,
293+
};
294+
295+
score
277296
}
278297

279298
/// Returns true when the score for this threshold is above

crates/ide-completion/src/render.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use ide_db::{
1717
imports::import_assets::LocatedImport,
1818
RootDatabase, SnippetCap, SymbolKind,
1919
};
20-
use syntax::{AstNode, SmolStr, SyntaxKind, SyntaxToken, TextRange};
20+
use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
2121
use text_edit::TextEdit;
2222

2323
use crate::{
@@ -72,10 +72,6 @@ impl<'a> RenderContext<'a> {
7272
self.completion.db
7373
}
7474

75-
fn token(&self) -> &SyntaxToken {
76-
&self.completion.token
77-
}
78-
7975
fn source_range(&self) -> TextRange {
8076
self.completion.source_range()
8177
}
@@ -1180,7 +1176,7 @@ fn main() { let _: m::Spam = S$0 }
11801176
is_private_editable: false,
11811177
postfix_match: None,
11821178
is_definite: false,
1183-
bonus_score: 0,
1179+
constructor_type: None,
11841180
},
11851181
trigger_call_info: true,
11861182
},
@@ -1207,7 +1203,7 @@ fn main() { let _: m::Spam = S$0 }
12071203
is_private_editable: false,
12081204
postfix_match: None,
12091205
is_definite: false,
1210-
bonus_score: 0,
1206+
constructor_type: None,
12111207
},
12121208
trigger_call_info: true,
12131209
},
@@ -1286,7 +1282,7 @@ fn foo() { A { the$0 } }
12861282
is_private_editable: false,
12871283
postfix_match: None,
12881284
is_definite: false,
1289-
bonus_score: 0,
1285+
constructor_type: None,
12901286
},
12911287
},
12921288
]
@@ -2083,6 +2079,21 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
20832079
kind: Method,
20842080
lookup: "baz",
20852081
detail: "fn(&self) -> u32",
2082+
relevance: CompletionRelevance {
2083+
exact_name_match: false,
2084+
type_match: None,
2085+
is_local: false,
2086+
is_item_from_trait: false,
2087+
is_name_already_imported: false,
2088+
requires_import: false,
2089+
is_op_method: false,
2090+
is_private_editable: false,
2091+
postfix_match: None,
2092+
is_definite: false,
2093+
constructor_type: Some(
2094+
DirectConstructorWithArgs,
2095+
),
2096+
},
20862097
ref_match: "&@107",
20872098
},
20882099
CompletionItem {
@@ -2156,7 +2167,7 @@ fn foo() {
21562167
is_private_editable: false,
21572168
postfix_match: None,
21582169
is_definite: false,
2159-
bonus_score: 0,
2170+
constructor_type: None,
21602171
},
21612172
},
21622173
]
@@ -2205,7 +2216,9 @@ fn main() {
22052216
is_private_editable: false,
22062217
postfix_match: None,
22072218
is_definite: false,
2208-
bonus_score: 30,
2219+
constructor_type: Some(
2220+
DirectConstructor,
2221+
),
22092222
},
22102223
ref_match: "&@92",
22112224
},

crates/ide-completion/src/render/function.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ use syntax::{AstNode, SmolStr};
88

99
use crate::{
1010
context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind},
11-
item::{Builder, CompletionItem, CompletionItemKind, CompletionRelevance},
11+
item::{
12+
Builder, CompletionItem, CompletionItemKind, CompletionRelevance,
13+
CompletionRelevanceConstructorType,
14+
},
1215
render::{compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext},
1316
CallableSnippets,
1417
};
@@ -105,7 +108,7 @@ fn render(
105108
},
106109
exact_name_match: compute_exact_name_match(completion, &call),
107110
is_op_method,
108-
bonus_score: calculate_bonus(&ctx, func, db),
111+
constructor_type: compute_constructor_type(&ctx, func, db),
109112
..ctx.completion_relevance()
110113
});
111114

@@ -154,32 +157,30 @@ fn render(
154157
item
155158
}
156159

157-
/// When typing `::` of a type, the preferred order is:
158-
/// * Constructors: new like functions to be able to create the type,
159-
/// * Builder Methods,
160-
/// * Constructors that take args: Any other function that creates Self
161-
/// * Regular methods & Associated functions
162-
///
163-
fn calculate_bonus(ctx: &RenderContext<'_>, func: hir::Function, db: &dyn HirDatabase) -> u32 {
164-
if ctx.token().kind() != syntax::SyntaxKind::COLON2 || func.self_param(db).is_some() {
165-
return 0;
160+
fn compute_constructor_type(
161+
ctx: &RenderContext<'_>,
162+
func: hir::Function,
163+
db: &dyn HirDatabase,
164+
) -> Option<CompletionRelevanceConstructorType> {
165+
if func.as_assoc_item(ctx.db()).is_none() {
166+
return None;
166167
}
167168

168-
let mut bonus = 0;
169-
170169
let has_args = !func.assoc_fn_params(db).is_empty();
171170
let ret_type = func.ret_type(db);
171+
172172
if !has_args && !ret_type.is_unit() {
173173
// fn() -> A
174-
bonus += 30;
174+
Some(CompletionRelevanceConstructorType::DirectConstructor)
175175
} else if has_args && !ret_type.is_unit() {
176176
// fn(..) -> A
177-
bonus += 20;
177+
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs)
178178
} else if !has_args && ret_type.display(db).to_string().ends_with("Builder") {
179179
// -> [..]Builder
180-
bonus += 10;
180+
Some(CompletionRelevanceConstructorType::Builder)
181+
} else {
182+
None
181183
}
182-
bonus
183184
}
184185

185186
pub(super) fn add_call_parens<'b>(

0 commit comments

Comments
 (0)