diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/function.rs | 61 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 1 |
3 files changed, 68 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 5bbdaa4b2..02e649cc7 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -8,6 +8,7 @@ use ra_syntax::ast; | |||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 10 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | function::FunctionData, | ||
11 | generics::GenericParams, | 12 | generics::GenericParams, |
12 | impls::ImplData, | 13 | impls::ImplData, |
13 | nameres::{ | 14 | nameres::{ |
@@ -16,7 +17,8 @@ use crate::{ | |||
16 | }, | 17 | }, |
17 | traits::TraitData, | 18 | traits::TraitData, |
18 | type_alias::TypeAliasData, | 19 | type_alias::TypeAliasData, |
19 | DefWithBodyId, EnumId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, TypeAliasId, | 20 | DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, |
21 | TypeAliasId, | ||
20 | }; | 22 | }; |
21 | 23 | ||
22 | #[salsa::query_group(InternDatabaseStorage)] | 24 | #[salsa::query_group(InternDatabaseStorage)] |
@@ -68,6 +70,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
68 | #[salsa::invoke(TypeAliasData::type_alias_data_query)] | 70 | #[salsa::invoke(TypeAliasData::type_alias_data_query)] |
69 | fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>; | 71 | fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>; |
70 | 72 | ||
73 | #[salsa::invoke(FunctionData::fn_data_query)] | ||
74 | fn function_data(&self, func: FunctionId) -> Arc<FunctionData>; | ||
75 | |||
71 | #[salsa::invoke(Body::body_with_source_map_query)] | 76 | #[salsa::invoke(Body::body_with_source_map_query)] |
72 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); | 77 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); |
73 | 78 | ||
diff --git a/crates/ra_hir_def/src/function.rs b/crates/ra_hir_def/src/function.rs new file mode 100644 index 000000000..33265275e --- /dev/null +++ b/crates/ra_hir_def/src/function.rs | |||
@@ -0,0 +1,61 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use hir_expand::name::{self, AsName, Name}; | ||
4 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | ||
5 | |||
6 | use crate::{ | ||
7 | db::DefDatabase2, | ||
8 | type_ref::{Mutability, TypeRef}, | ||
9 | FunctionId, HasSource, Lookup, | ||
10 | }; | ||
11 | |||
12 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
13 | pub struct FunctionData { | ||
14 | pub name: Name, | ||
15 | pub params: Vec<TypeRef>, | ||
16 | pub ret_type: TypeRef, | ||
17 | /// True if the first param is `self`. This is relevant to decide whether this | ||
18 | /// can be called as a method. | ||
19 | pub has_self_param: bool, | ||
20 | } | ||
21 | |||
22 | impl FunctionData { | ||
23 | pub(crate) fn fn_data_query(db: &impl DefDatabase2, func: FunctionId) -> Arc<FunctionData> { | ||
24 | let src = func.lookup(db).source(db); | ||
25 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | ||
26 | let mut params = Vec::new(); | ||
27 | let mut has_self_param = false; | ||
28 | if let Some(param_list) = src.value.param_list() { | ||
29 | if let Some(self_param) = param_list.self_param() { | ||
30 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | ||
31 | TypeRef::from_ast(type_ref) | ||
32 | } else { | ||
33 | let self_type = TypeRef::Path(name::SELF_TYPE.into()); | ||
34 | match self_param.kind() { | ||
35 | ast::SelfParamKind::Owned => self_type, | ||
36 | ast::SelfParamKind::Ref => { | ||
37 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
38 | } | ||
39 | ast::SelfParamKind::MutRef => { | ||
40 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
41 | } | ||
42 | } | ||
43 | }; | ||
44 | params.push(self_type); | ||
45 | has_self_param = true; | ||
46 | } | ||
47 | for param in param_list.params() { | ||
48 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | ||
49 | params.push(type_ref); | ||
50 | } | ||
51 | } | ||
52 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | ||
53 | TypeRef::from_ast(type_ref) | ||
54 | } else { | ||
55 | TypeRef::unit() | ||
56 | }; | ||
57 | |||
58 | let sig = FunctionData { name, params, ret_type, has_self_param }; | ||
59 | Arc::new(sig) | ||
60 | } | ||
61 | } | ||
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 268144462..14ccad043 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -21,6 +21,7 @@ pub mod generics; | |||
21 | pub mod traits; | 21 | pub mod traits; |
22 | pub mod resolver; | 22 | pub mod resolver; |
23 | pub mod type_alias; | 23 | pub mod type_alias; |
24 | pub mod function; | ||
24 | 25 | ||
25 | #[cfg(test)] | 26 | #[cfg(test)] |
26 | mod test_db; | 27 | mod test_db; |