diff options
-rw-r--r-- | crates/ra_analysis/src/descriptors.rs | 12 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 74 | ||||
-rw-r--r-- | crates/ra_analysis/tests/tests.rs | 10 |
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::{ | |||
4 | use relative_path::RelativePathBuf; | 4 | use relative_path::RelativePathBuf; |
5 | use ra_syntax::{ | 5 | use 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 | }; |
10 | use { | 10 | use { |
@@ -222,15 +222,15 @@ fn resolve_submodule( | |||
222 | 222 | ||
223 | #[derive(Debug, Clone)] | 223 | #[derive(Debug, Clone)] |
224 | pub struct FnDescriptor { | 224 | pub 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 | ||
231 | impl FnDescriptor { | 231 | impl 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() { | |||
164 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} | 164 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} |
165 | fn bar() { foo(<|>3, ); }"#); | 165 | fn 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} |
177 | fn bar() { foo(3, <|>); }"#); | 177 | fn 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() { | |||
188 | r#"struct F; impl F { pub fn new() { F{}} } | 188 | r#"struct F; impl F { pub fn new() { F{}} } |
189 | fn bar() {let _ : F = F::new(<|>);}"#); | 189 | fn 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)); |