diff options
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r-- | crates/ra_ide/src/completion/complete_trait_impl.rs | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs index e2854ee97..cb15da647 100644 --- a/crates/ra_ide/src/completion/complete_trait_impl.rs +++ b/crates/ra_ide/src/completion/complete_trait_impl.rs | |||
@@ -2,25 +2,26 @@ use crate::completion::{ | |||
2 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 2 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, |
3 | }; | 3 | }; |
4 | 4 | ||
5 | use hir::{self, Docs}; | 5 | use ra_syntax::{ast::{self, edit}, AstNode, SyntaxKind, TextRange}; |
6 | use hir::{self, Docs, HasSource}; | ||
6 | 7 | ||
7 | use ra_assists::utils::get_missing_impl_items; | 8 | use ra_assists::utils::get_missing_impl_items; |
8 | 9 | ||
9 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { | 10 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { |
10 | let impl_block = ctx.impl_block.as_ref(); | ||
11 | let item_list = impl_block.and_then(|i| i.item_list()); | ||
12 | 11 | ||
13 | if item_list.is_none() || impl_block.is_none() || ctx.function_syntax.is_some() { | 12 | // it is possible to have a parent `fn` and `impl` block. Ignore completion |
13 | // attempts from within a `fn` block. | ||
14 | if ctx.function_syntax.is_some() { | ||
14 | return; | 15 | return; |
15 | } | 16 | } |
16 | 17 | ||
17 | let impl_block = impl_block.unwrap(); | 18 | if let Some(ref impl_block) = ctx.impl_block { |
18 | 19 | for item in get_missing_impl_items(ctx.db, &ctx.analyzer, impl_block) { | |
19 | for item in get_missing_impl_items(ctx.db, &ctx.analyzer, impl_block) { | 20 | match item { |
20 | match item { | 21 | hir::AssocItem::Function(f) => add_function_impl(acc, ctx, &f), |
21 | hir::AssocItem::Function(f) => add_function_impl(acc, ctx, &f), | 22 | hir::AssocItem::TypeAlias(t) => add_type_alias_impl(acc, ctx, &t), |
22 | hir::AssocItem::TypeAlias(t) => add_type_alias_impl(acc, ctx, &t), | 23 | hir::AssocItem::Const(c) => add_const_impl(acc, ctx, &c), |
23 | _ => {} | 24 | } |
24 | } | 25 | } |
25 | } | 26 | } |
26 | } | 27 | } |
@@ -71,6 +72,47 @@ fn add_type_alias_impl( | |||
71 | .add_to(acc); | 72 | .add_to(acc); |
72 | } | 73 | } |
73 | 74 | ||
75 | fn add_const_impl( | ||
76 | acc: &mut Completions, | ||
77 | ctx: &CompletionContext, | ||
78 | const_: &hir::Const, | ||
79 | ) { | ||
80 | let snippet = make_const_compl_syntax(&const_.source(ctx.db).value); | ||
81 | |||
82 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()) | ||
83 | .insert_text(snippet) | ||
84 | .kind(CompletionItemKind::Const) | ||
85 | .set_documentation(const_.docs(ctx.db)) | ||
86 | .add_to(acc); | ||
87 | } | ||
88 | |||
89 | fn make_const_compl_syntax(const_: &ast::ConstDef) -> String { | ||
90 | let const_ = edit::strip_attrs_and_docs(const_); | ||
91 | |||
92 | let const_start = const_.syntax().text_range().start(); | ||
93 | let const_end = const_.syntax().text_range().end(); | ||
94 | |||
95 | let start = const_ | ||
96 | .syntax() | ||
97 | .first_child_or_token() | ||
98 | .map_or( | ||
99 | const_start, | ||
100 | |f| f.text_range().start()); | ||
101 | |||
102 | let end = const_ | ||
103 | .syntax() | ||
104 | .children_with_tokens() | ||
105 | .find(|s| s.kind() == SyntaxKind::SEMI || s.kind() == SyntaxKind::EQ) | ||
106 | .map_or(const_end, |f| f.text_range().start()); | ||
107 | |||
108 | let len = end - start; | ||
109 | let range = TextRange::from_to(0.into(), len); | ||
110 | |||
111 | let syntax = const_.syntax().text().slice(range).to_string(); | ||
112 | |||
113 | format!("{} = ", syntax.trim_end()) | ||
114 | } | ||
115 | |||
74 | #[cfg(test)] | 116 | #[cfg(test)] |
75 | mod tests { | 117 | mod tests { |
76 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 118 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; |