From b112516f59e2e8be7b84b23368c8343c6a13c49c Mon Sep 17 00:00:00 2001 From: Piotr Figiela <77412592+Draggu@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:27:39 +0200 Subject: [PATCH] Add `ExpandDerive` handler commit-id:20ad0a61 --- .../methods/expand_derive.rs | 54 +++++++++++++++++++ .../src/ops/proc_macro_server/methods/mod.rs | 1 + scarb/src/ops/proc_macro_server/mod.rs | 3 +- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 scarb/src/ops/proc_macro_server/methods/expand_derive.rs diff --git a/scarb/src/ops/proc_macro_server/methods/expand_derive.rs b/scarb/src/ops/proc_macro_server/methods/expand_derive.rs new file mode 100644 index 000000000..73032484d --- /dev/null +++ b/scarb/src/ops/proc_macro_server/methods/expand_derive.rs @@ -0,0 +1,54 @@ +use crate::{ + compiler::plugin::proc_macro::{Expansion, ExpansionKind, ProcMacroHost}, + ops::proc_macro_server::json_rpc::Handler, +}; +use anyhow::Result; +use cairo_lang_macro::TokenStream; +use convert_case::{Case, Casing}; +use scarb_proc_macro_server_types::methods::{expand::ExpandDerive, ProcMacroResult}; +use std::sync::Arc; + +impl Handler for ExpandDerive { + fn handle(proc_macros: Arc, params: Self::Params) -> Result { + let mut derived_code = String::new(); + let mut all_diagnostics = vec![]; + + for derive in params.derives { + let expansion = Expansion::new(derive.to_case(Case::Snake), ExpansionKind::Derive); + let package_id = proc_macros + .macros() + .into_iter() + .find(|e| e.get_expansions().contains(&expansion)) + .map(|m| m.package_id()) + .unwrap(); + + let instance = proc_macros + .macros() + .iter() + .find(|m| m.package_id() == package_id) + .unwrap(); + + let result = instance.generate_code( + expansion.name.clone(), + TokenStream::empty(), + params.item.clone(), + ); + + // Register diagnostics. + all_diagnostics.extend(result.diagnostics); + + if result.token_stream.is_empty() { + // No code has been generated. + // We do not need to do anything. + continue; + } + + derived_code.push_str(result.token_stream.to_string().as_str()); + } + + Ok(ProcMacroResult { + token_stream: TokenStream::new(derived_code), + diagnostics: all_diagnostics, + }) + } +} diff --git a/scarb/src/ops/proc_macro_server/methods/mod.rs b/scarb/src/ops/proc_macro_server/methods/mod.rs index d4c1e839e..1a3926524 100644 --- a/scarb/src/ops/proc_macro_server/methods/mod.rs +++ b/scarb/src/ops/proc_macro_server/methods/mod.rs @@ -1,2 +1,3 @@ pub mod defined_macros; pub mod expand_attribute; +pub mod expand_derive; diff --git a/scarb/src/ops/proc_macro_server/mod.rs b/scarb/src/ops/proc_macro_server/mod.rs index 614fdc172..dc8ee6603 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 json_rpc::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; +use scarb_proc_macro_server_types::methods::expand::{ExpandAttribute, ExpandDerive}; 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 ExpandAttribute::METHOD => { run_handler::(proc_macros.clone(), request.value) } + ExpandDerive::METHOD => run_handler::(proc_macros.clone(), request.value), _ => Err(anyhow!("method not found")), } }