From f8a2b533045757c42c206b2596448baf4737f1f0 Mon Sep 17 00:00:00 2001 From: "Jeremy A. Kolb" Date: Tue, 9 Oct 2018 10:08:17 -0400 Subject: Language Server: textDocument/signatureHelp Implements a pretty barebones function signature help mechanism in the language server. Users can use `Analysis::resolve_callback()` to get basic information about a call site. Fixes #102 --- crates/ra_analysis/src/descriptors.rs | 56 ++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'crates/ra_analysis/src/descriptors.rs') diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs index 0731b5572..4dcac1aa2 100644 --- a/crates/ra_analysis/src/descriptors.rs +++ b/crates/ra_analysis/src/descriptors.rs @@ -4,7 +4,8 @@ use std::{ use relative_path::RelativePathBuf; use ra_syntax::{ SmolStr, - ast::{self, NameOwner}, + ast::{self, NameOwner, AstNode, TypeParamsOwner}, + text_utils::is_subrange }; use { FileId, @@ -218,3 +219,56 @@ fn resolve_submodule( } (points_to, problem) } + +#[derive(Debug, Clone)] +pub struct FnDescriptor { + pub name: Option, + pub label : String, + pub ret_type: Option, + pub params: Vec, +} + +impl FnDescriptor { + pub fn new(node: ast::FnDef) -> Self { + let name = node.name().map(|name| name.text().to_string()); + + // Strip the body out for the label. + let label : String = if let Some(body) = node.body() { + let body_range = body.syntax().range(); + let label : String = node.syntax().children() + .filter(|child| !is_subrange(body_range, child.range())) + .map(|node| node.text().to_string()) + .collect(); + label + } else { + node.syntax().text().to_string() + }; + + let params = FnDescriptor::param_list(node); + let ret_type = node.ret_type().map(|r| r.syntax().text().to_string()); + + FnDescriptor { + name, + ret_type, + params, + label + } + } + + fn param_list(node: ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + // Maybe use param.pat here? See if we can just extract the name? + //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); + res.extend(param_list.params() + .filter_map(|p| p.pat()) + .map(|pat| pat.syntax().text().to_string()) + ); + } + res + } +} \ No newline at end of file -- cgit v1.2.3