diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/docs.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 85 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion.rs | 61 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display.rs | 51 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 29 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 22 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 23 |
8 files changed, 210 insertions, 69 deletions
diff --git a/crates/ra_hir/src/docs.rs b/crates/ra_hir/src/docs.rs index 5db72c08a..e3a755b46 100644 --- a/crates/ra_hir/src/docs.rs +++ b/crates/ra_hir/src/docs.rs | |||
@@ -22,6 +22,12 @@ impl Into<String> for Documentation { | |||
22 | } | 22 | } |
23 | } | 23 | } |
24 | 24 | ||
25 | impl<'a> Into<String> for &'a Documentation { | ||
26 | fn into(self) -> String { | ||
27 | self.contents().into() | ||
28 | } | ||
29 | } | ||
30 | |||
25 | pub trait Docs { | 31 | pub trait Docs { |
26 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; | 32 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; |
27 | } | 33 | } |
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 | ||
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index a846a7a3c..d8e4410b2 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs | |||
@@ -13,11 +13,12 @@ mod complete_scope; | |||
13 | mod complete_postfix; | 13 | mod complete_postfix; |
14 | 14 | ||
15 | use ra_db::SourceDatabase; | 15 | use ra_db::SourceDatabase; |
16 | use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; | 16 | use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; |
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | db, | 19 | db, |
20 | FilePosition, | 20 | FilePosition, |
21 | FunctionSignature, | ||
21 | completion::{ | 22 | completion::{ |
22 | completion_item::{Completions, CompletionKind}, | 23 | completion_item::{Completions, CompletionKind}, |
23 | completion_context::CompletionContext, | 24 | completion_context::CompletionContext, |
@@ -71,22 +72,52 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti | |||
71 | Some(acc) | 72 | Some(acc) |
72 | } | 73 | } |
73 | 74 | ||
74 | pub fn function_label(node: &ast::FnDef) -> Option<String> { | 75 | pub fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> { |
75 | let label: String = if let Some(body) = node.body() { | 76 | let mut res = vec![]; |
76 | let body_range = body.syntax().range(); | 77 | if let Some(type_params) = node.type_param_list() { |
77 | let label: String = node | 78 | res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); |
78 | .syntax() | 79 | res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); |
79 | .children_with_tokens() | 80 | } |
80 | .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body | 81 | res |
81 | .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) // Filter out comments and attrs | 82 | } |
82 | .map(|node| node.to_string()) | 83 | |
83 | .collect(); | 84 | pub fn where_predicates<N: TypeParamsOwner>(node: &N) -> Vec<String> { |
84 | label | 85 | let mut res = vec![]; |
85 | } else { | 86 | if let Some(clause) = node.where_clause() { |
86 | node.syntax().text().to_string() | 87 | res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); |
88 | } | ||
89 | res | ||
90 | } | ||
91 | |||
92 | pub fn function_signature(node: &ast::FnDef) -> Option<FunctionSignature> { | ||
93 | fn param_list(node: &ast::FnDef) -> Vec<String> { | ||
94 | let mut res = vec![]; | ||
95 | if let Some(param_list) = node.param_list() { | ||
96 | if let Some(self_param) = param_list.self_param() { | ||
97 | res.push(self_param.syntax().text().to_string()) | ||
98 | } | ||
99 | |||
100 | res.extend(param_list.params().map(|param| param.syntax().text().to_string())); | ||
101 | } | ||
102 | res | ||
103 | } | ||
104 | |||
105 | let sig = FunctionSignature { | ||
106 | visibility: node.visibility().map(|n| n.syntax().text().to_string()), | ||
107 | name: node.name().map(|n| n.text().to_string()), | ||
108 | ret_type: node.ret_type().and_then(|r| r.type_ref()).map(|n| n.syntax().text().to_string()), | ||
109 | parameters: param_list(node), | ||
110 | generic_parameters: generic_parameters(node), | ||
111 | where_predicates: where_predicates(node), | ||
112 | // docs are processed separately | ||
113 | doc: None, | ||
87 | }; | 114 | }; |
88 | 115 | ||
89 | Some(label.trim().to_owned()) | 116 | Some(sig) |
117 | } | ||
118 | |||
119 | pub fn function_label(node: &ast::FnDef) -> Option<String> { | ||
120 | function_signature(node).map(|n| n.to_string()) | ||
90 | } | 121 | } |
91 | 122 | ||
92 | pub fn const_label(node: &ast::ConstDef) -> String { | 123 | pub fn const_label(node: &ast::ConstDef) -> String { |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 6146b7bb6..9d82f2270 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -145,7 +145,7 @@ mod tests { | |||
145 | check_reference_completion( | 145 | check_reference_completion( |
146 | "dont_show_both_completions_for_shadowing", | 146 | "dont_show_both_completions_for_shadowing", |
147 | r" | 147 | r" |
148 | fn foo() -> { | 148 | fn foo() { |
149 | let bar = 92; | 149 | let bar = 92; |
150 | { | 150 | { |
151 | let bar = 62; | 151 | let bar = 62; |
diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs new file mode 100644 index 000000000..60fa72f1b --- /dev/null +++ b/crates/ra_ide_api/src/display.rs | |||
@@ -0,0 +1,51 @@ | |||
1 | use super::*; | ||
2 | use std::fmt::{self, Display}; | ||
3 | |||
4 | impl Display for FunctionSignature { | ||
5 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
6 | if let Some(t) = &self.visibility { | ||
7 | write!(f, "{} ", t)?; | ||
8 | } | ||
9 | |||
10 | if let Some(name) = &self.name { | ||
11 | write!(f, "fn {}", name)?; | ||
12 | } | ||
13 | |||
14 | if !self.generic_parameters.is_empty() { | ||
15 | write!(f, "<")?; | ||
16 | write_joined(f, &self.generic_parameters, ", ")?; | ||
17 | write!(f, ">")?; | ||
18 | } | ||
19 | |||
20 | write!(f, "(")?; | ||
21 | write_joined(f, &self.parameters, ", ")?; | ||
22 | write!(f, ")")?; | ||
23 | |||
24 | if let Some(t) = &self.ret_type { | ||
25 | write!(f, " -> {}", t)?; | ||
26 | } | ||
27 | |||
28 | if !self.where_predicates.is_empty() { | ||
29 | write!(f, "\nwhere ")?; | ||
30 | write_joined(f, &self.where_predicates, ",\n ")?; | ||
31 | } | ||
32 | |||
33 | Ok(()) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | fn write_joined<T: Display>( | ||
38 | f: &mut fmt::Formatter, | ||
39 | items: impl IntoIterator<Item = T>, | ||
40 | sep: &str, | ||
41 | ) -> fmt::Result { | ||
42 | let mut first = true; | ||
43 | for e in items { | ||
44 | if !first { | ||
45 | write!(f, "{}", sep)?; | ||
46 | } | ||
47 | first = false; | ||
48 | write!(f, "{}", e)?; | ||
49 | } | ||
50 | Ok(()) | ||
51 | } | ||
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 9063f78a9..7f8f454bc 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -37,6 +37,7 @@ mod join_lines; | |||
37 | mod structure; | 37 | mod structure; |
38 | mod typing; | 38 | mod typing; |
39 | mod matching_brace; | 39 | mod matching_brace; |
40 | mod display; | ||
40 | 41 | ||
41 | #[cfg(test)] | 42 | #[cfg(test)] |
42 | mod marks; | 43 | mod marks; |
@@ -243,10 +244,34 @@ impl<T> RangeInfo<T> { | |||
243 | 244 | ||
244 | #[derive(Debug)] | 245 | #[derive(Debug)] |
245 | pub struct CallInfo { | 246 | pub struct CallInfo { |
246 | pub label: String, | 247 | pub signature: FunctionSignature, |
248 | pub active_parameter: Option<usize>, | ||
249 | } | ||
250 | |||
251 | /// Contains information about a function signature | ||
252 | #[derive(Debug)] | ||
253 | pub struct FunctionSignature { | ||
254 | /// Optional visibility | ||
255 | pub visibility: Option<String>, | ||
256 | /// Name of the function | ||
257 | pub name: Option<String>, | ||
258 | /// Documentation for the function | ||
247 | pub doc: Option<Documentation>, | 259 | pub doc: Option<Documentation>, |
260 | /// Generic parameters | ||
261 | pub generic_parameters: Vec<String>, | ||
262 | /// Parameters of the function | ||
248 | pub parameters: Vec<String>, | 263 | pub parameters: Vec<String>, |
249 | pub active_parameter: Option<usize>, | 264 | /// Optional return type |
265 | pub ret_type: Option<String>, | ||
266 | /// Where predicates | ||
267 | pub where_predicates: Vec<String>, | ||
268 | } | ||
269 | |||
270 | impl FunctionSignature { | ||
271 | pub(crate) fn with_doc_opt(mut self, doc: Option<Documentation>) -> Self { | ||
272 | self.doc = doc; | ||
273 | self | ||
274 | } | ||
250 | } | 275 | } |
251 | 276 | ||
252 | /// `AnalysisHost` stores the current state of the world. | 277 | /// `AnalysisHost` stores the current state of the world. |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 74e91c236..4d6ede316 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -174,6 +174,28 @@ impl Conv for ra_ide_api::Documentation { | |||
174 | } | 174 | } |
175 | } | 175 | } |
176 | 176 | ||
177 | impl Conv for ra_ide_api::FunctionSignature { | ||
178 | type Output = lsp_types::SignatureInformation; | ||
179 | fn conv(self) -> Self::Output { | ||
180 | use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation}; | ||
181 | |||
182 | let label = self.to_string(); | ||
183 | |||
184 | let documentation = self.doc.map(|it| it.conv()); | ||
185 | |||
186 | let parameters: Vec<ParameterInformation> = self | ||
187 | .parameters | ||
188 | .into_iter() | ||
189 | .map(|param| ParameterInformation { | ||
190 | label: ParameterLabel::Simple(param), | ||
191 | documentation: None, | ||
192 | }) | ||
193 | .collect(); | ||
194 | |||
195 | SignatureInformation { label, documentation, parameters: Some(parameters) } | ||
196 | } | ||
197 | } | ||
198 | |||
177 | impl ConvWith for TextEdit { | 199 | impl ConvWith for TextEdit { |
178 | type Ctx = LineIndex; | 200 | type Ctx = LineIndex; |
179 | type Output = Vec<lsp_types::TextEdit>; | 201 | type Output = Vec<lsp_types::TextEdit>; |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 89e96a33a..b96deb061 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -3,8 +3,8 @@ use lsp_types::{ | |||
3 | CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, CodeAction, | 3 | CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, CodeAction, |
4 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, | 4 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, |
5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, | 5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, |
6 | MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, | 6 | MarkupKind, Position, PrepareRenameResponse, Range, |
7 | RenameParams, SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, | 7 | RenameParams,SymbolInformation, TextDocumentIdentifier, TextEdit, |
8 | WorkspaceEdit, | 8 | WorkspaceEdit, |
9 | }; | 9 | }; |
10 | use ra_ide_api::{ | 10 | use ra_ide_api::{ |
@@ -403,26 +403,13 @@ pub fn handle_signature_help( | |||
403 | ) -> Result<Option<req::SignatureHelp>> { | 403 | ) -> Result<Option<req::SignatureHelp>> { |
404 | let position = params.try_conv_with(&world)?; | 404 | let position = params.try_conv_with(&world)?; |
405 | if let Some(call_info) = world.analysis().call_info(position)? { | 405 | if let Some(call_info) = world.analysis().call_info(position)? { |
406 | let parameters: Vec<ParameterInformation> = call_info | 406 | let active_parameter = call_info.active_parameter.map(|it| it as i64); |
407 | .parameters | 407 | let sig_info = call_info.signature.conv(); |
408 | .into_iter() | ||
409 | .map(|param| ParameterInformation { | ||
410 | label: ParameterLabel::Simple(param.clone()), | ||
411 | documentation: None, | ||
412 | }) | ||
413 | .collect(); | ||
414 | 408 | ||
415 | let documentation = call_info.doc.map(|it| it.conv()); | ||
416 | |||
417 | let sig_info = SignatureInformation { | ||
418 | label: call_info.label, | ||
419 | documentation, | ||
420 | parameters: Some(parameters), | ||
421 | }; | ||
422 | Ok(Some(req::SignatureHelp { | 409 | Ok(Some(req::SignatureHelp { |
423 | signatures: vec![sig_info], | 410 | signatures: vec![sig_info], |
424 | active_signature: Some(0), | 411 | active_signature: Some(0), |
425 | active_parameter: call_info.active_parameter.map(|it| it as i64), | 412 | active_parameter, |
426 | })) | 413 | })) |
427 | } else { | 414 | } else { |
428 | Ok(None) | 415 | Ok(None) |