diff options
author | kjeremy <[email protected]> | 2019-03-27 14:00:51 +0000 |
---|---|---|
committer | kjeremy <[email protected]> | 2019-03-27 14:00:51 +0000 |
commit | 7b34c4c002a96d928794f6d870edc0d01398df99 (patch) | |
tree | eb852662d1fceda1cc963c2e5fb935aa77001718 | |
parent | eeb21dc8cc38a0597fb7949b5c1f42408cd93e35 (diff) |
Take number of arguments at the call-site into account for signature help
Fixes #1065
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index c5e8d5843..831c4ad12 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -28,6 +28,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
28 | let function = hir::source_binder::function_from_source(db, symbol.file_id, fn_def)?; | 28 | let function = hir::source_binder::function_from_source(db, symbol.file_id, fn_def)?; |
29 | 29 | ||
30 | let mut call_info = CallInfo::new(db, function, fn_def)?; | 30 | let mut call_info = CallInfo::new(db, function, fn_def)?; |
31 | |||
31 | // If we have a calling expression let's find which argument we are on | 32 | // If we have a calling expression let's find which argument we are on |
32 | let num_params = call_info.parameters.len(); | 33 | let num_params = call_info.parameters.len(); |
33 | let has_self = fn_def.param_list().and_then(|l| l.self_param()).is_some(); | 34 | let has_self = fn_def.param_list().and_then(|l| l.self_param()).is_some(); |
@@ -38,7 +39,15 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
38 | } | 39 | } |
39 | } else if num_params > 1 { | 40 | } else if num_params > 1 { |
40 | // Count how many parameters into the call we are. | 41 | // Count how many parameters into the call we are. |
41 | if let Some(ref arg_list) = calling_node.arg_list() { | 42 | if let Some(arg_list) = calling_node.arg_list() { |
43 | // Number of arguments specified at the caller site | ||
44 | let mut num_args_of_call = arg_list.args().count(); | ||
45 | |||
46 | // If we are calling a method account for the `self` argument. | ||
47 | if has_self { | ||
48 | num_args_of_call = num_args_of_call + 1; | ||
49 | } | ||
50 | |||
42 | let arg_list_range = arg_list.syntax().range(); | 51 | let arg_list_range = arg_list.syntax().range(); |
43 | if !arg_list_range.contains_inclusive(position.offset) { | 52 | if !arg_list_range.contains_inclusive(position.offset) { |
44 | tested_by!(call_info_bad_offset); | 53 | tested_by!(call_info_bad_offset); |
@@ -49,6 +58,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
49 | .args() | 58 | .args() |
50 | .position(|arg| arg.syntax().range().contains(position.offset)) | 59 | .position(|arg| arg.syntax().range().contains(position.offset)) |
51 | .or(Some(num_params - 1)) | 60 | .or(Some(num_params - 1)) |
61 | .min(Some(num_args_of_call)) | ||
52 | .unwrap(); | 62 | .unwrap(); |
53 | 63 | ||
54 | call_info.active_parameter = Some(param); | 64 | call_info.active_parameter = Some(param); |
@@ -156,6 +166,17 @@ fn bar() { foo(3, <|>); }"#, | |||
156 | } | 166 | } |
157 | 167 | ||
158 | #[test] | 168 | #[test] |
169 | fn test_fn_signature_two_args_empty() { | ||
170 | let info = call_info( | ||
171 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} | ||
172 | fn bar() { foo(<|>); }"#, | ||
173 | ); | ||
174 | |||
175 | assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); | ||
176 | assert_eq!(info.active_parameter, Some(0)); | ||
177 | } | ||
178 | |||
179 | #[test] | ||
159 | fn test_fn_signature_for_impl() { | 180 | fn test_fn_signature_for_impl() { |
160 | let info = call_info( | 181 | let info = call_info( |
161 | r#"struct F; impl F { pub fn new() { F{}} } | 182 | r#"struct F; impl F { pub fn new() { F{}} } |