Skip to content

Commit 601f89f

Browse files
bors[bot]matklad
andauthored
Merge #4114
4114: Refactor completion sorting r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 5eb51c1 + 88d243c commit 601f89f

File tree

10 files changed

+329
-333
lines changed

10 files changed

+329
-333
lines changed

crates/ra_ide/src/call_info.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,24 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
1919
call_info_for_token(&sema, token)
2020
}
2121

22-
pub(crate) fn call_info_for_token(
23-
sema: &Semantics<RootDatabase>,
24-
token: SyntaxToken,
25-
) -> Option<CallInfo> {
22+
#[derive(Debug)]
23+
pub(crate) struct ActiveParameter {
24+
/// FIXME: should be `Type` and `Name
25+
pub(crate) ty: String,
26+
pub(crate) name: String,
27+
}
28+
29+
impl ActiveParameter {
30+
pub(crate) fn at(db: &RootDatabase, position: FilePosition) -> Option<Self> {
31+
call_info(db, position)?.into_active_parameter()
32+
}
33+
34+
pub(crate) fn at_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Option<Self> {
35+
call_info_for_token(sema, token)?.into_active_parameter()
36+
}
37+
}
38+
39+
fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Option<CallInfo> {
2640
// Find the calling expression and it's NameRef
2741
let calling_node = FnCallNode::with_node(&token.parent())?;
2842

@@ -160,6 +174,14 @@ impl FnCallNode {
160174
}
161175

162176
impl CallInfo {
177+
fn into_active_parameter(self) -> Option<ActiveParameter> {
178+
let idx = self.active_parameter?;
179+
let ty = self.signature.parameter_types.get(idx)?.clone();
180+
let name = self.signature.parameter_names.get(idx)?.clone();
181+
let res = ActiveParameter { ty, name };
182+
Some(res)
183+
}
184+
163185
fn with_fn(db: &RootDatabase, function: hir::Function) -> Self {
164186
let signature = FunctionSignature::from_hir(db, function);
165187

crates/ra_ide/src/completion/complete_dot.rs

Lines changed: 0 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -105,237 +105,6 @@ mod tests {
105105
);
106106
}
107107

108-
#[test]
109-
fn test_struct_field_completion_in_func_call() {
110-
assert_debug_snapshot!(
111-
do_ref_completion(
112-
r"
113-
struct A { another_field: i64, the_field: u32, my_string: String }
114-
fn test(my_param: u32) -> u32 { my_param }
115-
fn foo(a: A) {
116-
test(a.<|>)
117-
}
118-
",
119-
),
120-
@r###"
121-
[
122-
CompletionItem {
123-
label: "another_field",
124-
source_range: [201; 201),
125-
delete: [201; 201),
126-
insert: "another_field",
127-
kind: Field,
128-
detail: "i64",
129-
},
130-
CompletionItem {
131-
label: "my_string",
132-
source_range: [201; 201),
133-
delete: [201; 201),
134-
insert: "my_string",
135-
kind: Field,
136-
detail: "{unknown}",
137-
},
138-
CompletionItem {
139-
label: "the_field",
140-
source_range: [201; 201),
141-
delete: [201; 201),
142-
insert: "the_field",
143-
kind: Field,
144-
detail: "u32",
145-
score: TypeMatch,
146-
},
147-
]
148-
"###
149-
);
150-
}
151-
152-
#[test]
153-
fn test_struct_field_completion_in_func_call_with_type_and_name() {
154-
assert_debug_snapshot!(
155-
do_ref_completion(
156-
r"
157-
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
158-
fn test(the_field: u32) -> u32 { the_field }
159-
fn foo(a: A) {
160-
test(a.<|>)
161-
}
162-
",
163-
),
164-
@r###"
165-
[
166-
CompletionItem {
167-
label: "another_field",
168-
source_range: [208; 208),
169-
delete: [208; 208),
170-
insert: "another_field",
171-
kind: Field,
172-
detail: "i64",
173-
},
174-
CompletionItem {
175-
label: "another_good_type",
176-
source_range: [208; 208),
177-
delete: [208; 208),
178-
insert: "another_good_type",
179-
kind: Field,
180-
detail: "u32",
181-
score: TypeMatch,
182-
},
183-
CompletionItem {
184-
label: "the_field",
185-
source_range: [208; 208),
186-
delete: [208; 208),
187-
insert: "the_field",
188-
kind: Field,
189-
detail: "u32",
190-
score: TypeAndNameMatch,
191-
},
192-
]
193-
"###
194-
);
195-
}
196-
197-
#[test]
198-
fn test_struct_field_completion_in_record_lit() {
199-
assert_debug_snapshot!(
200-
do_ref_completion(
201-
r"
202-
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
203-
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
204-
fn foo(a: A) {
205-
let b = B {
206-
the_field: a.<|>
207-
};
208-
}
209-
",
210-
),
211-
@r###"
212-
[
213-
CompletionItem {
214-
label: "another_field",
215-
source_range: [270; 270),
216-
delete: [270; 270),
217-
insert: "another_field",
218-
kind: Field,
219-
detail: "i64",
220-
},
221-
CompletionItem {
222-
label: "another_good_type",
223-
source_range: [270; 270),
224-
delete: [270; 270),
225-
insert: "another_good_type",
226-
kind: Field,
227-
detail: "u32",
228-
score: TypeMatch,
229-
},
230-
CompletionItem {
231-
label: "the_field",
232-
source_range: [270; 270),
233-
delete: [270; 270),
234-
insert: "the_field",
235-
kind: Field,
236-
detail: "u32",
237-
score: TypeAndNameMatch,
238-
},
239-
]
240-
"###
241-
);
242-
}
243-
244-
#[test]
245-
fn test_struct_field_completion_in_record_lit_and_fn_call() {
246-
assert_debug_snapshot!(
247-
do_ref_completion(
248-
r"
249-
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
250-
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
251-
fn test(the_field: i64) -> i64 { the_field }
252-
fn foo(a: A) {
253-
let b = B {
254-
the_field: test(a.<|>)
255-
};
256-
}
257-
",
258-
),
259-
@r###"
260-
[
261-
CompletionItem {
262-
label: "another_field",
263-
source_range: [336; 336),
264-
delete: [336; 336),
265-
insert: "another_field",
266-
kind: Field,
267-
detail: "i64",
268-
score: TypeMatch,
269-
},
270-
CompletionItem {
271-
label: "another_good_type",
272-
source_range: [336; 336),
273-
delete: [336; 336),
274-
insert: "another_good_type",
275-
kind: Field,
276-
detail: "u32",
277-
},
278-
CompletionItem {
279-
label: "the_field",
280-
source_range: [336; 336),
281-
delete: [336; 336),
282-
insert: "the_field",
283-
kind: Field,
284-
detail: "u32",
285-
},
286-
]
287-
"###
288-
);
289-
}
290-
291-
#[test]
292-
fn test_struct_field_completion_in_fn_call_and_record_lit() {
293-
assert_debug_snapshot!(
294-
do_ref_completion(
295-
r"
296-
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
297-
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
298-
fn test(the_field: i64) -> i64 { the_field }
299-
fn foo(a: A) {
300-
test(B {
301-
the_field: a.<|>
302-
});
303-
}
304-
",
305-
),
306-
@r###"
307-
[
308-
CompletionItem {
309-
label: "another_field",
310-
source_range: [328; 328),
311-
delete: [328; 328),
312-
insert: "another_field",
313-
kind: Field,
314-
detail: "i64",
315-
},
316-
CompletionItem {
317-
label: "another_good_type",
318-
source_range: [328; 328),
319-
delete: [328; 328),
320-
insert: "another_good_type",
321-
kind: Field,
322-
detail: "u32",
323-
score: TypeMatch,
324-
},
325-
CompletionItem {
326-
label: "the_field",
327-
source_range: [328; 328),
328-
delete: [328; 328),
329-
insert: "the_field",
330-
kind: Field,
331-
detail: "u32",
332-
score: TypeAndNameMatch,
333-
},
334-
]
335-
"###
336-
);
337-
}
338-
339108
#[test]
340109
fn test_struct_field_completion_self() {
341110
assert_debug_snapshot!(

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ra_syntax::{
1111
};
1212
use ra_text_edit::AtomTextEdit;
1313

14-
use crate::{completion::CompletionConfig, FilePosition};
14+
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
1515

1616
/// `CompletionContext` is created early during completion to figure out, where
1717
/// exactly is the cursor, syntax-wise.
@@ -21,7 +21,6 @@ pub(crate) struct CompletionContext<'a> {
2121
pub(super) db: &'a RootDatabase,
2222
pub(super) config: &'a CompletionConfig,
2323
pub(super) offset: TextUnit,
24-
pub(super) file_position: FilePosition,
2524
/// The token before the cursor, in the original file.
2625
pub(super) original_token: SyntaxToken,
2726
/// The token before the cursor, in the macro-expanded file.
@@ -34,6 +33,8 @@ pub(crate) struct CompletionContext<'a> {
3433
pub(super) record_pat_syntax: Option<ast::RecordPat>,
3534
pub(super) record_field_syntax: Option<ast::RecordField>,
3635
pub(super) impl_def: Option<ast::ImplDef>,
36+
/// FIXME: `ActiveParameter` is string-based, which is very wrong
37+
pub(super) active_parameter: Option<ActiveParameter>,
3738
pub(super) is_param: bool,
3839
/// If a name-binding or reference to a const in a pattern.
3940
/// Irrefutable patterns (like let) are excluded.
@@ -90,7 +91,6 @@ impl<'a> CompletionContext<'a> {
9091
original_token,
9192
token,
9293
offset: position.offset,
93-
file_position: position,
9494
krate,
9595
name_ref_syntax: None,
9696
function_syntax: None,
@@ -99,6 +99,7 @@ impl<'a> CompletionContext<'a> {
9999
record_pat_syntax: None,
100100
record_field_syntax: None,
101101
impl_def: None,
102+
active_parameter: ActiveParameter::at(db, position),
102103
is_param: false,
103104
is_pat_binding_or_const: false,
104105
is_trivial_path: false,

crates/ra_ide/src/completion/completion_item.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct CompletionItem {
5252
/// after completion.
5353
trigger_call_info: bool,
5454

55-
/// Score is usefull to pre select or display in better order completion items
55+
/// Score is useful to pre select or display in better order completion items
5656
score: Option<CompletionScore>,
5757
}
5858

@@ -93,6 +93,14 @@ impl fmt::Debug for CompletionItem {
9393
}
9494
}
9595

96+
#[derive(Debug, Clone, Copy)]
97+
pub enum CompletionScore {
98+
/// If only type match
99+
TypeMatch,
100+
/// If type and name match
101+
TypeAndNameMatch,
102+
}
103+
96104
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97105
pub enum CompletionItemKind {
98106
Snippet,
@@ -182,7 +190,7 @@ impl CompletionItem {
182190
}
183191
/// What string is used for filtering.
184192
pub fn lookup(&self) -> &str {
185-
self.lookup.as_deref().unwrap_or_else(|| self.label())
193+
self.lookup.as_deref().unwrap_or(&self.label)
186194
}
187195

188196
pub fn kind(&self) -> Option<CompletionItemKind> {
@@ -194,11 +202,7 @@ impl CompletionItem {
194202
}
195203

196204
pub fn score(&self) -> Option<CompletionScore> {
197-
self.score.clone()
198-
}
199-
200-
pub fn set_score(&mut self, score: CompletionScore) {
201-
self.score = Some(score);
205+
self.score
202206
}
203207

204208
pub fn trigger_call_info(&self) -> bool {
@@ -302,7 +306,6 @@ impl Builder {
302306
self.deprecated = Some(deprecated);
303307
self
304308
}
305-
#[allow(unused)]
306309
pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder {
307310
self.score = Some(score);
308311
self
@@ -319,14 +322,6 @@ impl<'a> Into<CompletionItem> for Builder {
319322
}
320323
}
321324

322-
#[derive(Debug, Clone)]
323-
pub enum CompletionScore {
324-
/// If only type match
325-
TypeMatch,
326-
/// If type and name match
327-
TypeAndNameMatch,
328-
}
329-
330325
/// Represents an in-progress set of completions being built.
331326
#[derive(Debug, Default)]
332327
pub(crate) struct Completions {

0 commit comments

Comments
 (0)