diff options
author | Aleksey Kladov <[email protected]> | 2019-04-11 13:34:13 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-04-11 14:29:33 +0100 |
commit | 505acc973b3b865195d7d0aeb47c419c35f6bbbc (patch) | |
tree | f5130e4e301e2adadf12f0b69f65f6cc19480ed0 /crates/ra_ide_api | |
parent | 10d66d63d716a10ba7a5a8d1b69c9066249caf69 (diff) |
Make call info to use real name resolution
Diffstat (limited to 'crates/ra_ide_api')
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 37 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_context.rs | 6 |
2 files changed, 20 insertions, 23 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index dbb3853d0..d06876777 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -2,7 +2,6 @@ use test_utils::tested_by; | |||
2 | use ra_db::SourceDatabase; | 2 | use ra_db::SourceDatabase; |
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | AstNode, SyntaxNode, TextUnit, | 4 | AstNode, SyntaxNode, TextUnit, |
5 | SyntaxKind::FN_DEF, | ||
6 | ast::{self, ArgListOwner}, | 5 | ast::{self, ArgListOwner}, |
7 | algo::find_node_at_offset, | 6 | algo::find_node_at_offset, |
8 | }; | 7 | }; |
@@ -18,19 +17,26 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
18 | let calling_node = FnCallNode::with_node(syntax, position.offset)?; | 17 | let calling_node = FnCallNode::with_node(syntax, position.offset)?; |
19 | let name_ref = calling_node.name_ref()?; | 18 | let name_ref = calling_node.name_ref()?; |
20 | 19 | ||
21 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | 20 | let analyser = hir::SourceAnalyser::new(db, position.file_id, name_ref.syntax()); |
22 | let file_symbols = crate::symbol_index::index_resolve(db, name_ref); | 21 | let function = match calling_node { |
23 | let symbol = file_symbols.into_iter().find(|it| it.ptr.kind() == FN_DEF)?; | 22 | FnCallNode::CallExpr(expr) => { |
24 | let fn_file = db.parse(symbol.file_id); | 23 | //FIXME: apply subst |
25 | let fn_def = symbol.ptr.to_node(&fn_file); | 24 | let (callable_def, _subst) = |
26 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); | 25 | analyser.type_of(db, expr.expr()?.into())?.as_callable()?; |
27 | let function = hir::source_binder::function_from_source(db, symbol.file_id, fn_def)?; | 26 | match callable_def { |
27 | hir::CallableDef::Function(it) => it, | ||
28 | //FIXME: handle other callables | ||
29 | _ => return None, | ||
30 | } | ||
31 | } | ||
32 | FnCallNode::MethodCallExpr(expr) => analyser.resolve_method_call(expr)?, | ||
33 | }; | ||
28 | 34 | ||
29 | let mut call_info = CallInfo::new(db, function); | 35 | let mut call_info = CallInfo::new(db, function); |
30 | 36 | ||
31 | // If we have a calling expression let's find which argument we are on | 37 | // If we have a calling expression let's find which argument we are on |
32 | let num_params = call_info.parameters().len(); | 38 | let num_params = call_info.parameters().len(); |
33 | let has_self = fn_def.param_list().and_then(|l| l.self_param()).is_some(); | 39 | let has_self = function.signature(db).has_self_param(); |
34 | 40 | ||
35 | if num_params == 1 { | 41 | if num_params == 1 { |
36 | if !has_self { | 42 | if !has_self { |
@@ -142,7 +148,7 @@ mod tests { | |||
142 | } | 148 | } |
143 | 149 | ||
144 | #[test] | 150 | #[test] |
145 | fn test_fn_signature_two_args_first() { | 151 | fn test_fn_signature_two_args_firstx() { |
146 | let info = call_info( | 152 | let info = call_info( |
147 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} | 153 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} |
148 | fn bar() { foo(<|>3, ); }"#, | 154 | fn bar() { foo(<|>3, ); }"#, |
@@ -382,11 +388,9 @@ assert_eq!(6, my_crate::add_one(5)); | |||
382 | fn test_fn_signature_with_docs_from_actix() { | 388 | fn test_fn_signature_with_docs_from_actix() { |
383 | let info = call_info( | 389 | let info = call_info( |
384 | r#" | 390 | r#" |
385 | pub trait WriteHandler<E> | 391 | struct WriteHandler<E>; |
386 | where | 392 | |
387 | Self: Actor, | 393 | impl<E> WriteHandler<E> { |
388 | Self::Context: ActorContext, | ||
389 | { | ||
390 | /// Method is called when writer emits error. | 394 | /// Method is called when writer emits error. |
391 | /// | 395 | /// |
392 | /// If this method returns `ErrorAction::Continue` writer processing | 396 | /// If this method returns `ErrorAction::Continue` writer processing |
@@ -403,8 +407,7 @@ where | |||
403 | } | 407 | } |
404 | } | 408 | } |
405 | 409 | ||
406 | pub fn foo() { | 410 | pub fn foo(mut r: WriteHandler<()>) { |
407 | WriteHandler r; | ||
408 | r.finished(<|>); | 411 | r.finished(<|>); |
409 | } | 412 | } |
410 | 413 | ||
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index ce21fca9b..ddcf46b4e 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -19,7 +19,6 @@ pub(crate) struct CompletionContext<'a> { | |||
19 | pub(super) token: SyntaxToken<'a>, | 19 | pub(super) token: SyntaxToken<'a>, |
20 | pub(super) resolver: Resolver, | 20 | pub(super) resolver: Resolver, |
21 | pub(super) module: Option<hir::Module>, | 21 | pub(super) module: Option<hir::Module>, |
22 | pub(super) function: Option<hir::Function>, | ||
23 | pub(super) function_syntax: Option<&'a ast::FnDef>, | 22 | pub(super) function_syntax: Option<&'a ast::FnDef>, |
24 | pub(super) use_item_syntax: Option<&'a ast::UseItem>, | 23 | pub(super) use_item_syntax: Option<&'a ast::UseItem>, |
25 | pub(super) struct_lit_syntax: Option<&'a ast::StructLit>, | 24 | pub(super) struct_lit_syntax: Option<&'a ast::StructLit>, |
@@ -59,7 +58,6 @@ impl<'a> CompletionContext<'a> { | |||
59 | offset: position.offset, | 58 | offset: position.offset, |
60 | resolver, | 59 | resolver, |
61 | module, | 60 | module, |
62 | function: None, | ||
63 | function_syntax: None, | 61 | function_syntax: None, |
64 | use_item_syntax: None, | 62 | use_item_syntax: None, |
65 | struct_lit_syntax: None, | 63 | struct_lit_syntax: None, |
@@ -150,10 +148,6 @@ impl<'a> CompletionContext<'a> { | |||
150 | .ancestors() | 148 | .ancestors() |
151 | .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) | 149 | .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) |
152 | .find_map(ast::FnDef::cast); | 150 | .find_map(ast::FnDef::cast); |
153 | if let (Some(module), Some(fn_def)) = (self.module, self.function_syntax) { | ||
154 | let function = source_binder::function_from_module(self.db, module, fn_def); | ||
155 | self.function = Some(function); | ||
156 | } | ||
157 | 151 | ||
158 | let parent = match name_ref.syntax().parent() { | 152 | let parent = match name_ref.syntax().parent() { |
159 | Some(it) => it, | 153 | Some(it) => it, |