aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/call_info.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/call_info.rs')
-rw-r--r--crates/ra_ide/src/call_info.rs76
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};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{CallInfo, FilePosition, FunctionSignature}; 10use crate::{FilePosition, FunctionSignature};
11
12/// Contains information about a call site. Specifically the
13/// `FunctionSignature`and current parameter.
14#[derive(Debug)]
15pub 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.
13pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 21pub(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(&macro_call)?; 73 let macro_def = sema.resolve_macro_call(&macro_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)| {