diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model_impl/krate.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/module_tree.rs | 245 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 64 |
7 files changed, 155 insertions, 193 deletions
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 591a81597..3275eafed 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, Cancelable}; | 1 | use ra_db::{CrateId, Cancelable}; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, | 4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, |
5 | db::HirDatabase, | 5 | db::HirDatabase, |
6 | }; | 6 | }; |
7 | 7 | ||
@@ -27,15 +27,17 @@ impl Crate { | |||
27 | let file_id = HirFileId::from(file_id); | 27 | let file_id = HirFileId::from(file_id); |
28 | let module_tree = db.module_tree(source_root_id)?; | 28 | let module_tree = db.module_tree(source_root_id)?; |
29 | // FIXME: teach module tree about crate roots instead of guessing | 29 | // FIXME: teach module tree about crate roots instead of guessing |
30 | let (module_id, _) = ctry!(module_tree | 30 | let source = SourceItemId { |
31 | .modules_with_sources() | 31 | file_id, |
32 | .find(|(_, src)| src.file_id() == file_id)); | 32 | item_id: None, |
33 | }; | ||
34 | let module_id = ctry!(module_tree.find_module_by_source(source)); | ||
33 | 35 | ||
34 | let def_loc = DefLoc { | 36 | let def_loc = DefLoc { |
35 | kind: DefKind::Module, | 37 | kind: DefKind::Module, |
36 | source_root_id, | 38 | source_root_id, |
37 | module_id, | 39 | module_id, |
38 | source_item_id: module_id.source(&module_tree).0, | 40 | source_item_id: module_id.source(&module_tree), |
39 | }; | 41 | }; |
40 | let def_id = def_loc.id(db); | 42 | let def_id = def_loc.id(db); |
41 | 43 | ||
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 02078f188..eb35779f1 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -22,7 +22,7 @@ impl Module { | |||
22 | kind: DefKind::Module, | 22 | kind: DefKind::Module, |
23 | source_root_id, | 23 | source_root_id, |
24 | module_id, | 24 | module_id, |
25 | source_item_id: module_id.source(&module_tree).0, | 25 | source_item_id: module_id.source(&module_tree), |
26 | }; | 26 | }; |
27 | let def_id = def_loc.id(db); | 27 | let def_id = def_loc.id(db); |
28 | let module = Module::new(def_id); | 28 | let module = Module::new(def_id); |
@@ -63,9 +63,9 @@ impl Module { | |||
63 | let file_id = link | 63 | let file_id = link |
64 | .owner(&module_tree) | 64 | .owner(&module_tree) |
65 | .source(&module_tree) | 65 | .source(&module_tree) |
66 | .file_id() | 66 | .file_id |
67 | .as_original_file(); | 67 | .as_original_file(); |
68 | let src = link.bind_source(&module_tree, db); | 68 | let src = link.source(&module_tree, db); |
69 | Ok(Some((file_id, src))) | 69 | Ok(Some((file_id, src))) |
70 | } | 70 | } |
71 | 71 | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index e4249de14..033f9d25f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -9,7 +9,7 @@ use crate::{ | |||
9 | query_definitions, | 9 | query_definitions, |
10 | FnSignature, FnScopes, | 10 | FnSignature, FnScopes, |
11 | macros::MacroExpansion, | 11 | macros::MacroExpansion, |
12 | module_tree::{ModuleId, ModuleTree, ModuleSource}, | 12 | module_tree::{ModuleId, ModuleTree}, |
13 | nameres::{ItemMap, InputModuleItems}, | 13 | nameres::{ItemMap, InputModuleItems}, |
14 | ty::{InferenceResult, Ty}, | 14 | ty::{InferenceResult, Ty}, |
15 | adt::{StructData, EnumData}, | 15 | adt::{StructData, EnumData}, |
@@ -71,7 +71,7 @@ pub trait HirDatabase: SyntaxDatabase | |||
71 | use fn query_definitions::file_item; | 71 | use fn query_definitions::file_item; |
72 | } | 72 | } |
73 | 73 | ||
74 | fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::module_tree::Submodule>>> { | 74 | fn submodules(source: SourceItemId) -> Cancelable<Arc<Vec<crate::module_tree::Submodule>>> { |
75 | type SubmodulesQuery; | 75 | type SubmodulesQuery; |
76 | use fn crate::module_tree::Submodule::submodules_query; | 76 | use fn crate::module_tree::Submodule::submodules_query; |
77 | } | 77 | } |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index b7912ba5e..c7a442319 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -11,55 +11,70 @@ use ra_syntax::{ | |||
11 | }; | 11 | }; |
12 | use ra_arena::{Arena, RawId, impl_arena_id}; | 12 | use ra_arena::{Arena, RawId, impl_arena_id}; |
13 | 13 | ||
14 | use crate::{Name, AsName, HirDatabase, SourceItemId, SourceFileItemId, HirFileId, Problem}; | 14 | use crate::{Name, AsName, HirDatabase, SourceItemId, HirFileId, Problem, SourceFileItems, ModuleSource}; |
15 | |||
16 | impl ModuleSource { | ||
17 | pub fn from_source_item_id( | ||
18 | db: &impl HirDatabase, | ||
19 | source_item_id: SourceItemId, | ||
20 | ) -> ModuleSource { | ||
21 | let module_syntax = db.file_item(source_item_id); | ||
22 | let module_syntax = module_syntax.borrowed(); | ||
23 | if let Some(source_file) = ast::SourceFile::cast(module_syntax) { | ||
24 | ModuleSource::SourceFile(source_file.owned()) | ||
25 | } else if let Some(module) = ast::Module::cast(module_syntax) { | ||
26 | assert!(module.item_list().is_some(), "expected inline module"); | ||
27 | ModuleSource::Module(module.owned()) | ||
28 | } else { | ||
29 | panic!("expected file or inline module") | ||
30 | } | ||
31 | } | ||
32 | } | ||
15 | 33 | ||
16 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] | 34 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] |
17 | pub enum Submodule { | 35 | pub struct Submodule { |
18 | Declaration(Name), | 36 | name: Name, |
19 | Definition(Name, ModuleSource), | 37 | is_declaration: bool, |
38 | source: SourceItemId, | ||
20 | } | 39 | } |
21 | 40 | ||
22 | impl Submodule { | 41 | impl Submodule { |
23 | pub(crate) fn submodules_query( | 42 | pub(crate) fn submodules_query( |
24 | db: &impl HirDatabase, | 43 | db: &impl HirDatabase, |
25 | source: ModuleSource, | 44 | source: SourceItemId, |
26 | ) -> Cancelable<Arc<Vec<Submodule>>> { | 45 | ) -> Cancelable<Arc<Vec<Submodule>>> { |
27 | db.check_canceled()?; | 46 | db.check_canceled()?; |
28 | let file_id = source.file_id(); | 47 | let file_id = source.file_id; |
29 | let submodules = match source.resolve(db) { | 48 | let file_items = db.file_items(file_id); |
30 | ModuleSourceNode::SourceFile(it) => collect_submodules(db, file_id, it.borrowed()), | 49 | let module_source = ModuleSource::from_source_item_id(db, source); |
31 | ModuleSourceNode::Module(it) => it | 50 | let submodules = match module_source { |
32 | .borrowed() | 51 | ModuleSource::SourceFile(source_file) => { |
33 | .item_list() | 52 | collect_submodules(file_id, &file_items, source_file.borrowed()) |
34 | .map(|it| collect_submodules(db, file_id, it)) | 53 | } |
35 | .unwrap_or_else(Vec::new), | 54 | ModuleSource::Module(module) => { |
55 | let module = module.borrowed(); | ||
56 | collect_submodules(file_id, &file_items, module.item_list().unwrap()) | ||
57 | } | ||
36 | }; | 58 | }; |
37 | return Ok(Arc::new(submodules)); | 59 | return Ok(Arc::new(submodules)); |
38 | 60 | ||
39 | fn collect_submodules<'a>( | 61 | fn collect_submodules<'a>( |
40 | db: &impl HirDatabase, | ||
41 | file_id: HirFileId, | 62 | file_id: HirFileId, |
63 | file_items: &SourceFileItems, | ||
42 | root: impl ast::ModuleItemOwner<'a>, | 64 | root: impl ast::ModuleItemOwner<'a>, |
43 | ) -> Vec<Submodule> { | 65 | ) -> Vec<Submodule> { |
44 | modules(root) | 66 | modules(root) |
45 | .map(|(name, m)| { | 67 | .map(|(name, m)| Submodule { |
46 | if m.has_semi() { | 68 | name, |
47 | Submodule::Declaration(name) | 69 | is_declaration: m.has_semi(), |
48 | } else { | 70 | source: SourceItemId { |
49 | let src = ModuleSource::new_inline(db, file_id, m); | 71 | file_id, |
50 | Submodule::Definition(name, src) | 72 | item_id: Some(file_items.id_of(file_id, m.syntax())), |
51 | } | 73 | }, |
52 | }) | 74 | }) |
53 | .collect() | 75 | .collect() |
54 | } | 76 | } |
55 | } | 77 | } |
56 | |||
57 | fn name(&self) -> &Name { | ||
58 | match self { | ||
59 | Submodule::Declaration(name) => name, | ||
60 | Submodule::Definition(name, _) => name, | ||
61 | } | ||
62 | } | ||
63 | } | 78 | } |
64 | 79 | ||
65 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 80 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
@@ -85,13 +100,14 @@ pub struct ModuleTree { | |||
85 | 100 | ||
86 | #[derive(Debug, PartialEq, Eq, Hash)] | 101 | #[derive(Debug, PartialEq, Eq, Hash)] |
87 | pub struct ModuleData { | 102 | pub struct ModuleData { |
88 | source: ModuleSource, | 103 | source: SourceItemId, |
89 | parent: Option<LinkId>, | 104 | parent: Option<LinkId>, |
90 | children: Vec<LinkId>, | 105 | children: Vec<LinkId>, |
91 | } | 106 | } |
92 | 107 | ||
93 | #[derive(Hash, Debug, PartialEq, Eq)] | 108 | #[derive(Hash, Debug, PartialEq, Eq)] |
94 | struct LinkData { | 109 | struct LinkData { |
110 | source: SourceItemId, | ||
95 | owner: ModuleId, | 111 | owner: ModuleId, |
96 | name: Name, | 112 | name: Name, |
97 | points_to: Vec<ModuleId>, | 113 | points_to: Vec<ModuleId>, |
@@ -112,27 +128,14 @@ impl ModuleTree { | |||
112 | self.mods.iter().map(|(id, _)| id) | 128 | self.mods.iter().map(|(id, _)| id) |
113 | } | 129 | } |
114 | 130 | ||
115 | pub(crate) fn modules_with_sources<'a>( | 131 | pub(crate) fn find_module_by_source(&self, source: SourceItemId) -> Option<ModuleId> { |
116 | &'a self, | 132 | let (res, _) = self.mods.iter().find(|(_, m)| m.source == source)?; |
117 | ) -> impl Iterator<Item = (ModuleId, ModuleSource)> + 'a { | 133 | Some(res) |
118 | self.mods.iter().map(|(id, m)| (id, m.source)) | ||
119 | } | 134 | } |
120 | } | 135 | } |
121 | 136 | ||
122 | /// `ModuleSource` is the syntax tree element that produced this module: | ||
123 | /// either a file, or an inlinde module. | ||
124 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
125 | pub struct ModuleSource(pub(crate) SourceItemId); | ||
126 | |||
127 | /// An owned syntax node for a module. Unlike `ModuleSource`, | ||
128 | /// this holds onto the AST for the whole file. | ||
129 | pub(crate) enum ModuleSourceNode { | ||
130 | SourceFile(ast::SourceFileNode), | ||
131 | Module(ast::ModuleNode), | ||
132 | } | ||
133 | |||
134 | impl ModuleId { | 137 | impl ModuleId { |
135 | pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { | 138 | pub(crate) fn source(self, tree: &ModuleTree) -> SourceItemId { |
136 | tree.mods[self].source | 139 | tree.mods[self].source |
137 | } | 140 | } |
138 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { | 141 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { |
@@ -173,9 +176,9 @@ impl ModuleId { | |||
173 | tree.mods[self] | 176 | tree.mods[self] |
174 | .children | 177 | .children |
175 | .iter() | 178 | .iter() |
176 | .filter_map(|&it| { | 179 | .filter_map(|&link| { |
177 | let p = tree.links[it].problem.clone()?; | 180 | let p = tree.links[link].problem.clone()?; |
178 | let s = it.bind_source(tree, db); | 181 | let s = link.source(tree, db); |
179 | let s = s.borrowed().name().unwrap().syntax().owned(); | 182 | let s = s.borrowed().name().unwrap().syntax().owned(); |
180 | Some((s, p)) | 183 | Some((s, p)) |
181 | }) | 184 | }) |
@@ -190,59 +193,11 @@ impl LinkId { | |||
190 | pub(crate) fn name(self, tree: &ModuleTree) -> &Name { | 193 | pub(crate) fn name(self, tree: &ModuleTree) -> &Name { |
191 | &tree.links[self].name | 194 | &tree.links[self].name |
192 | } | 195 | } |
193 | pub(crate) fn bind_source<'a>( | 196 | pub(crate) fn source(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { |
194 | self, | 197 | let syntax_node = db.file_item(tree.links[self].source); |
195 | tree: &ModuleTree, | 198 | ast::ModuleNode::cast(syntax_node.borrowed()) |
196 | db: &impl HirDatabase, | 199 | .unwrap() |
197 | ) -> ast::ModuleNode { | 200 | .owned() |
198 | let owner = self.owner(tree); | ||
199 | match owner.source(tree).resolve(db) { | ||
200 | ModuleSourceNode::SourceFile(root) => { | ||
201 | let ast = modules(root.borrowed()) | ||
202 | .find(|(name, _)| name == &tree.links[self].name) | ||
203 | .unwrap() | ||
204 | .1; | ||
205 | ast.owned() | ||
206 | } | ||
207 | ModuleSourceNode::Module(it) => it, | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | impl ModuleSource { | ||
213 | // precondition: item_id **must** point to module | ||
214 | fn new(file_id: HirFileId, item_id: Option<SourceFileItemId>) -> ModuleSource { | ||
215 | let source_item_id = SourceItemId { file_id, item_id }; | ||
216 | ModuleSource(source_item_id) | ||
217 | } | ||
218 | |||
219 | pub(crate) fn new_file(file_id: HirFileId) -> ModuleSource { | ||
220 | ModuleSource::new(file_id, None) | ||
221 | } | ||
222 | |||
223 | pub(crate) fn new_inline( | ||
224 | db: &impl HirDatabase, | ||
225 | file_id: HirFileId, | ||
226 | m: ast::Module, | ||
227 | ) -> ModuleSource { | ||
228 | assert!(!m.has_semi()); | ||
229 | let file_items = db.file_items(file_id); | ||
230 | let item_id = file_items.id_of(file_id, m.syntax()); | ||
231 | ModuleSource::new(file_id, Some(item_id)) | ||
232 | } | ||
233 | |||
234 | pub(crate) fn file_id(self) -> HirFileId { | ||
235 | self.0.file_id | ||
236 | } | ||
237 | |||
238 | pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode { | ||
239 | let syntax_node = db.file_item(self.0); | ||
240 | let syntax_node = syntax_node.borrowed(); | ||
241 | if let Some(file) = ast::SourceFile::cast(syntax_node) { | ||
242 | return ModuleSourceNode::SourceFile(file.owned()); | ||
243 | } | ||
244 | let module = ast::Module::cast(syntax_node).unwrap(); | ||
245 | ModuleSourceNode::Module(module.owned()) | ||
246 | } | 201 | } |
247 | } | 202 | } |
248 | 203 | ||
@@ -283,7 +238,10 @@ fn create_module_tree<'a>( | |||
283 | 238 | ||
284 | let source_root = db.source_root(source_root); | 239 | let source_root = db.source_root(source_root); |
285 | for &file_id in source_root.files.values() { | 240 | for &file_id in source_root.files.values() { |
286 | let source = ModuleSource::new_file(file_id.into()); | 241 | let source = SourceItemId { |
242 | file_id: file_id.into(), | ||
243 | item_id: None, | ||
244 | }; | ||
287 | if visited.contains(&source) { | 245 | if visited.contains(&source) { |
288 | continue; // TODO: use explicit crate_roots here | 246 | continue; // TODO: use explicit crate_roots here |
289 | } | 247 | } |
@@ -306,10 +264,10 @@ fn build_subtree( | |||
306 | db: &impl HirDatabase, | 264 | db: &impl HirDatabase, |
307 | source_root: &SourceRoot, | 265 | source_root: &SourceRoot, |
308 | tree: &mut ModuleTree, | 266 | tree: &mut ModuleTree, |
309 | visited: &mut FxHashSet<ModuleSource>, | 267 | visited: &mut FxHashSet<SourceItemId>, |
310 | roots: &mut FxHashMap<FileId, ModuleId>, | 268 | roots: &mut FxHashMap<FileId, ModuleId>, |
311 | parent: Option<LinkId>, | 269 | parent: Option<LinkId>, |
312 | source: ModuleSource, | 270 | source: SourceItemId, |
313 | ) -> Cancelable<ModuleId> { | 271 | ) -> Cancelable<ModuleId> { |
314 | visited.insert(source); | 272 | visited.insert(source); |
315 | let id = tree.push_mod(ModuleData { | 273 | let id = tree.push_mod(ModuleData { |
@@ -319,47 +277,48 @@ fn build_subtree( | |||
319 | }); | 277 | }); |
320 | for sub in db.submodules(source)?.iter() { | 278 | for sub in db.submodules(source)?.iter() { |
321 | let link = tree.push_link(LinkData { | 279 | let link = tree.push_link(LinkData { |
322 | name: sub.name().clone(), | 280 | source: sub.source, |
281 | name: sub.name.clone(), | ||
323 | owner: id, | 282 | owner: id, |
324 | points_to: Vec::new(), | 283 | points_to: Vec::new(), |
325 | problem: None, | 284 | problem: None, |
326 | }); | 285 | }); |
327 | 286 | ||
328 | let (points_to, problem) = match sub { | 287 | let (points_to, problem) = if sub.is_declaration { |
329 | Submodule::Declaration(name) => { | 288 | let (points_to, problem) = resolve_submodule(db, source.file_id, &sub.name); |
330 | let (points_to, problem) = resolve_submodule(db, source, &name); | 289 | let points_to = points_to |
331 | let points_to = points_to | 290 | .into_iter() |
332 | .into_iter() | 291 | .map(|file_id| match roots.remove(&file_id) { |
333 | .map(|file_id| match roots.remove(&file_id) { | 292 | Some(module_id) => { |
334 | Some(module_id) => { | 293 | tree.mods[module_id].parent = Some(link); |
335 | tree.mods[module_id].parent = Some(link); | 294 | Ok(module_id) |
336 | Ok(module_id) | 295 | } |
337 | } | 296 | None => build_subtree( |
338 | None => build_subtree( | 297 | db, |
339 | db, | 298 | source_root, |
340 | source_root, | 299 | tree, |
341 | tree, | 300 | visited, |
342 | visited, | 301 | roots, |
343 | roots, | 302 | Some(link), |
344 | Some(link), | 303 | SourceItemId { |
345 | ModuleSource::new_file(file_id.into()), | 304 | file_id: file_id.into(), |
346 | ), | 305 | item_id: None, |
347 | }) | 306 | }, |
348 | .collect::<Cancelable<Vec<_>>>()?; | 307 | ), |
349 | (points_to, problem) | 308 | }) |
350 | } | 309 | .collect::<Cancelable<Vec<_>>>()?; |
351 | Submodule::Definition(_name, submodule_source) => { | 310 | (points_to, problem) |
352 | let points_to = build_subtree( | 311 | } else { |
353 | db, | 312 | let points_to = build_subtree( |
354 | source_root, | 313 | db, |
355 | tree, | 314 | source_root, |
356 | visited, | 315 | tree, |
357 | roots, | 316 | visited, |
358 | Some(link), | 317 | roots, |
359 | *submodule_source, | 318 | Some(link), |
360 | )?; | 319 | sub.source, |
361 | (vec![points_to], None) | 320 | )?; |
362 | } | 321 | (vec![points_to], None) |
363 | }; | 322 | }; |
364 | 323 | ||
365 | tree.links[link].points_to = points_to; | 324 | tree.links[link].points_to = points_to; |
@@ -370,11 +329,11 @@ fn build_subtree( | |||
370 | 329 | ||
371 | fn resolve_submodule( | 330 | fn resolve_submodule( |
372 | db: &impl HirDatabase, | 331 | db: &impl HirDatabase, |
373 | source: ModuleSource, | 332 | file_id: HirFileId, |
374 | name: &Name, | 333 | name: &Name, |
375 | ) -> (Vec<FileId>, Option<Problem>) { | 334 | ) -> (Vec<FileId>, Option<Problem>) { |
376 | // FIXME: handle submodules of inline modules properly | 335 | // FIXME: handle submodules of inline modules properly |
377 | let file_id = source.file_id().original_file(db); | 336 | let file_id = file_id.original_file(db); |
378 | let source_root_id = db.file_source_root(file_id); | 337 | let source_root_id = db.file_source_root(file_id); |
379 | let path = db.file_relative_path(file_id); | 338 | let path = db.file_relative_path(file_id); |
380 | let root = RelativePathBuf::default(); | 339 | let root = RelativePathBuf::default(); |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index e65cbcb27..9a412bc82 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -339,7 +339,7 @@ where | |||
339 | // Populate extern crates prelude | 339 | // Populate extern crates prelude |
340 | { | 340 | { |
341 | let root_id = module_id.crate_root(&self.module_tree); | 341 | let root_id = module_id.crate_root(&self.module_tree); |
342 | let file_id = root_id.source(&self.module_tree).file_id(); | 342 | let file_id = root_id.source(&self.module_tree).file_id; |
343 | let crate_graph = self.db.crate_graph(); | 343 | let crate_graph = self.db.crate_graph(); |
344 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file()) | 344 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id.as_original_file()) |
345 | { | 345 | { |
@@ -399,7 +399,7 @@ where | |||
399 | kind: DefKind::Module, | 399 | kind: DefKind::Module, |
400 | source_root_id: self.source_root, | 400 | source_root_id: self.source_root, |
401 | module_id, | 401 | module_id, |
402 | source_item_id: module_id.source(&self.module_tree).0, | 402 | source_item_id: module_id.source(&self.module_tree), |
403 | }; | 403 | }; |
404 | let def_id = def_loc.id(self.db); | 404 | let def_id = def_loc.id(self.db); |
405 | self.add_module_item(&mut module_items, name, PerNs::types(def_id)); | 405 | self.add_module_item(&mut module_items, name, PerNs::types(def_id)); |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index f4b380022..8f2c40669 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -11,11 +11,11 @@ use ra_syntax::{ | |||
11 | use ra_db::{SourceRootId, Cancelable,}; | 11 | use ra_db::{SourceRootId, Cancelable,}; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | SourceFileItems, SourceItemId, DefKind, DefId, HirFileId, | 14 | SourceFileItems, SourceItemId, DefKind, DefId, HirFileId, ModuleSource, |
15 | MacroCallLoc, | 15 | MacroCallLoc, |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | function::FnScopes, | 17 | function::FnScopes, |
18 | module_tree::{ModuleId, ModuleSourceNode}, | 18 | module_tree::ModuleId, |
19 | nameres::{InputModuleItems, ItemMap, Resolver}, | 19 | nameres::{InputModuleItems, ItemMap, Resolver}, |
20 | adt::{StructData, EnumData}, | 20 | adt::{StructData, EnumData}, |
21 | }; | 21 | }; |
@@ -65,7 +65,8 @@ pub(super) fn input_module_items( | |||
65 | ) -> Cancelable<Arc<InputModuleItems>> { | 65 | ) -> Cancelable<Arc<InputModuleItems>> { |
66 | let module_tree = db.module_tree(source_root_id)?; | 66 | let module_tree = db.module_tree(source_root_id)?; |
67 | let source = module_id.source(&module_tree); | 67 | let source = module_id.source(&module_tree); |
68 | let file_id = source.file_id(); | 68 | let file_id = source.file_id; |
69 | let source = ModuleSource::from_source_item_id(db, source); | ||
69 | let file_items = db.file_items(file_id); | 70 | let file_items = db.file_items(file_id); |
70 | let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| { | 71 | let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| { |
71 | for item in items { | 72 | for item in items { |
@@ -96,9 +97,9 @@ pub(super) fn input_module_items( | |||
96 | }; | 97 | }; |
97 | 98 | ||
98 | let mut res = InputModuleItems::default(); | 99 | let mut res = InputModuleItems::default(); |
99 | match source.resolve(db) { | 100 | match source { |
100 | ModuleSourceNode::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()), | 101 | ModuleSource::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()), |
101 | ModuleSourceNode::Module(it) => { | 102 | ModuleSource::Module(it) => { |
102 | if let Some(item_list) = it.borrowed().item_list() { | 103 | if let Some(item_list) = it.borrowed().item_list() { |
103 | fill(&mut res, &mut item_list.items_with_macros()) | 104 | fill(&mut res, &mut item_list.items_with_macros()) |
104 | } | 105 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index b7e3ff9b0..4c14650c0 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -14,15 +14,15 @@ use ra_syntax::{ | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, SourceItemId, | 16 | HirDatabase, Function, SourceItemId, |
17 | module_tree::ModuleSource, | 17 | DefKind, DefLoc, AsName, Module, |
18 | DefKind, DefLoc, AsName, | ||
19 | }; | 18 | }; |
20 | 19 | ||
21 | use crate::code_model_api::Module; | ||
22 | |||
23 | /// Locates the module by `FileId`. Picks topmost module in the file. | 20 | /// Locates the module by `FileId`. Picks topmost module in the file. |
24 | pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable<Option<Module>> { | 21 | pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Cancelable<Option<Module>> { |
25 | let module_source = ModuleSource::new_file(file_id.into()); | 22 | let module_source = SourceItemId { |
23 | file_id: file_id.into(), | ||
24 | item_id: None, | ||
25 | }; | ||
26 | module_from_source(db, module_source) | 26 | module_from_source(db, module_source) |
27 | } | 27 | } |
28 | 28 | ||
@@ -51,11 +51,26 @@ pub fn module_from_position( | |||
51 | position: FilePosition, | 51 | position: FilePosition, |
52 | ) -> Cancelable<Option<Module>> { | 52 | ) -> Cancelable<Option<Module>> { |
53 | let file = db.source_file(position.file_id); | 53 | let file = db.source_file(position.file_id); |
54 | let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { | 54 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { |
55 | Some(m) if !m.has_semi() => ModuleSource::new_inline(db, position.file_id.into(), m), | 55 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), |
56 | _ => ModuleSource::new_file(position.file_id.into()), | 56 | _ => module_from_file_id(db, position.file_id.into()), |
57 | } | ||
58 | } | ||
59 | |||
60 | fn module_from_inline( | ||
61 | db: &impl HirDatabase, | ||
62 | file_id: FileId, | ||
63 | module: ast::Module, | ||
64 | ) -> Cancelable<Option<Module>> { | ||
65 | assert!(!module.has_semi()); | ||
66 | let file_id = file_id.into(); | ||
67 | let file_items = db.file_items(file_id); | ||
68 | let item_id = file_items.id_of(file_id, module.syntax()); | ||
69 | let source = SourceItemId { | ||
70 | file_id, | ||
71 | item_id: Some(item_id), | ||
57 | }; | 72 | }; |
58 | module_from_source(db, module_source) | 73 | module_from_source(db, source) |
59 | } | 74 | } |
60 | 75 | ||
61 | /// Locates the module by child syntax element within the module | 76 | /// Locates the module by child syntax element within the module |
@@ -64,37 +79,22 @@ pub fn module_from_child_node( | |||
64 | file_id: FileId, | 79 | file_id: FileId, |
65 | child: SyntaxNodeRef, | 80 | child: SyntaxNodeRef, |
66 | ) -> Cancelable<Option<Module>> { | 81 | ) -> Cancelable<Option<Module>> { |
67 | let module_source = if let Some(m) = child | 82 | if let Some(m) = child |
68 | .ancestors() | 83 | .ancestors() |
69 | .filter_map(ast::Module::cast) | 84 | .filter_map(ast::Module::cast) |
70 | .find(|it| !it.has_semi()) | 85 | .find(|it| !it.has_semi()) |
71 | { | 86 | { |
72 | ModuleSource::new_inline(db, file_id.into(), m) | 87 | module_from_inline(db, file_id.into(), m) |
73 | } else { | 88 | } else { |
74 | ModuleSource::new_file(file_id.into()) | 89 | module_from_file_id(db, file_id.into()) |
75 | }; | 90 | } |
76 | module_from_source(db, module_source) | ||
77 | } | 91 | } |
78 | 92 | ||
79 | fn module_from_source( | 93 | fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Cancelable<Option<Module>> { |
80 | db: &impl HirDatabase, | 94 | let source_root_id = db.file_source_root(source.file_id.as_original_file()); |
81 | module_source: ModuleSource, | ||
82 | ) -> Cancelable<Option<Module>> { | ||
83 | let source_root_id = db.file_source_root(module_source.file_id().as_original_file()); | ||
84 | let module_tree = db.module_tree(source_root_id)?; | 95 | let module_tree = db.module_tree(source_root_id)?; |
85 | let m = module_tree | 96 | let module_id = ctry!(module_tree.find_module_by_source(source)); |
86 | .modules_with_sources() | 97 | Ok(Some(Module::from_module_id(db, source_root_id, module_id)?)) |
87 | .find(|(_id, src)| src == &module_source); | ||
88 | let module_id = ctry!(m).0; | ||
89 | let def_loc = DefLoc { | ||
90 | kind: DefKind::Module, | ||
91 | source_root_id, | ||
92 | module_id, | ||
93 | source_item_id: module_source.0, | ||
94 | }; | ||
95 | let def_id = def_loc.id(db); | ||
96 | |||
97 | Ok(Some(Module::new(def_id))) | ||
98 | } | 98 | } |
99 | 99 | ||
100 | pub fn function_from_position( | 100 | pub fn function_from_position( |