aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/completion/complete_trait_impl.rs64
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
5use hir::{self, Docs}; 5use ra_syntax::{ast::{self, edit}, AstNode, SyntaxKind, TextRange};
6use hir::{self, Docs, HasSource};
6 7
7use ra_assists::utils::get_missing_impl_items; 8use ra_assists::utils::get_missing_impl_items;
8 9
9pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { 10pub(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
75fn 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
89fn 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)]
75mod tests { 117mod tests {
76 use crate::completion::{do_completion, CompletionItem, CompletionKind}; 118 use crate::completion::{do_completion, CompletionItem, CompletionKind};