Submodule is enum

This commit is contained in:
Aleksey Kladov 2018-11-05 13:23:37 +03:00
parent 17a88928f4
commit 44d8919384
3 changed files with 67 additions and 21 deletions

View file

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{ use ra_syntax::{
ast::{self, ModuleItemOwner, NameOwner}, ast::{self, ModuleItemOwner, NameOwner, AstNode},
SmolStr, SmolStr,
}; };
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
@ -12,6 +12,7 @@ use crate::{
descriptors::DescriptorDatabase, descriptors::DescriptorDatabase,
input::{SourceRoot, SourceRootId}, input::{SourceRoot, SourceRootId},
Cancelable, FileId, FileResolverImp, Cancelable, FileId, FileResolverImp,
syntax_ptr::SyntaxPtr,
}; };
use super::{ use super::{
@ -20,8 +21,18 @@ use super::{
}; };
#[derive(Clone, Hash, PartialEq, Eq, Debug)] #[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub(crate) struct Submodule { pub(crate) enum Submodule {
name: SmolStr, 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( pub(crate) fn submodules(
@ -29,20 +40,29 @@ pub(crate) fn submodules(
source: ModuleSource, source: ModuleSource,
) -> Cancelable<Arc<Vec<Submodule>>> { ) -> Cancelable<Arc<Vec<Submodule>>> {
db::check_canceled(db)?; db::check_canceled(db)?;
let file_id = source.file_id();
let submodules = match source.resolve(db) { 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 ModuleSourceNode::Inline(it) => it
.ast() .ast()
.item_list() .item_list()
.map(collect_submodules) .map(|it| collect_submodules(file_id, it))
.unwrap_or_else(Vec::new), .unwrap_or_else(Vec::new),
}; };
return Ok(Arc::new(submodules)); return Ok(Arc::new(submodules));
fn collect_submodules<'a>(root: impl ast::ModuleItemOwner<'a>) -> Vec<Submodule> { fn collect_submodules<'a>(
file_id: FileId,
root: impl ast::ModuleItemOwner<'a>,
) -> Vec<Submodule> {
modules(root) modules(root)
.filter(|(_, m)| m.has_semi()) .map(|(name, m)| {
.map(|(name, _)| Submodule { name }) if m.has_semi() {
Submodule::Declaration(name)
} else {
Submodule::Definition(name, SyntaxPtr::new(file_id, m.syntax()))
}
})
.collect() .collect()
} }
} }
@ -135,25 +155,40 @@ fn build_subtree(
children: Vec::new(), children: Vec::new(),
}); });
for sub in db.submodules(ModuleSource::File(file_id))?.iter() { 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 { let link = tree.push_link(LinkData {
name, name: sub.name().clone(),
owner: id, owner: id,
points_to: Vec::new(), points_to: Vec::new(),
problem: None, problem: None,
}); });
let points_to = points_to let (points_to, problem) = match sub {
.into_iter() Submodule::Declaration(name) => {
.map(|file_id| match roots.remove(&file_id) { let (points_to, problem) =
Some(module_id) => { resolve_submodule(file_id, &name, &source_root.file_resolver);
tree.module_mut(module_id).parent = Some(link); let points_to = points_to
Ok(module_id) .into_iter()
} .map(|file_id| match roots.remove(&file_id) {
None => build_subtree(db, source_root, tree, visited, roots, Some(link), file_id), Some(module_id) => {
}) tree.module_mut(module_id).parent = Some(link);
.collect::<Cancelable<Vec<_>>>()?; Ok(module_id)
}
None => build_subtree(
db,
source_root,
tree,
visited,
roots,
Some(link),
file_id,
),
})
.collect::<Cancelable<Vec<_>>>()?;
(points_to, problem)
}
Submodule::Definition(..) => continue,
};
tree.link_mut(link).points_to = points_to; tree.link_mut(link).points_to = points_to;
tree.link_mut(link).problem = problem; tree.link_mut(link).problem = problem;
} }

View file

@ -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 { fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
match self { match self {
ModuleSource::File(file_id) => { ModuleSource::File(file_id) => {

View file

@ -22,6 +22,10 @@ impl SyntaxPtr {
let local = LocalSyntaxPtr::new(node); let local = LocalSyntaxPtr::new(node);
SyntaxPtr { file_id, local } SyntaxPtr { file_id, local }
} }
pub(crate) fn file_id(self) -> FileId {
self.file_id
}
} }
/// A pionter to a syntax node inside a file. /// A pionter to a syntax node inside a file.