From ba0072401c3b8b6c9391428672bd91055150c8ee Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 21 Dec 2018 15:46:01 +0300 Subject: use Completions to collect completions --- crates/ra_analysis/src/completion.rs | 19 ++++++++----- .../ra_analysis/src/completion/completion_item.rs | 13 +++++++-- .../src/completion/reference_completion.rs | 32 +++++++++++----------- 3 files changed, 38 insertions(+), 26 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 222b6854c..074033ad8 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs @@ -15,7 +15,8 @@ use hir::source_binder; use crate::{ db, - Cancelable, FilePosition + Cancelable, FilePosition, + completion::completion_item::Completions, }; pub use crate::completion::completion_item::{CompletionItem, InsertText}; @@ -33,15 +34,15 @@ pub(crate) fn completions( let module = ctry!(source_binder::module_from_position(db, position)?); - let mut res = Vec::new(); + let mut acc = Completions::default(); let mut has_completions = false; // First, let's try to complete a reference to some declaration. if let Some(name_ref) = find_node_at_offset::(file.syntax(), position.offset) { has_completions = true; - reference_completion::completions(&mut res, db, &module, &file, name_ref)?; + reference_completion::completions(&mut acc, db, &module, &file, name_ref)?; // special case, `trait T { fn foo(i_am_a_name_ref) {} }` if is_node::(name_ref.syntax()) { - param_completions(&mut res, name_ref.syntax()); + param_completions(&mut acc, name_ref.syntax()); } } @@ -49,10 +50,14 @@ pub(crate) fn completions( if let Some(name) = find_node_at_offset::(file.syntax(), position.offset) { if is_node::(name.syntax()) { has_completions = true; - param_completions(&mut res, name.syntax()); + param_completions(&mut acc, name.syntax()); } } - let res = if has_completions { Some(res) } else { None }; + let res = if has_completions { + Some(acc.into()) + } else { + None + }; Ok(res) } @@ -60,7 +65,7 @@ pub(crate) fn completions( /// functions in a file have a `spam: &mut Spam` parameter, a completion with /// `spam: &mut Spam` insert text/label and `spam` lookup string will be /// suggested. -fn param_completions(acc: &mut Vec, ctx: SyntaxNodeRef) { +fn param_completions(acc: &mut Completions, ctx: SyntaxNodeRef) { let mut params = FxHashMap::default(); for node in ctx.ancestors() { let _ = visitor_ctx(&mut params) diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs index 445d6bf41..8aa9da005 100644 --- a/crates/ra_analysis/src/completion/completion_item.rs +++ b/crates/ra_analysis/src/completion/completion_item.rs @@ -53,8 +53,8 @@ pub(crate) struct Builder { } impl Builder { - pub fn add_to(self, acc: &mut Vec) { - acc.push(self.build()) + pub fn add_to(self, acc: &mut Completions) { + acc.add(self.build()) } pub fn build(self) -> CompletionItem { @@ -81,7 +81,7 @@ impl Into for Builder { } /// Represents an in-progress set of completions being built. -#[derive(Debug)] +#[derive(Debug, Default)] pub(crate) struct Completions { buf: Vec, } @@ -90,6 +90,13 @@ impl Completions { pub(crate) fn add(&mut self, item: impl Into) { self.buf.push(item.into()) } + pub(crate) fn add_all(&mut self, items: I) + where + I: IntoIterator, + I::Item: Into, + { + items.into_iter().for_each(|item| self.add(item.into())) + } } impl Into> for Completions { diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index f9f01a642..c578e9e8b 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -13,12 +13,12 @@ use hir::{ use crate::{ db::RootDatabase, - completion::CompletionItem, + completion::{CompletionItem, Completions}, Cancelable }; pub(super) fn completions( - acc: &mut Vec, + acc: &mut Completions, db: &RootDatabase, module: &hir::Module, file: &SourceFileNode, @@ -117,7 +117,7 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option { None } -fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec) { +fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Completions) { let mut shadowed = FxHashSet::default(); scopes .scope_chain(name_ref.syntax()) @@ -130,7 +130,7 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec, + acc: &mut Completions, db: &RootDatabase, module: &hir::Module, mut path: Path, @@ -154,7 +154,7 @@ fn complete_path( Ok(()) } -fn complete_mod_item_snippets(acc: &mut Vec) { +fn complete_mod_item_snippets(acc: &mut Completions) { CompletionItem::new("Test function") .lookup_by("tfn") .snippet( @@ -174,26 +174,26 @@ fn complete_expr_keywords( file: &SourceFileNode, fn_def: ast::FnDef, name_ref: ast::NameRef, - acc: &mut Vec, + acc: &mut Completions, ) { - acc.push(keyword("if", "if $0 {}")); - acc.push(keyword("match", "match $0 {}")); - acc.push(keyword("while", "while $0 {}")); - acc.push(keyword("loop", "loop {$0}")); + acc.add(keyword("if", "if $0 {}")); + acc.add(keyword("match", "match $0 {}")); + acc.add(keyword("while", "while $0 {}")); + acc.add(keyword("loop", "loop {$0}")); if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { if let Some(if_expr) = find_node_at_offset::(file.syntax(), off) { if if_expr.syntax().range().end() < name_ref.syntax().range().start() { - acc.push(keyword("else", "else {$0}")); - acc.push(keyword("else if", "else if $0 {}")); + acc.add(keyword("else", "else {$0}")); + acc.add(keyword("else if", "else if $0 {}")); } } } if is_in_loop_body(name_ref) { - acc.push(keyword("continue", "continue")); - acc.push(keyword("break", "break")); + acc.add(keyword("continue", "continue")); + acc.add(keyword("break", "break")); } - acc.extend(complete_return(fn_def, name_ref)); + acc.add_all(complete_return(fn_def, name_ref)); } fn is_in_loop_body(name_ref: ast::NameRef) -> bool { @@ -252,7 +252,7 @@ fn keyword(kw: &str, snippet: &str) -> CompletionItem { CompletionItem::new(kw).snippet(snippet).build() } -fn complete_expr_snippets(acc: &mut Vec) { +fn complete_expr_snippets(acc: &mut Completions) { CompletionItem::new("pd") .snippet("eprintln!(\"$0 = {:?}\", $0);") .add_to(acc); -- cgit v1.2.3