aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r--crates/ra_ide_api/src/display/function_signature.rs112
1 files changed, 110 insertions, 2 deletions
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs
index 43f022ccd..9075ca443 100644
--- a/crates/ra_ide_api/src/display/function_signature.rs
+++ b/crates/ra_ide_api/src/display/function_signature.rs
@@ -2,7 +2,7 @@
2 2
3use std::fmt::{self, Display}; 3use std::fmt::{self, Display};
4 4
5use hir::{Docs, Documentation, HasSource}; 5use hir::{Docs, Documentation, HasSource, HirDisplay};
6use join_to_string::join; 6use join_to_string::join;
7use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; 7use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
8use std::convert::From; 8use std::convert::From;
@@ -12,9 +12,18 @@ use crate::{
12 display::{generic_parameters, where_predicates}, 12 display::{generic_parameters, where_predicates},
13}; 13};
14 14
15#[derive(Debug)]
16pub enum CallableKind {
17 Function,
18 StructConstructor,
19 VariantConstructor,
20 Macro,
21}
22
15/// Contains information about a function signature 23/// Contains information about a function signature
16#[derive(Debug)] 24#[derive(Debug)]
17pub struct FunctionSignature { 25pub struct FunctionSignature {
26 pub kind: CallableKind,
18 /// Optional visibility 27 /// Optional visibility
19 pub visibility: Option<String>, 28 pub visibility: Option<String>,
20 /// Name of the function 29 /// Name of the function
@@ -42,6 +51,99 @@ impl FunctionSignature {
42 let ast_node = function.source(db).ast; 51 let ast_node = function.source(db).ast;
43 FunctionSignature::from(&ast_node).with_doc_opt(doc) 52 FunctionSignature::from(&ast_node).with_doc_opt(doc)
44 } 53 }
54
55 pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Option<Self> {
56 let node: ast::StructDef = st.source(db).ast;
57 match node.kind() {
58 ast::StructKind::Named(_) => return None,
59 _ => (),
60 };
61
62 let params = st
63 .fields(db)
64 .into_iter()
65 .map(|field: hir::StructField| {
66 let ty = field.ty(db);
67 format!("{}", ty.display(db))
68 })
69 .collect();
70
71 Some(
72 FunctionSignature {
73 kind: CallableKind::StructConstructor,
74 visibility: node.visibility().map(|n| n.syntax().text().to_string()),
75 name: node.name().map(|n| n.text().to_string()),
76 ret_type: node.name().map(|n| n.text().to_string()),
77 parameters: params,
78 generic_parameters: generic_parameters(&node),
79 where_predicates: where_predicates(&node),
80 doc: None,
81 }
82 .with_doc_opt(st.docs(db)),
83 )
84 }
85
86 pub(crate) fn from_enum_variant(
87 db: &db::RootDatabase,
88 variant: hir::EnumVariant,
89 ) -> Option<Self> {
90 let node: ast::EnumVariant = variant.source(db).ast;
91 match node.kind() {
92 ast::StructKind::Named(_) | ast::StructKind::Unit => return None,
93 _ => (),
94 };
95
96 let parent_name = match variant.parent_enum(db).name(db) {
97 Some(name) => name.to_string(),
98 None => "missing".into(),
99 };
100
101 let name = format!("{}::{}", parent_name, variant.name(db).unwrap());
102
103 let params = variant
104 .fields(db)
105 .into_iter()
106 .map(|field: hir::StructField| {
107 let name = field.name(db);
108 let ty = field.ty(db);
109 format!("{}: {}", name, ty.display(db))
110 })
111 .collect();
112
113 Some(
114 FunctionSignature {
115 kind: CallableKind::VariantConstructor,
116 visibility: None,
117 name: Some(name),
118 ret_type: None,
119 parameters: params,
120 generic_parameters: vec![],
121 where_predicates: vec![],
122 doc: None,
123 }
124 .with_doc_opt(variant.docs(db)),
125 )
126 }
127
128 pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
129 let node: ast::MacroCall = macro_def.source(db).ast;
130
131 let params = vec![];
132
133 Some(
134 FunctionSignature {
135 kind: CallableKind::Macro,
136 visibility: None,
137 name: node.name().map(|n| n.text().to_string()),
138 ret_type: None,
139 parameters: params,
140 generic_parameters: vec![],
141 where_predicates: vec![],
142 doc: None,
143 }
144 .with_doc_opt(macro_def.docs(db)),
145 )
146 }
45} 147}
46 148
47impl From<&'_ ast::FnDef> for FunctionSignature { 149impl From<&'_ ast::FnDef> for FunctionSignature {
@@ -59,6 +161,7 @@ impl From<&'_ ast::FnDef> for FunctionSignature {
59 } 161 }
60 162
61 FunctionSignature { 163 FunctionSignature {
164 kind: CallableKind::Function,
62 visibility: node.visibility().map(|n| n.syntax().text().to_string()), 165 visibility: node.visibility().map(|n| n.syntax().text().to_string()),
63 name: node.name().map(|n| n.text().to_string()), 166 name: node.name().map(|n| n.text().to_string()),
64 ret_type: node 167 ret_type: node
@@ -81,7 +184,12 @@ impl Display for FunctionSignature {
81 } 184 }
82 185
83 if let Some(name) = &self.name { 186 if let Some(name) = &self.name {
84 write!(f, "fn {}", name)?; 187 match self.kind {
188 CallableKind::Function => write!(f, "fn {}", name)?,
189 CallableKind::StructConstructor => write!(f, "struct {}", name)?,
190 CallableKind::VariantConstructor => write!(f, "{}", name)?,
191 CallableKind::Macro => write!(f, "{}!", name)?,
192 }
85 } 193 }
86 194
87 if !self.generic_parameters.is_empty() { 195 if !self.generic_parameters.is_empty() {