aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion.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/completion.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/completion.rs')
-rw-r--r--crates/ra_ide_api/src/completion.rs61
1 files changed, 46 insertions, 15 deletions
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;
13mod complete_postfix; 13mod complete_postfix;
14 14
15use ra_db::SourceDatabase; 15use ra_db::SourceDatabase;
16use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; 16use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}};
17 17
18use crate::{ 18use 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
74pub fn function_label(node: &ast::FnDef) -> Option<String> { 75pub 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(); 84pub 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
92pub 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
119pub fn function_label(node: &ast::FnDef) -> Option<String> {
120 function_signature(node).map(|n| n.to_string())
90} 121}
91 122
92pub fn const_label(node: &ast::ConstDef) -> String { 123pub fn const_label(node: &ast::ConstDef) -> String {