diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-08 17:35:08 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-08 17:35:08 +0000 |
commit | 1c25bf05d714680c048d250a5d39e8a4c25f0c31 (patch) | |
tree | 9879fc268f2812576839118cf7e4c88df180a30b /crates/ra_hir/src/code_model_impl/function.rs | |
parent | 3b166aee3c116762c817f1acd0f5e01e48452932 (diff) | |
parent | ac92973a6c5934377c6eca9906f3b7f17e220d4e (diff) |
Merge #467
467: move function to code_model_api r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/code_model_impl/function.rs')
-rw-r--r-- | crates/ra_hir/src/code_model_impl/function.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs new file mode 100644 index 000000000..13c57ed21 --- /dev/null +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -0,0 +1,82 @@ | |||
1 | mod scope; | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use ra_db::Cancelable; | ||
6 | use ra_syntax::{ | ||
7 | TreePtr, | ||
8 | ast::{self, AstNode}, | ||
9 | }; | ||
10 | |||
11 | use crate::{ | ||
12 | DefId, DefKind, HirDatabase, Name, Function, FnSignature, Module, | ||
13 | type_ref::{TypeRef, Mutability}, | ||
14 | expr::Body, | ||
15 | impl_block::ImplBlock, | ||
16 | }; | ||
17 | |||
18 | pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; | ||
19 | |||
20 | impl Function { | ||
21 | pub(crate) fn new(def_id: DefId) -> Function { | ||
22 | Function { def_id } | ||
23 | } | ||
24 | |||
25 | pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> TreePtr<ast::FnDef> { | ||
26 | let def_loc = self.def_id.loc(db); | ||
27 | assert!(def_loc.kind == DefKind::Function); | ||
28 | let syntax = db.file_item(def_loc.source_item_id); | ||
29 | ast::FnDef::cast(&syntax).unwrap().to_owned() | ||
30 | } | ||
31 | |||
32 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> { | ||
33 | db.body_hir(self.def_id) | ||
34 | } | ||
35 | |||
36 | pub(crate) fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> { | ||
37 | self.def_id.module(db) | ||
38 | } | ||
39 | |||
40 | /// The containing impl block, if this is a method. | ||
41 | pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> { | ||
42 | self.def_id.impl_block(db) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | impl FnSignature { | ||
47 | pub(crate) fn fn_signature_query(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { | ||
48 | let func = Function::new(def_id); | ||
49 | let node = func.source(db); | ||
50 | let mut args = Vec::new(); | ||
51 | if let Some(param_list) = node.param_list() { | ||
52 | if let Some(self_param) = param_list.self_param() { | ||
53 | let self_type = if let Some(type_ref) = self_param.type_ref() { | ||
54 | TypeRef::from_ast(type_ref) | ||
55 | } else { | ||
56 | let self_type = TypeRef::Path(Name::self_type().into()); | ||
57 | match self_param.flavor() { | ||
58 | ast::SelfParamFlavor::Owned => self_type, | ||
59 | ast::SelfParamFlavor::Ref => { | ||
60 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
61 | } | ||
62 | ast::SelfParamFlavor::MutRef => { | ||
63 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
64 | } | ||
65 | } | ||
66 | }; | ||
67 | args.push(self_type); | ||
68 | } | ||
69 | for param in param_list.params() { | ||
70 | let type_ref = TypeRef::from_ast_opt(param.type_ref()); | ||
71 | args.push(type_ref); | ||
72 | } | ||
73 | } | ||
74 | let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { | ||
75 | TypeRef::from_ast(type_ref) | ||
76 | } else { | ||
77 | TypeRef::unit() | ||
78 | }; | ||
79 | let sig = FnSignature { args, ret_type }; | ||
80 | Arc::new(sig) | ||
81 | } | ||
82 | } | ||