diff options
Diffstat (limited to 'crates/ra_hir/src/function.rs')
-rw-r--r-- | crates/ra_hir/src/function.rs | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs index 4dbdf81d8..4627be071 100644 --- a/crates/ra_hir/src/function.rs +++ b/crates/ra_hir/src/function.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, | 11 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}}; | 14 | use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}, type_ref::{TypeRef, Mutability}, Name}; |
15 | 15 | ||
16 | pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; | 16 | pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; |
17 | 17 | ||
@@ -53,6 +53,10 @@ impl Function { | |||
53 | }) | 53 | }) |
54 | } | 54 | } |
55 | 55 | ||
56 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { | ||
57 | db.fn_signature(self.def_id) | ||
58 | } | ||
59 | |||
56 | pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { | 60 | pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { |
57 | let syntax = self.syntax(db); | 61 | let syntax = self.syntax(db); |
58 | FnSignatureInfo::new(syntax.borrowed()) | 62 | FnSignatureInfo::new(syntax.borrowed()) |
@@ -76,6 +80,60 @@ impl Function { | |||
76 | } | 80 | } |
77 | } | 81 | } |
78 | 82 | ||
83 | /// The declared signature of a function. | ||
84 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
85 | pub struct FnSignature { | ||
86 | args: Vec<TypeRef>, | ||
87 | ret_type: TypeRef, | ||
88 | } | ||
89 | |||
90 | impl FnSignature { | ||
91 | pub fn args(&self) -> &[TypeRef] { | ||
92 | &self.args | ||
93 | } | ||
94 | |||
95 | pub fn ret_type(&self) -> &TypeRef { | ||
96 | &self.ret_type | ||
97 | } | ||
98 | } | ||
99 | |||
100 | pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { | ||
101 | let func = Function::new(def_id); | ||
102 | let syntax = func.syntax(db); | ||
103 | let node = syntax.borrowed(); | ||
104 | let mut args = Vec::new(); | ||
105 | if let Some(param_list) = node.param_list() { | ||
106 | if let Some(self_param) = param_list.self_param() { | ||
107 | let self_type = if let Some(type_ref) = self_param.type_ref() { | ||
108 | TypeRef::from_ast(type_ref) | ||
109 | } else { | ||
110 | let self_type = TypeRef::Path(Name::self_type().into()); | ||
111 | match self_param.flavor() { | ||
112 | ast::SelfParamFlavor::Owned => self_type, | ||
113 | ast::SelfParamFlavor::Ref => { | ||
114 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
115 | } | ||
116 | ast::SelfParamFlavor::MutRef => { | ||
117 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
118 | } | ||
119 | } | ||
120 | }; | ||
121 | args.push(self_type); | ||
122 | } | ||
123 | for param in param_list.params() { | ||
124 | let type_ref = TypeRef::from_ast_opt(param.type_ref()); | ||
125 | args.push(type_ref); | ||
126 | } | ||
127 | } | ||
128 | let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { | ||
129 | TypeRef::from_ast(type_ref) | ||
130 | } else { | ||
131 | TypeRef::unit() | ||
132 | }; | ||
133 | let sig = FnSignature { args, ret_type }; | ||
134 | Arc::new(sig) | ||
135 | } | ||
136 | |||
79 | #[derive(Debug, Clone)] | 137 | #[derive(Debug, Clone)] |
80 | pub struct FnSignatureInfo { | 138 | pub struct FnSignatureInfo { |
81 | pub name: String, | 139 | pub name: String, |