diff options
Diffstat (limited to 'crates/ra_ide/src/call_info.rs')
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 76 |
1 files changed, 28 insertions, 48 deletions
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index e1d6efb2a..0ef92ed4b 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -7,7 +7,15 @@ use ra_syntax::{ | |||
7 | }; | 7 | }; |
8 | use test_utils::mark; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{CallInfo, FilePosition, FunctionSignature}; | 10 | use crate::{FilePosition, FunctionSignature}; |
11 | |||
12 | /// Contains information about a call site. Specifically the | ||
13 | /// `FunctionSignature`and current parameter. | ||
14 | #[derive(Debug)] | ||
15 | pub struct CallInfo { | ||
16 | pub signature: FunctionSignature, | ||
17 | pub active_parameter: Option<usize>, | ||
18 | } | ||
11 | 19 | ||
12 | /// Computes parameter information for the given call expression. | 20 | /// Computes parameter information for the given call expression. |
13 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 21 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { |
@@ -40,43 +48,40 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op | |||
40 | // Find the calling expression and it's NameRef | 48 | // Find the calling expression and it's NameRef |
41 | let calling_node = FnCallNode::with_node(&token.parent())?; | 49 | let calling_node = FnCallNode::with_node(&token.parent())?; |
42 | 50 | ||
43 | let (mut call_info, has_self) = match &calling_node { | 51 | let signature = match &calling_node { |
44 | FnCallNode::CallExpr(call) => { | 52 | FnCallNode::CallExpr(call) => { |
45 | //FIXME: Type::as_callable is broken | 53 | //FIXME: Type::as_callable is broken |
46 | let callable_def = sema.type_of_expr(&call.expr()?)?.as_callable()?; | 54 | let callable_def = sema.type_of_expr(&call.expr()?)?.as_callable()?; |
47 | match callable_def { | 55 | match callable_def { |
48 | hir::CallableDef::FunctionId(it) => { | 56 | hir::CallableDef::FunctionId(it) => { |
49 | let fn_def = it.into(); | 57 | let fn_def = it.into(); |
50 | (CallInfo::with_fn(sema.db, fn_def), fn_def.has_self_param(sema.db)) | 58 | FunctionSignature::from_hir(sema.db, fn_def) |
51 | } | 59 | } |
52 | hir::CallableDef::StructId(it) => { | 60 | hir::CallableDef::StructId(it) => { |
53 | (CallInfo::with_struct(sema.db, it.into())?, false) | 61 | FunctionSignature::from_struct(sema.db, it.into())? |
54 | } | 62 | } |
55 | hir::CallableDef::EnumVariantId(it) => { | 63 | hir::CallableDef::EnumVariantId(it) => { |
56 | (CallInfo::with_enum_variant(sema.db, it.into())?, false) | 64 | FunctionSignature::from_enum_variant(sema.db, it.into())? |
57 | } | 65 | } |
58 | } | 66 | } |
59 | } | 67 | } |
60 | FnCallNode::MethodCallExpr(method_call) => { | 68 | FnCallNode::MethodCallExpr(method_call) => { |
61 | let function = sema.resolve_method_call(&method_call)?; | 69 | let function = sema.resolve_method_call(&method_call)?; |
62 | (CallInfo::with_fn(sema.db, function), function.has_self_param(sema.db)) | 70 | FunctionSignature::from_hir(sema.db, function) |
63 | } | 71 | } |
64 | FnCallNode::MacroCallExpr(macro_call) => { | 72 | FnCallNode::MacroCallExpr(macro_call) => { |
65 | let macro_def = sema.resolve_macro_call(¯o_call)?; | 73 | let macro_def = sema.resolve_macro_call(¯o_call)?; |
66 | (CallInfo::with_macro(sema.db, macro_def)?, false) | 74 | FunctionSignature::from_macro(sema.db, macro_def)? |
67 | } | 75 | } |
68 | }; | 76 | }; |
69 | 77 | ||
70 | // If we have a calling expression let's find which argument we are on | 78 | // If we have a calling expression let's find which argument we are on |
71 | let num_params = call_info.parameters().len(); | 79 | let num_params = signature.parameters.len(); |
72 | 80 | ||
73 | match num_params { | 81 | let active_parameter = match num_params { |
74 | 0 => (), | 82 | 0 => None, |
75 | 1 => { | 83 | 1 if signature.has_self_param => None, |
76 | if !has_self { | 84 | 1 => Some(0), |
77 | call_info.active_parameter = Some(0); | ||
78 | } | ||
79 | } | ||
80 | _ => { | 85 | _ => { |
81 | if let Some(arg_list) = calling_node.arg_list() { | 86 | if let Some(arg_list) = calling_node.arg_list() { |
82 | // Number of arguments specified at the call site | 87 | // Number of arguments specified at the call site |
@@ -99,16 +104,18 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op | |||
99 | ); | 104 | ); |
100 | 105 | ||
101 | // If we are in a method account for `self` | 106 | // If we are in a method account for `self` |
102 | if has_self { | 107 | if signature.has_self_param { |
103 | param += 1; | 108 | param += 1; |
104 | } | 109 | } |
105 | 110 | ||
106 | call_info.active_parameter = Some(param); | 111 | Some(param) |
112 | } else { | ||
113 | None | ||
107 | } | 114 | } |
108 | } | 115 | } |
109 | } | 116 | }; |
110 | 117 | ||
111 | Some(call_info) | 118 | Some(CallInfo { signature, active_parameter }) |
112 | } | 119 | } |
113 | 120 | ||
114 | #[derive(Debug)] | 121 | #[derive(Debug)] |
@@ -181,34 +188,6 @@ impl CallInfo { | |||
181 | let res = ActiveParameter { ty, name }; | 188 | let res = ActiveParameter { ty, name }; |
182 | Some(res) | 189 | Some(res) |
183 | } | 190 | } |
184 | |||
185 | fn with_fn(db: &RootDatabase, function: hir::Function) -> Self { | ||
186 | let signature = FunctionSignature::from_hir(db, function); | ||
187 | |||
188 | CallInfo { signature, active_parameter: None } | ||
189 | } | ||
190 | |||
191 | fn with_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> { | ||
192 | let signature = FunctionSignature::from_struct(db, st)?; | ||
193 | |||
194 | Some(CallInfo { signature, active_parameter: None }) | ||
195 | } | ||
196 | |||
197 | fn with_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> { | ||
198 | let signature = FunctionSignature::from_enum_variant(db, variant)?; | ||
199 | |||
200 | Some(CallInfo { signature, active_parameter: None }) | ||
201 | } | ||
202 | |||
203 | fn with_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { | ||
204 | let signature = FunctionSignature::from_macro(db, macro_def)?; | ||
205 | |||
206 | Some(CallInfo { signature, active_parameter: None }) | ||
207 | } | ||
208 | |||
209 | fn parameters(&self) -> &[String] { | ||
210 | &self.signature.parameters | ||
211 | } | ||
212 | } | 191 | } |
213 | 192 | ||
214 | #[cfg(test)] | 193 | #[cfg(test)] |
@@ -228,7 +207,8 @@ mod tests { | |||
228 | Some(docs) => format!("{}\n------\n", docs.as_str()), | 207 | Some(docs) => format!("{}\n------\n", docs.as_str()), |
229 | }; | 208 | }; |
230 | let params = call_info | 209 | let params = call_info |
231 | .parameters() | 210 | .signature |
211 | .parameters | ||
232 | .iter() | 212 | .iter() |
233 | .enumerate() | 213 | .enumerate() |
234 | .map(|(i, param)| { | 214 | .map(|(i, param)| { |