aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model/src
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2021-05-23 18:56:54 +0100
committerKirill Bulatov <[email protected]>2021-05-23 20:46:20 +0100
commitde090749d9643a8035135092e2546cd0ddb854a6 (patch)
tree01f0564f53a7763ecf28a46860997c294a042f3c /crates/project_model/src
parent695569d9784b4a7d6e91451a0cc354f8bd009b59 (diff)
Drag detached files towards loading
Diffstat (limited to 'crates/project_model/src')
-rw-r--r--crates/project_model/src/lib.rs1
-rw-r--r--crates/project_model/src/sysroot.rs4
-rw-r--r--crates/project_model/src/workspace.rs73
3 files changed, 72 insertions, 6 deletions
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs
index c2fde00d5..8c6cf94c2 100644
--- a/crates/project_model/src/lib.rs
+++ b/crates/project_model/src/lib.rs
@@ -50,7 +50,6 @@ pub use proc_macro_api::ProcMacroClient;
50pub enum ProjectManifest { 50pub enum ProjectManifest {
51 ProjectJson(AbsPathBuf), 51 ProjectJson(AbsPathBuf),
52 CargoToml(AbsPathBuf), 52 CargoToml(AbsPathBuf),
53 DetachedFile(AbsPathBuf),
54} 53}
55 54
56impl ProjectManifest { 55impl ProjectManifest {
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs
index 3b0ff506d..c89e2f6e1 100644
--- a/crates/project_model/src/sysroot.rs
+++ b/crates/project_model/src/sysroot.rs
@@ -50,7 +50,9 @@ impl Sysroot {
50 50
51 pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> { 51 pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
52 log::debug!("Discovering sysroot for {}", cargo_toml.display()); 52 log::debug!("Discovering sysroot for {}", cargo_toml.display());
53 let current_dir = cargo_toml.parent().unwrap(); 53 let current_dir = cargo_toml.parent().ok_or_else(|| {
54 format_err!("Failed to find the parent directory for file {:?}", cargo_toml)
55 })?;
54 let sysroot_dir = discover_sysroot_dir(current_dir)?; 56 let sysroot_dir = discover_sysroot_dir(current_dir)?;
55 let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?; 57 let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?;
56 let res = Sysroot::load(&sysroot_src_dir)?; 58 let res = Sysroot::load(&sysroot_src_dir)?;
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 5fd648710..ad4c202f2 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -4,7 +4,7 @@
4 4
5use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; 5use std::{collections::VecDeque, fmt, fs, path::Path, process::Command};
6 6
7use anyhow::{Context, Result}; 7use anyhow::{format_err, Context, Result};
8use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; 8use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
9use cargo_workspace::DepKind; 9use cargo_workspace::DepKind;
10use cfg::CfgOptions; 10use cfg::CfgOptions;
@@ -49,6 +49,8 @@ pub enum ProjectWorkspace {
49 }, 49 },
50 /// Project workspace was manually specified using a `rust-project.json` file. 50 /// Project workspace was manually specified using a `rust-project.json` file.
51 Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> }, 51 Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
52 /// TODO kb docs
53 DetachedFiles { files: Vec<AbsPathBuf>, sysroot: Sysroot, rustc_cfg: Vec<CfgFlag> },
52} 54}
53 55
54impl fmt::Debug for ProjectWorkspace { 56impl fmt::Debug for ProjectWorkspace {
@@ -75,6 +77,12 @@ impl fmt::Debug for ProjectWorkspace {
75 debug_struct.field("n_rustc_cfg", &rustc_cfg.len()); 77 debug_struct.field("n_rustc_cfg", &rustc_cfg.len());
76 debug_struct.finish() 78 debug_struct.finish()
77 } 79 }
80 ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => f
81 .debug_struct("DetachedFiles")
82 .field("n_files", &files.len())
83 .field("n_sysroot_crates", &sysroot.crates().len())
84 .field("n_rustc_cfg", &rustc_cfg.len())
85 .finish(),
78 } 86 }
79 } 87 }
80} 88}
@@ -148,9 +156,6 @@ impl ProjectWorkspace {
148 let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref()); 156 let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref());
149 ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } 157 ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
150 } 158 }
151 ProjectManifest::DetachedFile(_) => {
152 todo!("TODO kb")
153 }
154 }; 159 };
155 160
156 Ok(res) 161 Ok(res)
@@ -168,6 +173,14 @@ impl ProjectWorkspace {
168 Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg }) 173 Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
169 } 174 }
170 175
176 pub fn load_detached_files(detached_files: Vec<AbsPathBuf>) -> Result<ProjectWorkspace> {
177 let sysroot = Sysroot::discover(
178 &detached_files.first().ok_or_else(|| format_err!("No detached files to load"))?,
179 )?;
180 let rustc_cfg = rustc_cfg::get(None, None);
181 Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
182 }
183
171 /// Returns the roots for the current `ProjectWorkspace` 184 /// Returns the roots for the current `ProjectWorkspace`
172 /// The return type contains the path and whether or not 185 /// The return type contains the path and whether or not
173 /// the root is a member of the current workspace 186 /// the root is a member of the current workspace
@@ -227,6 +240,19 @@ impl ProjectWorkspace {
227 }) 240 })
228 })) 241 }))
229 .collect(), 242 .collect(),
243 ProjectWorkspace::DetachedFiles { files, sysroot, .. } => files
244 .into_iter()
245 .map(|detached_file| PackageRoot {
246 is_member: true,
247 include: vec![detached_file.clone()],
248 exclude: Vec::new(),
249 })
250 .chain(sysroot.crates().map(|krate| PackageRoot {
251 is_member: false,
252 include: vec![sysroot[krate].root_dir().to_path_buf()],
253 exclude: Vec::new(),
254 }))
255 .collect(),
230 } 256 }
231 } 257 }
232 258
@@ -237,6 +263,9 @@ impl ProjectWorkspace {
237 let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); 263 let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len());
238 cargo.packages().len() + sysroot.crates().len() + rustc_package_len 264 cargo.packages().len() + sysroot.crates().len() + rustc_package_len
239 } 265 }
266 ProjectWorkspace::DetachedFiles { sysroot, files, .. } => {
267 sysroot.crates().len() + files.len()
268 }
240 } 269 }
241 } 270 }
242 271
@@ -270,6 +299,9 @@ impl ProjectWorkspace {
270 rustc, 299 rustc,
271 rustc.as_ref().zip(build_data).and_then(|(it, map)| map.get(it.workspace_root())), 300 rustc.as_ref().zip(build_data).and_then(|(it, map)| map.get(it.workspace_root())),
272 ), 301 ),
302 ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
303 detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot)
304 }
273 }; 305 };
274 if crate_graph.patch_cfg_if() { 306 if crate_graph.patch_cfg_if() {
275 log::debug!("Patched std to depend on cfg-if") 307 log::debug!("Patched std to depend on cfg-if")
@@ -477,6 +509,39 @@ fn cargo_to_crate_graph(
477 crate_graph 509 crate_graph
478} 510}
479 511
512// TODO kb refactor and check for correctness
513fn detached_files_to_crate_graph(
514 rustc_cfg: Vec<CfgFlag>,
515 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
516 detached_files: &[AbsPathBuf],
517 sysroot: &Sysroot,
518) -> CrateGraph {
519 let _p = profile::span("detached_files_to_crate_graph");
520 let mut crate_graph = CrateGraph::default();
521 let (public_deps, _libproc_macro) =
522 sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
523
524 let mut cfg_options = CfgOptions::default();
525 cfg_options.extend(rustc_cfg);
526
527 for detached_file in detached_files {
528 let file_id = load(&detached_file).unwrap();
529 let detached_file_crate = crate_graph.add_crate_root(
530 file_id,
531 Edition::Edition2018,
532 None,
533 cfg_options.clone(),
534 Env::default(),
535 Vec::new(),
536 );
537
538 for (name, krate) in public_deps.iter() {
539 add_dep(&mut crate_graph, detached_file_crate, name.clone(), *krate);
540 }
541 }
542 crate_graph
543}
544
480fn handle_rustc_crates( 545fn handle_rustc_crates(
481 rustc_workspace: &CargoWorkspace, 546 rustc_workspace: &CargoWorkspace,
482 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, 547 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,