Expose package roots more directly

This commit is contained in:
Aleksey Kladov 2020-07-21 12:52:51 +02:00
parent 818aeb8a24
commit 39a2bc5e3c
3 changed files with 51 additions and 55 deletions

View file

@ -37,28 +37,10 @@ pub enum ProjectWorkspace {
/// the current workspace. /// the current workspace.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PackageRoot { pub struct PackageRoot {
/// Path to the root folder
path: AbsPathBuf,
/// Is a member of the current workspace /// Is a member of the current workspace
is_member: bool, pub is_member: bool,
out_dir: Option<AbsPathBuf>, pub include: Vec<AbsPathBuf>,
} pub exclude: Vec<AbsPathBuf>,
impl PackageRoot {
pub fn new_member(path: AbsPathBuf) -> PackageRoot {
Self { path, is_member: true, out_dir: None }
}
pub fn new_non_member(path: AbsPathBuf) -> PackageRoot {
Self { path, is_member: false, out_dir: None }
}
pub fn path(&self) -> &AbsPath {
&self.path
}
pub fn out_dir(&self) -> Option<&AbsPath> {
self.out_dir.as_deref()
}
pub fn is_member(&self) -> bool {
self.is_member
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
@ -195,18 +177,38 @@ impl ProjectWorkspace {
/// the root is a member of the current workspace /// the root is a member of the current workspace
pub fn to_roots(&self) -> Vec<PackageRoot> { pub fn to_roots(&self) -> Vec<PackageRoot> {
match self { match self {
ProjectWorkspace::Json { project } => { ProjectWorkspace::Json { project } => project
project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect() .roots
} .iter()
.map(|r| {
let path = r.path.clone();
let include = vec![path];
PackageRoot { is_member: true, include, exclude: Vec::new() }
})
.collect(),
ProjectWorkspace::Cargo { cargo, sysroot } => cargo ProjectWorkspace::Cargo { cargo, sysroot } => cargo
.packages() .packages()
.map(|pkg| PackageRoot { .map(|pkg| {
path: cargo[pkg].root().to_path_buf(), let is_member = cargo[pkg].is_member;
is_member: cargo[pkg].is_member, let pkg_root = cargo[pkg].root().to_path_buf();
out_dir: cargo[pkg].out_dir.clone(),
let mut include = vec![pkg_root.clone()];
include.extend(cargo[pkg].out_dir.clone());
let mut exclude = vec![pkg_root.join(".git")];
if is_member {
exclude.push(pkg_root.join("target"));
} else {
exclude.push(pkg_root.join("tests"));
exclude.push(pkg_root.join("examples"));
exclude.push(pkg_root.join("benches"));
}
PackageRoot { is_member, include, exclude }
}) })
.chain(sysroot.crates().map(|krate| { .chain(sysroot.crates().map(|krate| PackageRoot {
PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) is_member: false,
include: vec![sysroot[krate].root_dir().to_path_buf()],
exclude: Vec::new(),
})) }))
.collect(), .collect(),
} }

View file

@ -5,7 +5,7 @@ use flycheck::FlycheckHandle;
use ra_db::{CrateGraph, SourceRoot, VfsPath}; use ra_db::{CrateGraph, SourceRoot, VfsPath};
use ra_ide::AnalysisChange; use ra_ide::AnalysisChange;
use ra_prof::profile; use ra_prof::profile;
use ra_project_model::{PackageRoot, ProcMacroClient, ProjectWorkspace}; use ra_project_model::{ProcMacroClient, ProjectWorkspace};
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
use crate::{ use crate::{
@ -149,8 +149,10 @@ impl GlobalState {
watchers: workspaces watchers: workspaces
.iter() .iter()
.flat_map(ProjectWorkspace::to_roots) .flat_map(ProjectWorkspace::to_roots)
.filter(PackageRoot::is_member) .filter(|it| it.is_member)
.map(|root| format!("{}/**/*.rs", root.path().display())) .flat_map(|root| {
root.include.into_iter().map(|it| format!("{}/**/*.rs", it.display()))
})
.map(|glob_pattern| lsp_types::FileSystemWatcher { glob_pattern, kind: None }) .map(|glob_pattern| lsp_types::FileSystemWatcher { glob_pattern, kind: None })
.collect(), .collect(),
}; };
@ -261,31 +263,23 @@ impl ProjectFolders {
let mut local_filesets = vec![]; let mut local_filesets = vec![];
for root in workspaces.iter().flat_map(|it| it.to_roots()) { for root in workspaces.iter().flat_map(|it| it.to_roots()) {
let path = root.path().to_owned(); let file_set_roots: Vec<VfsPath> =
root.include.iter().cloned().map(VfsPath::from).collect();
let mut file_set_roots: Vec<VfsPath> = vec![]; let entry = {
let mut dirs = vfs::loader::Directories::default();
let entry = if root.is_member() { dirs.extensions.push("rs".into());
vfs::loader::Entry::local_cargo_package(path.to_path_buf()) dirs.include.extend(root.include);
} else { dirs.exclude.extend(root.exclude);
vfs::loader::Entry::cargo_package_dependency(path.to_path_buf()) vfs::loader::Entry::Directories(dirs)
}; };
if root.is_member {
res.watch.push(res.load.len());
}
res.load.push(entry); res.load.push(entry);
if root.is_member() {
res.watch.push(res.load.len() - 1);
}
if let Some(out_dir) = root.out_dir() { if root.is_member {
let out_dir = out_dir.to_path_buf();
res.load.push(vfs::loader::Entry::rs_files_recursively(out_dir.clone()));
if root.is_member() {
res.watch.push(res.load.len() - 1);
}
file_set_roots.push(out_dir.into());
}
file_set_roots.push(path.to_path_buf().into());
if root.is_member() {
local_filesets.push(fsc.len()); local_filesets.push(fsc.len());
} }
fsc.add_file_set(file_set_roots) fsc.add_file_set(file_set_roots)

View file

@ -17,7 +17,7 @@ pub enum Entry {
/// * it is not under `exclude` path /// * it is not under `exclude` path
/// ///
/// If many include/exclude paths match, the longest one wins. /// If many include/exclude paths match, the longest one wins.
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub struct Directories { pub struct Directories {
pub extensions: Vec<String>, pub extensions: Vec<String>,
pub include: Vec<AbsPathBuf>, pub include: Vec<AbsPathBuf>,