mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Submodule is enum
This commit is contained in:
parent
17a88928f4
commit
44d8919384
3 changed files with 67 additions and 21 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue