From e4de2c8d7f5ced7a24d0a76213ab113218c99d30 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 27 Dec 2018 17:33:52 +0300 Subject: add function to completion ctx --- crates/ra_analysis/src/completion/complete_dot.rs | 17 +++-------------- crates/ra_analysis/src/completion/complete_keyword.rs | 2 +- crates/ra_analysis/src/completion/complete_scope.rs | 3 +-- crates/ra_analysis/src/completion/complete_snippet.rs | 2 +- crates/ra_analysis/src/completion/completion_context.rs | 15 ++++++++++++--- crates/ra_hir/src/function.rs | 1 + 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/crates/ra_analysis/src/completion/complete_dot.rs b/crates/ra_analysis/src/completion/complete_dot.rs index 93d657576..f24835d17 100644 --- a/crates/ra_analysis/src/completion/complete_dot.rs +++ b/crates/ra_analysis/src/completion/complete_dot.rs @@ -6,20 +6,9 @@ use crate::completion::{CompletionContext, Completions, CompletionKind, Completi /// Complete dot accesses, i.e. fields or methods (currently only fields). pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { - let module = if let Some(module) = &ctx.module { - module - } else { - 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 (function, receiver) = match (&ctx.function, ctx.dot_receiver) { + (Some(function), Some(receiver)) => (function, receiver), + _ => return Ok(()), }; let infer_result = function.infer(ctx.db)?; let receiver_ty = if let Some(ty) = infer_result.type_of_node(receiver.syntax()) { diff --git a/crates/ra_analysis/src/completion/complete_keyword.rs b/crates/ra_analysis/src/completion/complete_keyword.rs index 5427fcb11..d1e0a20a8 100644 --- a/crates/ra_analysis/src/completion/complete_keyword.rs +++ b/crates/ra_analysis/src/completion/complete_keyword.rs @@ -18,7 +18,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte if !ctx.is_trivial_path { return; } - let fn_def = match ctx.enclosing_fn { + let fn_def = match ctx.function_syntax { Some(it) => it, None => return, }; diff --git a/crates/ra_analysis/src/completion/complete_scope.rs b/crates/ra_analysis/src/completion/complete_scope.rs index a57670e3b..514fd2f88 100644 --- a/crates/ra_analysis/src/completion/complete_scope.rs +++ b/crates/ra_analysis/src/completion/complete_scope.rs @@ -14,8 +14,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> Some(it) => it, None => return Ok(()), }; - if let Some(fn_def) = ctx.enclosing_fn { - let function = hir::source_binder::function_from_module(ctx.db, module, fn_def); + if let Some(function) = &ctx.function { let scopes = function.scopes(ctx.db); complete_fn(acc, &scopes, ctx.offset); } diff --git a/crates/ra_analysis/src/completion/complete_snippet.rs b/crates/ra_analysis/src/completion/complete_snippet.rs index fb9da0a4f..a495751dd 100644 --- a/crates/ra_analysis/src/completion/complete_snippet.rs +++ b/crates/ra_analysis/src/completion/complete_snippet.rs @@ -7,7 +7,7 @@ fn snippet(label: &str, snippet: &str) -> Builder { } 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; } snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); diff --git a/crates/ra_analysis/src/completion/completion_context.rs b/crates/ra_analysis/src/completion/completion_context.rs index 978772fd4..71bf7fd32 100644 --- a/crates/ra_analysis/src/completion/completion_context.rs +++ b/crates/ra_analysis/src/completion/completion_context.rs @@ -22,7 +22,8 @@ pub(super) struct CompletionContext<'a> { pub(super) offset: TextUnit, pub(super) leaf: SyntaxNodeRef<'a>, pub(super) module: Option, - pub(super) enclosing_fn: Option>, + pub(super) function: Option, + pub(super) function_syntax: Option>, pub(super) is_param: bool, /// A single-indent path, like `foo`. pub(super) is_trivial_path: bool, @@ -52,7 +53,8 @@ impl<'a> CompletionContext<'a> { leaf, offset: position.offset, module, - enclosing_fn: None, + function: None, + function_syntax: None, is_param: false, is_trivial_path: false, path_prefix: None, @@ -112,11 +114,18 @@ impl<'a> CompletionContext<'a> { _ => (), } - self.enclosing_fn = self + self.function_syntax = self .leaf .ancestors() .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) .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() { Some(it) => it, diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs index 01f0f3a66..d4159cee2 100644 --- a/crates/ra_hir/src/function.rs +++ b/crates/ra_hir/src/function.rs @@ -18,6 +18,7 @@ pub use self::scope::FnScopes; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct FnId(pub(crate) DefId); +#[derive(Debug)] pub struct Function { pub(crate) fn_id: FnId, } -- cgit v1.2.3