From e00a1e0b79e2b2c0c20a96e5341e3a35f46f99b7 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 10 Mar 2020 22:00:58 +0800 Subject: Setup Env in world --- crates/ra_project_model/src/lib.rs | 18 ++++++++++++--- crates/rust-analyzer/src/cli/load_cargo.rs | 5 +++- crates/rust-analyzer/src/world.rs | 37 ++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 37845ca56..b46320304 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -14,7 +14,7 @@ use std::{ use anyhow::{bail, Context, Result}; use ra_cfg::CfgOptions; -use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; +use ra_db::{CrateGraph, CrateName, Edition, Env, ExternSourceId, FileId}; use rustc_hash::FxHashMap; use serde_json::from_reader; @@ -162,6 +162,7 @@ impl ProjectWorkspace { pub fn to_crate_graph( &self, default_cfg_options: &CfgOptions, + outdirs: &FxHashMap, load: &mut dyn FnMut(&Path) -> Option, ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); @@ -185,6 +186,8 @@ impl ProjectWorkspace { } opts }; + + // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env crates.insert( crate_id, crate_graph.add_crate_root( @@ -231,12 +234,17 @@ impl ProjectWorkspace { opts }; + let mut env = Env::default(); + if let Some((id, path)) = outdirs.get(krate.name(&sysroot)) { + env.set_extern_path("OUT_DIR", &path, *id); + } + let crate_id = crate_graph.add_crate_root( file_id, Edition::Edition2018, Some(krate.name(&sysroot).to_string()), cfg_options, - Env::default(), + env, ); sysroot_crates.insert(krate, crate_id); } @@ -275,12 +283,16 @@ impl ProjectWorkspace { opts.insert_features(pkg.features(&cargo).iter().map(Into::into)); opts }; + let mut env = Env::default(); + if let Some((id, path)) = outdirs.get(pkg.name(&cargo)) { + env.set_extern_path("OUT_DIR", &path, *id); + } let crate_id = crate_graph.add_crate_root( file_id, edition, Some(pkg.name(&cargo).to_string()), cfg_options, - Env::default(), + env, ); if tgt.kind(&cargo) == TargetKind::Lib { lib_tgt = Some(crate_id); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 4be987860..403f353f1 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -52,7 +52,10 @@ pub(crate) fn load_cargo( opts }; - let crate_graph = ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { + // FIXME: outdirs? + let outdirs = FxHashMap::default(); + + let crate_graph = ws.to_crate_graph(&default_cfg_options, &outdirs, &mut |path: &Path| { let vfs_file = vfs.load(path); log::debug!("vfs file {:?} -> {:?}", path, vfs_file); vfs_file.map(vfs_file_to_id) diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index ac4395617..b64140b74 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs @@ -26,6 +26,8 @@ use crate::{ vfs_glob::{Glob, RustPackageFilterBuilder}, LspError, Result, }; +use ra_db::ExternSourceId; +use rustc_hash::{FxHashMap, FxHashSet}; #[derive(Debug, Clone)] pub struct Options { @@ -98,6 +100,19 @@ impl WorldState { RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) })); } + + let extern_dirs: FxHashSet<_> = + additional_out_dirs.iter().map(|(_, path)| (PathBuf::from(path))).collect(); + let mut extern_source_roots = FxHashMap::default(); + + roots.extend(additional_out_dirs.iter().map(|(_, path)| { + let mut filter = RustPackageFilterBuilder::default().set_member(false); + for glob in exclude_globs.iter() { + filter = filter.exclude(glob.clone()); + } + RootEntry::new(PathBuf::from(&path), filter.into_vfs_filter()) + })); + let (task_sender, task_receiver) = unbounded(); let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); @@ -107,6 +122,11 @@ impl WorldState { let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); change.add_root(SourceRootId(r.0), is_local); change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string()); + + // FIXME: add path2root in vfs to simpily this logic + if extern_dirs.contains(&vfs_root_path) { + extern_source_roots.insert(vfs_root_path, ExternSourceId(r.0)); + } } // FIXME: Read default cfgs from config @@ -124,11 +144,20 @@ impl WorldState { vfs_file.map(|f| FileId(f.0)) }; - workspaces.iter().map(|ws| ws.to_crate_graph(&default_cfg_options, &mut load)).for_each( - |graph| { + let mut outdirs = FxHashMap::default(); + for (name, path) in additional_out_dirs { + let path = PathBuf::from(&path); + if let Some(id) = extern_source_roots.get(&path) { + outdirs.insert(name, (id.clone(), path.to_string_lossy().replace("\\", "/"))); + } + } + + workspaces + .iter() + .map(|ws| ws.to_crate_graph(&default_cfg_options, &outdirs, &mut load)) + .for_each(|graph| { crate_graph.extend(graph); - }, - ); + }); change.set_crate_graph(crate_graph); // FIXME: Figure out the multi-workspace situation -- cgit v1.2.3