mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge #4723
4723: Derive local roots from Workspaces r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
5100f77073
@ -5,6 +5,13 @@ use std::path::PathBuf;
|
|||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
/// Roots and crates that compose this Rust project.
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
pub struct JsonProject {
|
||||||
|
pub(crate) roots: Vec<Root>,
|
||||||
|
pub(crate) crates: Vec<Crate>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A root points to the directory which contains Rust crates. rust-analyzer watches all files in
|
/// A root points to the directory which contains Rust crates. rust-analyzer watches all files in
|
||||||
/// all roots. Roots might be nested.
|
/// all roots. Roots might be nested.
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
@ -57,13 +64,6 @@ pub struct Dep {
|
|||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Roots and crates that compose this Rust project.
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
|
||||||
pub struct JsonProject {
|
|
||||||
pub(crate) roots: Vec<Root>,
|
|
||||||
pub(crate) crates: Vec<Crate>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -164,7 +164,6 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WorldState::new(
|
WorldState::new(
|
||||||
ws_roots,
|
|
||||||
workspaces,
|
workspaces,
|
||||||
config.lru_capacity,
|
config.lru_capacity,
|
||||||
&globs,
|
&globs,
|
||||||
|
@ -58,7 +58,7 @@ fn create_flycheck(workspaces: &[ProjectWorkspace], config: &FlycheckConfig) ->
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WorldState {
|
pub struct WorldState {
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub roots: Vec<PathBuf>,
|
pub local_roots: Vec<PathBuf>,
|
||||||
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||||
pub analysis_host: AnalysisHost,
|
pub analysis_host: AnalysisHost,
|
||||||
pub vfs: Arc<RwLock<Vfs>>,
|
pub vfs: Arc<RwLock<Vfs>>,
|
||||||
@ -81,7 +81,6 @@ pub struct WorldSnapshot {
|
|||||||
|
|
||||||
impl WorldState {
|
impl WorldState {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
folder_roots: Vec<PathBuf>,
|
|
||||||
workspaces: Vec<ProjectWorkspace>,
|
workspaces: Vec<ProjectWorkspace>,
|
||||||
lru_capacity: Option<usize>,
|
lru_capacity: Option<usize>,
|
||||||
exclude_globs: &[Glob],
|
exclude_globs: &[Glob],
|
||||||
@ -93,6 +92,7 @@ impl WorldState {
|
|||||||
let extern_dirs: FxHashSet<_> =
|
let extern_dirs: FxHashSet<_> =
|
||||||
workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect();
|
workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect();
|
||||||
|
|
||||||
|
let mut local_roots = Vec::new();
|
||||||
let roots: Vec<_> = {
|
let roots: Vec<_> = {
|
||||||
let create_filter = |is_member| {
|
let create_filter = |is_member| {
|
||||||
RustPackageFilterBuilder::default()
|
RustPackageFilterBuilder::default()
|
||||||
@ -100,12 +100,16 @@ impl WorldState {
|
|||||||
.exclude(exclude_globs.iter().cloned())
|
.exclude(exclude_globs.iter().cloned())
|
||||||
.into_vfs_filter()
|
.into_vfs_filter()
|
||||||
};
|
};
|
||||||
folder_roots
|
workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.map(|path| RootEntry::new(path.clone(), create_filter(true)))
|
.flat_map(ProjectWorkspace::to_roots)
|
||||||
.chain(workspaces.iter().flat_map(ProjectWorkspace::to_roots).map(|pkg_root| {
|
.map(|pkg_root| {
|
||||||
RootEntry::new(pkg_root.path().to_owned(), create_filter(pkg_root.is_member()))
|
let path = pkg_root.path().to_owned();
|
||||||
}))
|
if pkg_root.is_member() {
|
||||||
|
local_roots.push(path.clone());
|
||||||
|
}
|
||||||
|
RootEntry::new(path, create_filter(pkg_root.is_member()))
|
||||||
|
})
|
||||||
.chain(
|
.chain(
|
||||||
extern_dirs
|
extern_dirs
|
||||||
.iter()
|
.iter()
|
||||||
@ -121,7 +125,7 @@ impl WorldState {
|
|||||||
let mut extern_source_roots = FxHashMap::default();
|
let mut extern_source_roots = FxHashMap::default();
|
||||||
for r in vfs_roots {
|
for r in vfs_roots {
|
||||||
let vfs_root_path = vfs.root2path(r);
|
let vfs_root_path = vfs.root2path(r);
|
||||||
let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it));
|
let is_local = local_roots.iter().any(|it| vfs_root_path.starts_with(it));
|
||||||
change.add_root(SourceRootId(r.0), is_local);
|
change.add_root(SourceRootId(r.0), is_local);
|
||||||
change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string());
|
change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string());
|
||||||
|
|
||||||
@ -178,7 +182,7 @@ impl WorldState {
|
|||||||
analysis_host.apply_change(change);
|
analysis_host.apply_change(change);
|
||||||
WorldState {
|
WorldState {
|
||||||
config,
|
config,
|
||||||
roots: folder_roots,
|
local_roots,
|
||||||
workspaces: Arc::new(workspaces),
|
workspaces: Arc::new(workspaces),
|
||||||
analysis_host,
|
analysis_host,
|
||||||
vfs: Arc::new(RwLock::new(vfs)),
|
vfs: Arc::new(RwLock::new(vfs)),
|
||||||
@ -216,7 +220,7 @@ impl WorldState {
|
|||||||
match c {
|
match c {
|
||||||
VfsChange::AddRoot { root, files } => {
|
VfsChange::AddRoot { root, files } => {
|
||||||
let root_path = self.vfs.read().root2path(root);
|
let root_path = self.vfs.read().root2path(root);
|
||||||
let is_local = self.roots.iter().any(|r| root_path.starts_with(r));
|
let is_local = self.local_roots.iter().any(|r| root_path.starts_with(r));
|
||||||
if is_local {
|
if is_local {
|
||||||
*roots_scanned += 1;
|
*roots_scanned += 1;
|
||||||
for (file, path, text) in files {
|
for (file, path, text) in files {
|
||||||
|
@ -58,55 +58,6 @@ use std::collections::Spam;
|
|||||||
eprintln!("completion took {:?}", completion_start.elapsed());
|
eprintln!("completion took {:?}", completion_start.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_runnables_no_project() {
|
|
||||||
if skip_slow_tests() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let server = project(
|
|
||||||
r"
|
|
||||||
//- lib.rs
|
|
||||||
#[test]
|
|
||||||
fn foo() {
|
|
||||||
}
|
|
||||||
",
|
|
||||||
);
|
|
||||||
server.wait_until_workspace_is_loaded();
|
|
||||||
server.request::<Runnables>(
|
|
||||||
RunnablesParams { text_document: server.doc_id("lib.rs"), position: None },
|
|
||||||
json!([
|
|
||||||
{
|
|
||||||
"args": {
|
|
||||||
"cargoArgs": ["test"],
|
|
||||||
"executableArgs": ["foo", "--nocapture"],
|
|
||||||
},
|
|
||||||
"kind": "cargo",
|
|
||||||
"label": "test foo",
|
|
||||||
"location": {
|
|
||||||
"targetRange": {
|
|
||||||
"end": { "character": 1, "line": 2 },
|
|
||||||
"start": { "character": 0, "line": 0 }
|
|
||||||
},
|
|
||||||
"targetSelectionRange": {
|
|
||||||
"end": { "character": 6, "line": 1 },
|
|
||||||
"start": { "character": 3, "line": 1 }
|
|
||||||
},
|
|
||||||
"targetUri": "file:///[..]/lib.rs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"args": {
|
|
||||||
"cargoArgs": ["check", "--workspace"],
|
|
||||||
"executableArgs": [],
|
|
||||||
},
|
|
||||||
"kind": "cargo",
|
|
||||||
"label": "cargo check --workspace"
|
|
||||||
}
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_runnables_project() {
|
fn test_runnables_project() {
|
||||||
if skip_slow_tests() {
|
if skip_slow_tests() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user