mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
add function to completion ctx
This commit is contained in:
parent
7a1ed6400d
commit
e4de2c8d7f
6 changed files with 19 additions and 21 deletions
|
@ -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()) {
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue