aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/function.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/function.rs')
-rw-r--r--crates/ra_hir/src/function.rs79
1 files changed, 75 insertions, 4 deletions
diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs
index 75ef308ae..4627be071 100644
--- a/crates/ra_hir/src/function.rs
+++ b/crates/ra_hir/src/function.rs
@@ -11,9 +11,9 @@ 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}; 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; 16pub use self::scope::{FnScopes, ScopesWithSyntaxMapping};
17 17
18#[derive(Debug, Clone, PartialEq, Eq)] 18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct Function { 19pub struct Function {
@@ -36,8 +36,25 @@ impl Function {
36 ast::FnDef::cast(syntax.borrowed()).unwrap().owned() 36 ast::FnDef::cast(syntax.borrowed()).unwrap().owned()
37 } 37 }
38 38
39 pub fn scopes(&self, db: &impl HirDatabase) -> Arc<FnScopes> { 39 pub fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> {
40 db.fn_scopes(self.def_id) 40 db.body_hir(self.def_id)
41 }
42
43 pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Cancelable<Arc<BodySyntaxMapping>> {
44 db.body_syntax_mapping(self.def_id)
45 }
46
47 pub fn scopes(&self, db: &impl HirDatabase) -> Cancelable<ScopesWithSyntaxMapping> {
48 let scopes = db.fn_scopes(self.def_id)?;
49 let syntax_mapping = db.body_syntax_mapping(self.def_id)?;
50 Ok(ScopesWithSyntaxMapping {
51 scopes,
52 syntax_mapping,
53 })
54 }
55
56 pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
57 db.fn_signature(self.def_id)
41 } 58 }
42 59
43 pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { 60 pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
@@ -63,6 +80,60 @@ impl Function {
63 } 80 }
64} 81}
65 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
66#[derive(Debug, Clone)] 137#[derive(Debug, Clone)]
67pub struct FnSignatureInfo { 138pub struct FnSignatureInfo {
68 pub name: String, 139 pub name: String,