diff options
author | Kevin DeLorey <[email protected]> | 2020-01-23 04:25:41 +0000 |
---|---|---|
committer | Kevin DeLorey <[email protected]> | 2020-01-23 04:34:00 +0000 |
commit | e3cda83f90a5e64ccf288438466e6c447df253a8 (patch) | |
tree | 78e4d56d4195e42bc68c21f8e6a91b5671a79c6d /crates/ra_ide/src/completion/complete_impl_fn.rs | |
parent | 2fb8a461225800ca605a9f2e997cd5e82fb37574 (diff) |
Added basic support for completing `fn` for trait impl.
Diffstat (limited to 'crates/ra_ide/src/completion/complete_impl_fn.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_impl_fn.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/crates/ra_ide/src/completion/complete_impl_fn.rs b/crates/ra_ide/src/completion/complete_impl_fn.rs new file mode 100644 index 000000000..6d464cc1f --- /dev/null +++ b/crates/ra_ide/src/completion/complete_impl_fn.rs | |||
@@ -0,0 +1,80 @@ | |||
1 | |||
2 | use crate::completion::{CompletionContext, Completions}; | ||
3 | |||
4 | use hir::{ self, db::HirDatabase, HasSource }; | ||
5 | |||
6 | use ra_syntax::{ ast, ast::AstNode }; | ||
7 | |||
8 | pub(crate) fn complete_impl_fn(acc: &mut Completions, ctx: &CompletionContext) { | ||
9 | let impl_trait = ast::ItemList::cast(ctx.token.parent()) | ||
10 | .and_then(|item_list| item_list.syntax().parent()) | ||
11 | .and_then(|item_list_parent| ast::ImplBlock::cast(item_list_parent)) | ||
12 | .and_then(|impl_block| resolve_target_trait(ctx.db, &ctx.analyzer, &impl_block)); | ||
13 | |||
14 | if let Some(x) = &impl_trait { | ||
15 | for trait_item in x.0.items(ctx.db) { | ||
16 | match trait_item { | ||
17 | hir::AssocItem::Function(f) => acc.add_function_impl(ctx, f), | ||
18 | _ => {} | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 | |||
24 | fn resolve_target_trait( | ||
25 | db: &impl HirDatabase, | ||
26 | analyzer: &hir::SourceAnalyzer, | ||
27 | impl_block: &ast::ImplBlock | ||
28 | ) -> Option<(hir::Trait, ast::TraitDef)> { | ||
29 | let ast_path = impl_block | ||
30 | .target_trait() | ||
31 | .map(|it| it.syntax().clone()) | ||
32 | .and_then(ast::PathType::cast)? | ||
33 | .path()?; | ||
34 | |||
35 | match analyzer.resolve_path(db, &ast_path) { | ||
36 | Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => { | ||
37 | Some((def, def.source(db).value)) | ||
38 | } | ||
39 | _ => None, | ||
40 | } | ||
41 | } | ||
42 | |||
43 | #[cfg(test)] | ||
44 | mod tests { | ||
45 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | ||
46 | use insta::assert_debug_snapshot; | ||
47 | |||
48 | fn complete(code: &str) -> Vec<CompletionItem> { | ||
49 | do_completion(code, CompletionKind::Reference) | ||
50 | } | ||
51 | |||
52 | #[test] | ||
53 | fn single_function() { | ||
54 | let completions = complete( | ||
55 | r" | ||
56 | trait Test { | ||
57 | fn foo(); | ||
58 | } | ||
59 | |||
60 | struct T1; | ||
61 | |||
62 | impl Test for T1 { | ||
63 | <|> | ||
64 | } | ||
65 | ", | ||
66 | ); | ||
67 | assert_debug_snapshot!(completions, @r###" | ||
68 | [ | ||
69 | CompletionItem { | ||
70 | label: "fn foo()", | ||
71 | source_range: [138; 138), | ||
72 | delete: [138; 138), | ||
73 | insert: "fn foo() { $0 }", | ||
74 | kind: Function, | ||
75 | lookup: "foo", | ||
76 | }, | ||
77 | ] | ||
78 | "###); | ||
79 | } | ||
80 | } \ No newline at end of file | ||