aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model_impl
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model_impl')
-rw-r--r--crates/ra_hir/src/code_model_impl/function.rs23
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs28
2 files changed, 43 insertions, 8 deletions
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs
index 13c57ed21..1bd4cc802 100644
--- a/crates/ra_hir/src/code_model_impl/function.rs
+++ b/crates/ra_hir/src/code_model_impl/function.rs
@@ -5,11 +5,11 @@ use std::sync::Arc;
5use ra_db::Cancelable; 5use ra_db::Cancelable;
6use ra_syntax::{ 6use ra_syntax::{
7 TreePtr, 7 TreePtr,
8 ast::{self, AstNode}, 8 ast::{self, AstNode, NameOwner},
9}; 9};
10 10
11use crate::{ 11use crate::{
12 DefId, DefKind, HirDatabase, Name, Function, FnSignature, Module, 12 DefId, DefKind, HirDatabase, Name, AsName, Function, FnSignature, Module, HirFileId,
13 type_ref::{TypeRef, Mutability}, 13 type_ref::{TypeRef, Mutability},
14 expr::Body, 14 expr::Body,
15 impl_block::ImplBlock, 15 impl_block::ImplBlock,
@@ -22,11 +22,14 @@ impl Function {
22 Function { def_id } 22 Function { def_id }
23 } 23 }
24 24
25 pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> TreePtr<ast::FnDef> { 25 pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> (HirFileId, TreePtr<ast::FnDef>) {
26 let def_loc = self.def_id.loc(db); 26 let def_loc = self.def_id.loc(db);
27 assert!(def_loc.kind == DefKind::Function); 27 assert!(def_loc.kind == DefKind::Function);
28 let syntax = db.file_item(def_loc.source_item_id); 28 let syntax = db.file_item(def_loc.source_item_id);
29 ast::FnDef::cast(&syntax).unwrap().to_owned() 29 (
30 def_loc.source_item_id.file_id,
31 ast::FnDef::cast(&syntax).unwrap().to_owned(),
32 )
30 } 33 }
31 34
32 pub(crate) fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> { 35 pub(crate) fn body(&self, db: &impl HirDatabase) -> Cancelable<Arc<Body>> {
@@ -46,7 +49,11 @@ impl Function {
46impl FnSignature { 49impl FnSignature {
47 pub(crate) fn fn_signature_query(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> { 50 pub(crate) fn fn_signature_query(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
48 let func = Function::new(def_id); 51 let func = Function::new(def_id);
49 let node = func.source(db); 52 let node = func.source_impl(db).1; // TODO we're using source_impl here to avoid returning Cancelable... this is a bit hacky
53 let name = node
54 .name()
55 .map(|n| n.as_name())
56 .unwrap_or_else(Name::missing);
50 let mut args = Vec::new(); 57 let mut args = Vec::new();
51 if let Some(param_list) = node.param_list() { 58 if let Some(param_list) = node.param_list() {
52 if let Some(self_param) = param_list.self_param() { 59 if let Some(self_param) = param_list.self_param() {
@@ -76,7 +83,11 @@ impl FnSignature {
76 } else { 83 } else {
77 TypeRef::unit() 84 TypeRef::unit()
78 }; 85 };
79 let sig = FnSignature { args, ret_type }; 86 let sig = FnSignature {
87 name,
88 args,
89 ret_type,
90 };
80 Arc::new(sig) 91 Arc::new(sig)
81 } 92 }
82} 93}
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 1cb408cff..878dc37c8 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -13,6 +13,7 @@ impl Module {
13 pub(crate) fn new(def_id: DefId) -> Self { 13 pub(crate) fn new(def_id: DefId) -> Self {
14 crate::code_model_api::Module { def_id } 14 crate::code_model_api::Module { def_id }
15 } 15 }
16
16 pub(crate) fn from_module_id( 17 pub(crate) fn from_module_id(
17 db: &impl HirDatabase, 18 db: &impl HirDatabase,
18 source_root_id: SourceRootId, 19 source_root_id: SourceRootId,
@@ -85,6 +86,7 @@ impl Module {
85 let module_id = loc.module_id.crate_root(&module_tree); 86 let module_id = loc.module_id.crate_root(&module_tree);
86 Module::from_module_id(db, loc.source_root_id, module_id) 87 Module::from_module_id(db, loc.source_root_id, module_id)
87 } 88 }
89
88 /// Finds a child module with the specified name. 90 /// Finds a child module with the specified name.
89 pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { 91 pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
90 let loc = self.def_id.loc(db); 92 let loc = self.def_id.loc(db);
@@ -92,12 +94,14 @@ impl Module {
92 let child_id = ctry!(loc.module_id.child(&module_tree, name)); 94 let child_id = ctry!(loc.module_id.child(&module_tree, name));
93 Module::from_module_id(db, loc.source_root_id, child_id).map(Some) 95 Module::from_module_id(db, loc.source_root_id, child_id).map(Some)
94 } 96 }
97
95 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { 98 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
96 let loc = self.def_id.loc(db); 99 let loc = self.def_id.loc(db);
97 let module_tree = db.module_tree(loc.source_root_id)?; 100 let module_tree = db.module_tree(loc.source_root_id)?;
98 let parent_id = ctry!(loc.module_id.parent(&module_tree)); 101 let parent_id = ctry!(loc.module_id.parent(&module_tree));
99 Module::from_module_id(db, loc.source_root_id, parent_id).map(Some) 102 Module::from_module_id(db, loc.source_root_id, parent_id).map(Some)
100 } 103 }
104
101 /// Returns a `ModuleScope`: a set of items, visible in this module. 105 /// Returns a `ModuleScope`: a set of items, visible in this module.
102 pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { 106 pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
103 let loc = self.def_id.loc(db); 107 let loc = self.def_id.loc(db);
@@ -105,6 +109,7 @@ impl Module {
105 let res = item_map.per_module[&loc.module_id].clone(); 109 let res = item_map.per_module[&loc.module_id].clone();
106 Ok(res) 110 Ok(res)
107 } 111 }
112
108 pub fn resolve_path_impl( 113 pub fn resolve_path_impl(
109 &self, 114 &self,
110 db: &impl HirDatabase, 115 db: &impl HirDatabase,
@@ -126,7 +131,7 @@ impl Module {
126 ); 131 );
127 132
128 let segments = &path.segments; 133 let segments = &path.segments;
129 for name in segments.iter() { 134 for (idx, name) in segments.iter().enumerate() {
130 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { 135 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() {
131 r 136 r
132 } else { 137 } else {
@@ -134,7 +139,25 @@ impl Module {
134 }; 139 };
135 let module = match curr.resolve(db)? { 140 let module = match curr.resolve(db)? {
136 Def::Module(it) => it, 141 Def::Module(it) => it,
137 // TODO here would be the place to handle enum variants... 142 Def::Enum(e) => {
143 if segments.len() == idx + 1 {
144 // enum variant
145 let matching_variant =
146 e.variants(db)?.into_iter().find(|(n, _variant)| n == name);
147
148 if let Some((_n, variant)) = matching_variant {
149 return Ok(PerNs::both(variant.def_id(), e.def_id()));
150 } else {
151 return Ok(PerNs::none());
152 }
153 } else if segments.len() == idx {
154 // enum
155 return Ok(PerNs::types(e.def_id()));
156 } else {
157 // malformed enum?
158 return Ok(PerNs::none());
159 }
160 }
138 _ => return Ok(PerNs::none()), 161 _ => return Ok(PerNs::none()),
139 }; 162 };
140 let scope = module.scope(db)?; 163 let scope = module.scope(db)?;
@@ -146,6 +169,7 @@ impl Module {
146 } 169 }
147 Ok(curr_per_ns) 170 Ok(curr_per_ns)
148 } 171 }
172
149 pub fn problems_impl( 173 pub fn problems_impl(
150 &self, 174 &self,
151 db: &impl HirDatabase, 175 db: &impl HirDatabase,