Auto-completion in function like procedural macro

I am not good at English. Sorry if there are any funny expressions.

Background

Today I am creating my first procedural macro.
(In my opinion, macro is useful but fearful, and procedural macro is more :fearful:)
(IDE is not responding due to my infinite loop bug :skull:)

At my first attempt, auto-completion did not work within block of my macro.
(I am very forgetful. So, I cannot live without IDE and auto-completion🦮)

Solution?

After struggling a while, I found following rules.
(Inspired by tips about other than block.)

  • Avoid errors where auto-completion is expected.
  • Instead, output the code as it is entered.

Finally, I wrote the following code.
This code simply executes the given block.

- macros/src/lib.rs

use proc_macro as pm;
use proc_macro2::TokenStream;
use quote::quote;
use syn::parse::{ParseStream, Parser};
use syn::{braced, Error, Result, Stmt};

#[proc_macro]
pub fn exec_block(input: pm::TokenStream) -> pm::TokenStream {
    exec_block_impl(input.into()).into()
}

fn exec_block_impl(input: TokenStream) -> TokenStream {
    exec_block_parse
        .parse2(input)
        .unwrap_or_else(Error::into_compile_error)
}

fn exec_block_parse(input: ParseStream) -> Result<TokenStream> {
    let mut result = TokenStream::new();
    let content;
    braced!(content in input);
    while !content.is_empty() {
        let orig = content.fork().cursor().token_stream();
        let stmt = content.parse::<Stmt>();
        let trns = stmt.as_ref().map_or(orig, |x| quote! {#x});

        result.extend(trns);

        if stmt.is_err() {
            break;
        }
    }

    Ok(result)
}

- app/src/main.rs

use macros::exec_block;

fn main() {
    let vec = vec!["Hello", "procedural", "macro"];
    exec_block!({
        let pos = 2;
        // Input this code manually for auto-completion test.
        assert_eq!(vec[pos].len(), 5);
    });
}

My question.

Is this solution reasonable?
(When I am not feeling good in my code, I look for similar code by experts to reassure myself.)
(But in this case, I can't find any similar code when I Google the code fragment...)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.