Skip to content

Commit 3e71fa0

Browse files
authored
Add ExpandDerive handler (#1685)
**Stack**: - #1686 - #1685⚠️ *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.*
1 parent 3be33e4 commit 3e71fa0

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::sync::Arc;
2+
3+
use anyhow::Result;
4+
use cairo_lang_macro::TokenStream;
5+
use convert_case::{Case, Casing};
6+
use scarb_proc_macro_server_types::methods::{expand::ExpandDerive, ProcMacroResult};
7+
8+
use super::Handler;
9+
use crate::compiler::plugin::proc_macro::{Expansion, ExpansionKind, ProcMacroHost};
10+
11+
impl Handler for ExpandDerive {
12+
fn handle(proc_macro_host: Arc<ProcMacroHost>, params: Self::Params) -> Result<Self::Response> {
13+
let mut derived_code = String::new();
14+
let mut all_diagnostics = vec![];
15+
16+
for derive in params.derives {
17+
let expansion = Expansion::new(derive.to_case(Case::Snake), ExpansionKind::Derive);
18+
let instance = proc_macro_host
19+
.macros()
20+
.iter()
21+
.find(|e| e.get_expansions().contains(&expansion))
22+
.unwrap();
23+
24+
let result = instance.generate_code(
25+
expansion.name.clone(),
26+
TokenStream::empty(),
27+
params.item.clone(),
28+
);
29+
30+
// Register diagnostics.
31+
all_diagnostics.extend(result.diagnostics);
32+
// Add generated code.
33+
derived_code.push_str(&result.token_stream.to_string());
34+
}
35+
36+
Ok(ProcMacroResult {
37+
token_stream: TokenStream::new(derived_code),
38+
diagnostics: all_diagnostics,
39+
})
40+
}
41+
}

scarb/src/ops/proc_macro_server/methods/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::compiler::plugin::proc_macro::ProcMacroHost;
77

88
pub mod defined_macros;
99
pub mod expand_attribute;
10+
pub mod expand_derive;
1011

1112
pub trait Handler: Method {
1213
fn handle(proc_macro_host: Arc<ProcMacroHost>, params: Self::Params) -> Result<Self::Response>;

scarb/src/ops/proc_macro_server/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crossbeam_channel::{Receiver, Sender};
88
use methods::Handler;
99
use scarb_proc_macro_server_types::jsonrpc::{ResponseError, RpcRequest, RpcResponse};
1010
use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacros;
11-
use scarb_proc_macro_server_types::methods::expand::ExpandAttribute;
11+
use scarb_proc_macro_server_types::methods::expand::{ExpandAttribute, ExpandDerive};
1212
use scarb_proc_macro_server_types::methods::Method;
1313
use serde_json::Value;
1414

@@ -74,6 +74,7 @@ fn route_request(proc_macros: Arc<ProcMacroHost>, request: RpcRequest) -> Result
7474
ExpandAttribute::METHOD => {
7575
run_handler::<ExpandAttribute>(proc_macros.clone(), request.value)
7676
}
77+
ExpandDerive::METHOD => run_handler::<ExpandDerive>(proc_macros.clone(), request.value),
7778
_ => Err(anyhow!("method not found")),
7879
}
7980
}

scarb/tests/proc_macro_server.rs

+38
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacros;
55
use scarb_proc_macro_server_types::methods::defined_macros::DefinedMacrosParams;
66
use scarb_proc_macro_server_types::methods::expand::ExpandAttribute;
77
use scarb_proc_macro_server_types::methods::expand::ExpandAttributeParams;
8+
use scarb_proc_macro_server_types::methods::expand::ExpandDerive;
9+
use scarb_proc_macro_server_types::methods::expand::ExpandDeriveParams;
810
use scarb_test_support::cairo_plugin_project_builder::CairoPluginProjectBuilder;
911
use scarb_test_support::proc_macro_server::ProcMacroClient;
1012
use scarb_test_support::proc_macro_server::SIMPLE_MACROS;
@@ -88,3 +90,39 @@ fn expand_attribute() {
8890
TokenStream::new("fn very_new_name(){}".to_string())
8991
);
9092
}
93+
94+
#[test]
95+
fn expand_derive() {
96+
let t = TempDir::new().unwrap();
97+
let plugin_package = t.child("some");
98+
99+
CairoPluginProjectBuilder::default()
100+
.lib_rs(SIMPLE_MACROS)
101+
.build(&plugin_package);
102+
103+
let project = t.child("test_package");
104+
105+
ProjectBuilder::start()
106+
.name("test_package")
107+
.version("1.0.0")
108+
.lib_cairo("")
109+
.dep("some", plugin_package)
110+
.build(&project);
111+
112+
let mut proc_macro_server = ProcMacroClient::new(&project);
113+
114+
let item = TokenStream::new("fn some_test_fn(){}".to_string());
115+
116+
let response = proc_macro_server
117+
.request_and_wait::<ExpandDerive>(ExpandDeriveParams {
118+
derives: vec!["some_derive".to_string()],
119+
item,
120+
})
121+
.unwrap();
122+
123+
assert_eq!(response.diagnostics, vec![]);
124+
assert_eq!(
125+
response.token_stream,
126+
TokenStream::new("impl SomeImpl of SomeTrait {}".to_string())
127+
);
128+
}

0 commit comments

Comments
 (0)