aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/project_model/src/lib.rs65
-rw-r--r--crates/project_model/src/project_json.rs11
-rw-r--r--docs/user/manual.adoc16
3 files changed, 70 insertions, 22 deletions
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs
index 724c586db..2d91939ce 100644
--- a/crates/project_model/src/lib.rs
+++ b/crates/project_model/src/lib.rs
@@ -39,11 +39,18 @@ pub enum ProjectWorkspace {
39impl fmt::Debug for ProjectWorkspace { 39impl fmt::Debug for ProjectWorkspace {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 match self { 41 match self {
42 ProjectWorkspace::Cargo { cargo, .. } => { 42 ProjectWorkspace::Cargo { cargo, sysroot } => f
43 f.debug_struct("Cargo").field("n_packages", &cargo.packages().len()).finish() 43 .debug_struct("Cargo")
44 } 44 .field("n_packages", &cargo.packages().len())
45 .field("n_sysroot_crates", &sysroot.crates().len())
46 .finish(),
45 ProjectWorkspace::Json { project } => { 47 ProjectWorkspace::Json { project } => {
46 f.debug_struct("Json").field("n_crates", &project.n_crates()).finish() 48 let mut debug_struct = f.debug_struct("Json");
49 debug_struct.field("n_crates", &project.n_crates());
50 if let Some(sysroot) = &project.sysroot {
51 debug_struct.field("n_sysroot_crates", &sysroot.crates().len());
52 }
53 debug_struct.finish()
47 } 54 }
48 } 55 }
49 } 56 }
@@ -210,6 +217,13 @@ impl ProjectWorkspace {
210 }) 217 })
211 .collect::<FxHashSet<_>>() 218 .collect::<FxHashSet<_>>()
212 .into_iter() 219 .into_iter()
220 .chain(project.sysroot.as_ref().into_iter().flat_map(|sysroot| {
221 sysroot.crates().map(move |krate| PackageRoot {
222 is_member: false,
223 include: vec![sysroot[krate].root_dir().to_path_buf()],
224 exclude: Vec::new(),
225 })
226 }))
213 .collect::<Vec<_>>(), 227 .collect::<Vec<_>>(),
214 ProjectWorkspace::Cargo { cargo, sysroot } => cargo 228 ProjectWorkspace::Cargo { cargo, sysroot } => cargo
215 .packages() 229 .packages()
@@ -272,6 +286,11 @@ impl ProjectWorkspace {
272 let mut crate_graph = CrateGraph::default(); 286 let mut crate_graph = CrateGraph::default();
273 match self { 287 match self {
274 ProjectWorkspace::Json { project } => { 288 ProjectWorkspace::Json { project } => {
289 let sysroot_dps = project
290 .sysroot
291 .as_ref()
292 .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load));
293
275 let mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default(); 294 let mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default();
276 let crates: FxHashMap<_, _> = project 295 let crates: FxHashMap<_, _> = project
277 .crates() 296 .crates()
@@ -309,25 +328,33 @@ impl ProjectWorkspace {
309 .collect(); 328 .collect();
310 329
311 for (from, krate) in project.crates() { 330 for (from, krate) in project.crates() {
312 for dep in &krate.deps { 331 if let Some(&from) = crates.get(&from) {
313 let to_crate_id = dep.crate_id; 332 if let Some((public_deps, _proc_macro)) = &sysroot_dps {
314 if let (Some(&from), Some(&to)) = 333 for (name, to) in public_deps.iter() {
315 (crates.get(&from), crates.get(&to_crate_id)) 334 if let Err(_) = crate_graph.add_dep(from, name.clone(), *to) {
316 { 335 log::error!("cyclic dependency on {} for {:?}", name, from)
317 if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) { 336 }
318 log::error!("cyclic dependency {:?} -> {:?}", from, to_crate_id); 337 }
338 }
339
340 for dep in &krate.deps {
341 let to_crate_id = dep.crate_id;
342 if let Some(&to) = crates.get(&to_crate_id) {
343 if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
344 log::error!("cyclic dependency {:?} -> {:?}", from, to);
345 }
319 } 346 }
320 } 347 }
321 } 348 }
322 } 349 }
323 } 350 }
324 ProjectWorkspace::Cargo { cargo, sysroot } => { 351 ProjectWorkspace::Cargo { cargo, sysroot } => {
352 let (public_deps, libproc_macro) =
353 sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load);
354
325 let mut cfg_options = CfgOptions::default(); 355 let mut cfg_options = CfgOptions::default();
326 cfg_options.extend(get_rustc_cfg_options(target)); 356 cfg_options.extend(get_rustc_cfg_options(target));
327 357
328 let (public_deps, libproc_macro) =
329 sysroot_to_crate_graph(&mut crate_graph, sysroot, &cfg_options, load);
330
331 let mut pkg_to_lib_crate = FxHashMap::default(); 358 let mut pkg_to_lib_crate = FxHashMap::default();
332 let mut pkg_crates = FxHashMap::default(); 359 let mut pkg_crates = FxHashMap::default();
333 360
@@ -410,7 +437,11 @@ impl ProjectWorkspace {
410 } 437 }
411 for (name, krate) in public_deps.iter() { 438 for (name, krate) in public_deps.iter() {
412 if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) { 439 if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
413 log::error!("cyclic dependency on core for {}", &cargo[pkg].name) 440 log::error!(
441 "cyclic dependency on {} for {}",
442 name,
443 &cargo[pkg].name
444 )
414 } 445 }
415 } 446 }
416 } 447 }
@@ -485,9 +516,11 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
485fn sysroot_to_crate_graph( 516fn sysroot_to_crate_graph(
486 crate_graph: &mut CrateGraph, 517 crate_graph: &mut CrateGraph,
487 sysroot: &Sysroot, 518 sysroot: &Sysroot,
488 cfg_options: &CfgOptions, 519 target: Option<&str>,
489 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, 520 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
490) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { 521) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
522 let mut cfg_options = CfgOptions::default();
523 cfg_options.extend(get_rustc_cfg_options(target));
491 let sysroot_crates: FxHashMap<_, _> = sysroot 524 let sysroot_crates: FxHashMap<_, _> = sysroot
492 .crates() 525 .crates()
493 .filter_map(|krate| { 526 .filter_map(|krate| {
diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs
index ae14e5126..5a0fe749a 100644
--- a/crates/project_model/src/project_json.rs
+++ b/crates/project_model/src/project_json.rs
@@ -7,11 +7,12 @@ use paths::{AbsPath, AbsPathBuf};
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8use serde::{de, Deserialize}; 8use serde::{de, Deserialize};
9 9
10use crate::cfg_flag::CfgFlag; 10use crate::{cfg_flag::CfgFlag, Sysroot};
11 11
12/// Roots and crates that compose this Rust project. 12/// Roots and crates that compose this Rust project.
13#[derive(Clone, Debug, Eq, PartialEq)] 13#[derive(Clone, Debug, Eq, PartialEq)]
14pub struct ProjectJson { 14pub struct ProjectJson {
15 pub(crate) sysroot: Option<Sysroot>,
15 crates: Vec<Crate>, 16 crates: Vec<Crate>,
16} 17}
17 18
@@ -34,6 +35,7 @@ pub struct Crate {
34impl ProjectJson { 35impl ProjectJson {
35 pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson { 36 pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
36 ProjectJson { 37 ProjectJson {
38 sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)),
37 crates: data 39 crates: data
38 .crates 40 .crates
39 .into_iter() 41 .into_iter()
@@ -43,11 +45,13 @@ impl ProjectJson {
43 && !crate_data.root_module.starts_with("..") 45 && !crate_data.root_module.starts_with("..")
44 || crate_data.root_module.starts_with(base) 46 || crate_data.root_module.starts_with(base)
45 }); 47 });
46 let root_module = base.join(crate_data.root_module); 48 let root_module = base.join(crate_data.root_module).normalize();
47 let (include, exclude) = match crate_data.source { 49 let (include, exclude) = match crate_data.source {
48 Some(src) => { 50 Some(src) => {
49 let absolutize = |dirs: Vec<PathBuf>| { 51 let absolutize = |dirs: Vec<PathBuf>| {
50 dirs.into_iter().map(|it| base.join(it)).collect::<Vec<_>>() 52 dirs.into_iter()
53 .map(|it| base.join(it).normalize())
54 .collect::<Vec<_>>()
51 }; 55 };
52 (absolutize(src.include_dirs), absolutize(src.exclude_dirs)) 56 (absolutize(src.include_dirs), absolutize(src.exclude_dirs))
53 } 57 }
@@ -89,6 +93,7 @@ impl ProjectJson {
89 93
90#[derive(Deserialize)] 94#[derive(Deserialize)]
91pub struct ProjectJsonData { 95pub struct ProjectJsonData {
96 sysroot_src: Option<PathBuf>,
92 crates: Vec<CrateData>, 97 crates: Vec<CrateData>,
93} 98}
94 99
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index bebcee023..144130b51 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -273,9 +273,19 @@ However, if you use some other build system, you'll have to describe the structu
273[source,TypeScript] 273[source,TypeScript]
274---- 274----
275interface JsonProject { 275interface JsonProject {
276 /// The set of crates comprising the current project. 276 /// Path to the directory with *source code* of sysroot crates.
277 /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such). 277 ///
278 crates: Crate[]; 278 /// It should point to the directory where std, core, and friends can be found:
279 /// https://github.com/rust-lang/rust/tree/master/library.
280 ///
281 /// If provided, rust-analyzer automatically adds dependencies on sysroot
282 /// crates. Conversely, if you omit this path, you can specify sysroot
283 /// dependencies yourself and, for example, have several different "sysroots" in
284 /// one graph of crates.
285 sysroot_src?: string;
286 /// The set of crates comprising the current project.
287 /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
288 crates: Crate[];
279} 289}
280 290
281interface Crate { 291interface Crate {