aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/module/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/module/mod.rs')
-rw-r--r--crates/ra_hir/src/module/mod.rs69
1 files changed, 31 insertions, 38 deletions
diff --git a/crates/ra_hir/src/module/mod.rs b/crates/ra_hir/src/module/mod.rs
index 3ae83d8cb..fa9ee94eb 100644
--- a/crates/ra_hir/src/module/mod.rs
+++ b/crates/ra_hir/src/module/mod.rs
@@ -14,7 +14,7 @@ use ra_db::{SourceRootId, FileId, FilePosition, Cancelable};
14use relative_path::RelativePathBuf; 14use relative_path::RelativePathBuf;
15 15
16use crate::{ 16use crate::{
17 DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, 17 DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId,
18 arena::{Arena, Id}, 18 arena::{Arena, Id},
19}; 19};
20 20
@@ -37,7 +37,8 @@ impl Module {
37 db: &impl HirDatabase, 37 db: &impl HirDatabase,
38 file_id: FileId, 38 file_id: FileId,
39 ) -> Cancelable<Option<Module>> { 39 ) -> Cancelable<Option<Module>> {
40 Module::guess_from_source(db, file_id, ModuleSource::SourceFile(file_id)) 40 let module_source = ModuleSource::new_file(db, file_id);
41 Module::guess_from_source(db, module_source)
41 } 42 }
42 43
43 /// Lookup `Module` by position in the source code. Note that this 44 /// Lookup `Module` by position in the source code. Note that this
@@ -51,17 +52,16 @@ impl Module {
51 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) 52 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset)
52 { 53 {
53 Some(m) if !m.has_semi() => ModuleSource::new_inline(db, position.file_id, m), 54 Some(m) if !m.has_semi() => ModuleSource::new_inline(db, position.file_id, m),
54 _ => ModuleSource::SourceFile(position.file_id), 55 _ => ModuleSource::new_file(db, position.file_id),
55 }; 56 };
56 Module::guess_from_source(db, position.file_id, module_source) 57 Module::guess_from_source(db, module_source)
57 } 58 }
58 59
59 fn guess_from_source( 60 fn guess_from_source(
60 db: &impl HirDatabase, 61 db: &impl HirDatabase,
61 file_id: FileId,
62 module_source: ModuleSource, 62 module_source: ModuleSource,
63 ) -> Cancelable<Option<Module>> { 63 ) -> Cancelable<Option<Module>> {
64 let source_root_id = db.file_source_root(file_id); 64 let source_root_id = db.file_source_root(module_source.file_id());
65 let module_tree = db.module_tree(source_root_id)?; 65 let module_tree = db.module_tree(source_root_id)?;
66 66
67 let res = match module_tree.any_module_for_source(module_source) { 67 let res = match module_tree.any_module_for_source(module_source) {
@@ -209,10 +209,7 @@ impl ModuleTree {
209/// `ModuleSource` is the syntax tree element that produced this module: 209/// `ModuleSource` is the syntax tree element that produced this module:
210/// either a file, or an inlinde module. 210/// either a file, or an inlinde module.
211#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 211#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
212pub enum ModuleSource { 212pub struct ModuleSource(SourceItemId);
213 SourceFile(FileId),
214 Module(SourceItemId),
215}
216 213
217/// An owned syntax node for a module. Unlike `ModuleSource`, 214/// An owned syntax node for a module. Unlike `ModuleSource`,
218/// this holds onto the AST for the whole file. 215/// this holds onto the AST for the whole file.
@@ -310,45 +307,41 @@ pub struct ModuleData {
310} 307}
311 308
312impl ModuleSource { 309impl ModuleSource {
310 // precondition: item_id **must** point to module
311 fn new(file_id: FileId, item_id: SourceFileItemId) -> ModuleSource {
312 let source_item_id = SourceItemId { file_id, item_id };
313 ModuleSource(source_item_id)
314 }
315
316 pub(crate) fn new_file(db: &impl HirDatabase, file_id: FileId) -> ModuleSource {
317 let file_items = db.file_items(file_id);
318 let item_id = file_items.id_of_source_file();
319 ModuleSource::new(file_id, item_id)
320 }
321
313 pub(crate) fn new_inline( 322 pub(crate) fn new_inline(
314 db: &impl HirDatabase, 323 db: &impl HirDatabase,
315 file_id: FileId, 324 file_id: FileId,
316 module: ast::Module, 325 m: ast::Module,
317 ) -> ModuleSource { 326 ) -> ModuleSource {
318 assert!(!module.has_semi()); 327 assert!(!m.has_semi());
319 let items = db.file_items(file_id); 328 let file_items = db.file_items(file_id);
320 let item_id = items.id_of(module.syntax()); 329 let item_id = file_items.id_of(m.syntax());
321 let id = SourceItemId { file_id, item_id }; 330 ModuleSource::new(file_id, item_id)
322 ModuleSource::Module(id)
323 }
324
325 pub fn as_file(self) -> Option<FileId> {
326 match self {
327 ModuleSource::SourceFile(f) => Some(f),
328 ModuleSource::Module(..) => None,
329 }
330 } 331 }
331 332
332 pub fn file_id(self) -> FileId { 333 pub fn file_id(self) -> FileId {
333 match self { 334 self.0.file_id
334 ModuleSource::SourceFile(f) => f,
335 ModuleSource::Module(source_item_id) => source_item_id.file_id,
336 }
337 } 335 }
338 336
339 pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode { 337 pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode {
340 match self { 338 let syntax_node = db.file_item(self.0);
341 ModuleSource::SourceFile(file_id) => { 339 let syntax_node = syntax_node.borrowed();
342 let syntax = db.source_file(file_id); 340 if let Some(file) = ast::SourceFile::cast(syntax_node) {
343 ModuleSourceNode::SourceFile(syntax.ast().owned()) 341 return ModuleSourceNode::SourceFile(file.owned());
344 }
345 ModuleSource::Module(item_id) => {
346 let syntax = db.file_item(item_id);
347 let syntax = syntax.borrowed();
348 let module = ast::Module::cast(syntax).unwrap();
349 ModuleSourceNode::Module(module.owned())
350 }
351 } 342 }
343 let module = ast::Module::cast(syntax_node).unwrap();
344 ModuleSourceNode::Module(module.owned())
352 } 345 }
353} 346}
354 347