diff --git a/scarb/src/ops/proc_macro_server/methods/expand_inline.rs b/scarb/src/ops/proc_macro_server/methods/expand_inline.rs new file mode 100644 index 000000000..1e209fae1 --- /dev/null +++ b/scarb/src/ops/proc_macro_server/methods/expand_inline.rs @@ -0,0 +1,30 @@ +use std::sync::Arc; + +use anyhow::Result; +use cairo_lang_macro::TokenStream; +use scarb_proc_macro_server_types::methods::{expand::ExpandInline, ProcMacroResult}; + +use super::Handler; +use crate::compiler::plugin::proc_macro::{ExpansionKind, ProcMacroHost}; + +impl Handler for ExpandInline { + fn handle(proc_macro_host: Arc, params: Self::Params) -> Result { + let instance = proc_macro_host + .macros() + .iter() + .find(|e| { + e.get_expansions() + .iter() + .filter(|expansion| expansion.kind == ExpansionKind::Inline) + .any(|expansion| expansion.name == params.name) + }) + .unwrap(); + + let result = instance.generate_code(params.name.into(), TokenStream::empty(), params.args); + + Ok(ProcMacroResult { + token_stream: result.token_stream, + diagnostics: result.diagnostics, + }) + } +} diff --git a/scarb/src/ops/proc_macro_server/methods/mod.rs b/scarb/src/ops/proc_macro_server/methods/mod.rs index 604d5561c..b9225412f 100644 --- a/scarb/src/ops/proc_macro_server/methods/mod.rs +++ b/scarb/src/ops/proc_macro_server/methods/mod.rs @@ -8,6 +8,7 @@ use crate::compiler::plugin::proc_macro::ProcMacroHost; pub mod defined_macros; pub mod expand_attribute; pub mod expand_derive; +pub mod expand_inline; pub trait Handler: Method { fn handle(proc_macro_host: Arc, params: Self::Params) -> Result; diff --git a/scarb/src/ops/proc_macro_server/mod.rs b/scarb/src/ops/proc_macro_server/mod.rs index 50510c6c9..4cf5cdb5b 100644 --- a/scarb/src/ops/proc_macro_server/mod.rs +++ b/scarb/src/ops/proc_macro_server/mod.rs @@ -8,7 +8,7 @@ use crossbeam_channel::{Receiver, Sender}; use methods::Handler; use scarb_proc_macro_server_types::jsonrpc::{ResponseError, RpcRequest, RpcResponse}; use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacros; -use scarb_proc_macro_server_types::methods::expand::{ExpandAttribute, ExpandDerive}; +use scarb_proc_macro_server_types::methods::expand::{ExpandAttribute, ExpandDerive, ExpandInline}; use scarb_proc_macro_server_types::methods::Method; use serde_json::Value; @@ -75,6 +75,7 @@ fn route_request(proc_macros: Arc, request: RpcRequest) -> Result run_handler::(proc_macros.clone(), request.value) } ExpandDerive::METHOD => run_handler::(proc_macros.clone(), request.value), + ExpandInline::METHOD => run_handler::(proc_macros.clone(), request.value), _ => Err(anyhow!("method not found")), } } diff --git a/scarb/tests/proc_macro_server.rs b/scarb/tests/proc_macro_server.rs index 704267c03..b01f865dc 100644 --- a/scarb/tests/proc_macro_server.rs +++ b/scarb/tests/proc_macro_server.rs @@ -7,6 +7,8 @@ use scarb_proc_macro_server_types::methods::expand::ExpandAttribute; use scarb_proc_macro_server_types::methods::expand::ExpandAttributeParams; use scarb_proc_macro_server_types::methods::expand::ExpandDerive; use scarb_proc_macro_server_types::methods::expand::ExpandDeriveParams; +use scarb_proc_macro_server_types::methods::expand::ExpandInline; +use scarb_proc_macro_server_types::methods::expand::ExpandInlineMacroParams; use scarb_test_support::cairo_plugin_project_builder::CairoPluginProjectBuilder; use scarb_test_support::proc_macro_server::ProcMacroClient; use scarb_test_support::proc_macro_server::SIMPLE_MACROS; @@ -126,3 +128,46 @@ fn expand_derive() { TokenStream::new("impl SomeImpl of SomeTrait {}".to_string()) ); } + +#[test] +fn expand_inline() { + let t = TempDir::new().unwrap(); + let plugin_package = t.child("some"); + + let replace_all_15_with_25 = r#" + #[inline_macro] + pub fn replace_all_15_with_25(token_stream: TokenStream) -> ProcMacroResult { + ProcMacroResult::new(TokenStream::new(token_stream.to_string().replace("15", "25"))) + } + "#; + + CairoPluginProjectBuilder::default() + .lib_rs(format!("{SIMPLE_MACROS}\n{replace_all_15_with_25}")) + .build(&plugin_package); + + let project = t.child("test_package"); + + ProjectBuilder::start() + .name("test_package") + .version("1.0.0") + .lib_cairo("") + .dep("some", plugin_package) + .build(&project); + + let mut proc_macro_server = ProcMacroClient::new(&project); + + let response = proc_macro_server + .request_and_wait::(ExpandInlineMacroParams { + name: "replace_all_15_with_25".to_string(), + args: TokenStream::new( + "struct A { field: 15 , other_field: macro_call!(12)}".to_string(), + ), + }) + .unwrap(); + + assert_eq!(response.diagnostics, vec![]); + assert_eq!( + response.token_stream, + TokenStream::new("struct A { field: 25 , other_field: macro_call!(12)}".to_string()) + ); +}