From e42e6f9ab902ba05c3f534876ca6ab0dcdce13a2 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Dec 2020 13:55:41 +0100 Subject: ProcMacroProcessExpander: support attribute macros --- crates/proc_macro_api/src/lib.rs | 12 ++++++++++-- crates/proc_macro_api/src/process.rs | 20 +------------------- 2 files changed, 11 insertions(+), 21 deletions(-) (limited to 'crates') diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index d5e87cf7d..0537286dd 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -42,9 +42,17 @@ impl tt::TokenExpander for ProcMacroProcessExpander { fn expand( &self, subtree: &Subtree, - _attr: Option<&Subtree>, + attr: Option<&Subtree>, ) -> Result { - self.process.custom_derive(&self.dylib_path, subtree, &self.name) + let task = ExpansionTask { + macro_body: subtree.clone(), + macro_name: self.name.to_string(), + attributes: attr.cloned(), + lib: self.dylib_path.to_path_buf(), + }; + + let result: ExpansionResult = self.process.send_task(msg::Request::ExpansionMacro(task))?; + Ok(result.expansion) } } diff --git a/crates/proc_macro_api/src/process.rs b/crates/proc_macro_api/src/process.rs index 301888a0e..d68723ada 100644 --- a/crates/proc_macro_api/src/process.rs +++ b/crates/proc_macro_api/src/process.rs @@ -10,11 +10,10 @@ use std::{ }; use crossbeam_channel::{bounded, Receiver, Sender}; -use tt::Subtree; use crate::{ msg::{ErrorCode, Message, Request, Response, ResponseError}, - rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind}, + rpc::{ListMacrosResult, ListMacrosTask, ProcMacroKind}, }; #[derive(Debug, Default)] @@ -58,23 +57,6 @@ impl ProcMacroProcessSrv { Ok(result.macros) } - pub(crate) fn custom_derive( - &self, - dylib_path: &Path, - subtree: &Subtree, - derive_name: &str, - ) -> Result { - let task = ExpansionTask { - macro_body: subtree.clone(), - macro_name: derive_name.to_string(), - attributes: None, - lib: dylib_path.to_path_buf(), - }; - - let result: ExpansionResult = self.send_task(Request::ExpansionMacro(task))?; - Ok(result.expansion) - } - pub(crate) fn send_task(&self, req: Request) -> Result where R: TryFrom, -- cgit v1.2.3 From e8a19e24eaa214d982fa8316a21dacb08ce50ec5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Dec 2020 14:11:17 +0100 Subject: Make `ProcMacroProcessExpander` private --- crates/proc_macro_api/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index 0537286dd..40fdbfd5a 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -23,7 +23,7 @@ use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread}; pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind}; #[derive(Debug, Clone)] -pub struct ProcMacroProcessExpander { +struct ProcMacroProcessExpander { process: Arc, dylib_path: PathBuf, name: SmolStr, -- cgit v1.2.3 From fb21a215be0968d1102aba842c0fdedcd401cb15 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Dec 2020 17:06:14 +0100 Subject: Retain types of proc macros and allow attr. macros --- crates/base_db/src/input.rs | 13 +++++++++---- crates/base_db/src/lib.rs | 2 +- crates/proc_macro_api/Cargo.toml | 1 + crates/proc_macro_api/src/lib.rs | 33 +++++++++++++++++---------------- crates/proc_macro_api/src/rpc.rs | 2 +- 5 files changed, 29 insertions(+), 22 deletions(-) (limited to 'crates') diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index 98ba372ad..cda5e57dc 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs @@ -143,9 +143,17 @@ impl CrateDisplayName { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct ProcMacroId(pub u32); +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum ProcMacroKind { + CustomDerive, + FuncLike, + Attr, +} + #[derive(Debug, Clone)] pub struct ProcMacro { pub name: SmolStr, + pub kind: ProcMacroKind, pub expander: Arc, } @@ -198,11 +206,8 @@ impl CrateGraph { display_name: Option, cfg_options: CfgOptions, env: Env, - proc_macro: Vec<(SmolStr, Arc)>, + proc_macro: Vec, ) -> CrateId { - let proc_macro = - proc_macro.into_iter().map(|(name, it)| ProcMacro { name, expander: it }).collect(); - let data = CrateData { root_file_id: file_id, edition, diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index ce75a5337..5571af495 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -14,7 +14,7 @@ pub use crate::{ change::Change, input::{ CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, - ProcMacroId, SourceRoot, SourceRootId, + ProcMacro, ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId, }, }; pub use salsa; diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml index 3863e5189..1af2bbca7 100644 --- a/crates/proc_macro_api/Cargo.toml +++ b/crates/proc_macro_api/Cargo.toml @@ -17,3 +17,4 @@ crossbeam-channel = "0.5.0" jod-thread = "0.1.1" tt = { path = "../tt", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index 40fdbfd5a..bf1f90879 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -16,6 +16,7 @@ use std::{ sync::Arc, }; +use base_db::ProcMacro; use tt::{SmolStr, Subtree}; use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread}; @@ -82,7 +83,7 @@ impl ProcMacroClient { ProcMacroClient { kind: ProcMacroClientKind::Dummy } } - pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<(SmolStr, Arc)> { + pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec { match &self.kind { ProcMacroClientKind::Dummy => vec![], ProcMacroClientKind::Process { process, .. } => { @@ -96,21 +97,21 @@ impl ProcMacroClient { macros .into_iter() - .filter_map(|(name, kind)| { - match kind { - ProcMacroKind::CustomDerive | ProcMacroKind::FuncLike => { - let name = SmolStr::new(&name); - let expander: Arc = - Arc::new(ProcMacroProcessExpander { - process: process.clone(), - name: name.clone(), - dylib_path: dylib_path.into(), - }); - Some((name, expander)) - } - // FIXME: Attribute macro are currently unsupported. - ProcMacroKind::Attr => None, - } + .map(|(name, kind)| { + let name = SmolStr::new(&name); + let kind = match kind { + ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, + ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, + ProcMacroKind::Attr => base_db::ProcMacroKind::Attr, + }; + let expander: Arc = + Arc::new(ProcMacroProcessExpander { + process: process.clone(), + name: name.clone(), + dylib_path: dylib_path.into(), + }); + + ProcMacro { name, kind, expander } }) .collect() } diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs index 203109ca4..b85f92eea 100644 --- a/crates/proc_macro_api/src/rpc.rs +++ b/crates/proc_macro_api/src/rpc.rs @@ -19,7 +19,7 @@ pub struct ListMacrosTask { pub lib: PathBuf, } -#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] pub enum ProcMacroKind { CustomDerive, FuncLike, -- cgit v1.2.3 From 2b2318e695e85d64c6a976a810620c77b7ccba6e Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Dec 2020 17:16:50 +0100 Subject: Remove dummy ProcMacroClient in favor of Option --- crates/proc_macro_api/src/lib.rs | 73 ++++++++++++------------------ crates/project_model/src/workspace.rs | 39 +++++++++------- crates/rust-analyzer/src/cli/load_cargo.rs | 6 +-- crates/rust-analyzer/src/global_state.rs | 4 +- crates/rust-analyzer/src/reload.rs | 8 ++-- 5 files changed, 59 insertions(+), 71 deletions(-) (limited to 'crates') diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index bf1f90879..0d061fd53 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -57,15 +57,10 @@ impl tt::TokenExpander for ProcMacroProcessExpander { } } -#[derive(Debug)] -enum ProcMacroClientKind { - Process { process: Arc, thread: ProcMacroProcessThread }, - Dummy, -} - #[derive(Debug)] pub struct ProcMacroClient { - kind: ProcMacroClientKind, + process: Arc, + thread: ProcMacroProcessThread, } impl ProcMacroClient { @@ -74,47 +69,35 @@ impl ProcMacroClient { args: impl IntoIterator>, ) -> io::Result { let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?; - Ok(ProcMacroClient { - kind: ProcMacroClientKind::Process { process: Arc::new(process), thread }, - }) - } - - pub fn dummy() -> ProcMacroClient { - ProcMacroClient { kind: ProcMacroClientKind::Dummy } + Ok(ProcMacroClient { process: Arc::new(process), thread }) } pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec { - match &self.kind { - ProcMacroClientKind::Dummy => vec![], - ProcMacroClientKind::Process { process, .. } => { - let macros = match process.find_proc_macros(dylib_path) { - Err(err) => { - eprintln!("Failed to find proc macros. Error: {:#?}", err); - return vec![]; - } - Ok(macros) => macros, - }; - - macros - .into_iter() - .map(|(name, kind)| { - let name = SmolStr::new(&name); - let kind = match kind { - ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, - ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, - ProcMacroKind::Attr => base_db::ProcMacroKind::Attr, - }; - let expander: Arc = - Arc::new(ProcMacroProcessExpander { - process: process.clone(), - name: name.clone(), - dylib_path: dylib_path.into(), - }); - - ProcMacro { name, kind, expander } - }) - .collect() + let macros = match self.process.find_proc_macros(dylib_path) { + Err(err) => { + eprintln!("Failed to find proc macros. Error: {:#?}", err); + return vec![]; } - } + Ok(macros) => macros, + }; + + macros + .into_iter() + .map(|(name, kind)| { + let name = SmolStr::new(&name); + let kind = match kind { + ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, + ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, + ProcMacroKind::Attr => base_db::ProcMacroKind::Attr, + }; + let expander: Arc = Arc::new(ProcMacroProcessExpander { + process: self.process.clone(), + name: name.clone(), + dylib_path: dylib_path.into(), + }); + + ProcMacro { name, kind, expander } + }) + .collect() } } diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index a71f96164..ab5cbae11 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -2,10 +2,14 @@ //! metadata` or `rust-project.json`) into representation stored in the salsa //! database -- `CrateGraph`. -use std::{fmt, fs, path::Component, process::Command}; +use std::{ + fmt, fs, + path::{Component, Path}, + process::Command, +}; use anyhow::{Context, Result}; -use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId}; +use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; use cfg::CfgOptions; use paths::{AbsPath, AbsPathBuf}; use proc_macro_api::ProcMacroClient; @@ -194,15 +198,20 @@ impl ProjectWorkspace { pub fn to_crate_graph( &self, target: Option<&str>, - proc_macro_client: &ProcMacroClient, + proc_macro_client: Option<&ProcMacroClient>, load: &mut dyn FnMut(&AbsPath) -> Option, ) -> CrateGraph { + let proc_macro_loader = |path: &Path| match proc_macro_client { + Some(client) => client.by_dylib_path(path), + None => Vec::new(), + }; + let mut crate_graph = match self { ProjectWorkspace::Json { project, sysroot } => { - project_json_to_crate_graph(target, proc_macro_client, load, project, sysroot) + project_json_to_crate_graph(target, &proc_macro_loader, load, project, sysroot) } ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { - cargo_to_crate_graph(target, proc_macro_client, load, cargo, sysroot, rustc) + cargo_to_crate_graph(target, &proc_macro_loader, load, cargo, sysroot, rustc) } }; if crate_graph.patch_cfg_if() { @@ -216,7 +225,7 @@ impl ProjectWorkspace { fn project_json_to_crate_graph( target: Option<&str>, - proc_macro_client: &ProcMacroClient, + proc_macro_loader: &dyn Fn(&Path) -> Vec, load: &mut dyn FnMut(&AbsPath) -> Option, project: &ProjectJson, sysroot: &Option, @@ -236,8 +245,7 @@ fn project_json_to_crate_graph( }) .map(|(crate_id, krate, file_id)| { let env = krate.env.clone().into_iter().collect(); - let proc_macro = - krate.proc_macro_dylib_path.clone().map(|it| proc_macro_client.by_dylib_path(&it)); + let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it)); let target = krate.target.as_deref().or(target); let target_cfgs = @@ -279,7 +287,7 @@ fn project_json_to_crate_graph( fn cargo_to_crate_graph( target: Option<&str>, - proc_macro_client: &ProcMacroClient, + proc_macro_loader: &dyn Fn(&Path) -> Vec, load: &mut dyn FnMut(&AbsPath) -> Option, cargo: &CargoWorkspace, sysroot: &Sysroot, @@ -309,7 +317,7 @@ fn cargo_to_crate_graph( &mut crate_graph, &cargo[pkg], &cfg_options, - proc_macro_client, + proc_macro_loader, file_id, ); if cargo[tgt].kind == TargetKind::Lib { @@ -385,7 +393,7 @@ fn cargo_to_crate_graph( &mut crate_graph, &rustc_workspace[pkg], &cfg_options, - proc_macro_client, + proc_macro_loader, file_id, ); pkg_to_lib_crate.insert(pkg, crate_id); @@ -433,7 +441,7 @@ fn add_target_crate_root( crate_graph: &mut CrateGraph, pkg: &cargo_workspace::PackageData, cfg_options: &CfgOptions, - proc_macro_client: &ProcMacroClient, + proc_macro_loader: &dyn Fn(&Path) -> Vec, file_id: FileId, ) -> CrateId { let edition = pkg.edition; @@ -452,11 +460,8 @@ fn add_target_crate_root( env.set("OUT_DIR", out_dir); } } - let proc_macro = pkg - .proc_macro_dylib_path - .as_ref() - .map(|it| proc_macro_client.by_dylib_path(&it)) - .unwrap_or_default(); + let proc_macro = + pkg.proc_macro_dylib_path.as_ref().map(|it| proc_macro_loader(&it)).unwrap_or_default(); let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); let crate_id = crate_graph.add_crate_root( diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 76526c66c..d51f4a93a 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -33,12 +33,12 @@ pub fn load_cargo( let proc_macro_client = if with_proc_macro { let path = std::env::current_exe()?; - ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap() + Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()) } else { - ProcMacroClient::dummy() + None }; - let crate_graph = ws.to_crate_graph(None, &proc_macro_client, &mut |path: &AbsPath| { + let crate_graph = ws.to_crate_graph(None, proc_macro_client.as_ref(), &mut |path: &AbsPath| { let contents = loader.load_sync(path); let path = vfs::VfsPath::from(path.to_path_buf()); vfs.set_file_contents(path.clone(), contents); diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index defe11c55..a27495d0d 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -75,7 +75,7 @@ pub(crate) struct GlobalState { pub(crate) shutdown_requested: bool, pub(crate) status: Status, pub(crate) source_root_config: SourceRootConfig, - pub(crate) proc_macro_client: ProcMacroClient, + pub(crate) proc_macro_client: Option, pub(crate) workspaces: Arc>, latest_requests: Arc>, } @@ -127,7 +127,7 @@ impl GlobalState { shutdown_requested: false, status: Status::default(), source_root_config: SourceRootConfig::default(), - proc_macro_client: ProcMacroClient::dummy(), + proc_macro_client: None, workspaces: Arc::new(Vec::new()), latest_requests: Default::default(), } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index b2d35f535..79e39e3a5 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -171,16 +171,16 @@ impl GlobalState { let project_folders = ProjectFolders::new(&workspaces); self.proc_macro_client = match &self.config.proc_macro_srv { - None => ProcMacroClient::dummy(), + None => None, Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) { - Ok(it) => it, + Ok(it) => Some(it), Err(err) => { log::error!( "Failed to run proc_macro_srv from path {}, error: {:?}", path.display(), err ); - ProcMacroClient::dummy() + None } }, }; @@ -212,7 +212,7 @@ impl GlobalState { for ws in workspaces.iter() { crate_graph.extend(ws.to_crate_graph( self.config.cargo.target.as_deref(), - &self.proc_macro_client, + self.proc_macro_client.as_ref(), &mut load, )); } -- cgit v1.2.3 From 577d5f1c337d5de8719bddcabd3d22a560a11b95 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Dec 2020 17:17:31 +0100 Subject: Remove resolved FIXME --- crates/hir_expand/src/proc_macro.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'crates') diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs index 97edf0fb6..38882d2b6 100644 --- a/crates/hir_expand/src/proc_macro.rs +++ b/crates/hir_expand/src/proc_macro.rs @@ -26,7 +26,6 @@ impl ProcMacroExpander { pub fn dummy(krate: CrateId) -> Self { // FIXME: Should store the name for better errors - // FIXME: I think this is the second layer of "dummy" expansion, we should reduce that Self { krate, proc_macro_id: None } } -- cgit v1.2.3