diff options
Diffstat (limited to 'crates/ra_ide_api/src/call_info.rs')
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 29fa7d30b..a65119315 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -30,7 +30,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
30 | let mut call_info = CallInfo::new(db, function, fn_def)?; | 30 | let mut call_info = CallInfo::new(db, function, fn_def)?; |
31 | 31 | ||
32 | // 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 |
33 | let num_params = call_info.parameters.len(); | 33 | let num_params = call_info.parameters().len(); |
34 | 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(); |
35 | 35 | ||
36 | if num_params == 1 { | 36 | if num_params == 1 { |
@@ -108,27 +108,26 @@ impl<'a> FnCallNode<'a> { | |||
108 | 108 | ||
109 | impl CallInfo { | 109 | impl CallInfo { |
110 | fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option<Self> { | 110 | fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option<Self> { |
111 | let label = crate::completion::function_label(node)?; | 111 | let sig = crate::completion::function_signature(node)?; |
112 | let doc = function.docs(db); | 112 | let doc = function.docs(db); |
113 | let sig = sig.with_doc_opt(doc); | ||
113 | 114 | ||
114 | Some(CallInfo { parameters: param_list(node), label, doc, active_parameter: None }) | 115 | Some(CallInfo { signature: sig, active_parameter: None }) |
115 | } | 116 | } |
116 | } | ||
117 | 117 | ||
118 | fn param_list(node: &ast::FnDef) -> Vec<String> { | 118 | fn parameters(&self) -> &[String] { |
119 | let mut res = vec![]; | 119 | &self.signature.parameters |
120 | if let Some(param_list) = node.param_list() { | 120 | } |
121 | if let Some(self_param) = param_list.self_param() { | ||
122 | res.push(self_param.syntax().text().to_string()) | ||
123 | } | ||
124 | 121 | ||
125 | // Maybe use param.pat here? See if we can just extract the name? | 122 | #[cfg(test)] |
126 | //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); | 123 | fn doc(&self) -> Option<&hir::Documentation> { |
127 | res.extend( | 124 | self.signature.doc.as_ref() |
128 | param_list.params().filter_map(|p| p.pat()).map(|pat| pat.syntax().text().to_string()), | 125 | } |
129 | ); | 126 | |
127 | #[cfg(test)] | ||
128 | fn label(&self) -> String { | ||
129 | self.signature.to_string() | ||
130 | } | 130 | } |
131 | res | ||
132 | } | 131 | } |
133 | 132 | ||
134 | #[cfg(test)] | 133 | #[cfg(test)] |
@@ -151,7 +150,7 @@ mod tests { | |||
151 | fn bar() { foo(<|>3, ); }"#, | 150 | fn bar() { foo(<|>3, ); }"#, |
152 | ); | 151 | ); |
153 | 152 | ||
154 | assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); | 153 | assert_eq!(info.parameters(), ["x: u32", "y: u32"]); |
155 | assert_eq!(info.active_parameter, Some(0)); | 154 | assert_eq!(info.active_parameter, Some(0)); |
156 | } | 155 | } |
157 | 156 | ||
@@ -162,7 +161,7 @@ fn bar() { foo(<|>3, ); }"#, | |||
162 | fn bar() { foo(3, <|>); }"#, | 161 | fn bar() { foo(3, <|>); }"#, |
163 | ); | 162 | ); |
164 | 163 | ||
165 | assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); | 164 | assert_eq!(info.parameters(), ["x: u32", "y: u32"]); |
166 | assert_eq!(info.active_parameter, Some(1)); | 165 | assert_eq!(info.active_parameter, Some(1)); |
167 | } | 166 | } |
168 | 167 | ||
@@ -173,7 +172,27 @@ fn bar() { foo(3, <|>); }"#, | |||
173 | fn bar() { foo(<|>); }"#, | 172 | fn bar() { foo(<|>); }"#, |
174 | ); | 173 | ); |
175 | 174 | ||
176 | assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); | 175 | assert_eq!(info.parameters(), ["x: u32", "y: u32"]); |
176 | assert_eq!(info.active_parameter, Some(0)); | ||
177 | } | ||
178 | |||
179 | #[test] | ||
180 | fn test_fn_signature_two_args_first_generics() { | ||
181 | let info = call_info( | ||
182 | r#"fn foo<T, U: Copy + Display>(x: T, y: U) -> u32 where T: Copy + Display, U: Debug {x + y} | ||
183 | fn bar() { foo(<|>3, ); }"#, | ||
184 | ); | ||
185 | |||
186 | assert_eq!(info.parameters(), ["x: T", "y: U"]); | ||
187 | assert_eq!( | ||
188 | info.label(), | ||
189 | r#" | ||
190 | fn foo<T, U: Copy + Display>(x: T, y: U) -> u32 | ||
191 | where T: Copy + Display, | ||
192 | U: Debug | ||
193 | "# | ||
194 | .trim() | ||
195 | ); | ||
177 | assert_eq!(info.active_parameter, Some(0)); | 196 | assert_eq!(info.active_parameter, Some(0)); |
178 | } | 197 | } |
179 | 198 | ||
@@ -184,7 +203,7 @@ fn bar() { foo(<|>); }"#, | |||
184 | fn bar() {let _ : F = F::new(<|>);}"#, | 203 | fn bar() {let _ : F = F::new(<|>);}"#, |
185 | ); | 204 | ); |
186 | 205 | ||
187 | assert_eq!(info.parameters, Vec::<String>::new()); | 206 | assert!(info.parameters().is_empty()); |
188 | assert_eq!(info.active_parameter, None); | 207 | assert_eq!(info.active_parameter, None); |
189 | } | 208 | } |
190 | 209 | ||
@@ -206,7 +225,7 @@ fn bar() { | |||
206 | }"#, | 225 | }"#, |
207 | ); | 226 | ); |
208 | 227 | ||
209 | assert_eq!(info.parameters, vec!["&self".to_string()]); | 228 | assert_eq!(info.parameters(), ["&self"]); |
210 | assert_eq!(info.active_parameter, None); | 229 | assert_eq!(info.active_parameter, None); |
211 | } | 230 | } |
212 | 231 | ||
@@ -228,7 +247,7 @@ fn bar() { | |||
228 | }"#, | 247 | }"#, |
229 | ); | 248 | ); |
230 | 249 | ||
231 | assert_eq!(info.parameters, vec!["&self".to_string(), "x".to_string()]); | 250 | assert_eq!(info.parameters(), ["&self", "x: i32"]); |
232 | assert_eq!(info.active_parameter, Some(1)); | 251 | assert_eq!(info.active_parameter, Some(1)); |
233 | } | 252 | } |
234 | 253 | ||
@@ -248,10 +267,10 @@ fn bar() { | |||
248 | "#, | 267 | "#, |
249 | ); | 268 | ); |
250 | 269 | ||
251 | assert_eq!(info.parameters, vec!["j".to_string()]); | 270 | assert_eq!(info.parameters(), ["j: u32"]); |
252 | assert_eq!(info.active_parameter, Some(0)); | 271 | assert_eq!(info.active_parameter, Some(0)); |
253 | assert_eq!(info.label, "fn foo(j: u32) -> u32".to_string()); | 272 | assert_eq!(info.label(), "fn foo(j: u32) -> u32"); |
254 | assert_eq!(info.doc.map(|it| it.into()), Some("test".to_string())); | 273 | assert_eq!(info.doc().map(|it| it.into()), Some("test".to_string())); |
255 | } | 274 | } |
256 | 275 | ||
257 | #[test] | 276 | #[test] |
@@ -276,11 +295,11 @@ pub fn do() { | |||
276 | }"#, | 295 | }"#, |
277 | ); | 296 | ); |
278 | 297 | ||
279 | assert_eq!(info.parameters, vec!["x".to_string()]); | 298 | assert_eq!(info.parameters(), ["x: i32"]); |
280 | assert_eq!(info.active_parameter, Some(0)); | 299 | assert_eq!(info.active_parameter, Some(0)); |
281 | assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); | 300 | assert_eq!(info.label(), "pub fn add_one(x: i32) -> i32"); |
282 | assert_eq!( | 301 | assert_eq!( |
283 | info.doc.map(|it| it.into()), | 302 | info.doc().map(|it| it.into()), |
284 | Some( | 303 | Some( |
285 | r#"Adds one to the number given. | 304 | r#"Adds one to the number given. |
286 | 305 | ||
@@ -322,11 +341,11 @@ pub fn do_it() { | |||
322 | }"#, | 341 | }"#, |
323 | ); | 342 | ); |
324 | 343 | ||
325 | assert_eq!(info.parameters, vec!["x".to_string()]); | 344 | assert_eq!(info.parameters(), ["x: i32"]); |
326 | assert_eq!(info.active_parameter, Some(0)); | 345 | assert_eq!(info.active_parameter, Some(0)); |
327 | assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); | 346 | assert_eq!(info.label(), "pub fn add_one(x: i32) -> i32"); |
328 | assert_eq!( | 347 | assert_eq!( |
329 | info.doc.map(|it| it.into()), | 348 | info.doc().map(|it| it.into()), |
330 | Some( | 349 | Some( |
331 | r#"Adds one to the number given. | 350 | r#"Adds one to the number given. |
332 | 351 | ||
@@ -375,10 +394,10 @@ pub fn foo() { | |||
375 | "#, | 394 | "#, |
376 | ); | 395 | ); |
377 | 396 | ||
378 | assert_eq!(info.parameters, vec!["&mut self".to_string(), "ctx".to_string()]); | 397 | assert_eq!(info.parameters(), ["&mut self", "ctx: &mut Self::Context"]); |
379 | assert_eq!(info.active_parameter, Some(1)); | 398 | assert_eq!(info.active_parameter, Some(1)); |
380 | assert_eq!( | 399 | assert_eq!( |
381 | info.doc.map(|it| it.into()), | 400 | info.doc().map(|it| it.into()), |
382 | Some( | 401 | Some( |
383 | r#"Method is called when writer finishes. | 402 | r#"Method is called when writer finishes. |
384 | 403 | ||