diff options
Diffstat (limited to 'crates/ra_ide/src/call_info.rs')
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index 9a1fc0d35..2b35a3803 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -3,7 +3,7 @@ use hir::Semantics; | |||
3 | use ra_ide_db::RootDatabase; | 3 | use ra_ide_db::RootDatabase; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | ast::{self, ArgListOwner}, | 5 | ast::{self, ArgListOwner}, |
6 | match_ast, AstNode, SyntaxNode, | 6 | match_ast, AstNode, SyntaxNode, SyntaxToken, |
7 | }; | 7 | }; |
8 | use test_utils::tested_by; | 8 | use test_utils::tested_by; |
9 | 9 | ||
@@ -16,7 +16,13 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
16 | let file = file.syntax(); | 16 | let file = file.syntax(); |
17 | let token = file.token_at_offset(position.offset).next()?; | 17 | let token = file.token_at_offset(position.offset).next()?; |
18 | let token = sema.descend_into_macros(token); | 18 | let token = sema.descend_into_macros(token); |
19 | call_info_for_token(&sema, token) | ||
20 | } | ||
19 | 21 | ||
22 | pub(crate) fn call_info_for_token( | ||
23 | sema: &Semantics<RootDatabase>, | ||
24 | token: SyntaxToken, | ||
25 | ) -> Option<CallInfo> { | ||
20 | // Find the calling expression and it's NameRef | 26 | // Find the calling expression and it's NameRef |
21 | let calling_node = FnCallNode::with_node(&token.parent())?; | 27 | let calling_node = FnCallNode::with_node(&token.parent())?; |
22 | 28 | ||
@@ -27,21 +33,23 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
27 | match callable_def { | 33 | match callable_def { |
28 | hir::CallableDef::FunctionId(it) => { | 34 | hir::CallableDef::FunctionId(it) => { |
29 | let fn_def = it.into(); | 35 | let fn_def = it.into(); |
30 | (CallInfo::with_fn(db, fn_def), fn_def.has_self_param(db)) | 36 | (CallInfo::with_fn(sema.db, fn_def), fn_def.has_self_param(sema.db)) |
37 | } | ||
38 | hir::CallableDef::StructId(it) => { | ||
39 | (CallInfo::with_struct(sema.db, it.into())?, false) | ||
31 | } | 40 | } |
32 | hir::CallableDef::StructId(it) => (CallInfo::with_struct(db, it.into())?, false), | ||
33 | hir::CallableDef::EnumVariantId(it) => { | 41 | hir::CallableDef::EnumVariantId(it) => { |
34 | (CallInfo::with_enum_variant(db, it.into())?, false) | 42 | (CallInfo::with_enum_variant(sema.db, it.into())?, false) |
35 | } | 43 | } |
36 | } | 44 | } |
37 | } | 45 | } |
38 | FnCallNode::MethodCallExpr(method_call) => { | 46 | FnCallNode::MethodCallExpr(method_call) => { |
39 | let function = sema.resolve_method_call(&method_call)?; | 47 | let function = sema.resolve_method_call(&method_call)?; |
40 | (CallInfo::with_fn(db, function), function.has_self_param(db)) | 48 | (CallInfo::with_fn(sema.db, function), function.has_self_param(sema.db)) |
41 | } | 49 | } |
42 | FnCallNode::MacroCallExpr(macro_call) => { | 50 | FnCallNode::MacroCallExpr(macro_call) => { |
43 | let macro_def = sema.resolve_macro_call(¯o_call)?; | 51 | let macro_def = sema.resolve_macro_call(¯o_call)?; |
44 | (CallInfo::with_macro(db, macro_def)?, false) | 52 | (CallInfo::with_macro(sema.db, macro_def)?, false) |
45 | } | 53 | } |
46 | }; | 54 | }; |
47 | 55 | ||
@@ -61,7 +69,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
61 | let num_args_at_callsite = arg_list.args().count(); | 69 | let num_args_at_callsite = arg_list.args().count(); |
62 | 70 | ||
63 | let arg_list_range = arg_list.syntax().text_range(); | 71 | let arg_list_range = arg_list.syntax().text_range(); |
64 | if !arg_list_range.contains_inclusive(position.offset) { | 72 | if !arg_list_range.contains_inclusive(token.text_range().start()) { |
65 | tested_by!(call_info_bad_offset); | 73 | tested_by!(call_info_bad_offset); |
66 | return None; | 74 | return None; |
67 | } | 75 | } |
@@ -70,7 +78,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
70 | num_args_at_callsite, | 78 | num_args_at_callsite, |
71 | arg_list | 79 | arg_list |
72 | .args() | 80 | .args() |
73 | .take_while(|arg| arg.syntax().text_range().end() < position.offset) | 81 | .take_while(|arg| { |
82 | arg.syntax().text_range().end() < token.text_range().start() | ||
83 | }) | ||
74 | .count(), | 84 | .count(), |
75 | ); | 85 | ); |
76 | 86 | ||
@@ -100,7 +110,13 @@ impl FnCallNode { | |||
100 | match_ast! { | 110 | match_ast! { |
101 | match node { | 111 | match node { |
102 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, | 112 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, |
103 | ast::MethodCallExpr(it) => { Some(FnCallNode::MethodCallExpr(it)) }, | 113 | ast::MethodCallExpr(it) => { |
114 | let arg_list = it.arg_list()?; | ||
115 | if !syntax.text_range().is_subrange(&arg_list.syntax().text_range()) { | ||
116 | return None; | ||
117 | } | ||
118 | Some(FnCallNode::MethodCallExpr(it)) | ||
119 | }, | ||
104 | ast::MacroCall(it) => { Some(FnCallNode::MacroCallExpr(it)) }, | 120 | ast::MacroCall(it) => { Some(FnCallNode::MacroCallExpr(it)) }, |
105 | _ => { None }, | 121 | _ => { None }, |
106 | } | 122 | } |