diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion.rs | 61 |
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; | |||
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 { |