mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-30 23:27:24 +00:00
Drag detached files towards loading
This commit is contained in:
parent
695569d978
commit
de090749d9
6 changed files with 83 additions and 11 deletions
|
@ -50,7 +50,6 @@ pub use proc_macro_api::ProcMacroClient;
|
||||||
pub enum ProjectManifest {
|
pub enum ProjectManifest {
|
||||||
ProjectJson(AbsPathBuf),
|
ProjectJson(AbsPathBuf),
|
||||||
CargoToml(AbsPathBuf),
|
CargoToml(AbsPathBuf),
|
||||||
DetachedFile(AbsPathBuf),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectManifest {
|
impl ProjectManifest {
|
||||||
|
|
|
@ -50,7 +50,9 @@ impl Sysroot {
|
||||||
|
|
||||||
pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
|
pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
|
||||||
log::debug!("Discovering sysroot for {}", cargo_toml.display());
|
log::debug!("Discovering sysroot for {}", cargo_toml.display());
|
||||||
let current_dir = cargo_toml.parent().unwrap();
|
let current_dir = cargo_toml.parent().ok_or_else(|| {
|
||||||
|
format_err!("Failed to find the parent directory for file {:?}", cargo_toml)
|
||||||
|
})?;
|
||||||
let sysroot_dir = discover_sysroot_dir(current_dir)?;
|
let sysroot_dir = discover_sysroot_dir(current_dir)?;
|
||||||
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?;
|
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?;
|
||||||
let res = Sysroot::load(&sysroot_src_dir)?;
|
let res = Sysroot::load(&sysroot_src_dir)?;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::{collections::VecDeque, fmt, fs, path::Path, process::Command};
|
use std::{collections::VecDeque, fmt, fs, path::Path, process::Command};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{format_err, Context, Result};
|
||||||
use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
|
use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
|
||||||
use cargo_workspace::DepKind;
|
use cargo_workspace::DepKind;
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
|
@ -49,6 +49,8 @@ pub enum ProjectWorkspace {
|
||||||
},
|
},
|
||||||
/// Project workspace was manually specified using a `rust-project.json` file.
|
/// Project workspace was manually specified using a `rust-project.json` file.
|
||||||
Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
|
Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
|
||||||
|
/// TODO kb docs
|
||||||
|
DetachedFiles { files: Vec<AbsPathBuf>, sysroot: Sysroot, rustc_cfg: Vec<CfgFlag> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ProjectWorkspace {
|
impl fmt::Debug for ProjectWorkspace {
|
||||||
|
@ -75,6 +77,12 @@ impl fmt::Debug for ProjectWorkspace {
|
||||||
debug_struct.field("n_rustc_cfg", &rustc_cfg.len());
|
debug_struct.field("n_rustc_cfg", &rustc_cfg.len());
|
||||||
debug_struct.finish()
|
debug_struct.finish()
|
||||||
}
|
}
|
||||||
|
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => f
|
||||||
|
.debug_struct("DetachedFiles")
|
||||||
|
.field("n_files", &files.len())
|
||||||
|
.field("n_sysroot_crates", &sysroot.crates().len())
|
||||||
|
.field("n_rustc_cfg", &rustc_cfg.len())
|
||||||
|
.finish(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,9 +156,6 @@ impl ProjectWorkspace {
|
||||||
let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref());
|
let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref());
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
|
||||||
}
|
}
|
||||||
ProjectManifest::DetachedFile(_) => {
|
|
||||||
todo!("TODO kb")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
@ -168,6 +173,14 @@ impl ProjectWorkspace {
|
||||||
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
|
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_detached_files(detached_files: Vec<AbsPathBuf>) -> Result<ProjectWorkspace> {
|
||||||
|
let sysroot = Sysroot::discover(
|
||||||
|
&detached_files.first().ok_or_else(|| format_err!("No detached files to load"))?,
|
||||||
|
)?;
|
||||||
|
let rustc_cfg = rustc_cfg::get(None, None);
|
||||||
|
Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the roots for the current `ProjectWorkspace`
|
/// Returns the roots for the current `ProjectWorkspace`
|
||||||
/// The return type contains the path and whether or not
|
/// The return type contains the path and whether or not
|
||||||
/// the root is a member of the current workspace
|
/// the root is a member of the current workspace
|
||||||
|
@ -227,6 +240,19 @@ impl ProjectWorkspace {
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
ProjectWorkspace::DetachedFiles { files, sysroot, .. } => files
|
||||||
|
.into_iter()
|
||||||
|
.map(|detached_file| PackageRoot {
|
||||||
|
is_member: true,
|
||||||
|
include: vec![detached_file.clone()],
|
||||||
|
exclude: Vec::new(),
|
||||||
|
})
|
||||||
|
.chain(sysroot.crates().map(|krate| PackageRoot {
|
||||||
|
is_member: false,
|
||||||
|
include: vec![sysroot[krate].root_dir().to_path_buf()],
|
||||||
|
exclude: Vec::new(),
|
||||||
|
}))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +263,9 @@ impl ProjectWorkspace {
|
||||||
let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len());
|
let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len());
|
||||||
cargo.packages().len() + sysroot.crates().len() + rustc_package_len
|
cargo.packages().len() + sysroot.crates().len() + rustc_package_len
|
||||||
}
|
}
|
||||||
|
ProjectWorkspace::DetachedFiles { sysroot, files, .. } => {
|
||||||
|
sysroot.crates().len() + files.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +299,9 @@ impl ProjectWorkspace {
|
||||||
rustc,
|
rustc,
|
||||||
rustc.as_ref().zip(build_data).and_then(|(it, map)| map.get(it.workspace_root())),
|
rustc.as_ref().zip(build_data).and_then(|(it, map)| map.get(it.workspace_root())),
|
||||||
),
|
),
|
||||||
|
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
|
||||||
|
detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if crate_graph.patch_cfg_if() {
|
if crate_graph.patch_cfg_if() {
|
||||||
log::debug!("Patched std to depend on cfg-if")
|
log::debug!("Patched std to depend on cfg-if")
|
||||||
|
@ -477,6 +509,39 @@ fn cargo_to_crate_graph(
|
||||||
crate_graph
|
crate_graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO kb refactor and check for correctness
|
||||||
|
fn detached_files_to_crate_graph(
|
||||||
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
|
detached_files: &[AbsPathBuf],
|
||||||
|
sysroot: &Sysroot,
|
||||||
|
) -> CrateGraph {
|
||||||
|
let _p = profile::span("detached_files_to_crate_graph");
|
||||||
|
let mut crate_graph = CrateGraph::default();
|
||||||
|
let (public_deps, _libproc_macro) =
|
||||||
|
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||||
|
|
||||||
|
let mut cfg_options = CfgOptions::default();
|
||||||
|
cfg_options.extend(rustc_cfg);
|
||||||
|
|
||||||
|
for detached_file in detached_files {
|
||||||
|
let file_id = load(&detached_file).unwrap();
|
||||||
|
let detached_file_crate = crate_graph.add_crate_root(
|
||||||
|
file_id,
|
||||||
|
Edition::Edition2018,
|
||||||
|
None,
|
||||||
|
cfg_options.clone(),
|
||||||
|
Env::default(),
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (name, krate) in public_deps.iter() {
|
||||||
|
add_dep(&mut crate_graph, detached_file_crate, name.clone(), *krate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate_graph
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_rustc_crates(
|
fn handle_rustc_crates(
|
||||||
rustc_workspace: &CargoWorkspace,
|
rustc_workspace: &CargoWorkspace,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
|
|
|
@ -236,7 +236,7 @@ impl Default for ConfigData {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
caps: lsp_types::ClientCapabilities,
|
caps: lsp_types::ClientCapabilities,
|
||||||
data: ConfigData,
|
data: ConfigData,
|
||||||
detached_files: Vec<ProjectManifest>,
|
detached_files: Vec<AbsPathBuf>,
|
||||||
pub discovered_projects: Option<Vec<ProjectManifest>>,
|
pub discovered_projects: Option<Vec<ProjectManifest>>,
|
||||||
pub root_path: AbsPathBuf,
|
pub root_path: AbsPathBuf,
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,6 @@ impl Config {
|
||||||
self.detached_files = get_field::<Vec<PathBuf>>(&mut json, "detachedFiles", None, "[]")
|
self.detached_files = get_field::<Vec<PathBuf>>(&mut json, "detachedFiles", None, "[]")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(AbsPathBuf::assert)
|
.map(AbsPathBuf::assert)
|
||||||
.map(ProjectManifest::DetachedFile)
|
|
||||||
.collect();
|
.collect();
|
||||||
self.data = ConfigData::from_json(json);
|
self.data = ConfigData::from_json(json);
|
||||||
}
|
}
|
||||||
|
@ -399,7 +398,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn detached_files(&self) -> &[ProjectManifest] {
|
pub fn detached_files(&self) -> &[AbsPathBuf] {
|
||||||
&self.detached_files
|
&self.detached_files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,7 @@ impl GlobalStateSnapshot {
|
||||||
cargo.target_by_root(&path).map(|it| (cargo, it))
|
cargo.target_by_root(&path).map(|it| (cargo, it))
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Json { .. } => None,
|
ProjectWorkspace::Json { .. } => None,
|
||||||
|
ProjectWorkspace::DetachedFiles { .. } => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,8 @@ impl GlobalState {
|
||||||
log::info!("will fetch workspaces");
|
log::info!("will fetch workspaces");
|
||||||
|
|
||||||
self.task_pool.handle.spawn_with_sender({
|
self.task_pool.handle.spawn_with_sender({
|
||||||
// TODO kb reload workspace here?
|
|
||||||
let linked_projects = self.config.linked_projects();
|
let linked_projects = self.config.linked_projects();
|
||||||
|
let detached_files = self.config.detached_files().to_vec();
|
||||||
let cargo_config = self.config.cargo();
|
let cargo_config = self.config.cargo();
|
||||||
|
|
||||||
move |sender| {
|
move |sender| {
|
||||||
|
@ -162,7 +162,7 @@ impl GlobalState {
|
||||||
|
|
||||||
sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).unwrap();
|
sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).unwrap();
|
||||||
|
|
||||||
let workspaces = linked_projects
|
let mut workspaces = linked_projects
|
||||||
.iter()
|
.iter()
|
||||||
.map(|project| match project {
|
.map(|project| match project {
|
||||||
LinkedProject::ProjectManifest(manifest) => {
|
LinkedProject::ProjectManifest(manifest) => {
|
||||||
|
@ -181,6 +181,11 @@ impl GlobalState {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !detached_files.is_empty() {
|
||||||
|
workspaces
|
||||||
|
.push(project_model::ProjectWorkspace::load_detached_files(detached_files));
|
||||||
|
}
|
||||||
|
|
||||||
log::info!("did fetch workspaces {:?}", workspaces);
|
log::info!("did fetch workspaces {:?}", workspaces);
|
||||||
sender
|
sender
|
||||||
.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(workspaces)))
|
.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(workspaces)))
|
||||||
|
@ -408,6 +413,7 @@ impl GlobalState {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProjectWorkspace::DetachedFiles { .. } => None,
|
||||||
})
|
})
|
||||||
.map(|(id, root)| {
|
.map(|(id, root)| {
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue