mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
ModuleTreeDescriptor
This commit is contained in:
parent
d59413c895
commit
58674dc3c4
8 changed files with 306 additions and 138 deletions
|
@ -18,8 +18,8 @@ use libsyntax2::{
|
|||
use {
|
||||
FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit,
|
||||
JobToken, CrateGraph, CrateId,
|
||||
module_map::{ModuleMap, Problem},
|
||||
roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot},
|
||||
descriptors::{ModuleTreeDescriptor, Problem},
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,25 +148,24 @@ impl AnalysisImpl {
|
|||
}
|
||||
pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> {
|
||||
let root = self.root(file_id);
|
||||
let module_map = root.module_map();
|
||||
let id = module_map.file2module(file_id);
|
||||
module_map
|
||||
.parent_modules(id, &|file_id| root.syntax(file_id))
|
||||
.into_iter()
|
||||
.map(|(id, name, node)| {
|
||||
let id = module_map.module2file(id);
|
||||
let module_tree = root.module_tree();
|
||||
module_tree.parent_modules(file_id)
|
||||
.iter()
|
||||
.map(|link| {
|
||||
let file_id = link.owner(&module_tree);
|
||||
let syntax = root.syntax(file_id);
|
||||
let decl = link.bind_source(&module_tree, syntax.ast());
|
||||
let sym = FileSymbol {
|
||||
name,
|
||||
node_range: node.range(),
|
||||
name: link.name(&module_tree),
|
||||
node_range: decl.syntax().range(),
|
||||
kind: MODULE,
|
||||
};
|
||||
(id, sym)
|
||||
(file_id, sym)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> {
|
||||
let module_map = self.root(file_id).module_map();
|
||||
let module_tree = self.root(file_id).module_tree();
|
||||
let crate_graph = &self.data.crate_graph;
|
||||
let mut res = Vec::new();
|
||||
let mut work = VecDeque::new();
|
||||
|
@ -177,11 +176,10 @@ impl AnalysisImpl {
|
|||
res.push(crate_id);
|
||||
continue;
|
||||
}
|
||||
let mid = module_map.file2module(id);
|
||||
let parents = module_map
|
||||
.parent_module_ids(mid, &|file_id| self.file_syntax(file_id))
|
||||
let parents = module_tree
|
||||
.parent_modules(id)
|
||||
.into_iter()
|
||||
.map(|id| module_map.module2file(id))
|
||||
.map(|link| link.owner(&module_tree))
|
||||
.filter(|&id| visited.insert(id));
|
||||
work.extend(parents);
|
||||
}
|
||||
|
@ -197,7 +195,7 @@ impl AnalysisImpl {
|
|||
token: &JobToken,
|
||||
) -> Vec<(FileId, FileSymbol)> {
|
||||
let root = self.root(file_id);
|
||||
let module_map = root.module_map();
|
||||
let module_tree = root.module_tree();
|
||||
let file = root.syntax(file_id);
|
||||
let syntax = file.syntax();
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
|
||||
|
@ -206,7 +204,7 @@ impl AnalysisImpl {
|
|||
if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) {
|
||||
if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
|
||||
if module.has_semi() {
|
||||
let file_ids = self.resolve_module(module_map, file_id, module);
|
||||
let file_ids = self.resolve_module(&*module_tree, file_id, module);
|
||||
|
||||
let res = file_ids.into_iter().map(|id| {
|
||||
let name = module.name()
|
||||
|
@ -229,7 +227,7 @@ impl AnalysisImpl {
|
|||
|
||||
pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> {
|
||||
let root = self.root(file_id);
|
||||
let module_map = root.module_map();
|
||||
let module_tree = root.module_tree();
|
||||
let syntax = root.syntax(file_id);
|
||||
|
||||
let mut res = libeditor::diagnostics(&syntax)
|
||||
|
@ -237,47 +235,43 @@ impl AnalysisImpl {
|
|||
.map(|d| Diagnostic { range: d.range, message: d.msg, fix: None })
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
module_map.problems(
|
||||
file_id,
|
||||
&|file_id| self.file_syntax(file_id),
|
||||
|name_node, problem| {
|
||||
let diag = match problem {
|
||||
Problem::UnresolvedModule { candidate } => {
|
||||
let create_file = FileSystemEdit::CreateFile {
|
||||
anchor: file_id,
|
||||
path: candidate.clone(),
|
||||
};
|
||||
let fix = SourceChange {
|
||||
label: "create module".to_string(),
|
||||
source_file_edits: Vec::new(),
|
||||
file_system_edits: vec![create_file],
|
||||
cursor_position: None,
|
||||
};
|
||||
Diagnostic {
|
||||
range: name_node.syntax().range(),
|
||||
message: "unresolved module".to_string(),
|
||||
fix: Some(fix),
|
||||
}
|
||||
for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) {
|
||||
let diag = match problem {
|
||||
Problem::UnresolvedModule { candidate } => {
|
||||
let create_file = FileSystemEdit::CreateFile {
|
||||
anchor: file_id,
|
||||
path: candidate.clone(),
|
||||
};
|
||||
let fix = SourceChange {
|
||||
label: "create module".to_string(),
|
||||
source_file_edits: Vec::new(),
|
||||
file_system_edits: vec![create_file],
|
||||
cursor_position: None,
|
||||
};
|
||||
Diagnostic {
|
||||
range: name_node.syntax().range(),
|
||||
message: "unresolved module".to_string(),
|
||||
fix: Some(fix),
|
||||
}
|
||||
Problem::NotDirOwner { move_to, candidate } => {
|
||||
let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() };
|
||||
let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) };
|
||||
let fix = SourceChange {
|
||||
label: "move file and create module".to_string(),
|
||||
source_file_edits: Vec::new(),
|
||||
file_system_edits: vec![move_file, create_file],
|
||||
cursor_position: None,
|
||||
};
|
||||
Diagnostic {
|
||||
range: name_node.syntax().range(),
|
||||
message: "can't declare module at this location".to_string(),
|
||||
fix: Some(fix),
|
||||
}
|
||||
}
|
||||
Problem::NotDirOwner { move_to, candidate } => {
|
||||
let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() };
|
||||
let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) };
|
||||
let fix = SourceChange {
|
||||
label: "move file and create module".to_string(),
|
||||
source_file_edits: Vec::new(),
|
||||
file_system_edits: vec![move_file, create_file],
|
||||
cursor_position: None,
|
||||
};
|
||||
Diagnostic {
|
||||
range: name_node.syntax().range(),
|
||||
message: "can't declare module at this location".to_string(),
|
||||
fix: Some(fix),
|
||||
}
|
||||
};
|
||||
res.push(diag)
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
res.push(diag)
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
|
@ -307,20 +301,12 @@ impl AnalysisImpl {
|
|||
self.world_symbols(query, token)
|
||||
}
|
||||
|
||||
fn resolve_module(&self, module_map: &ModuleMap, file_id: FileId, module: ast::Module) -> Vec<FileId> {
|
||||
fn resolve_module(&self, module_tree: &ModuleTreeDescriptor, file_id: FileId, module: ast::Module) -> Vec<FileId> {
|
||||
let name = match module.name() {
|
||||
Some(name) => name.text(),
|
||||
None => return Vec::new(),
|
||||
};
|
||||
let id = module_map.file2module(file_id);
|
||||
module_map
|
||||
.child_module_by_name(
|
||||
id, name.as_str(),
|
||||
&|file_id| self.file_syntax(file_id),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|id| module_map.module2file(id))
|
||||
.collect()
|
||||
module_tree.child_module_by_name(file_id, name.as_str())
|
||||
}
|
||||
|
||||
fn reindex(&self) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue