aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/descriptors.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-10-15 17:41:57 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-10-15 17:41:57 +0100
commite031b65f93f73164a5729cf81ff60299708bc931 (patch)
tree1a891b75af3b436549381e8726c48ec5028a8341 /crates/ra_analysis/src/descriptors.rs
parent8cec1d986161298dbe9cc53f5477e87bfe5d0f47 (diff)
parentc9909f42ba4adf55b1e73e7118b48f1b10c80ac6 (diff)
Merge #110
110: Signature help r=matklad a=kjeremy @matklad Once this is in shape I would like to add tests. I think a separate PR should be done for returning documentation information and markdown. Fixes #102 Co-authored-by: Jeremy A. Kolb <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/descriptors.rs')
-rw-r--r--crates/ra_analysis/src/descriptors.rs56
1 files changed, 55 insertions, 1 deletions
diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs
index 0731b5572..faf945a41 100644
--- a/crates/ra_analysis/src/descriptors.rs
+++ b/crates/ra_analysis/src/descriptors.rs
@@ -4,7 +4,8 @@ use std::{
4use relative_path::RelativePathBuf; 4use relative_path::RelativePathBuf;
5use ra_syntax::{ 5use ra_syntax::{
6 SmolStr, 6 SmolStr,
7 ast::{self, NameOwner}, 7 ast::{self, NameOwner, AstNode},
8 text_utils::is_subrange
8}; 9};
9use { 10use {
10 FileId, 11 FileId,
@@ -218,3 +219,56 @@ fn resolve_submodule(
218 } 219 }
219 (points_to, problem) 220 (points_to, problem)
220} 221}
222
223#[derive(Debug, Clone)]
224pub struct FnDescriptor {
225 pub name: String,
226 pub label : String,
227 pub ret_type: Option<String>,
228 pub params: Vec<String>,
229}
230
231impl FnDescriptor {
232 pub fn new(node: ast::FnDef) -> Option<Self> {
233 let name = node.name()?.text().to_string();
234
235 // Strip the body out for the label.
236 let label : String = if let Some(body) = node.body() {
237 let body_range = body.syntax().range();
238 let label : String = node.syntax().children()
239 .filter(|child| !is_subrange(body_range, child.range()))
240 .map(|node| node.text().to_string())
241 .collect();
242 label
243 } else {
244 node.syntax().text().to_string()
245 };
246
247 let params = FnDescriptor::param_list(node);
248 let ret_type = node.ret_type().map(|r| r.syntax().text().to_string());
249
250 Some(FnDescriptor {
251 name,
252 ret_type,
253 params,
254 label
255 })
256 }
257
258 fn param_list(node: ast::FnDef) -> Vec<String> {
259 let mut res = vec![];
260 if let Some(param_list) = node.param_list() {
261 if let Some(self_param) = param_list.self_param() {
262 res.push(self_param.syntax().text().to_string())
263 }
264
265 // Maybe use param.pat here? See if we can just extract the name?
266 //res.extend(param_list.params().map(|p| p.syntax().text().to_string()));
267 res.extend(param_list.params()
268 .filter_map(|p| p.pat())
269 .map(|pat| pat.syntax().text().to_string())
270 );
271 }
272 res
273 }
274} \ No newline at end of file