mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +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 {
|
||||
ProjectJson(AbsPathBuf),
|
||||
CargoToml(AbsPathBuf),
|
||||
DetachedFile(AbsPathBuf),
|
||||
}
|
||||
|
||||
impl ProjectManifest {
|
||||
|
|
|
@ -50,7 +50,9 @@ impl Sysroot {
|
|||
|
||||
pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
|
||||
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_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?;
|
||||
let res = Sysroot::load(&sysroot_src_dir)?;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
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 cargo_workspace::DepKind;
|
||||
use cfg::CfgOptions;
|
||||
|
@ -49,6 +49,8 @@ pub enum ProjectWorkspace {
|
|||
},
|
||||
/// Project workspace was manually specified using a `rust-project.json` file.
|
||||
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 {
|
||||
|
@ -75,6 +77,12 @@ impl fmt::Debug for ProjectWorkspace {
|
|||
debug_struct.field("n_rustc_cfg", &rustc_cfg.len());
|
||||
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());
|
||||
ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
|
||||
}
|
||||
ProjectManifest::DetachedFile(_) => {
|
||||
todo!("TODO kb")
|
||||
}
|
||||
};
|
||||
|
||||
Ok(res)
|
||||
|
@ -168,6 +173,14 @@ impl ProjectWorkspace {
|
|||
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`
|
||||
/// The return type contains the path and whether or not
|
||||
/// the root is a member of the current workspace
|
||||
|
@ -227,6 +240,19 @@ impl ProjectWorkspace {
|
|||
})
|
||||
}))
|
||||
.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());
|
||||
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.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() {
|
||||
log::debug!("Patched std to depend on cfg-if")
|
||||
|
@ -477,6 +509,39 @@ fn cargo_to_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(
|
||||
rustc_workspace: &CargoWorkspace,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
|
|
|
@ -236,7 +236,7 @@ impl Default for ConfigData {
|
|||
pub struct Config {
|
||||
caps: lsp_types::ClientCapabilities,
|
||||
data: ConfigData,
|
||||
detached_files: Vec<ProjectManifest>,
|
||||
detached_files: Vec<AbsPathBuf>,
|
||||
pub discovered_projects: Option<Vec<ProjectManifest>>,
|
||||
pub root_path: AbsPathBuf,
|
||||
}
|
||||
|
@ -345,7 +345,6 @@ impl Config {
|
|||
self.detached_files = get_field::<Vec<PathBuf>>(&mut json, "detachedFiles", None, "[]")
|
||||
.into_iter()
|
||||
.map(AbsPathBuf::assert)
|
||||
.map(ProjectManifest::DetachedFile)
|
||||
.collect();
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ impl GlobalStateSnapshot {
|
|||
cargo.target_by_root(&path).map(|it| (cargo, it))
|
||||
}
|
||||
ProjectWorkspace::Json { .. } => None,
|
||||
ProjectWorkspace::DetachedFiles { .. } => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,8 +146,8 @@ impl GlobalState {
|
|||
log::info!("will fetch workspaces");
|
||||
|
||||
self.task_pool.handle.spawn_with_sender({
|
||||
// TODO kb reload workspace here?
|
||||
let linked_projects = self.config.linked_projects();
|
||||
let detached_files = self.config.detached_files().to_vec();
|
||||
let cargo_config = self.config.cargo();
|
||||
|
||||
move |sender| {
|
||||
|
@ -162,7 +162,7 @@ impl GlobalState {
|
|||
|
||||
sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).unwrap();
|
||||
|
||||
let workspaces = linked_projects
|
||||
let mut workspaces = linked_projects
|
||||
.iter()
|
||||
.map(|project| match project {
|
||||
LinkedProject::ProjectManifest(manifest) => {
|
||||
|
@ -181,6 +181,11 @@ impl GlobalState {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if !detached_files.is_empty() {
|
||||
workspaces
|
||||
.push(project_model::ProjectWorkspace::load_detached_files(detached_files));
|
||||
}
|
||||
|
||||
log::info!("did fetch workspaces {:?}", workspaces);
|
||||
sender
|
||||
.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(workspaces)))
|
||||
|
@ -408,6 +413,7 @@ impl GlobalState {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
ProjectWorkspace::DetachedFiles { .. } => None,
|
||||
})
|
||||
.map(|(id, root)| {
|
||||
let sender = sender.clone();
|
||||
|
|
Loading…
Reference in a new issue