mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
Expose package roots more directly
This commit is contained in:
parent
818aeb8a24
commit
39a2bc5e3c
3 changed files with 51 additions and 55 deletions
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
Loading…
Reference in a new issue