diff options
Diffstat (limited to 'crates/ra_hir/src/code_model_impl')
-rw-r--r-- | crates/ra_hir/src/code_model_impl/krate.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 180 |
2 files changed, 79 insertions, 125 deletions
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 8c6e34873..cdd30b402 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use ra_db::CrateId; | 1 | use ra_db::CrateId; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, | 4 | Crate, CrateDependency, AsName, Module, |
5 | db::HirDatabase, | 5 | db::HirDatabase, |
6 | }; | 6 | }; |
7 | 7 | ||
@@ -21,27 +21,13 @@ impl Crate { | |||
21 | .collect() | 21 | .collect() |
22 | } | 22 | } |
23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { | 23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
24 | let crate_graph = db.crate_graph(); | 24 | let module_tree = db.module_tree(self.crate_id); |
25 | let file_id = crate_graph.crate_root(self.crate_id); | 25 | let module_id = module_tree.modules().next()?; |
26 | let source_root_id = db.file_source_root(file_id); | ||
27 | let file_id = HirFileId::from(file_id); | ||
28 | let module_tree = db.module_tree(source_root_id); | ||
29 | // FIXME: teach module tree about crate roots instead of guessing | ||
30 | let source = SourceItemId { | ||
31 | file_id, | ||
32 | item_id: None, | ||
33 | }; | ||
34 | let module_id = module_tree.find_module_by_source(source)?; | ||
35 | 26 | ||
36 | let def_loc = DefLoc { | 27 | let module = Module { |
37 | kind: DefKind::Module, | 28 | krate: self.crate_id, |
38 | source_root_id, | ||
39 | module_id, | 29 | module_id, |
40 | source_item_id: module_id.source(&module_tree), | ||
41 | }; | 30 | }; |
42 | let def_id = def_loc.id(db); | ||
43 | |||
44 | let module = Module::new(def_id); | ||
45 | Some(module) | 31 | Some(module) |
46 | } | 32 | } |
47 | } | 33 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index d94079f11..5d00e905b 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,52 +1,33 @@ | |||
1 | use ra_db::{SourceRootId, FileId}; | 1 | use ra_db::FileId; |
2 | use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; | 2 | use ra_syntax::{ast, SyntaxNode, TreeArc}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Problem, | 5 | Module, ModuleSource, Problem, ModuleDef, |
6 | Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, | 6 | Crate, Name, Path, PathKind, PerNs, Def, |
7 | module_tree::ModuleId, | 7 | module_tree::ModuleId, |
8 | nameres::{ModuleScope, lower::ImportId}, | 8 | nameres::{ModuleScope, lower::ImportId}, |
9 | db::HirDatabase, | 9 | db::HirDatabase, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | impl Module { | 12 | impl Module { |
13 | pub(crate) fn new(def_id: DefId) -> Self { | 13 | fn with_module_id(&self, module_id: ModuleId) -> Module { |
14 | crate::code_model_api::Module { def_id } | 14 | Module { |
15 | } | ||
16 | |||
17 | pub(crate) fn from_module_id( | ||
18 | db: &impl HirDatabase, | ||
19 | source_root_id: SourceRootId, | ||
20 | module_id: ModuleId, | ||
21 | ) -> Self { | ||
22 | let module_tree = db.module_tree(source_root_id); | ||
23 | let def_loc = DefLoc { | ||
24 | kind: DefKind::Module, | ||
25 | source_root_id, | ||
26 | module_id, | 15 | module_id, |
27 | source_item_id: module_id.source(&module_tree), | 16 | krate: self.krate, |
28 | }; | 17 | } |
29 | let def_id = def_loc.id(db); | ||
30 | Module::new(def_id) | ||
31 | } | 18 | } |
32 | 19 | ||
33 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { | 20 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { |
34 | let loc = self.def_id.loc(db); | 21 | let module_tree = db.module_tree(self.krate); |
35 | let module_tree = db.module_tree(loc.source_root_id); | 22 | let link = self.module_id.parent_link(&module_tree)?; |
36 | let link = loc.module_id.parent_link(&module_tree)?; | ||
37 | Some(link.name(&module_tree).clone()) | 23 | Some(link.name(&module_tree).clone()) |
38 | } | 24 | } |
39 | 25 | ||
40 | pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { | 26 | pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { |
41 | let loc = self.def_id.loc(db); | 27 | let module_tree = db.module_tree(self.krate); |
42 | let file_id = loc.source_item_id.file_id.as_original_file(); | 28 | let source = self.module_id.source(&module_tree); |
43 | let syntax_node = db.file_item(loc.source_item_id); | 29 | let module_source = ModuleSource::from_source_item_id(db, source); |
44 | let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) { | 30 | let file_id = source.file_id.as_original_file(); |
45 | ModuleSource::SourceFile(source_file.to_owned()) | ||
46 | } else { | ||
47 | let module = ast::Module::cast(&syntax_node).unwrap(); | ||
48 | ModuleSource::Module(module.to_owned()) | ||
49 | }; | ||
50 | (file_id, module_source) | 31 | (file_id, module_source) |
51 | } | 32 | } |
52 | 33 | ||
@@ -54,9 +35,8 @@ impl Module { | |||
54 | &self, | 35 | &self, |
55 | db: &impl HirDatabase, | 36 | db: &impl HirDatabase, |
56 | ) -> Option<(FileId, TreeArc<ast::Module>)> { | 37 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
57 | let loc = self.def_id.loc(db); | 38 | let module_tree = db.module_tree(self.krate); |
58 | let module_tree = db.module_tree(loc.source_root_id); | 39 | let link = self.module_id.parent_link(&module_tree)?; |
59 | let link = loc.module_id.parent_link(&module_tree)?; | ||
60 | let file_id = link | 40 | let file_id = link |
61 | .owner(&module_tree) | 41 | .owner(&module_tree) |
62 | .source(&module_tree) | 42 | .source(&module_tree) |
@@ -71,85 +51,67 @@ impl Module { | |||
71 | db: &impl HirDatabase, | 51 | db: &impl HirDatabase, |
72 | import: ImportId, | 52 | import: ImportId, |
73 | ) -> TreeArc<ast::PathSegment> { | 53 | ) -> TreeArc<ast::PathSegment> { |
74 | let loc = self.def_id.loc(db); | 54 | let source_map = db.lower_module_source_map(self.clone()); |
75 | let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id); | ||
76 | let (_, source) = self.definition_source(db); | 55 | let (_, source) = self.definition_source(db); |
77 | source_map.get(&source, import) | 56 | source_map.get(&source, import) |
78 | } | 57 | } |
79 | 58 | ||
80 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> { | 59 | pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> { |
81 | let root = self.crate_root(db); | 60 | Some(Crate::new(self.krate)) |
82 | let loc = root.def_id.loc(db); | ||
83 | let file_id = loc.source_item_id.file_id.as_original_file(); | ||
84 | |||
85 | let crate_graph = db.crate_graph(); | ||
86 | let crate_id = crate_graph.crate_id_for_crate_root(file_id)?; | ||
87 | Some(Crate::new(crate_id)) | ||
88 | } | 61 | } |
89 | 62 | ||
90 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { | 63 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { |
91 | let loc = self.def_id.loc(db); | 64 | let module_tree = db.module_tree(self.krate); |
92 | let module_tree = db.module_tree(loc.source_root_id); | 65 | let module_id = self.module_id.crate_root(&module_tree); |
93 | let module_id = loc.module_id.crate_root(&module_tree); | 66 | self.with_module_id(module_id) |
94 | Module::from_module_id(db, loc.source_root_id, module_id) | ||
95 | } | 67 | } |
96 | 68 | ||
97 | /// Finds a child module with the specified name. | 69 | /// Finds a child module with the specified name. |
98 | pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { | 70 | pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
99 | let loc = self.def_id.loc(db); | 71 | let module_tree = db.module_tree(self.krate); |
100 | let module_tree = db.module_tree(loc.source_root_id); | 72 | let child_id = self.module_id.child(&module_tree, name)?; |
101 | let child_id = loc.module_id.child(&module_tree, name)?; | 73 | Some(self.with_module_id(child_id)) |
102 | Some(Module::from_module_id(db, loc.source_root_id, child_id)) | ||
103 | } | 74 | } |
104 | 75 | ||
105 | /// Iterates over all child modules. | 76 | /// Iterates over all child modules. |
106 | pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { | 77 | pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { |
107 | // FIXME this should be implementable without collecting into a vec, but | 78 | let module_tree = db.module_tree(self.krate); |
108 | // it's kind of hard since the iterator needs to keep a reference to the | 79 | let children = self |
109 | // module tree. | ||
110 | let loc = self.def_id.loc(db); | ||
111 | let module_tree = db.module_tree(loc.source_root_id); | ||
112 | let children = loc | ||
113 | .module_id | 80 | .module_id |
114 | .children(&module_tree) | 81 | .children(&module_tree) |
115 | .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) | 82 | .map(|(_, module_id)| self.with_module_id(module_id)) |
116 | .collect::<Vec<_>>(); | 83 | .collect::<Vec<_>>(); |
117 | children.into_iter() | 84 | children.into_iter() |
118 | } | 85 | } |
119 | 86 | ||
120 | pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { | 87 | pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
121 | let loc = self.def_id.loc(db); | 88 | let module_tree = db.module_tree(self.krate); |
122 | let module_tree = db.module_tree(loc.source_root_id); | 89 | let parent_id = self.module_id.parent(&module_tree)?; |
123 | let parent_id = loc.module_id.parent(&module_tree)?; | 90 | Some(self.with_module_id(parent_id)) |
124 | Some(Module::from_module_id(db, loc.source_root_id, parent_id)) | ||
125 | } | 91 | } |
126 | 92 | ||
127 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 93 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
128 | pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { | 94 | pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { |
129 | let loc = self.def_id.loc(db); | 95 | let item_map = db.item_map(self.krate); |
130 | let item_map = db.item_map(loc.source_root_id); | 96 | item_map.per_module[&self.module_id].clone() |
131 | item_map.per_module[&loc.module_id].clone() | ||
132 | } | 97 | } |
133 | 98 | ||
134 | pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { | 99 | pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> { |
135 | let mut curr_per_ns = PerNs::types( | 100 | let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind { |
136 | match path.kind { | 101 | PathKind::Crate => self.crate_root(db).into(), |
137 | PathKind::Crate => self.crate_root(db), | 102 | PathKind::Self_ | PathKind::Plain => self.clone().into(), |
138 | PathKind::Self_ | PathKind::Plain => self.clone(), | 103 | PathKind::Super => { |
139 | PathKind::Super => { | 104 | if let Some(p) = self.parent(db) { |
140 | if let Some(p) = self.parent(db) { | 105 | p.into() |
141 | p | 106 | } else { |
142 | } else { | ||
143 | return PerNs::none(); | ||
144 | } | ||
145 | } | ||
146 | PathKind::Abs => { | ||
147 | // TODO: absolute use is not supported | ||
148 | return PerNs::none(); | 107 | return PerNs::none(); |
149 | } | 108 | } |
150 | } | 109 | } |
151 | .def_id, | 110 | PathKind::Abs => { |
152 | ); | 111 | // TODO: absolute use is not supported |
112 | return PerNs::none(); | ||
113 | } | ||
114 | }); | ||
153 | 115 | ||
154 | for segment in path.segments.iter() { | 116 | for segment in path.segments.iter() { |
155 | let curr = match curr_per_ns.as_ref().take_types() { | 117 | let curr = match curr_per_ns.as_ref().take_types() { |
@@ -164,32 +126,39 @@ impl Module { | |||
164 | } | 126 | } |
165 | }; | 127 | }; |
166 | // resolve segment in curr | 128 | // resolve segment in curr |
167 | curr_per_ns = match curr.resolve(db) { | 129 | |
168 | Def::Module(m) => { | 130 | curr_per_ns = match curr { |
131 | ModuleDef::Module(m) => { | ||
169 | let scope = m.scope(db); | 132 | let scope = m.scope(db); |
170 | match scope.get(&segment.name) { | 133 | match scope.get(&segment.name) { |
171 | Some(r) => r.def_id, | 134 | Some(r) => r.def_id.clone(), |
172 | None => PerNs::none(), | 135 | None => PerNs::none(), |
173 | } | 136 | } |
174 | } | 137 | } |
175 | Def::Enum(e) => { | 138 | ModuleDef::Def(def) => { |
176 | // enum variant | 139 | match def.resolve(db) { |
177 | let matching_variant = e | 140 | Def::Enum(e) => { |
178 | .variants(db) | 141 | // enum variant |
179 | .into_iter() | 142 | let matching_variant = e |
180 | .find(|(n, _variant)| n == &segment.name); | 143 | .variants(db) |
181 | 144 | .into_iter() | |
182 | match matching_variant { | 145 | .find(|(n, _variant)| n == &segment.name); |
183 | Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()), | 146 | |
184 | None => PerNs::none(), | 147 | match matching_variant { |
148 | Some((_n, variant)) => { | ||
149 | PerNs::both(variant.def_id().into(), e.def_id().into()) | ||
150 | } | ||
151 | None => PerNs::none(), | ||
152 | } | ||
153 | } | ||
154 | _ => { | ||
155 | // could be an inherent method call in UFCS form | ||
156 | // (`Struct::method`), or some other kind of associated | ||
157 | // item... Which we currently don't handle (TODO) | ||
158 | PerNs::none() | ||
159 | } | ||
185 | } | 160 | } |
186 | } | 161 | } |
187 | _ => { | ||
188 | // could be an inherent method call in UFCS form | ||
189 | // (`Struct::method`), or some other kind of associated | ||
190 | // item... Which we currently don't handle (TODO) | ||
191 | PerNs::none() | ||
192 | } | ||
193 | }; | 162 | }; |
194 | } | 163 | } |
195 | curr_per_ns | 164 | curr_per_ns |
@@ -199,8 +168,7 @@ impl Module { | |||
199 | &self, | 168 | &self, |
200 | db: &impl HirDatabase, | 169 | db: &impl HirDatabase, |
201 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | 170 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { |
202 | let loc = self.def_id.loc(db); | 171 | let module_tree = db.module_tree(self.krate); |
203 | let module_tree = db.module_tree(loc.source_root_id); | 172 | self.module_id.problems(&module_tree, db) |
204 | loc.module_id.problems(&module_tree, db) | ||
205 | } | 173 | } |
206 | } | 174 | } |