diff options
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r-- | crates/ra_ide_api/src/display/function_signature.rs | 112 |
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 | ||
3 | use std::fmt::{self, Display}; | 3 | use std::fmt::{self, Display}; |
4 | 4 | ||
5 | use hir::{Docs, Documentation, HasSource}; | 5 | use hir::{Docs, Documentation, HasSource, HirDisplay}; |
6 | use join_to_string::join; | 6 | use join_to_string::join; |
7 | use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; | 7 | use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; |
8 | use std::convert::From; | 8 | use 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)] | ||
16 | pub 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)] |
17 | pub struct FunctionSignature { | 25 | pub 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 | ||
47 | impl From<&'_ ast::FnDef> for FunctionSignature { | 149 | impl 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() { |