add function to completion ctx

This commit is contained in:
Aleksey Kladov 2018-12-27 17:33:52 +03:00
parent 7a1ed6400d
commit e4de2c8d7f
6 changed files with 19 additions and 21 deletions

View file

@ -6,20 +6,9 @@ use crate::completion::{CompletionContext, Completions, CompletionKind, Completi
/// Complete dot accesses, i.e. fields or methods (currently only fields). /// Complete dot accesses, i.e. fields or methods (currently only fields).
pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> {
let module = if let Some(module) = &ctx.module { let (function, receiver) = match (&ctx.function, ctx.dot_receiver) {
module (Some(function), Some(receiver)) => (function, receiver),
} else { _ => return Ok(()),
return Ok(());
};
let function = if let Some(fn_def) = ctx.enclosing_fn {
hir::source_binder::function_from_module(ctx.db, module, fn_def)
} else {
return Ok(());
};
let receiver = if let Some(receiver) = ctx.dot_receiver {
receiver
} else {
return Ok(());
}; };
let infer_result = function.infer(ctx.db)?; let infer_result = function.infer(ctx.db)?;
let receiver_ty = if let Some(ty) = infer_result.type_of_node(receiver.syntax()) { let receiver_ty = if let Some(ty) = infer_result.type_of_node(receiver.syntax()) {

View file

@ -18,7 +18,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
if !ctx.is_trivial_path { if !ctx.is_trivial_path {
return; return;
} }
let fn_def = match ctx.enclosing_fn { let fn_def = match ctx.function_syntax {
Some(it) => it, Some(it) => it,
None => return, None => return,
}; };

View file

@ -14,8 +14,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) ->
Some(it) => it, Some(it) => it,
None => return Ok(()), None => return Ok(()),
}; };
if let Some(fn_def) = ctx.enclosing_fn { if let Some(function) = &ctx.function {
let function = hir::source_binder::function_from_module(ctx.db, module, fn_def);
let scopes = function.scopes(ctx.db); let scopes = function.scopes(ctx.db);
complete_fn(acc, &scopes, ctx.offset); complete_fn(acc, &scopes, ctx.offset);
} }

View file

@ -7,7 +7,7 @@ fn snippet(label: &str, snippet: &str) -> Builder {
} }
pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
if !(ctx.is_trivial_path && ctx.enclosing_fn.is_some()) { if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) {
return; return;
} }
snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);

View file

@ -22,7 +22,8 @@ pub(super) struct CompletionContext<'a> {
pub(super) offset: TextUnit, pub(super) offset: TextUnit,
pub(super) leaf: SyntaxNodeRef<'a>, pub(super) leaf: SyntaxNodeRef<'a>,
pub(super) module: Option<hir::Module>, pub(super) module: Option<hir::Module>,
pub(super) enclosing_fn: Option<ast::FnDef<'a>>, pub(super) function: Option<hir::Function>,
pub(super) function_syntax: Option<ast::FnDef<'a>>,
pub(super) is_param: bool, pub(super) is_param: bool,
/// A single-indent path, like `foo`. /// A single-indent path, like `foo`.
pub(super) is_trivial_path: bool, pub(super) is_trivial_path: bool,
@ -52,7 +53,8 @@ impl<'a> CompletionContext<'a> {
leaf, leaf,
offset: position.offset, offset: position.offset,
module, module,
enclosing_fn: None, function: None,
function_syntax: None,
is_param: false, is_param: false,
is_trivial_path: false, is_trivial_path: false,
path_prefix: None, path_prefix: None,
@ -112,11 +114,18 @@ impl<'a> CompletionContext<'a> {
_ => (), _ => (),
} }
self.enclosing_fn = self self.function_syntax = self
.leaf .leaf
.ancestors() .ancestors()
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
.find_map(ast::FnDef::cast); .find_map(ast::FnDef::cast);
match (&self.module, self.function_syntax) {
(Some(module), Some(fn_def)) => {
let function = source_binder::function_from_module(self.db, module, fn_def);
self.function = Some(function);
}
_ => (),
}
let parent = match name_ref.syntax().parent() { let parent = match name_ref.syntax().parent() {
Some(it) => it, Some(it) => it,

View file

@ -18,6 +18,7 @@ pub use self::scope::FnScopes;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct FnId(pub(crate) DefId); pub struct FnId(pub(crate) DefId);
#[derive(Debug)]
pub struct Function { pub struct Function {
pub(crate) fn_id: FnId, pub(crate) fn_id: FnId,
} }