aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_api.rs10
-rw-r--r--crates/ra_hir/src/code_model_impl.rs56
-rw-r--r--crates/ra_hir/src/module.rs2
-rw-r--r--crates/ra_hir/src/module/nameres.rs4
4 files changed, 67 insertions, 5 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 6bbc80e17..236cb3ab4 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,7 +1,7 @@
1use ra_db::{CrateId, Cancelable, FileId}; 1use ra_db::{CrateId, Cancelable, FileId};
2use ra_syntax::ast; 2use ra_syntax::ast;
3 3
4use crate::{Name, db::HirDatabase, DefId}; 4use crate::{Name, db::HirDatabase, DefId, Path, PerNs};
5 5
6/// hir::Crate describes a single crate. It's the main inteface with which 6/// hir::Crate describes a single crate. It's the main inteface with which
7/// crate's dependencies interact. Mostly, it should be just a proxy for the 7/// crate's dependencies interact. Mostly, it should be just a proxy for the
@@ -52,4 +52,12 @@ impl Module {
52 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { 52 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
53 self.child_impl(db, name) 53 self.child_impl(db, name)
54 } 54 }
55 /// Finds a parent module.
56 pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
57 self.parent_impl(db)
58 }
59
60 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
61 self.resolve_path_impl(db, path)
62 }
55} 63}
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs
index 83ee8186e..678758956 100644
--- a/crates/ra_hir/src/code_model_impl.rs
+++ b/crates/ra_hir/src/code_model_impl.rs
@@ -1,7 +1,7 @@
1use ra_db::{CrateId, Cancelable, FileId}; 1use ra_db::{CrateId, Cancelable, FileId};
2use ra_syntax::{AstNode, ast}; 2use ra_syntax::{AstNode, ast};
3 3
4use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name}; 4use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def};
5 5
6use crate::code_model_api::Module; 6use crate::code_model_api::Module;
7 7
@@ -102,4 +102,58 @@ impl Module {
102 let module = Module::new(def_id); 102 let module = Module::new(def_id);
103 Ok(Some(module)) 103 Ok(Some(module))
104 } 104 }
105 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
106 let loc = self.def_id.loc(db);
107 let module_tree = db.module_tree(loc.source_root_id)?;
108 let parent_id = ctry!(loc.module_id.parent(&module_tree));
109 let def_loc = DefLoc {
110 module_id: parent_id,
111 source_item_id: parent_id.source(&module_tree).0,
112 ..loc
113 };
114 let def_id = def_loc.id(db);
115 let module = Module::new(def_id);
116 Ok(Some(module))
117 }
118 pub fn resolve_path_impl(
119 &self,
120 db: &impl HirDatabase,
121 path: &Path,
122 ) -> Cancelable<PerNs<DefId>> {
123 let mut curr_per_ns = PerNs::types(
124 match path.kind {
125 PathKind::Crate => self.crate_root(db)?,
126 PathKind::Self_ | PathKind::Plain => self.clone(),
127 PathKind::Super => {
128 if let Some(p) = self.parent(db)? {
129 p
130 } else {
131 return Ok(PerNs::none());
132 }
133 }
134 }
135 .def_id,
136 );
137
138 let segments = &path.segments;
139 for name in segments.iter() {
140 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() {
141 r
142 } else {
143 return Ok(PerNs::none());
144 };
145 let module = match curr.resolve(db)? {
146 Def::Module(it) => it,
147 // TODO here would be the place to handle enum variants...
148 _ => return Ok(PerNs::none()),
149 };
150 let scope = module.scope(db)?;
151 curr_per_ns = if let Some(r) = scope.get(&name) {
152 r.def_id
153 } else {
154 return Ok(PerNs::none());
155 };
156 }
157 Ok(curr_per_ns)
158 }
105} 159}
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs
index f0b673908..11e3f6782 100644
--- a/crates/ra_hir/src/module.rs
+++ b/crates/ra_hir/src/module.rs
@@ -251,7 +251,7 @@ impl ModuleId {
251 fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { 251 fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
252 tree.mods[self].parent 252 tree.mods[self].parent
253 } 253 }
254 fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { 254 pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
255 let link = self.parent_link(tree)?; 255 let link = self.parent_link(tree)?;
256 Some(tree.links[link].owner) 256 Some(tree.links[link].owner)
257 } 257 }
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs
index 059301b05..dac524384 100644
--- a/crates/ra_hir/src/module/nameres.rs
+++ b/crates/ra_hir/src/module/nameres.rs
@@ -177,11 +177,11 @@ impl<T> PerNs<T> {
177 } 177 }
178 178
179 pub fn take_types(self) -> Option<T> { 179 pub fn take_types(self) -> Option<T> {
180 self.types 180 self.take(Namespace::Types)
181 } 181 }
182 182
183 pub fn take_values(self) -> Option<T> { 183 pub fn take_values(self) -> Option<T> {
184 self.values 184 self.take(Namespace::Values)
185 } 185 }
186 186
187 pub fn get(&self, namespace: Namespace) -> Option<&T> { 187 pub fn get(&self, namespace: Namespace) -> Option<&T> {