aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/display.rs103
-rw-r--r--crates/ra_ide_api/src/display/function_signature.rs101
2 files changed, 104 insertions, 100 deletions
diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs
index e29ae3371..f1717b008 100644
--- a/crates/ra_ide_api/src/display.rs
+++ b/crates/ra_ide_api/src/display.rs
@@ -1,18 +1,15 @@
1//! This module contains utilities for turning SyntaxNodes and HIR types 1//! This module contains utilities for turning SyntaxNodes and HIR types
2//! into things that may be used to render in a UI. 2//! into things that may be used to render in a UI.
3 3
4mod function_signature;
4mod navigation_target; 5mod navigation_target;
5mod structure; 6mod structure;
6 7
7use super::*; 8use ra_syntax::{ast::{self, AstNode, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}};
8use std::fmt::{self, Display};
9use join_to_string::join;
10use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}};
11use std::convert::From;
12use hir::Docs;
13 9
14pub use navigation_target::NavigationTarget; 10pub use navigation_target::NavigationTarget;
15pub use structure::{StructureNode, file_structure}; 11pub use structure::{StructureNode, file_structure};
12pub use function_signature::FunctionSignature;
16 13
17pub(crate) fn function_label(node: &ast::FnDef) -> String { 14pub(crate) fn function_label(node: &ast::FnDef) -> String {
18 FunctionSignature::from(node).to_string() 15 FunctionSignature::from(node).to_string()
@@ -40,100 +37,6 @@ pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String {
40 label.trim().to_owned() 37 label.trim().to_owned()
41} 38}
42 39
43/// Contains information about a function signature
44#[derive(Debug)]
45pub struct FunctionSignature {
46 /// Optional visibility
47 pub visibility: Option<String>,
48 /// Name of the function
49 pub name: Option<String>,
50 /// Documentation for the function
51 pub doc: Option<Documentation>,
52 /// Generic parameters
53 pub generic_parameters: Vec<String>,
54 /// Parameters of the function
55 pub parameters: Vec<String>,
56 /// Optional return type
57 pub ret_type: Option<String>,
58 /// Where predicates
59 pub where_predicates: Vec<String>,
60}
61
62impl FunctionSignature {
63 pub(crate) fn with_doc_opt(mut self, doc: Option<Documentation>) -> Self {
64 self.doc = doc;
65 self
66 }
67
68 pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self {
69 let doc = function.docs(db);
70 let (_, ast_node) = function.source(db);
71 FunctionSignature::from(&*ast_node).with_doc_opt(doc)
72 }
73}
74
75impl From<&'_ ast::FnDef> for FunctionSignature {
76 fn from(node: &ast::FnDef) -> FunctionSignature {
77 fn param_list(node: &ast::FnDef) -> Vec<String> {
78 let mut res = vec![];
79 if let Some(param_list) = node.param_list() {
80 if let Some(self_param) = param_list.self_param() {
81 res.push(self_param.syntax().text().to_string())
82 }
83
84 res.extend(param_list.params().map(|param| param.syntax().text().to_string()));
85 }
86 res
87 }
88
89 FunctionSignature {
90 visibility: node.visibility().map(|n| n.syntax().text().to_string()),
91 name: node.name().map(|n| n.text().to_string()),
92 ret_type: node
93 .ret_type()
94 .and_then(|r| r.type_ref())
95 .map(|n| n.syntax().text().to_string()),
96 parameters: param_list(node),
97 generic_parameters: generic_parameters(node),
98 where_predicates: where_predicates(node),
99 // docs are processed separately
100 doc: None,
101 }
102 }
103}
104
105impl Display for FunctionSignature {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 if let Some(t) = &self.visibility {
108 write!(f, "{} ", t)?;
109 }
110
111 if let Some(name) = &self.name {
112 write!(f, "fn {}", name)?;
113 }
114
115 if !self.generic_parameters.is_empty() {
116 join(self.generic_parameters.iter())
117 .separator(", ")
118 .surround_with("<", ">")
119 .to_fmt(f)?;
120 }
121
122 join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?;
123
124 if let Some(t) = &self.ret_type {
125 write!(f, " -> {}", t)?;
126 }
127
128 if !self.where_predicates.is_empty() {
129 write!(f, "\nwhere ")?;
130 join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?;
131 }
132
133 Ok(())
134 }
135}
136
137pub(crate) fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> { 40pub(crate) fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> {
138 let mut res = vec![]; 41 let mut res = vec![];
139 if let Some(type_params) = node.type_param_list() { 42 if let Some(type_params) = node.type_param_list() {
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs
new file mode 100644
index 000000000..d09950bce
--- /dev/null
+++ b/crates/ra_ide_api/src/display/function_signature.rs
@@ -0,0 +1,101 @@
1use super::{where_predicates, generic_parameters};
2use crate::db;
3use std::fmt::{self, Display};
4use join_to_string::join;
5use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
6use std::convert::From;
7use hir::{Docs, Documentation};
8
9/// Contains information about a function signature
10#[derive(Debug)]
11pub struct FunctionSignature {
12 /// Optional visibility
13 pub visibility: Option<String>,
14 /// Name of the function
15 pub name: Option<String>,
16 /// Documentation for the function
17 pub doc: Option<Documentation>,
18 /// Generic parameters
19 pub generic_parameters: Vec<String>,
20 /// Parameters of the function
21 pub parameters: Vec<String>,
22 /// Optional return type
23 pub ret_type: Option<String>,
24 /// Where predicates
25 pub where_predicates: Vec<String>,
26}
27
28impl FunctionSignature {
29 pub(crate) fn with_doc_opt(mut self, doc: Option<Documentation>) -> Self {
30 self.doc = doc;
31 self
32 }
33
34 pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self {
35 let doc = function.docs(db);
36 let (_, ast_node) = function.source(db);
37 FunctionSignature::from(&*ast_node).with_doc_opt(doc)
38 }
39}
40
41impl From<&'_ ast::FnDef> for FunctionSignature {
42 fn from(node: &ast::FnDef) -> FunctionSignature {
43 fn param_list(node: &ast::FnDef) -> Vec<String> {
44 let mut res = vec![];
45 if let Some(param_list) = node.param_list() {
46 if let Some(self_param) = param_list.self_param() {
47 res.push(self_param.syntax().text().to_string())
48 }
49
50 res.extend(param_list.params().map(|param| param.syntax().text().to_string()));
51 }
52 res
53 }
54
55 FunctionSignature {
56 visibility: node.visibility().map(|n| n.syntax().text().to_string()),
57 name: node.name().map(|n| n.text().to_string()),
58 ret_type: node
59 .ret_type()
60 .and_then(|r| r.type_ref())
61 .map(|n| n.syntax().text().to_string()),
62 parameters: param_list(node),
63 generic_parameters: generic_parameters(node),
64 where_predicates: where_predicates(node),
65 // docs are processed separately
66 doc: None,
67 }
68 }
69}
70
71impl Display for FunctionSignature {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 if let Some(t) = &self.visibility {
74 write!(f, "{} ", t)?;
75 }
76
77 if let Some(name) = &self.name {
78 write!(f, "fn {}", name)?;
79 }
80
81 if !self.generic_parameters.is_empty() {
82 join(self.generic_parameters.iter())
83 .separator(", ")
84 .surround_with("<", ">")
85 .to_fmt(f)?;
86 }
87
88 join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?;
89
90 if let Some(t) = &self.ret_type {
91 write!(f, " -> {}", t)?;
92 }
93
94 if !self.where_predicates.is_empty() {
95 write!(f, "\nwhere ")?;
96 join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?;
97 }
98
99 Ok(())
100 }
101}