diff options
Diffstat (limited to 'crates/ra_hir/src/module.rs')
-rw-r--r-- | crates/ra_hir/src/module.rs | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index 891119953..e1a0e4b59 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 | ||
20 | pub use self::nameres::{ModuleScope, Resolution}; | 20 | pub 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 | /// |