diff options
Diffstat (limited to 'crates/ra_hir/src/code_model_impl.rs')
-rw-r--r-- | crates/ra_hir/src/code_model_impl.rs | 56 |
1 files changed, 55 insertions, 1 deletions
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 @@ | |||
1 | use ra_db::{CrateId, Cancelable, FileId}; | 1 | use ra_db::{CrateId, Cancelable, FileId}; |
2 | use ra_syntax::{AstNode, ast}; | 2 | use ra_syntax::{AstNode, ast}; |
3 | 3 | ||
4 | use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name}; | 4 | use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def}; |
5 | 5 | ||
6 | use crate::code_model_api::Module; | 6 | use 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 | } |