From 0e49abb7fbe9239b97f0b7168ec359014c63f8c0 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Tue, 12 Mar 2019 09:24:46 +0200 Subject: 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. --- crates/ra_ide_api/src/completion.rs | 61 ++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'crates/ra_ide_api/src/completion.rs') 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; mod complete_postfix; use ra_db::SourceDatabase; -use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; +use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; use crate::{ db, FilePosition, + FunctionSignature, completion::{ completion_item::{Completions, CompletionKind}, completion_context::CompletionContext, @@ -71,22 +72,52 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti Some(acc) } -pub fn function_label(node: &ast::FnDef) -> Option { - let label: String = if let Some(body) = node.body() { - let body_range = body.syntax().range(); - let label: String = node - .syntax() - .children_with_tokens() - .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body - .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) // Filter out comments and attrs - .map(|node| node.to_string()) - .collect(); - label - } else { - node.syntax().text().to_string() +pub fn generic_parameters(node: &N) -> Vec { + let mut res = vec![]; + if let Some(type_params) = node.type_param_list() { + res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); + res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); + } + res +} + +pub fn where_predicates(node: &N) -> Vec { + let mut res = vec![]; + if let Some(clause) = node.where_clause() { + res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); + } + res +} + +pub fn function_signature(node: &ast::FnDef) -> Option { + 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()) + } + + res.extend(param_list.params().map(|param| param.syntax().text().to_string())); + } + res + } + + let sig = FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node.ret_type().and_then(|r| r.type_ref()).map(|n| n.syntax().text().to_string()), + parameters: param_list(node), + generic_parameters: generic_parameters(node), + where_predicates: where_predicates(node), + // docs are processed separately + doc: None, }; - Some(label.trim().to_owned()) + Some(sig) +} + +pub fn function_label(node: &ast::FnDef) -> Option { + function_signature(node).map(|n| n.to_string()) } pub fn const_label(node: &ast::ConstDef) -> String { -- cgit v1.2.3