0

来自Syn 文档

Syn 对proc-macro2crates.io 的 crate 提供的令牌表示进行操作,而不是直接使用编译器内置的proc-macrocrate。这使得代码可以Syn在过程宏的上下文之外执行,例如在单元测试或build.rs

我正在尝试为某些 Syn 功能启用单元测试,但是无论我尝试了什么,我都无法让它工作。它不适用于proc_macro2::TokenStream类型,但它不适用于 the,proc_macro::TokenStream因为我们不在 proc-macro 上下文中。

链接到游乐场

use quote::quote;
use syn;

fn test() {
    // let stream: syn::export::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
    let stream: proc_macro2::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
    // let item = parse_macro_input!(stream as Item); // doesn't work
    let item = syn::parse(stream).unwrap();

}

fn main() {
    test();
}

任何有关如何在 proc-macro 上下文之外测试 syn 函数的帮助将不胜感激。我知道trybuild crate,但我希望能够先对宏的功能进行单元测试。

4

1 回答 1

1

它不适用于proc_macro2::TokenStream类型,但它不适用于 the,proc_macro::TokenStream因为我们不在 proc-macro 上下文中。

是的,这就是重点!导出过程宏的 crates 不能导出其他任何东西,但proc_macro只能在导出宏的 crates 中使用。这就是为什么proc_macro2首先存在的原因。

syn您需要使用多个 crate 才能为使用and的代码编写测试proc_macro2

  • 您的公共 crate 用 etc. 声明宏,除了将 a 转换为 a#[proc_macro]外,它几乎没有做任何事情,反之亦然。proc_macro::TokenStreamproc_macro2::TokenStream
  • 一个“内部”板条箱,包含大部分实际代码,它依赖于proc_macro2但不依赖于proc_macro. 你的测试可以在这里进行。

您看到的错误是因为syn::parse接受proc_macro::TokenStream. 您可以改用syn::parse2, 除了它接受一个proc_macro2::TokenStream.

于 2020-12-12T20:22:57.477 回答