From 44d891938493cc32efd2e44d81bc76cc3bc391c0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 5 Nov 2018 13:23:37 +0300 Subject: Submodule is enum --- crates/ra_analysis/src/descriptors/module/imp.rs | 77 +++++++++++++++++------- crates/ra_analysis/src/descriptors/module/mod.rs | 7 +++ crates/ra_analysis/src/syntax_ptr.rs | 4 ++ 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index d67ffa9de..257a323ed 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use ra_syntax::{ - ast::{self, ModuleItemOwner, NameOwner}, + ast::{self, ModuleItemOwner, NameOwner, AstNode}, SmolStr, }; use relative_path::RelativePathBuf; @@ -12,6 +12,7 @@ use crate::{ descriptors::DescriptorDatabase, input::{SourceRoot, SourceRootId}, Cancelable, FileId, FileResolverImp, + syntax_ptr::SyntaxPtr, }; use super::{ @@ -20,8 +21,18 @@ use super::{ }; #[derive(Clone, Hash, PartialEq, Eq, Debug)] -pub(crate) struct Submodule { - name: SmolStr, +pub(crate) enum Submodule { + Declaration(SmolStr), + Definition(SmolStr, SyntaxPtr), +} + +impl Submodule { + fn name(&self) -> &SmolStr { + match self { + Submodule::Declaration(name) => name, + Submodule::Definition(name, _) => name, + } + } } pub(crate) fn submodules( @@ -29,20 +40,29 @@ pub(crate) fn submodules( source: ModuleSource, ) -> Cancelable>> { db::check_canceled(db)?; + let file_id = source.file_id(); let submodules = match source.resolve(db) { - ModuleSourceNode::Root(it) => collect_submodules(it.ast()), + ModuleSourceNode::Root(it) => collect_submodules(file_id, it.ast()), ModuleSourceNode::Inline(it) => it .ast() .item_list() - .map(collect_submodules) + .map(|it| collect_submodules(file_id, it)) .unwrap_or_else(Vec::new), }; return Ok(Arc::new(submodules)); - fn collect_submodules<'a>(root: impl ast::ModuleItemOwner<'a>) -> Vec { + fn collect_submodules<'a>( + file_id: FileId, + root: impl ast::ModuleItemOwner<'a>, + ) -> Vec { modules(root) - .filter(|(_, m)| m.has_semi()) - .map(|(name, _)| Submodule { name }) + .map(|(name, m)| { + if m.has_semi() { + Submodule::Declaration(name) + } else { + Submodule::Definition(name, SyntaxPtr::new(file_id, m.syntax())) + } + }) .collect() } } @@ -135,25 +155,40 @@ fn build_subtree( children: Vec::new(), }); for sub in db.submodules(ModuleSource::File(file_id))?.iter() { - let name = sub.name.clone(); - let (points_to, problem) = resolve_submodule(file_id, &name, &source_root.file_resolver); let link = tree.push_link(LinkData { - name, + name: sub.name().clone(), owner: id, points_to: Vec::new(), problem: None, }); - let points_to = points_to - .into_iter() - .map(|file_id| match roots.remove(&file_id) { - Some(module_id) => { - tree.module_mut(module_id).parent = Some(link); - Ok(module_id) - } - None => build_subtree(db, source_root, tree, visited, roots, Some(link), file_id), - }) - .collect::>>()?; + let (points_to, problem) = match sub { + Submodule::Declaration(name) => { + let (points_to, problem) = + resolve_submodule(file_id, &name, &source_root.file_resolver); + let points_to = points_to + .into_iter() + .map(|file_id| match roots.remove(&file_id) { + Some(module_id) => { + tree.module_mut(module_id).parent = Some(link); + Ok(module_id) + } + None => build_subtree( + db, + source_root, + tree, + visited, + roots, + Some(link), + file_id, + ), + }) + .collect::>>()?; + (points_to, problem) + } + Submodule::Definition(..) => continue, + }; + tree.link_mut(link).points_to = points_to; tree.link_mut(link).problem = problem; } diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 13bab0087..8464b0618 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -164,6 +164,13 @@ impl ModuleSource { } } + fn file_id(self) -> FileId { + match self { + ModuleSource::File(f) => f, + ModuleSource::Inline(ptr) => ptr.file_id(), + } + } + fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode { match self { ModuleSource::File(file_id) => { diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs index 4db1529c2..4afb1fc93 100644 --- a/crates/ra_analysis/src/syntax_ptr.rs +++ b/crates/ra_analysis/src/syntax_ptr.rs @@ -22,6 +22,10 @@ impl SyntaxPtr { let local = LocalSyntaxPtr::new(node); SyntaxPtr { file_id, local } } + + pub(crate) fn file_id(self) -> FileId { + self.file_id + } } /// A pionter to a syntax node inside a file. -- cgit v1.2.3