aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/module.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/module.rs')
-rw-r--r--crates/ra_hir/src/module.rs44
1 files changed, 31 insertions, 13 deletions
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs
index 891119953..b9d36f01f 100644
--- a/crates/ra_hir/src/module.rs
+++ b/crates/ra_hir/src/module.rs
@@ -17,7 +17,7 @@ use crate::{
17 arena::{Arena, Id}, 17 arena::{Arena, Id},
18}; 18};
19 19
20pub use self::nameres::{ModuleScope, Resolution}; 20pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs};
21 21
22/// `Module` is API entry point to get all the information 22/// `Module` is API entry point to get all the information
23/// about a particular module. 23/// about a particular module.
@@ -115,16 +115,29 @@ impl Module {
115 Ok(res) 115 Ok(res)
116 } 116 }
117 117
118 pub fn resolve_path(&self, db: &impl HirDatabase, path: Path) -> Cancelable<Option<DefId>> { 118 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
119 let mut curr = match path.kind { 119 let mut curr_per_ns = PerNs::types(
120 PathKind::Crate => self.crate_root(), 120 match path.kind {
121 PathKind::Self_ | PathKind::Plain => self.clone(), 121 PathKind::Crate => self.crate_root(),
122 PathKind::Super => ctry!(self.parent()), 122 PathKind::Self_ | PathKind::Plain => self.clone(),
123 } 123 PathKind::Super => {
124 .def_id(db); 124 if let Some(p) = self.parent() {
125 p
126 } else {
127 return Ok(PerNs::none());
128 }
129 }
130 }
131 .def_id(db),
132 );
125 133
126 let segments = path.segments; 134 let segments = &path.segments;
127 for name in segments.iter() { 135 for name in segments.iter() {
136 let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) {
137 r
138 } else {
139 return Ok(PerNs::none());
140 };
128 let module = match curr.loc(db) { 141 let module = match curr.loc(db) {
129 DefLoc { 142 DefLoc {
130 kind: DefKind::Module, 143 kind: DefKind::Module,
@@ -132,12 +145,17 @@ impl Module {
132 module_id, 145 module_id,
133 .. 146 ..
134 } => Module::new(db, source_root_id, module_id)?, 147 } => Module::new(db, source_root_id, module_id)?,
135 _ => return Ok(None), 148 // TODO here would be the place to handle enum variants...
149 _ => return Ok(PerNs::none()),
136 }; 150 };
137 let scope = module.scope(db)?; 151 let scope = module.scope(db)?;
138 curr = ctry!(ctry!(scope.get(&name)).def_id); 152 curr_per_ns = if let Some(r) = scope.get(&name) {
153 r.def_id
154 } else {
155 return Ok(PerNs::none());
156 };
139 } 157 }
140 Ok(Some(curr)) 158 Ok(curr_per_ns)
141 } 159 }
142 160
143 pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { 161 pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> {
@@ -145,7 +163,7 @@ impl Module {
145 } 163 }
146} 164}
147 165
148/// Phisically, rust source is organized as a set of files, but logically it is 166/// Physically, rust source is organized as a set of files, but logically it is
149/// organized as a tree of modules. Usually, a single file corresponds to a 167/// organized as a tree of modules. Usually, a single file corresponds to a
150/// single module, but it is not nessary the case. 168/// single module, but it is not nessary the case.
151/// 169///