diff --git a/Cargo.lock b/Cargo.lock index 67119b892d..428846b246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1120,7 +1120,6 @@ dependencies = [ name = "proc_macro_api" version = "0.0.0" dependencies = [ - "base_db", "crossbeam-channel", "jod-thread", "log", diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml index 49202bccfb..a0fd10441f 100644 --- a/crates/proc_macro_api/Cargo.toml +++ b/crates/proc_macro_api/Cargo.toml @@ -15,17 +15,16 @@ log = "0.4.8" crossbeam-channel = "0.5.0" jod-thread = "0.1.1" memmap2 = "0.3.0" -object = { version = "0.26", default-features = false, features = [ - "std", - "read_core", - "elf", - "macho", - "pe", -] } snap = "1.0" paths = { path = "../paths", version = "0.0.0" } tt = { path = "../tt", version = "0.0.0" } -base_db = { path = "../base_db", version = "0.0.0" } stdx = { path = "../stdx", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } +# Intentionally *not* depend on anything salsa-related +# base_db = { path = "../base_db", version = "0.0.0" } + +[dependencies.object] +version = "0.26" +default-features = false +features = [ "std", "read_core", "elf", "macho", "pe" ] diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index 2bcaf74678..bbd26caf76 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -10,7 +10,6 @@ mod process; mod rpc; mod version; -use base_db::{Env, ProcMacro}; use paths::{AbsPath, AbsPathBuf}; use std::{ ffi::OsStr, @@ -26,34 +25,44 @@ pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, pub use version::{read_dylib_info, RustCInfo}; #[derive(Debug, Clone)] -struct ProcMacroProcessExpander { +pub struct ProcMacroProcessExpander { process: Arc>, dylib_path: AbsPathBuf, name: SmolStr, + kind: ProcMacroKind, } impl Eq for ProcMacroProcessExpander {} impl PartialEq for ProcMacroProcessExpander { fn eq(&self, other: &Self) -> bool { self.name == other.name + && self.kind == other.kind && self.dylib_path == other.dylib_path && Arc::ptr_eq(&self.process, &other.process) } } -impl base_db::ProcMacroExpander for ProcMacroProcessExpander { - fn expand( +impl ProcMacroProcessExpander { + pub fn name(&self) -> &str { + &self.name + } + + pub fn kind(&self) -> ProcMacroKind { + self.kind + } + + pub fn expand( &self, subtree: &Subtree, attr: Option<&Subtree>, - env: &Env, + env: Vec<(String, String)>, ) -> Result { let task = ExpansionTask { macro_body: subtree.clone(), macro_name: self.name.to_string(), attributes: attr.cloned(), lib: self.dylib_path.to_path_buf(), - env: env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(), + env, }; let result: ExpansionResult = self @@ -86,7 +95,7 @@ impl ProcMacroClient { Ok(ProcMacroClient { process: Arc::new(Mutex::new(process)) }) } - pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec { + pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec { let _p = profile::span("ProcMacroClient::by_dylib_path"); match version::read_dylib_info(dylib_path) { Ok(info) => { @@ -118,20 +127,11 @@ impl ProcMacroClient { 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::new(ProcMacroProcessExpander { - process: self.process.clone(), - name: name.clone(), - dylib_path: dylib_path.to_path_buf(), - }); - - ProcMacro { name, kind, expander } + .map(|(name, kind)| ProcMacroProcessExpander { + process: self.process.clone(), + name: name.into(), + kind, + dylib_path: dylib_path.to_path_buf(), }) .collect() } diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 3c9e052a69..d194879f04 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -52,6 +52,7 @@ vfs = { path = "../vfs", version = "0.0.0" } vfs-notify = { path = "../vfs-notify", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" } toolchain = { path = "../toolchain", version = "0.0.0" } +tt = { path = "../tt", version = "0.0.0" } proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } # This should only be used in CLI diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 9fe81cc8f6..65607bbc6f 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -11,7 +11,7 @@ use proc_macro_api::ProcMacroClient; use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, WorkspaceBuildScripts}; use vfs::{loader::Handle, AbsPath, AbsPathBuf}; -use crate::reload::{ProjectFolders, SourceRootConfig}; +use crate::reload::{load_proc_macro, ProjectFolders, SourceRootConfig}; // Note: Since this type is used by external tools that use rust-analyzer as a library // what otherwise would be `pub(crate)` has to be `pub` here instead. @@ -69,9 +69,7 @@ pub fn load_workspace( }); let crate_graph = ws.to_crate_graph( - &mut |path: &AbsPath| { - proc_macro_client.as_ref().map(|it| it.by_dylib_path(path)).unwrap_or_default() - }, + &mut |path: &AbsPath| load_proc_macro(proc_macro_client.as_ref(), path), &mut |path: &AbsPath| { let contents = loader.load_sync(path); let path = vfs::VfsPath::from(path.to_path_buf()); diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index f8c770ccf4..5c23caa685 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -4,7 +4,9 @@ use std::{mem, sync::Arc}; use flycheck::{FlycheckConfig, FlycheckHandle}; use hir::db::DefDatabase; use ide::Change; -use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; +use ide_db::base_db::{ + CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroKind, SourceRoot, VfsPath, +}; use proc_macro_api::ProcMacroClient; use project_model::{ProjectWorkspace, WorkspaceBuildScripts}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; @@ -398,9 +400,8 @@ impl GlobalState { // Create crate graph from all the workspaces let crate_graph = { let proc_macro_client = self.proc_macro_client.as_ref(); - let mut load_proc_macro = move |path: &AbsPath| { - proc_macro_client.map(|it| it.by_dylib_path(path)).unwrap_or_default() - }; + let mut load_proc_macro = + move |path: &AbsPath| load_proc_macro(proc_macro_client, path); let vfs = &mut self.vfs.write().0; let loader = &mut self.loader; @@ -587,3 +588,38 @@ impl SourceRootConfig { .collect() } } + +pub(crate) fn load_proc_macro(client: Option<&ProcMacroClient>, path: &AbsPath) -> Vec { + return client + .map(|it| it.by_dylib_path(path)) + .unwrap_or_default() + .into_iter() + .map(expander_to_proc_macro) + .collect(); + + fn expander_to_proc_macro(expander: proc_macro_api::ProcMacroProcessExpander) -> ProcMacro { + let name = expander.name().into(); + let kind = match expander.kind() { + proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive, + proc_macro_api::ProcMacroKind::FuncLike => ProcMacroKind::FuncLike, + proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr, + }; + let expander = Arc::new(Expander(expander)); + ProcMacro { name, kind, expander } + } + + #[derive(Debug)] + struct Expander(proc_macro_api::ProcMacroProcessExpander); + + impl ProcMacroExpander for Expander { + fn expand( + &self, + subtree: &tt::Subtree, + attrs: Option<&tt::Subtree>, + env: &Env, + ) -> Result { + let env = env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(); + self.0.expand(subtree, attrs, env) + } + } +}