make source_root API more abstract

This commit is contained in:
Aleksey Kladov 2019-09-05 22:36:04 +03:00
parent 3bdb456d17
commit 9ae455ea52
7 changed files with 31 additions and 17 deletions

View file

@ -34,10 +34,11 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
.iter()
.find_map(|(source_root_id, project_root)| {
if project_root.is_member() {
for (rel_path, file_id) in &db.source_root(*source_root_id).files {
for file_id in db.source_root(*source_root_id).walk() {
let rel_path = db.file_relative_path(file_id);
let abs_path = rel_path.to_path(project_root.path());
if abs_path == path {
return Some(*file_id);
return Some(file_id);
}
}
}

View file

@ -5,7 +5,7 @@
/// Note that neither this module, nor any other part of the analyzer's core do
/// actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how
/// actual IO is done and lowered to input.
use relative_path::RelativePathBuf;
use relative_path::{RelativePath, RelativePathBuf};
use rustc_hash::FxHashMap;
use ra_syntax::SmolStr;
@ -36,7 +36,7 @@ pub struct SourceRoot {
/// Libraries are considered mostly immutable, this assumption is used to
/// optimize salsa's query structure
pub is_library: bool,
pub files: FxHashMap<RelativePathBuf, FileId>,
files: FxHashMap<RelativePathBuf, FileId>,
}
impl SourceRoot {
@ -46,6 +46,18 @@ impl SourceRoot {
pub fn new_library() -> SourceRoot {
SourceRoot { is_library: true, ..SourceRoot::new() }
}
pub fn file_by_relative_path(&self, path: &RelativePath) -> Option<FileId> {
self.files.get(path).copied()
}
pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) {
self.files.insert(path, file_id);
}
pub fn remove_file(&mut self, path: &RelativePath) {
self.files.remove(path);
}
pub fn walk(&self) -> impl Iterator<Item = FileId> + '_ {
self.files.values().copied()
}
}
/// `CrateGraph` is a bit of information which turns a set of text files into a

View file

@ -12,7 +12,7 @@ pub use crate::{
cancellation::Canceled,
input::{CrateGraph, CrateId, Dependency, Edition, FileId, SourceRoot, SourceRootId},
};
pub use ::salsa;
pub use salsa;
pub trait CheckCanceled {
/// Aborts current query if there are pending changes.
@ -93,8 +93,7 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug {
fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> {
let root = db.source_root(id);
let graph = db.crate_graph();
let res =
root.files.values().filter_map(|&it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>();
let res = root.walk().filter_map(|it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>();
Arc::new(res)
}

View file

@ -157,7 +157,7 @@ impl MockDatabase {
self.set_file_text(file_id, text);
self.set_file_relative_path(file_id, rel_path.clone());
self.set_file_source_root(file_id, source_root_id);
source_root.files.insert(rel_path, file_id);
source_root.insert_file(rel_path, file_id);
if is_crate_root {
let mut crate_graph = CrateGraph::default();

View file

@ -120,10 +120,12 @@ enum OutOfLineMode {
impl OutOfLineMode {
pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
match self {
OutOfLineMode::RootOrModRs { file, directory } => match source_root.files.get(file) {
None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
file_id => resolve_find_result(file_id, file),
},
OutOfLineMode::RootOrModRs { file, directory } => {
match source_root.file_by_relative_path(file) {
None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
file_id => resolve_find_result(file_id, file),
}
}
OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path),
OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path),
}
@ -168,11 +170,11 @@ fn resolve_simple_path(
source_root: Arc<SourceRoot>,
path: &RelativePathBuf,
) -> Result<FileId, RelativePathBuf> {
resolve_find_result(source_root.files.get(path), path)
resolve_find_result(source_root.file_by_relative_path(path), path)
}
fn resolve_find_result(
file_id: Option<&FileId>,
file_id: Option<FileId>,
path: &RelativePathBuf,
) -> Result<FileId, RelativePathBuf> {
match file_id {

View file

@ -213,11 +213,11 @@ impl RootDatabase {
durability,
);
self.set_file_source_root_with_durability(add_file.file_id, root_id, durability);
source_root.files.insert(add_file.path, add_file.file_id);
source_root.insert_file(add_file.path, add_file.file_id);
}
for remove_file in root_change.removed {
self.set_file_text_with_durability(remove_file.file_id, Default::default(), durability);
source_root.files.remove(&remove_file.path);
source_root.remove_file(&remove_file.path);
}
self.set_source_root_with_durability(root_id, Arc::new(source_root), durability);
}

View file

@ -87,7 +87,7 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol>
let mut files = Vec::new();
for &root in db.local_roots().iter() {
let sr = db.source_root(root);
files.extend(sr.files.values().copied())
files.extend(sr.walk())
}
let snap = Snap(db.snapshot());