Collect locals in context
This commit is contained in:
parent
04fc937700
commit
d9bb86ad7d
@ -1,7 +1,7 @@
|
|||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use base_db::SourceDatabase;
|
use base_db::SourceDatabase;
|
||||||
use hir::{Semantics, SemanticsScope, Type};
|
use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
|
||||||
use ide_db::RootDatabase;
|
use ide_db::RootDatabase;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::{find_covering_element, find_node_at_offset},
|
algo::{find_covering_element, find_node_at_offset},
|
||||||
@ -90,6 +90,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||||||
pub(super) impl_as_prev_sibling: bool,
|
pub(super) impl_as_prev_sibling: bool,
|
||||||
pub(super) is_match_arm: bool,
|
pub(super) is_match_arm: bool,
|
||||||
pub(super) has_item_list_or_source_file_parent: bool,
|
pub(super) has_item_list_or_source_file_parent: bool,
|
||||||
|
pub(super) locals: Vec<(String, Local)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompletionContext<'a> {
|
impl<'a> CompletionContext<'a> {
|
||||||
@ -118,6 +119,12 @@ impl<'a> CompletionContext<'a> {
|
|||||||
original_file.syntax().token_at_offset(position.offset).left_biased()?;
|
original_file.syntax().token_at_offset(position.offset).left_biased()?;
|
||||||
let token = sema.descend_into_macros(original_token.clone());
|
let token = sema.descend_into_macros(original_token.clone());
|
||||||
let scope = sema.scope_at_offset(&token.parent(), position.offset);
|
let scope = sema.scope_at_offset(&token.parent(), position.offset);
|
||||||
|
let mut locals = vec![];
|
||||||
|
scope.process_all_names(&mut |name, scope| {
|
||||||
|
if let ScopeDef::Local(local) = scope {
|
||||||
|
locals.push((name.to_string(), local));
|
||||||
|
}
|
||||||
|
});
|
||||||
let mut ctx = CompletionContext {
|
let mut ctx = CompletionContext {
|
||||||
sema,
|
sema,
|
||||||
scope,
|
scope,
|
||||||
@ -165,6 +172,7 @@ impl<'a> CompletionContext<'a> {
|
|||||||
if_is_prev: false,
|
if_is_prev: false,
|
||||||
is_match_arm: false,
|
is_match_arm: false,
|
||||||
has_item_list_or_source_file_parent: false,
|
has_item_list_or_source_file_parent: false,
|
||||||
|
locals,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut original_file = original_file.syntax().clone();
|
let mut original_file = original_file.syntax().clone();
|
||||||
|
@ -192,20 +192,15 @@ impl Completions {
|
|||||||
local_name: Option<String>,
|
local_name: Option<String>,
|
||||||
) {
|
) {
|
||||||
fn add_arg(arg: &str, ty: &Type, ctx: &CompletionContext) -> String {
|
fn add_arg(arg: &str, ty: &Type, ctx: &CompletionContext) -> String {
|
||||||
let mut prefix = "";
|
|
||||||
if let Some(derefed_ty) = ty.remove_ref() {
|
if let Some(derefed_ty) = ty.remove_ref() {
|
||||||
ctx.scope.process_all_names(&mut |name, scope| {
|
for (name, local) in ctx.locals.iter() {
|
||||||
if prefix != "" {
|
if name == arg && local.can_unify(derefed_ty.clone(), ctx.db) {
|
||||||
return;
|
return (if ty.is_mutable_reference() { "&mut " } else { "&" }).to_string()
|
||||||
|
+ &arg.to_string();
|
||||||
}
|
}
|
||||||
if let ScopeDef::Local(local) = scope {
|
}
|
||||||
if name.to_string() == arg && local.can_unify(derefed_ty.clone(), ctx.db) {
|
|
||||||
prefix = if ty.is_mutable_reference() { "&mut " } else { "&" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
prefix.to_string() + arg
|
arg.to_string()
|
||||||
};
|
};
|
||||||
let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string());
|
let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string());
|
||||||
let ast_node = func.source(ctx.db).value;
|
let ast_node = func.source(ctx.db).value;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user