diff --git a/scarb/src/compiler/plugin/proc_macro/ffi.rs b/scarb/src/compiler/plugin/proc_macro/ffi.rs index bb358ade9..62c4eb1da 100644 --- a/scarb/src/compiler/plugin/proc_macro/ffi.rs +++ b/scarb/src/compiler/plugin/proc_macro/ffi.rs @@ -134,6 +134,15 @@ impl ProcMacroInstance { .collect() } + pub fn inline_macros(&self) -> Vec { + self.get_expansions() + .iter() + .filter(|e| e.kind == ExpansionKind::Inline) + .map(|e| e.name.clone()) + .map(Into::into) + .collect() + } + /// Apply expansion to token stream. /// /// This function implements the actual calls to functions from the dynamic library. diff --git a/scarb/src/compiler/plugin/proc_macro/host.rs b/scarb/src/compiler/plugin/proc_macro/host.rs index c32ff0eed..4708b18b1 100644 --- a/scarb/src/compiler/plugin/proc_macro/host.rs +++ b/scarb/src/compiler/plugin/proc_macro/host.rs @@ -1101,4 +1101,8 @@ impl ProcMacroHost { pub fn into_plugin(self) -> Result { ProcMacroHostPlugin::try_new(self.macros) } + + pub fn macros(&self) -> &[Arc] { + &self.macros + } } diff --git a/scarb/src/ops/proc_macro_server/json_rpc.rs b/scarb/src/ops/proc_macro_server/json_rpc.rs index e63d8ae2a..ceee14bd8 100644 --- a/scarb/src/ops/proc_macro_server/json_rpc.rs +++ b/scarb/src/ops/proc_macro_server/json_rpc.rs @@ -1,4 +1,12 @@ +use crate::compiler::plugin::proc_macro::ProcMacroHost; +use anyhow::Result; +use proc_macro_server_api::Method; use serde::Serialize; +use std::sync::Arc; + +pub trait Handler: Method { + fn handle(proc_macros: Arc, params: Self::Params) -> Result; +} #[derive(Serialize)] pub struct ErrResponse { diff --git a/scarb/src/ops/proc_macro_server/methods/defined_macros.rs b/scarb/src/ops/proc_macro_server/methods/defined_macros.rs new file mode 100644 index 000000000..097f88d09 --- /dev/null +++ b/scarb/src/ops/proc_macro_server/methods/defined_macros.rs @@ -0,0 +1,27 @@ +use crate::{ + compiler::plugin::proc_macro::ProcMacroHost, ops::proc_macro_server::json_rpc::Handler, +}; +use anyhow::Result; +use proc_macro_server_api::methods::defined_macros::{DefinedMacros, DefinedMacrosResponse}; +use std::sync::Arc; + +impl Handler for DefinedMacros { + fn handle(proc_macros: Arc, _params: Self::Params) -> Result { + let mut response: DefinedMacrosResponse = proc_macros + .macros() + .into_iter() + .map(|e| DefinedMacrosResponse { + attributes: e.declared_attributes(), + inline_macros: e.inline_macros(), + derives: e.declared_derives(), + executables: e.executable_attributes(), + }) + .sum(); + + response + .attributes + .retain(|attr| !response.executables.contains(attr)); + + Ok(response) + } +} diff --git a/scarb/src/ops/proc_macro_server/methods/mod.rs b/scarb/src/ops/proc_macro_server/methods/mod.rs new file mode 100644 index 000000000..fea512b83 --- /dev/null +++ b/scarb/src/ops/proc_macro_server/methods/mod.rs @@ -0,0 +1 @@ +pub mod defined_macros; diff --git a/scarb/src/ops/proc_macro_server/mod.rs b/scarb/src/ops/proc_macro_server/mod.rs index 9b18af89d..1450b9620 100644 --- a/scarb/src/ops/proc_macro_server/mod.rs +++ b/scarb/src/ops/proc_macro_server/mod.rs @@ -1,25 +1,32 @@ use crate::compiler::plugin::proc_macro::ProcMacroHost; use anyhow::{anyhow, Result}; use connection::Connection; -use json_rpc::ErrResponse; -use proc_macro_server_api::RpcResponse; +use json_rpc::{ErrResponse, Handler}; +use proc_macro_server_api::{methods::defined_macros::DefinedMacros, Method, RpcResponse}; +use serde_json::Value; +use std::sync::Arc; mod connection; mod json_rpc; +mod methods; pub fn start_proc_macro_server(proc_macros: ProcMacroHost) -> Result<()> { let connection = Connection::new(); + let proc_macros = Arc::new(proc_macros); for i in 0..4 { let receiver = connection.receiver.clone(); let sender = connection.sender.clone(); + let proc_macros = proc_macros.clone(); std::thread::Builder::new() .name(format!("proc-macro-server-worker-thread-{i}")) .spawn(move || { for request in receiver { let response = match request.method.as_str() { - //TODO add method handlers + DefinedMacros::METHOD => { + run_handler::(proc_macros.clone(), request.value) + } _ => Err(anyhow!("method not found")), }; @@ -41,3 +48,8 @@ pub fn start_proc_macro_server(proc_macros: ProcMacroHost) -> Result<()> { Ok(()) } + +fn run_handler(proc_macros: Arc, value: Value) -> Result { + M::handle(proc_macros.clone(), serde_json::from_value(value).unwrap()) + .map(|res| serde_json::to_value(res).unwrap()) +}