From 45fce9034909f2f0c5f6ac70eca7cf87ec3db856 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 4 Dec 2018 22:46:23 +0300 Subject: ModuleSource is ItemSource --- crates/ra_analysis/src/imp.rs | 5 +-- crates/ra_hir/src/lib.rs | 4 +++ crates/ra_hir/src/module/imp.rs | 13 +++----- crates/ra_hir/src/module/mod.rs | 69 ++++++++++++++++++----------------------- 4 files changed, 40 insertions(+), 51 deletions(-) diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index f5cb3550e..942b5b945 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -190,10 +190,7 @@ impl AnalysisImpl { Some(it) => it, }; let root = descr.crate_root(); - let file_id = root - .source() - .as_file() - .expect("root module always has a file as a source"); + let file_id = root.source().file_id(); let crate_graph = self.db.crate_graph(); let crate_id = crate_graph.crate_id_for_crate_root(file_id); diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index e7b6a81f4..0f84b2d61 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -131,6 +131,10 @@ impl SourceFileItems { .unwrap(); id } + pub fn id_of_source_file(&self) -> SourceFileItemId { + let (id, _syntax) = self.arena.iter().next().unwrap(); + id + } } impl Index for SourceFileItems { diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index 76ea129a7..0eec38797 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs @@ -66,7 +66,7 @@ fn create_module_tree<'a>( let source_root = db.source_root(source_root); for &file_id in source_root.files.iter() { - let source = ModuleSource::SourceFile(file_id); + let source = ModuleSource::new_file(db, file_id); if visited.contains(&source) { continue; // TODO: use explicit crate_roots here } @@ -126,7 +126,7 @@ fn build_subtree( visited, roots, Some(link), - ModuleSource::SourceFile(file_id), + ModuleSource::new_file(db, file_id), ), }) .collect::>>()?; @@ -157,13 +157,8 @@ fn resolve_submodule( name: &SmolStr, file_resolver: &FileResolverImp, ) -> (Vec, Option) { - let file_id = match source { - ModuleSource::SourceFile(it) => it, - ModuleSource::Module(..) => { - // TODO - return (Vec::new(), None); - } - }; + // TODO: handle submodules of inline modules properly + let file_id = source.file_id(); let mod_name = file_resolver.file_stem(file_id); let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; 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}; use relative_path::RelativePathBuf; use crate::{ - DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, + DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, arena::{Arena, Id}, }; @@ -37,7 +37,8 @@ impl Module { db: &impl HirDatabase, file_id: FileId, ) -> Cancelable> { - Module::guess_from_source(db, file_id, ModuleSource::SourceFile(file_id)) + let module_source = ModuleSource::new_file(db, file_id); + Module::guess_from_source(db, module_source) } /// Lookup `Module` by position in the source code. Note that this @@ -51,17 +52,16 @@ impl Module { let module_source = match find_node_at_offset::(file.syntax(), position.offset) { Some(m) if !m.has_semi() => ModuleSource::new_inline(db, position.file_id, m), - _ => ModuleSource::SourceFile(position.file_id), + _ => ModuleSource::new_file(db, position.file_id), }; - Module::guess_from_source(db, position.file_id, module_source) + Module::guess_from_source(db, module_source) } fn guess_from_source( db: &impl HirDatabase, - file_id: FileId, module_source: ModuleSource, ) -> Cancelable> { - let source_root_id = db.file_source_root(file_id); + let source_root_id = db.file_source_root(module_source.file_id()); let module_tree = db.module_tree(source_root_id)?; let res = match module_tree.any_module_for_source(module_source) { @@ -209,10 +209,7 @@ impl ModuleTree { /// `ModuleSource` is the syntax tree element that produced this module: /// either a file, or an inlinde module. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum ModuleSource { - SourceFile(FileId), - Module(SourceItemId), -} +pub struct ModuleSource(SourceItemId); /// An owned syntax node for a module. Unlike `ModuleSource`, /// this holds onto the AST for the whole file. @@ -310,45 +307,41 @@ pub struct ModuleData { } impl ModuleSource { + // precondition: item_id **must** point to module + fn new(file_id: FileId, item_id: SourceFileItemId) -> ModuleSource { + let source_item_id = SourceItemId { file_id, item_id }; + ModuleSource(source_item_id) + } + + pub(crate) fn new_file(db: &impl HirDatabase, file_id: FileId) -> ModuleSource { + let file_items = db.file_items(file_id); + let item_id = file_items.id_of_source_file(); + ModuleSource::new(file_id, item_id) + } + pub(crate) fn new_inline( db: &impl HirDatabase, file_id: FileId, - module: ast::Module, + m: ast::Module, ) -> ModuleSource { - assert!(!module.has_semi()); - let items = db.file_items(file_id); - let item_id = items.id_of(module.syntax()); - let id = SourceItemId { file_id, item_id }; - ModuleSource::Module(id) - } - - pub fn as_file(self) -> Option { - match self { - ModuleSource::SourceFile(f) => Some(f), - ModuleSource::Module(..) => None, - } + assert!(!m.has_semi()); + let file_items = db.file_items(file_id); + let item_id = file_items.id_of(m.syntax()); + ModuleSource::new(file_id, item_id) } pub fn file_id(self) -> FileId { - match self { - ModuleSource::SourceFile(f) => f, - ModuleSource::Module(source_item_id) => source_item_id.file_id, - } + self.0.file_id } pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode { - match self { - ModuleSource::SourceFile(file_id) => { - let syntax = db.source_file(file_id); - ModuleSourceNode::SourceFile(syntax.ast().owned()) - } - ModuleSource::Module(item_id) => { - let syntax = db.file_item(item_id); - let syntax = syntax.borrowed(); - let module = ast::Module::cast(syntax).unwrap(); - ModuleSourceNode::Module(module.owned()) - } + let syntax_node = db.file_item(self.0); + let syntax_node = syntax_node.borrowed(); + if let Some(file) = ast::SourceFile::cast(syntax_node) { + return ModuleSourceNode::SourceFile(file.owned()); } + let module = ast::Module::cast(syntax_node).unwrap(); + ModuleSourceNode::Module(module.owned()) } } -- cgit v1.2.3