Skip to content

Commit 49ec70b

Browse files
committed
Add CompletionRelevanceConstructorType enum and implement compute_constructor_type function
1 parent 46bca0c commit 49ec70b

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
@@ -166,8 +166,8 @@ pub struct CompletionRelevance {
166166
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
167167
/// This is set for type inference results
168168
pub is_definite: bool,
169-
/// Any other bonuses we want to add,
170-
pub bonus_score: u32,
169+
/// This is set for items that are constructors for the type of the impl/trait
170+
pub constructor_type: Option<CompletionRelevanceConstructorType>,
171171
}
172172

173173
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -209,6 +209,17 @@ pub enum CompletionRelevancePostfixMatch {
209209
Exact,
210210
}
211211

212+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
213+
pub enum CompletionRelevanceConstructorType {
214+
/// Returns the Self type of the impl/trait
215+
DirectConstructor,
216+
DirectConstructorWithArgs,
217+
/// Returns something that indirectly constructs the `Self` type of the impl/trait e.g. `Result<Self, ()>`, `Option<Self>`
218+
Constructor,
219+
/// Returns a possible builder for the type
220+
Builder,
221+
}
222+
212223
impl CompletionRelevance {
213224
/// Provides a relevance score. Higher values are more relevant.
214225
///
@@ -233,7 +244,7 @@ impl CompletionRelevance {
233244
postfix_match,
234245
is_definite,
235246
is_item_from_notable_trait,
236-
bonus_score,
247+
constructor_type,
237248
} = self;
238249

239250
// lower rank private things
@@ -279,7 +290,15 @@ impl CompletionRelevance {
279290
score += 10;
280291
}
281292

282-
score + bonus_score
293+
score += match constructor_type {
294+
Some(CompletionRelevanceConstructorType::DirectConstructor) => 3,
295+
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs) => 2,
296+
Some(CompletionRelevanceConstructorType::Builder) => 2,
297+
Some(CompletionRelevanceConstructorType::Constructor) => 2,
298+
None => 0,
299+
};
300+
301+
score
283302
}
284303

285304
/// 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
}
@@ -1181,7 +1177,7 @@ fn main() { let _: m::Spam = S$0 }
11811177
is_private_editable: false,
11821178
postfix_match: None,
11831179
is_definite: false,
1184-
bonus_score: 0,
1180+
constructor_type: None,
11851181
},
11861182
trigger_call_info: true,
11871183
},
@@ -1209,7 +1205,7 @@ fn main() { let _: m::Spam = S$0 }
12091205
is_private_editable: false,
12101206
postfix_match: None,
12111207
is_definite: false,
1212-
bonus_score: 0,
1208+
constructor_type: None,
12131209
},
12141210
trigger_call_info: true,
12151211
},
@@ -1289,7 +1285,7 @@ fn foo() { A { the$0 } }
12891285
is_private_editable: false,
12901286
postfix_match: None,
12911287
is_definite: false,
1292-
bonus_score: 0,
1288+
constructor_type: None,
12931289
},
12941290
},
12951291
]
@@ -2086,6 +2082,21 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
20862082
kind: Method,
20872083
lookup: "baz",
20882084
detail: "fn(&self) -> u32",
2085+
relevance: CompletionRelevance {
2086+
exact_name_match: false,
2087+
type_match: None,
2088+
is_local: false,
2089+
is_item_from_trait: false,
2090+
is_name_already_imported: false,
2091+
requires_import: false,
2092+
is_op_method: false,
2093+
is_private_editable: false,
2094+
postfix_match: None,
2095+
is_definite: false,
2096+
constructor_type: Some(
2097+
DirectConstructorWithArgs,
2098+
),
2099+
},
20892100
ref_match: "&@107",
20902101
},
20912102
CompletionItem {
@@ -2160,7 +2171,7 @@ fn foo() {
21602171
is_private_editable: false,
21612172
postfix_match: None,
21622173
is_definite: false,
2163-
bonus_score: 0,
2174+
constructor_type: None,
21642175
},
21652176
},
21662177
]
@@ -2209,7 +2220,9 @@ fn main() {
22092220
is_private_editable: false,
22102221
postfix_match: None,
22112222
is_definite: false,
2212-
bonus_score: 30,
2223+
constructor_type: Some(
2224+
DirectConstructor,
2225+
),
22132226
},
22142227
ref_match: "&@92",
22152228
},

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
};
@@ -109,7 +112,7 @@ fn render(
109112
exact_name_match: compute_exact_name_match(completion, &call),
110113
is_op_method,
111114
is_item_from_notable_trait,
112-
bonus_score: calculate_bonus(&ctx, func, db),
115+
constructor_type: compute_constructor_type(&ctx, func, db),
113116
..ctx.completion_relevance()
114117
});
115118

@@ -158,32 +161,30 @@ fn render(
158161
item
159162
}
160163

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

172-
let mut bonus = 0;
173-
174173
let has_args = !func.assoc_fn_params(db).is_empty();
175174
let ret_type = func.ret_type(db);
175+
176176
if !has_args && !ret_type.is_unit() {
177177
// fn() -> A
178-
bonus += 30;
178+
Some(CompletionRelevanceConstructorType::DirectConstructor)
179179
} else if has_args && !ret_type.is_unit() {
180180
// fn(..) -> A
181-
bonus += 20;
181+
Some(CompletionRelevanceConstructorType::DirectConstructorWithArgs)
182182
} else if !has_args && ret_type.display(db).to_string().ends_with("Builder") {
183183
// -> [..]Builder
184-
bonus += 10;
184+
Some(CompletionRelevanceConstructorType::Builder)
185+
} else {
186+
None
185187
}
186-
bonus
187188
}
188189

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

0 commit comments

Comments
 (0)