aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/function.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-01-06 00:00:34 +0000
committerFlorian Diebold <[email protected]>2019-01-06 00:13:31 +0000
commit98957f4e6f66469310072dff5dfc3e521a7cd555 (patch)
tree8c8075dcc234c3548f63bfb74fbc9d5806933c14 /crates/ra_hir/src/function.rs
parente5a6cf815372150ad40dee995b7b89f29e701427 (diff)
Add fn signature query
Diffstat (limited to 'crates/ra_hir/src/function.rs')
-rw-r--r--crates/ra_hir/src/function.rs60
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
14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}}; 14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}, type_ref::{TypeRef, Mutability}, Name};
15 15
16pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; 16pub 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)]
85pub struct FnSignature {
86 args: Vec<TypeRef>,
87 ret_type: TypeRef,
88}
89
90impl 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
100pub(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)]
80pub struct FnSignatureInfo { 138pub struct FnSignatureInfo {
81 pub name: String, 139 pub name: String,