aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkjeremy <[email protected]>2019-03-27 14:00:51 +0000
committerkjeremy <[email protected]>2019-03-27 14:00:51 +0000
commit7b34c4c002a96d928794f6d870edc0d01398df99 (patch)
treeeb852662d1fceda1cc963c2e5fb935aa77001718
parenteeb21dc8cc38a0597fb7949b5c1f42408cd93e35 (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.rs23
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}
172fn 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{}} }