0

为了这个例子:我想写一个 proc 宏属性来修改函数体中的所有数字文字。

我有一个syn::Block来自syn::FnItem. 我想映射块中的所有标记并更改文字。我目前有:

let token_stream = func
    .block
    .to_token_stream()
    .into_iter()
    .map(|token| ...)

func.block = Box::new(syn::parse2::<Block>(token_stream.collect()).unwrap());

问题to_token_stream来自Quote::ToTokens返回 a proc_macro2::TokenStream,它的into_iter项目是proc_macro2::TokenTree令牌的嵌套表示。

所以对于代表的块2 + (3 + 4)

迭代器在以下单个项目上:

Group {
    delimiter: Brace,
    stream: TokenStream [
        Literal {
            kind: Integer,
            symbol: "2",
            suffix: None,
            span: #0 bytes(209..210),
        },
        Punct {
            ch: '+',
            spacing: Alone,
            span: #0 bytes(211..212),
        },
        Group {
            delimiter: Parenthesis,
            stream: TokenStream [
                Literal {
                    kind: Integer,
                    symbol: "3",
                    suffix: None,
                    span: #0 bytes(214..215),
                },
                Punct {
                    ch: '+',
                    spacing: Alone,
                    span: #0 bytes(216..217),
                },
                Literal {
                    kind: Integer,
                    symbol: "4",
                    suffix: None,
                    span: #0 bytes(218..219),
                },
            ],
            span: #0 bytes(213..220),
        },
    ],
    span: #0 bytes(203..222),
}

令牌深深嵌套在结构中的位置。

我需要一个看起来像这样的平面表示:

Literal("2")
Plus
ParenthesisOpen
Literal("3")
Plus
Literal("4")
ParenthesisClose

这可能吗?我可以写我自己的flat_mapthinh,然后map让它工作,但这是很多工作。syn 是否暴露了任何东西来做到这一点?也许我不应该syn::Block在进行转换之前将其解析为...?

4

1 回答 1

0

原来 syn 有一个可变的访问模块。您可以使用递归访问者,而不是触摸令牌流,如下所示:

use syn::{visit_mut::{self, VisitMut}, LitInt};

struct MyNumberLiteralModifier;

impl VisitMut for MyNumberLiteralModifier {
    fn visit_lit_int_mut(&mut self, node: &mut LitInt) {
        *node = LitInt::new("10", node.span());   
    }
}

MyNumberLiteralModifier.walk_block(&mut my_block);

为此,"visit-mut"必须为 syn 启用功能

于 2021-08-07T20:46:25.710 回答