aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/call_info.rs
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-03-12 07:24:46 +0000
committerVille Penttinen <[email protected]>2019-04-09 12:45:04 +0100
commit0e49abb7fbe9239b97f0b7168ec359014c63f8c0 (patch)
treeb76168a2cf9f09336e446dcc584879a918681055 /crates/ra_ide_api/src/call_info.rs
parent5f700179fc7ed16d2848a6dbc7cf23da3b8df6c7 (diff)
Refactor CallInfo function signatures to new FunctionSignature type
This is used by CallInfo to create a pretty printed function signature that can be used with completions and other places as well.
Diffstat (limited to 'crates/ra_ide_api/src/call_info.rs')
-rw-r--r--crates/ra_ide_api/src/call_info.rs85
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
109impl CallInfo { 109impl 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
118fn 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 {
151fn bar() { foo(<|>3, ); }"#, 150fn 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, ); }"#,
162fn bar() { foo(3, <|>); }"#, 161fn 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, <|>); }"#,
173fn bar() { foo(<|>); }"#, 172fn 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}
183fn bar() { foo(<|>3, ); }"#,
184 );
185
186 assert_eq!(info.parameters(), ["x: T", "y: U"]);
187 assert_eq!(
188 info.label(),
189 r#"
190fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
191where 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(<|>); }"#,
184fn bar() {let _ : F = F::new(<|>);}"#, 203fn 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