From d0b6ed4441469acfb6bc6555d78abf12637b6cf4 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 18 Mar 2020 20:56:46 +0800 Subject: Add ProcMacroClient --- crates/ra_project_model/src/cargo_workspace.rs | 31 ++++++++++++++----- crates/ra_project_model/src/json_project.rs | 1 + crates/ra_project_model/src/lib.rs | 41 +++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 9 deletions(-) (limited to 'crates/ra_project_model/src') diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index c7f9bd873..291594e2a 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -83,6 +83,7 @@ pub struct PackageData { pub edition: Edition, pub features: Vec, pub out_dir: Option, + pub proc_macro_dylib_path: Option, } #[derive(Debug, Clone)] @@ -158,8 +159,11 @@ impl CargoWorkspace { })?; let mut out_dir_by_id = FxHashMap::default(); + let mut proc_macro_dylib_paths = FxHashMap::default(); if cargo_features.load_out_dirs_from_check { - out_dir_by_id = load_out_dirs(cargo_toml, cargo_features); + let resources = load_extern_resources(cargo_toml, cargo_features); + out_dir_by_id = resources.out_dirs; + proc_macro_dylib_paths = resources.proc_dylib_paths; } let mut pkg_by_id = FxHashMap::default(); @@ -183,6 +187,7 @@ impl CargoWorkspace { dependencies: Vec::new(), features: Vec::new(), out_dir: out_dir_by_id.get(&id).cloned(), + proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), }); let pkg_data = &mut packages[pkg]; pkg_by_id.insert(id, pkg); @@ -246,10 +251,13 @@ impl CargoWorkspace { } } -pub fn load_out_dirs( - cargo_toml: &Path, - cargo_features: &CargoFeatures, -) -> FxHashMap { +#[derive(Debug, Clone, Default)] +pub struct ExternResources { + out_dirs: FxHashMap, + proc_dylib_paths: FxHashMap, +} + +pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures) -> ExternResources { let mut args: Vec = vec![ "check".to_string(), "--message-format=json".to_string(), @@ -267,14 +275,21 @@ pub fn load_out_dirs( args.extend(cargo_features.features.iter().cloned()); } - let mut acc = FxHashMap::default(); + let mut acc = ExternResources::default(); let res = run_cargo(&args, cargo_toml.parent(), &mut |message| { match message { Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { - acc.insert(package_id, out_dir); + acc.out_dirs.insert(package_id, out_dir); } - Message::CompilerArtifact(_) => (), + Message::CompilerArtifact(message) => { + if message.target.kind.contains(&"proc-macro".to_string()) { + let package_id = message.package_id; + if let Some(filename) = message.filenames.get(0) { + acc.proc_dylib_paths.insert(package_id, filename.clone()); + } + } + } Message::CompilerMessage(_) => (), Message::Unknown => (), } diff --git a/crates/ra_project_model/src/json_project.rs b/crates/ra_project_model/src/json_project.rs index 336446e58..b030c8a6a 100644 --- a/crates/ra_project_model/src/json_project.rs +++ b/crates/ra_project_model/src/json_project.rs @@ -23,6 +23,7 @@ pub struct Crate { pub(crate) atom_cfgs: FxHashSet, pub(crate) key_value_cfgs: FxHashMap, pub(crate) out_dir: Option, + pub(crate) proc_macro_dylib_path: Option, } #[derive(Clone, Copy, Debug, Deserialize)] diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index a3ef9acdc..444d3bb3f 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -23,6 +23,7 @@ pub use crate::{ json_project::JsonProject, sysroot::Sysroot, }; +pub use ra_proc_macro::ProcMacroClient; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct CargoTomlNotFoundError { @@ -173,6 +174,29 @@ impl ProjectWorkspace { } } + pub fn proc_macro_dylib_paths(&self) -> Vec { + match self { + ProjectWorkspace::Json { project } => { + let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len()); + for krate in &project.crates { + if let Some(out_dir) = &krate.proc_macro_dylib_path { + proc_macro_dylib_paths.push(out_dir.to_path_buf()); + } + } + proc_macro_dylib_paths + } + ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { + let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len()); + for pkg in cargo.packages() { + if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path { + proc_macro_dylib_paths.push(dylib_path.to_path_buf()); + } + } + proc_macro_dylib_paths + } + } + } + pub fn n_packages(&self) -> usize { match self { ProjectWorkspace::Json { project } => project.crates.len(), @@ -186,6 +210,7 @@ impl ProjectWorkspace { &self, default_cfg_options: &CfgOptions, extern_source_roots: &FxHashMap, + proc_macro_client: &ProcMacroClient, load: &mut dyn FnMut(&Path) -> Option, ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); @@ -219,7 +244,10 @@ impl ProjectWorkspace { extern_source.set_extern_path(&out_dir, extern_source_id); } } - + let proc_macro = krate + .proc_macro_dylib_path + .clone() + .map(|it| proc_macro_client.by_dylib_path(&it)); // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env crates.insert( crate_id, @@ -231,6 +259,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro.unwrap_or_default(), ), ); } @@ -270,6 +299,8 @@ impl ProjectWorkspace { let env = Env::default(); let extern_source = ExternSource::default(); + let proc_macro = vec![]; + let crate_id = crate_graph.add_crate_root( file_id, Edition::Edition2018, @@ -280,6 +311,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro, ); sysroot_crates.insert(krate, crate_id); } @@ -327,6 +359,12 @@ impl ProjectWorkspace { extern_source.set_extern_path(&out_dir, extern_source_id); } } + let proc_macro = cargo[pkg] + .proc_macro_dylib_path + .as_ref() + .map(|it| proc_macro_client.by_dylib_path(&it)) + .unwrap_or_default(); + let crate_id = crate_graph.add_crate_root( file_id, edition, @@ -334,6 +372,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro.clone(), ); if cargo[tgt].kind == TargetKind::Lib { lib_tgt = Some((crate_id, cargo[tgt].name.clone())); -- cgit v1.2.3