diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 17 | ||||
-rw-r--r-- | crates/ra_ide/src/display.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/display/function_signature.rs | 152 |
3 files changed, 7 insertions, 180 deletions
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 6aab93e17..c7b74e635 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -11,10 +11,7 @@ use crate::{ | |||
11 | completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, | 11 | completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, |
12 | CompletionKind, Completions, | 12 | CompletionKind, Completions, |
13 | }, | 13 | }, |
14 | display::{ | 14 | display::{const_label, function_declaration, macro_label, type_label}, |
15 | const_label, function_declaration, function_signature::FunctionSignature, macro_label, | ||
16 | type_label, | ||
17 | }, | ||
18 | CompletionScore, RootDatabase, | 15 | CompletionScore, RootDatabase, |
19 | }; | 16 | }; |
20 | 17 | ||
@@ -198,7 +195,6 @@ impl Completions { | |||
198 | 195 | ||
199 | let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); | 196 | let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); |
200 | let ast_node = func.source(ctx.db).value; | 197 | let ast_node = func.source(ctx.db).value; |
201 | let function_signature = FunctionSignature::from(&ast_node); | ||
202 | 198 | ||
203 | let mut builder = | 199 | let mut builder = |
204 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone()) | 200 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone()) |
@@ -211,11 +207,12 @@ impl Completions { | |||
211 | .set_deprecated(is_deprecated(func, ctx.db)) | 207 | .set_deprecated(is_deprecated(func, ctx.db)) |
212 | .detail(function_declaration(&ast_node)); | 208 | .detail(function_declaration(&ast_node)); |
213 | 209 | ||
214 | let params = function_signature | 210 | let params = ast_node |
215 | .parameter_names | 211 | .param_list() |
216 | .iter() | 212 | .into_iter() |
217 | .skip(if function_signature.has_self_param { 1 } else { 0 }) | 213 | .flat_map(|it| it.params()) |
218 | .map(|name| name.trim_start_matches('_').into()) | 214 | .flat_map(|it| it.pat()) |
215 | .map(|pat| pat.to_string().trim_start_matches('_').into()) | ||
219 | .collect(); | 216 | .collect(); |
220 | 217 | ||
221 | builder = builder.add_call_parens(ctx, name, Params::Named(params)); | 218 | builder = builder.add_call_parens(ctx, name, Params::Named(params)); |
diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs index 34ce32e81..6d4151dd8 100644 --- a/crates/ra_ide/src/display.rs +++ b/crates/ra_ide/src/display.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | //! This module contains utilities for turning SyntaxNodes and HIR types | 1 | //! This module contains utilities for turning SyntaxNodes and HIR types |
2 | //! into types that may be used to render in a UI. | 2 | //! into types that may be used to render in a UI. |
3 | 3 | ||
4 | pub(crate) mod function_signature; | ||
5 | mod navigation_target; | 4 | mod navigation_target; |
6 | mod short_label; | 5 | mod short_label; |
7 | 6 | ||
@@ -77,23 +76,6 @@ pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String { | |||
77 | label.trim().to_owned() | 76 | label.trim().to_owned() |
78 | } | 77 | } |
79 | 78 | ||
80 | pub(crate) fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> { | ||
81 | let mut res = vec![]; | ||
82 | if let Some(type_params) = node.type_param_list() { | ||
83 | res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); | ||
84 | res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); | ||
85 | } | ||
86 | res | ||
87 | } | ||
88 | |||
89 | pub(crate) fn where_predicates<N: TypeParamsOwner>(node: &N) -> Vec<String> { | ||
90 | let mut res = vec![]; | ||
91 | if let Some(clause) = node.where_clause() { | ||
92 | res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); | ||
93 | } | ||
94 | res | ||
95 | } | ||
96 | |||
97 | pub(crate) fn macro_label(node: &ast::MacroCall) -> String { | 79 | pub(crate) fn macro_label(node: &ast::MacroCall) -> String { |
98 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); | 80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); |
99 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; | 81 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; |
diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs deleted file mode 100644 index f6e11357f..000000000 --- a/crates/ra_ide/src/display/function_signature.rs +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | // FIXME: this modules relies on strings and AST way too much, and it should be | ||
4 | // rewritten (matklad 2020-05-07) | ||
5 | use std::convert::From; | ||
6 | |||
7 | use hir::Documentation; | ||
8 | use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; | ||
9 | use stdx::split_delim; | ||
10 | |||
11 | use crate::display::{generic_parameters, where_predicates}; | ||
12 | |||
13 | #[derive(Debug)] | ||
14 | pub(crate) enum CallableKind { | ||
15 | Function, | ||
16 | } | ||
17 | |||
18 | /// Contains information about a function signature | ||
19 | #[derive(Debug)] | ||
20 | pub(crate) struct FunctionSignature { | ||
21 | pub(crate) kind: CallableKind, | ||
22 | /// Optional visibility | ||
23 | pub(crate) visibility: Option<String>, | ||
24 | /// Qualifiers like `async`, `unsafe`, ... | ||
25 | pub(crate) qualifier: FunctionQualifier, | ||
26 | /// Name of the function | ||
27 | pub(crate) name: Option<String>, | ||
28 | /// Documentation for the function | ||
29 | pub(crate) doc: Option<Documentation>, | ||
30 | /// Generic parameters | ||
31 | pub(crate) generic_parameters: Vec<String>, | ||
32 | /// Parameters of the function | ||
33 | pub(crate) parameters: Vec<String>, | ||
34 | /// Parameter names of the function | ||
35 | pub(crate) parameter_names: Vec<String>, | ||
36 | /// Parameter types of the function | ||
37 | pub(crate) parameter_types: Vec<String>, | ||
38 | /// Optional return type | ||
39 | pub(crate) ret_type: Option<String>, | ||
40 | /// Where predicates | ||
41 | pub(crate) where_predicates: Vec<String>, | ||
42 | /// Self param presence | ||
43 | pub(crate) has_self_param: bool, | ||
44 | } | ||
45 | |||
46 | #[derive(Debug, Default)] | ||
47 | pub(crate) struct FunctionQualifier { | ||
48 | // `async` and `const` are mutually exclusive. Do we need to enforcing it here? | ||
49 | pub(crate) is_async: bool, | ||
50 | pub(crate) is_const: bool, | ||
51 | pub(crate) is_unsafe: bool, | ||
52 | /// The string `extern ".."` | ||
53 | pub(crate) extern_abi: Option<String>, | ||
54 | } | ||
55 | |||
56 | impl From<&'_ ast::FnDef> for FunctionSignature { | ||
57 | fn from(node: &ast::FnDef) -> FunctionSignature { | ||
58 | fn param_list(node: &ast::FnDef) -> (bool, Vec<String>, Vec<String>) { | ||
59 | let mut res = vec![]; | ||
60 | let mut res_types = vec![]; | ||
61 | let mut has_self_param = false; | ||
62 | if let Some(param_list) = node.param_list() { | ||
63 | if let Some(self_param) = param_list.self_param() { | ||
64 | has_self_param = true; | ||
65 | let raw_param = self_param.syntax().text().to_string(); | ||
66 | |||
67 | res_types.push( | ||
68 | raw_param | ||
69 | .split(':') | ||
70 | .nth(1) | ||
71 | .and_then(|it| it.get(1..)) | ||
72 | .unwrap_or_else(|| "Self") | ||
73 | .to_string(), | ||
74 | ); | ||
75 | res.push(raw_param); | ||
76 | } | ||
77 | |||
78 | // macro-generated functions are missing whitespace | ||
79 | fn fmt_param(param: ast::Param) -> String { | ||
80 | let text = param.syntax().text().to_string(); | ||
81 | match split_delim(&text, ':') { | ||
82 | Some((left, right)) => format!("{}: {}", left.trim(), right.trim()), | ||
83 | _ => text, | ||
84 | } | ||
85 | } | ||
86 | |||
87 | res.extend(param_list.params().map(fmt_param)); | ||
88 | res_types.extend(param_list.params().map(|param| { | ||
89 | let param_text = param.syntax().text().to_string(); | ||
90 | match param_text.split(':').nth(1).and_then(|it| it.get(1..)) { | ||
91 | Some(it) => it.to_string(), | ||
92 | None => param_text, | ||
93 | } | ||
94 | })); | ||
95 | } | ||
96 | (has_self_param, res, res_types) | ||
97 | } | ||
98 | |||
99 | fn param_name_list(node: &ast::FnDef) -> Vec<String> { | ||
100 | let mut res = vec![]; | ||
101 | if let Some(param_list) = node.param_list() { | ||
102 | if let Some(self_param) = param_list.self_param() { | ||
103 | res.push(self_param.syntax().text().to_string()) | ||
104 | } | ||
105 | |||
106 | res.extend( | ||
107 | param_list | ||
108 | .params() | ||
109 | .map(|param| { | ||
110 | Some( | ||
111 | param | ||
112 | .pat()? | ||
113 | .syntax() | ||
114 | .descendants() | ||
115 | .find_map(ast::Name::cast)? | ||
116 | .text() | ||
117 | .to_string(), | ||
118 | ) | ||
119 | }) | ||
120 | .map(|param| param.unwrap_or_default()), | ||
121 | ); | ||
122 | } | ||
123 | res | ||
124 | } | ||
125 | |||
126 | let (has_self_param, parameters, parameter_types) = param_list(node); | ||
127 | |||
128 | FunctionSignature { | ||
129 | kind: CallableKind::Function, | ||
130 | visibility: node.visibility().map(|n| n.syntax().text().to_string()), | ||
131 | qualifier: FunctionQualifier { | ||
132 | is_async: node.async_token().is_some(), | ||
133 | is_const: node.const_token().is_some(), | ||
134 | is_unsafe: node.unsafe_token().is_some(), | ||
135 | extern_abi: node.abi().map(|n| n.to_string()), | ||
136 | }, | ||
137 | name: node.name().map(|n| n.text().to_string()), | ||
138 | ret_type: node | ||
139 | .ret_type() | ||
140 | .and_then(|r| r.type_ref()) | ||
141 | .map(|n| n.syntax().text().to_string()), | ||
142 | parameters, | ||
143 | parameter_names: param_name_list(node), | ||
144 | parameter_types, | ||
145 | generic_parameters: generic_parameters(node), | ||
146 | where_predicates: where_predicates(node), | ||
147 | // docs are processed separately | ||
148 | doc: None, | ||
149 | has_self_param, | ||
150 | } | ||
151 | } | ||
152 | } | ||