Skip to content

Commit

Permalink
Add ExpandAttribute handler (#1684)
Browse files Browse the repository at this point in the history
**Stack**:
- #1686
- #1685
- #1684⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do
not merge manually using the UI - doing so may have unexpected results.*
  • Loading branch information
Draggu authored Nov 9, 2024
1 parent 7f932b2 commit 3be33e4
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
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())
);
}

0 comments on commit 3be33e4

Please sign in to comment.