Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8395412

Browse files
committed
[fix] レシーバを持つメソッドに対して callee を付与できるようにした
1 parent fe2c6ae commit 8395412

File tree

4 files changed

+33
-21
lines changed

4 files changed

+33
-21
lines changed

‎crates/macros/src/impl/modifier.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ pub fn proc_macro_impl(_args: TokenStream, ast: ItemTrait) -> TokenStream {
1616
#[macro_export]
1717
macro_rules! #macro_ident {
1818
($($body:tt)*) => {{
19-
// 文脈付き呼び出しへの変換
19+
// 文脈付き呼び出しへの変換 (関数定義ではなくブロックに変換される)
2020
#[modifier_caller(#trait_name)]
2121
fn __mymodifier_caller() {
2222
$($body)*
2323
}
24-
25-
// 呼び出し
26-
__mymodifier_caller();
2724
}};
2825
}
2926
}

‎crates/macros/src/impl/modifier_callee.rs‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro2::TokenStream;
22
use quote::quote;
3-
use syn::ItemFn;
3+
use syn::{FnArg,ItemFn};
44

55
/// 対象: 関数
66
/// 動作: 文脈への制約を追加
@@ -9,13 +9,21 @@ pub fn proc_macro_impl(args: TokenStream, ast: ItemFn) -> TokenStream {
99

1010
let fn_visibility = ast.vis;
1111
let fn_ident = ast.sig.ident;
12-
let fn_args = ast.sig.inputs;
1312
let fn_ret_type = ast.sig.output;
1413
let fn_body = ast.block;
1514

15+
let fn_args = ast.sig.inputs;
16+
let fn_args = if let Some(FnArg::Receiver(..)) = fn_args.first() {
17+
let receiver = &fn_args[0];
18+
let remains = fn_args.iter().skip(1).collect::<Vec<_>>();
19+
quote! { #receiver, ctx: Ctx, #(#remains),*}
20+
} else {
21+
quote! { ctx: Ctx, #fn_args }
22+
};
23+
1624
quote! {
1725
// マクロ適用関数
18-
#fn_visibility fn #fn_ident <Ctx> (ctx:Ctx,#fn_args) #fn_ret_type
26+
#fn_visibility fn #fn_ident <Ctx> (#fn_args) #fn_ret_type
1927
where
2028
// 制約
2129
Ctx: #target_trait,

‎crates/macros/src/impl/modifier_caller.rs‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,20 @@ use syn::{Expr, ItemFn, Stmt};
77
pub fn proc_macro_impl(args: TokenStream, ast: ItemFn) -> TokenStream {
88
let target_trait = args;
99

10-
let fn_visibility = ast.vis;
11-
let fn_ident = ast.sig.ident;
12-
let fn_ret_type = ast.sig.output;
13-
let fn_stmts = &ast
10+
let stmts = &ast
1411
.block
1512
.stmts
1613
.iter()
1714
.map(append_ctx_if_calling)
1815
.collect::<Vec<_>>();
1916

2017
quote! {
21-
// マクロ適用関数
22-
#fn_visibility fn #fn_ident () #fn_ret_type {
23-
// 前準備
24-
#[allow(non_local_definitions)]
25-
impl #target_trait for Ctx {}
18+
// 前準備
19+
#[allow(non_local_definitions)]
20+
impl #target_trait for Ctx {}
2621

27-
// 関数本体
28-
#(#fn_stmts);*
29-
}
22+
// 関数本体
23+
#(#stmts);*
3024
}
3125
}
3226

@@ -36,6 +30,11 @@ fn append_ctx_if_calling(stmt: &Stmt) -> TokenStream {
3630
let func = call.func.to_token_stream();
3731
let args = call.args.to_token_stream();
3832
quote! { #func (Ctx, #args) }
33+
} else if let Expr::MethodCall(call) = expr {
34+
let receiver = call.receiver.to_token_stream();
35+
let method = call.method.to_token_stream();
36+
let args = call.args.to_token_stream();
37+
quote! { #receiver . #method (Ctx, #args) }
3938
} else {
4039
stmt.to_token_stream()
4140
}

‎crates/macros/tests/modifier_callee.rs‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,22 @@ fn fn_a() {}
1515
#[modifier_callee(B + C)]
1616
fn fn_b_c() {}
1717

18+
struct Object {}
19+
20+
impl Object {
21+
#[modifier_callee(A)]
22+
fn method(&mut self) {}
23+
}
24+
25+
1826
#[test]
1927
fn check_compile() {
2028
struct Ctx;
21-
2229
a! {
23-
fn_a();
2430
b! {
2531
c! {
32+
Object{}.method();
33+
fn_a();
2634
fn_b_c();
2735
}
2836
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /