Skip to content

Commit 34bc0f4

Browse files
authored
Merge pull request #3506 from slyngbaek/3183
Next steps in assoc item completion #3183
2 parents d53627b + f67e6a8 commit 34bc0f4

File tree

1 file changed

+128
-16
lines changed

1 file changed

+128
-16
lines changed

crates/ra_ide/src/completion/complete_trait_impl.rs

Lines changed: 128 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
use hir::{self, Docs, HasSource};
3535
use ra_assists::utils::get_missing_impl_items;
3636
use ra_syntax::{
37-
ast::{self, edit},
37+
ast::{self, edit, ImplDef},
3838
AstNode, SyntaxKind, SyntaxNode, TextRange,
3939
};
4040
use ra_text_edit::TextEdit;
@@ -47,22 +47,22 @@ use crate::{
4747
};
4848

4949
pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) {
50-
let trigger = ctx.token.ancestors().find(|p| match p.kind() {
51-
SyntaxKind::FN_DEF
52-
| SyntaxKind::TYPE_ALIAS_DEF
53-
| SyntaxKind::CONST_DEF
54-
| SyntaxKind::BLOCK_EXPR => true,
55-
_ => false,
56-
});
57-
58-
let impl_def = trigger
59-
.as_ref()
60-
.and_then(|node| node.parent())
61-
.and_then(|node| node.parent())
62-
.and_then(ast::ImplDef::cast);
63-
64-
if let (Some(trigger), Some(impl_def)) = (trigger, impl_def) {
50+
if let Some((trigger, impl_def)) = completion_match(ctx) {
6551
match trigger.kind() {
52+
SyntaxKind::NAME_REF => {
53+
get_missing_impl_items(&ctx.sema, &impl_def).iter().for_each(|item| match item {
54+
hir::AssocItem::Function(fn_item) => {
55+
add_function_impl(&trigger, acc, ctx, &fn_item)
56+
}
57+
hir::AssocItem::TypeAlias(type_item) => {
58+
add_type_alias_impl(&trigger, acc, ctx, &type_item)
59+
}
60+
hir::AssocItem::Const(const_item) => {
61+
add_const_impl(&trigger, acc, ctx, &const_item)
62+
}
63+
})
64+
}
65+
6666
SyntaxKind::FN_DEF => {
6767
for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map(
6868
|item| match item {
@@ -101,6 +101,21 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
101101
}
102102
}
103103

104+
fn completion_match(ctx: &CompletionContext) -> Option<(SyntaxNode, ImplDef)> {
105+
let (trigger, impl_def_offset) = ctx.token.ancestors().find_map(|p| match p.kind() {
106+
SyntaxKind::FN_DEF
107+
| SyntaxKind::TYPE_ALIAS_DEF
108+
| SyntaxKind::CONST_DEF
109+
| SyntaxKind::BLOCK_EXPR => Some((p, 2)),
110+
SyntaxKind::NAME_REF => Some((p, 5)),
111+
_ => None,
112+
})?;
113+
let impl_def = (0..impl_def_offset - 1)
114+
.try_fold(trigger.parent()?, |t, _| t.parent())
115+
.and_then(ast::ImplDef::cast)?;
116+
Some((trigger, impl_def))
117+
}
118+
104119
fn add_function_impl(
105120
fn_def_node: &SyntaxNode,
106121
acc: &mut Completions,
@@ -209,6 +224,103 @@ mod tests {
209224
do_completion(code, CompletionKind::Magic)
210225
}
211226

227+
#[test]
228+
fn name_ref_function_type_const() {
229+
let completions = complete(
230+
r"
231+
trait Test {
232+
type TestType;
233+
const TEST_CONST: u16;
234+
fn test();
235+
}
236+
237+
struct T1;
238+
239+
impl Test for T1 {
240+
t<|>
241+
}
242+
",
243+
);
244+
assert_debug_snapshot!(completions, @r###"
245+
[
246+
CompletionItem {
247+
label: "const TEST_CONST: u16 = ",
248+
source_range: [209; 210),
249+
delete: [209; 210),
250+
insert: "const TEST_CONST: u16 = ",
251+
kind: Const,
252+
lookup: "TEST_CONST",
253+
},
254+
CompletionItem {
255+
label: "fn test()",
256+
source_range: [209; 210),
257+
delete: [209; 210),
258+
insert: "fn test() {}",
259+
kind: Function,
260+
lookup: "test",
261+
},
262+
CompletionItem {
263+
label: "type TestType = ",
264+
source_range: [209; 210),
265+
delete: [209; 210),
266+
insert: "type TestType = ",
267+
kind: TypeAlias,
268+
lookup: "TestType",
269+
},
270+
]
271+
"###);
272+
}
273+
274+
#[test]
275+
fn no_nested_fn_completions() {
276+
let completions = complete(
277+
r"
278+
trait Test {
279+
fn test();
280+
fn test2();
281+
}
282+
283+
struct T1;
284+
285+
impl Test for T1 {
286+
fn test() {
287+
t<|>
288+
}
289+
}
290+
",
291+
);
292+
assert_debug_snapshot!(completions, @r###"[]"###);
293+
}
294+
295+
#[test]
296+
fn name_ref_single_function() {
297+
let completions = complete(
298+
r"
299+
trait Test {
300+
fn test();
301+
}
302+
303+
struct T1;
304+
305+
impl Test for T1 {
306+
t<|>
307+
}
308+
",
309+
);
310+
assert_debug_snapshot!(completions, @r###"
311+
[
312+
CompletionItem {
313+
label: "fn test()",
314+
source_range: [139; 140),
315+
delete: [139; 140),
316+
insert: "fn test() {}",
317+
kind: Function,
318+
lookup: "test",
319+
},
320+
]
321+
"###);
322+
}
323+
212324
#[test]
213325
fn single_function() {
214326
let completions = complete(

0 commit comments

Comments
 (0)