Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ExpandAttribute handler #1684

Merged
merged 1 commit into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions scarb/src/ops/proc_macro_server/methods/expand_attribute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::sync::Arc;

use anyhow::Result;
use scarb_proc_macro_server_types::methods::{expand::ExpandAttribute, ProcMacroResult};

use super::Handler;
use crate::compiler::plugin::proc_macro::{ExpansionKind, ProcMacroHost};

impl Handler for ExpandAttribute {
fn handle(proc_macro_host: Arc<ProcMacroHost>, params: Self::Params) -> Result<Self::Response> {
let instance = proc_macro_host
.macros()
.iter()
.find(|e| {
e.get_expansions()
.iter()
.filter(|expansion| expansion.kind == ExpansionKind::Attr)
.any(|expansion| expansion.name == params.attr)
})
.unwrap();

let result = instance.generate_code(params.attr.into(), params.args, params.item);

Ok(ProcMacroResult {
token_stream: result.token_stream,
diagnostics: result.diagnostics,
})
}
}
1 change: 1 addition & 0 deletions scarb/src/ops/proc_macro_server/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use scarb_proc_macro_server_types::methods::Method;
use crate::compiler::plugin::proc_macro::ProcMacroHost;

pub mod defined_macros;
pub mod expand_attribute;

pub trait Handler: Method {
fn handle(proc_macro_host: Arc<ProcMacroHost>, params: Self::Params) -> Result<Self::Response>;
Expand Down
4 changes: 4 additions & 0 deletions scarb/src/ops/proc_macro_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +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;
use scarb_proc_macro_server_types::methods::Method;
use serde_json::Value;

Expand Down Expand Up @@ -70,6 +71,9 @@ fn handle_requests(
fn route_request(proc_macros: Arc<ProcMacroHost>, request: RpcRequest) -> Result<Value> {
match request.method.as_str() {
DefinedMacros::METHOD => run_handler::<DefinedMacros>(proc_macros.clone(), request.value),
ExpandAttribute::METHOD => {
run_handler::<ExpandAttribute>(proc_macros.clone(), request.value)
}
_ => Err(anyhow!("method not found")),
}
}
Expand Down
52 changes: 52 additions & 0 deletions scarb/tests/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use assert_fs::prelude::PathChild;
use assert_fs::TempDir;
use cairo_lang_macro::TokenStream;
use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacros;
use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacrosParams;
use scarb_proc_macro_server_types::methods::expand::ExpandAttribute;
use scarb_proc_macro_server_types::methods::expand::ExpandAttributeParams;
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;
Expand Down Expand Up @@ -36,3 +39,52 @@ fn defined_macros() {
assert_eq!(response.inline_macros, vec!["inline_some".to_string()]);
assert_eq!(response.executables, vec!["some_executable".to_string()]);
}

#[test]
fn expand_attribute() {
let t = TempDir::new().unwrap();
let plugin_package = t.child("some");

let rename_to_very_new_name = r##"
#[attribute_macro]
pub fn rename_to_very_new_name(_attr: TokenStream, token_stream: TokenStream) -> ProcMacroResult {{
let re = regex::Regex::new(r#"fn (\w+)\(.*\)\{.*\}"#).unwrap();
let input = token_stream.to_string();
let name = re.captures(&input).unwrap().get(1).unwrap().as_str();

let output = input.replace(name, "very_new_name");

ProcMacroResult::new(TokenStream::new(output))
}}
"##;

CairoPluginProjectBuilder::default()
.lib_rs(format!("{SIMPLE_MACROS}\n{rename_to_very_new_name}"))
.add_dep(r#"regex = "1.11.1""#)
.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::<ExpandAttribute>(ExpandAttributeParams {
attr: "rename_to_very_new_name".to_string(),
args: TokenStream::empty(),
item: TokenStream::new("fn some_test_fn(){}".to_string()),
})
.unwrap();

assert_eq!(response.diagnostics, vec![]);
assert_eq!(
response.token_stream,
TokenStream::new("fn very_new_name(){}".to_string())
);
}
Loading