aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/descriptors.rs12
-rw-r--r--crates/ra_analysis/src/imp.rs74
-rw-r--r--crates/ra_analysis/tests/tests.rs10
3 files changed, 47 insertions, 49 deletions
diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs
index 4dcac1aa2..faf945a41 100644
--- a/crates/ra_analysis/src/descriptors.rs
+++ b/crates/ra_analysis/src/descriptors.rs
@@ -4,7 +4,7 @@ use std::{
4use relative_path::RelativePathBuf; 4use relative_path::RelativePathBuf;
5use ra_syntax::{ 5use ra_syntax::{
6 SmolStr, 6 SmolStr,
7 ast::{self, NameOwner, AstNode, TypeParamsOwner}, 7 ast::{self, NameOwner, AstNode},
8 text_utils::is_subrange 8 text_utils::is_subrange
9}; 9};
10use { 10use {
@@ -222,15 +222,15 @@ fn resolve_submodule(
222 222
223#[derive(Debug, Clone)] 223#[derive(Debug, Clone)]
224pub struct FnDescriptor { 224pub struct FnDescriptor {
225 pub name: Option<String>, 225 pub name: String,
226 pub label : String, 226 pub label : String,
227 pub ret_type: Option<String>, 227 pub ret_type: Option<String>,
228 pub params: Vec<String>, 228 pub params: Vec<String>,
229} 229}
230 230
231impl FnDescriptor { 231impl FnDescriptor {
232 pub fn new(node: ast::FnDef) -> Self { 232 pub fn new(node: ast::FnDef) -> Option<Self> {
233 let name = node.name().map(|name| name.text().to_string()); 233 let name = node.name()?.text().to_string();
234 234
235 // Strip the body out for the label. 235 // Strip the body out for the label.
236 let label : String = if let Some(body) = node.body() { 236 let label : String = if let Some(body) = node.body() {
@@ -247,12 +247,12 @@ impl FnDescriptor {
247 let params = FnDescriptor::param_list(node); 247 let params = FnDescriptor::param_list(node);
248 let ret_type = node.ret_type().map(|r| r.syntax().text().to_string()); 248 let ret_type = node.ret_type().map(|r| r.syntax().text().to_string());
249 249
250 FnDescriptor { 250 Some(FnDescriptor {
251 name, 251 name,
252 ret_type, 252 ret_type,
253 params, 253 params,
254 label 254 label
255 } 255 })
256 } 256 }
257 257
258 fn param_list(node: ast::FnDef) -> Vec<String> { 258 fn param_list(node: ast::FnDef) -> Vec<String> {
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 9e3ae2b03..aad54b977 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -321,47 +321,45 @@ impl AnalysisImpl {
321 for (_, fs) in file_symbols { 321 for (_, fs) in file_symbols {
322 if fs.kind == FN_DEF { 322 if fs.kind == FN_DEF {
323 if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) { 323 if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) {
324 let descriptor = FnDescriptor::new(fn_def); 324 if let Some(descriptor) = FnDescriptor::new(fn_def) {
325 325 // If we have a calling expression let's find which argument we are on
326 // If we have a calling expression let's find which argument we are on 326 let mut current_parameter = None;
327 let mut current_parameter = None; 327
328 328 let num_params = descriptor.params.len();
329 let num_params = descriptor.params.len(); 329 let has_self = fn_def.param_list()
330 let has_self = fn_def.param_list() 330 .and_then(|l| l.self_param())
331 .and_then(|l| l.self_param()) 331 .is_some();
332 .is_some(); 332
333 333 if num_params == 1 {
334 334 if !has_self {
335 if num_params == 1 { 335 current_parameter = Some(1);
336 if !has_self { 336 }
337 current_parameter = Some(1); 337 } else if num_params > 1 {
338 } 338 // Count how many parameters into the call we are.
339 } 339 // TODO: This is best effort for now and should be fixed at some point.
340 else if num_params > 1 { 340 // It may be better to see where we are in the arg_list and then check
341 // Count how many parameters into the call we are. 341 // where offset is in that list (or beyond).
342 // TODO: This is best effort for now and should be fixed at some point. 342 // Revisit this after we get documentation comments in.
343 // It may be better to see where we are in the arg_list and then check 343 if let Some(ref arg_list) = calling_node.arg_list() {
344 // where offset is in that list (or beyond). 344 let start = arg_list.syntax().range().start();
345 // Revisit this after we get documentation comments in. 345
346 if let Some(ref arg_list) = calling_node.arg_list() { 346 let range_search = TextRange::from_to(start, offset);
347 let start = arg_list.syntax().range().start(); 347 let mut commas: usize = arg_list.syntax().text()
348 348 .slice(range_search).to_string()
349 let range_search = TextRange::from_to(start, offset); 349 .matches(",")
350 let mut commas : usize = arg_list.syntax().text() 350 .count();
351 .slice(range_search).to_string() 351
352 .matches(",") 352 // If we have a method call eat the first param since it's just self.
353 .count(); 353 if has_self {
354 354 commas = commas + 1;
355 // If we have a method call eat the first param since it's just self. 355 }
356 if has_self { 356
357 commas = commas + 1; 357 current_parameter = Some(commas);
358 } 358 }
359
360 current_parameter = Some(commas);
361 } 359 }
362 }
363 360
364 return Some((descriptor, current_parameter)); 361 return Some((descriptor, current_parameter));
362 }
365 } 363 }
366 } 364 }
367 } 365 }
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 9417ddc1d..755640fb4 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -164,7 +164,7 @@ fn test_fn_signature_two_args_first() {
164r#"fn foo(x: u32, y: u32) -> u32 {x + y} 164r#"fn foo(x: u32, y: u32) -> u32 {x + y}
165fn bar() { foo(<|>3, ); }"#); 165fn bar() { foo(<|>3, ); }"#);
166 166
167 assert_eq!(desc.name, Some("foo".into())); 167 assert_eq!(desc.name, "foo".to_string());
168 assert_eq!(desc.params, vec!("x".to_string(),"y".to_string())); 168 assert_eq!(desc.params, vec!("x".to_string(),"y".to_string()));
169 assert_eq!(desc.ret_type, Some("-> u32".into())); 169 assert_eq!(desc.ret_type, Some("-> u32".into()));
170 assert_eq!(param, Some(0)); 170 assert_eq!(param, Some(0));
@@ -176,7 +176,7 @@ fn test_fn_signature_two_args_second() {
176 r#"fn foo(x: u32, y: u32) -> u32 {x + y} 176 r#"fn foo(x: u32, y: u32) -> u32 {x + y}
177fn bar() { foo(3, <|>); }"#); 177fn bar() { foo(3, <|>); }"#);
178 178
179 assert_eq!(desc.name, Some("foo".into())); 179 assert_eq!(desc.name, "foo".to_string());
180 assert_eq!(desc.params, vec!("x".to_string(),"y".to_string())); 180 assert_eq!(desc.params, vec!("x".to_string(),"y".to_string()));
181 assert_eq!(desc.ret_type, Some("-> u32".into())); 181 assert_eq!(desc.ret_type, Some("-> u32".into()));
182 assert_eq!(param, Some(1)); 182 assert_eq!(param, Some(1));
@@ -188,7 +188,7 @@ fn test_fn_signature_for_impl() {
188r#"struct F; impl F { pub fn new() { F{}} } 188r#"struct F; impl F { pub fn new() { F{}} }
189fn bar() {let _ : F = F::new(<|>);}"#); 189fn bar() {let _ : F = F::new(<|>);}"#);
190 190
191 assert_eq!(desc.name, Some("new".into())); 191 assert_eq!(desc.name, "new".to_string());
192 assert_eq!(desc.params, Vec::<String>::new()); 192 assert_eq!(desc.params, Vec::<String>::new());
193 assert_eq!(desc.ret_type, None); 193 assert_eq!(desc.ret_type, None);
194 assert_eq!(param, None); 194 assert_eq!(param, None);
@@ -211,7 +211,7 @@ fn bar() {
211 f.do_it(<|>); 211 f.do_it(<|>);
212}"#); 212}"#);
213 213
214 assert_eq!(desc.name, Some("do_it".into())); 214 assert_eq!(desc.name, "do_it".to_string());
215 assert_eq!(desc.params, vec!["&self".to_string()]); 215 assert_eq!(desc.params, vec!["&self".to_string()]);
216 assert_eq!(desc.ret_type, None); 216 assert_eq!(desc.ret_type, None);
217 assert_eq!(param, None); 217 assert_eq!(param, None);
@@ -234,7 +234,7 @@ fn bar() {
234 f.do_it(<|>); 234 f.do_it(<|>);
235}"#); 235}"#);
236 236
237 assert_eq!(desc.name, Some("do_it".into())); 237 assert_eq!(desc.name, "do_it".to_string());
238 assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]); 238 assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
239 assert_eq!(desc.ret_type, None); 239 assert_eq!(desc.ret_type, None);
240 assert_eq!(param, Some(1)); 240 assert_eq!(param, Some(1));