diff options
Diffstat (limited to 'crates/project_model')
-rw-r--r-- | crates/project_model/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/project_model/src/sysroot.rs | 4 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 73 |
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; | |||
50 | pub enum ProjectManifest { | 50 | pub enum ProjectManifest { |
51 | ProjectJson(AbsPathBuf), | 51 | ProjectJson(AbsPathBuf), |
52 | CargoToml(AbsPathBuf), | 52 | CargoToml(AbsPathBuf), |
53 | DetachedFile(AbsPathBuf), | ||
54 | } | 53 | } |
55 | 54 | ||
56 | impl ProjectManifest { | 55 | impl 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 | ||
5 | use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; | 5 | use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; |
6 | 6 | ||
7 | use anyhow::{Context, Result}; | 7 | use anyhow::{format_err, Context, Result}; |
8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; | 8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; |
9 | use cargo_workspace::DepKind; | 9 | use cargo_workspace::DepKind; |
10 | use cfg::CfgOptions; | 10 | use 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 | ||
54 | impl fmt::Debug for ProjectWorkspace { | 56 | impl 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 | ||
513 | fn 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 | |||
480 | fn handle_rustc_crates( | 545 | fn 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>, |