From 223fd2979c277cf402e4876d0e9a69257702f731 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 1 Nov 2018 00:15:11 +0300 Subject: [PATCH] Introduce ModuleSource --- .../ra_analysis/src/descriptors/module/imp.rs | 8 +++-- .../ra_analysis/src/descriptors/module/mod.rs | 31 ++++++++++++++++--- crates/ra_analysis/src/imp.rs | 12 ++++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index 1c102f4e5dd..22dbe71840b 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -14,7 +14,9 @@ use crate::{ Cancelable, FileId, FileResolverImp, }; -use super::{LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleTree, Problem}; +use super::{ + LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleSource, ModuleTree, Problem, +}; pub(crate) fn submodules( db: &impl DescriptorDatabase, @@ -43,7 +45,7 @@ pub(crate) fn module_scope( module_id: ModuleId, ) -> Cancelable> { let tree = db.module_tree(source_root_id)?; - let file_id = module_id.file_id(&tree); + let ModuleSource::File(file_id) = module_id.source(&tree); let syntax = db.file_syntax(file_id); let res = ModuleScope::new(&syntax); Ok(Arc::new(res)) @@ -106,7 +108,7 @@ fn build_subtree( ) -> Cancelable { visited.insert(file_id); let id = tree.push_mod(ModuleData { - file_id, + source: ModuleSource::File(file_id), parent, children: Vec::new(), }); diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 302e3e81cf2..cbccdb2e27b 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -11,6 +11,13 @@ use crate::FileId; pub(crate) use self::scope::ModuleScope; +/// Phisically, rust source is organized as a set of files, but logically it is +/// organized as a tree of modules. Usually, a single file corresponds to a +/// single module, but it is not nessary the case. +/// +/// Module encapsulate the logic of transitioning from the fuzzy world of files +/// (which can have multiple parents) to the precise world of modules (which +/// always have one parent). #[derive(Debug, PartialEq, Eq, Hash)] pub(crate) struct ModuleTree { mods: Vec, @@ -22,7 +29,7 @@ impl ModuleTree { self.mods .iter() .enumerate() - .filter(|(_idx, it)| it.file_id == file_id) + .filter(|(_idx, it)| it.source.is_file(file_id)) .map(|(idx, _)| ModuleId(idx as u32)) .collect() } @@ -50,8 +57,8 @@ pub enum Problem { } impl ModuleId { - pub(crate) fn file_id(self, tree: &ModuleTree) -> FileId { - tree.module(self).file_id + pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { + tree.module(self).source } pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option { tree.module(self).parent @@ -110,11 +117,27 @@ impl LinkId { #[derive(Debug, PartialEq, Eq, Hash)] struct ModuleData { - file_id: FileId, + source: ModuleSource, parent: Option, children: Vec, } +/// `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(crate) enum ModuleSource { + File(FileId), + // Inline(SyntaxPtr), +} + +impl ModuleSource { + fn is_file(self, file_id: FileId) -> bool { + match self { + ModuleSource::File(f) => f == file_id, + } + } +} + #[derive(Hash, Debug, PartialEq, Eq)] struct LinkData { owner: ModuleId, diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 0744ea9c8da..c1269025c8d 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -20,7 +20,7 @@ use crate::{ db::{self, FileSyntaxQuery, SyntaxDatabase}, descriptors::{ function::{FnDescriptor, FnId}, - module::{ModuleTree, Problem}, + module::{ModuleSource, ModuleTree, Problem}, DeclarationDescriptor, DescriptorDatabase, }, input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, @@ -222,7 +222,7 @@ impl AnalysisImpl { .into_iter() .filter_map(|module_id| { let link = module_id.parent_link(&module_tree)?; - let file_id = link.owner(&module_tree).file_id(&module_tree); + let ModuleSource::File(file_id) = link.owner(&module_tree).source(&module_tree); let syntax = self.db.file_syntax(file_id); let decl = link.bind_source(&module_tree, syntax.ast()); @@ -243,7 +243,9 @@ impl AnalysisImpl { .modules_for_file(file_id) .into_iter() .map(|it| it.root(&module_tree)) - .map(|it| it.file_id(&module_tree)) + .map(|it| match it.source(&module_tree) { + ModuleSource::File(file_id) => file_id, + }) .filter_map(|it| crate_graph.crate_id_for_crate_root(it)) .collect(); @@ -533,7 +535,9 @@ impl AnalysisImpl { }; module_id .child(module_tree, name.as_str()) - .map(|it| it.file_id(module_tree)) + .map(|it| match it.source(&module_tree) { + ModuleSource::File(file_id) => file_id, + }) .into_iter() .collect() }