aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
authoradamrk <[email protected]>2020-09-02 19:38:08 +0100
committeradamrk <[email protected]>2020-09-02 21:14:37 +0100
commitd9bb86ad7dfd17543e6e1c9ef184337f828b1027 (patch)
treec177524f22b19839d8e481a3d26b863740c23b7c /crates/ide/src
parent04fc937700105951442a9b6fa30591fb48a1e879 (diff)
Collect locals in context
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/completion/completion_context.rs10
-rw-r--r--crates/ide/src/completion/presentation.rs17
2 files changed, 15 insertions, 12 deletions
diff --git a/crates/ide/src/completion/completion_context.rs b/crates/ide/src/completion/completion_context.rs
index 47355d5dc..3ef1b97cf 100644
--- a/crates/ide/src/completion/completion_context.rs
+++ b/crates/ide/src/completion/completion_context.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use base_db::SourceDatabase; 3use base_db::SourceDatabase;
4use hir::{Semantics, SemanticsScope, Type}; 4use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
5use ide_db::RootDatabase; 5use ide_db::RootDatabase;
6use syntax::{ 6use syntax::{
7 algo::{find_covering_element, find_node_at_offset}, 7 algo::{find_covering_element, find_node_at_offset},
@@ -90,6 +90,7 @@ pub(crate) struct CompletionContext<'a> {
90 pub(super) impl_as_prev_sibling: bool, 90 pub(super) impl_as_prev_sibling: bool,
91 pub(super) is_match_arm: bool, 91 pub(super) is_match_arm: bool,
92 pub(super) has_item_list_or_source_file_parent: bool, 92 pub(super) has_item_list_or_source_file_parent: bool,
93 pub(super) locals: Vec<(String, Local)>,
93} 94}
94 95
95impl<'a> CompletionContext<'a> { 96impl<'a> CompletionContext<'a> {
@@ -118,6 +119,12 @@ impl<'a> CompletionContext<'a> {
118 original_file.syntax().token_at_offset(position.offset).left_biased()?; 119 original_file.syntax().token_at_offset(position.offset).left_biased()?;
119 let token = sema.descend_into_macros(original_token.clone()); 120 let token = sema.descend_into_macros(original_token.clone());
120 let scope = sema.scope_at_offset(&token.parent(), position.offset); 121 let scope = sema.scope_at_offset(&token.parent(), position.offset);
122 let mut locals = vec![];
123 scope.process_all_names(&mut |name, scope| {
124 if let ScopeDef::Local(local) = scope {
125 locals.push((name.to_string(), local));
126 }
127 });
121 let mut ctx = CompletionContext { 128 let mut ctx = CompletionContext {
122 sema, 129 sema,
123 scope, 130 scope,
@@ -165,6 +172,7 @@ impl<'a> CompletionContext<'a> {
165 if_is_prev: false, 172 if_is_prev: false,
166 is_match_arm: false, 173 is_match_arm: false,
167 has_item_list_or_source_file_parent: false, 174 has_item_list_or_source_file_parent: false,
175 locals,
168 }; 176 };
169 177
170 let mut original_file = original_file.syntax().clone(); 178 let mut original_file = original_file.syntax().clone();
diff --git a/crates/ide/src/completion/presentation.rs b/crates/ide/src/completion/presentation.rs
index 0c29d0be2..059fdfdc9 100644
--- a/crates/ide/src/completion/presentation.rs
+++ b/crates/ide/src/completion/presentation.rs
@@ -192,20 +192,15 @@ impl Completions {
192 local_name: Option<String>, 192 local_name: Option<String>,
193 ) { 193 ) {
194 fn add_arg(arg: &str, ty: &Type, ctx: &CompletionContext) -> String { 194 fn add_arg(arg: &str, ty: &Type, ctx: &CompletionContext) -> String {
195 let mut prefix = "";
196 if let Some(derefed_ty) = ty.remove_ref() { 195 if let Some(derefed_ty) = ty.remove_ref() {
197 ctx.scope.process_all_names(&mut |name, scope| { 196 for (name, local) in ctx.locals.iter() {
198 if prefix != "" { 197 if name == arg && local.can_unify(derefed_ty.clone(), ctx.db) {
199 return; 198 return (if ty.is_mutable_reference() { "&mut " } else { "&" }).to_string()
199 + &arg.to_string();
200 } 200 }
201 if let ScopeDef::Local(local) = scope { 201 }
202 if name.to_string() == arg && local.can_unify(derefed_ty.clone(), ctx.db) {
203 prefix = if ty.is_mutable_reference() { "&mut " } else { "&" };
204 }
205 }
206 });
207 } 202 }
208 prefix.to_string() + arg 203 arg.to_string()
209 }; 204 };
210 let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); 205 let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string());
211 let ast_node = func.source(ctx.db).value; 206 let ast_node = func.source(ctx.db).value;