From ea408f7ab617cd210c3704bdb75b064722f13c57 Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Fri, 22 Oct 2021 15:01:40 +0100 Subject: [PATCH] Avoid parsing function bodies for a better rust-analyzer experience. --- Cargo.toml | 4 ++-- sqlxmq_macros/Cargo.toml | 7 +++--- sqlxmq_macros/src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6740ce3..763ff00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlxmq" -version = "0.3.2" +version = "0.3.3" authors = ["Diggory Blake "] edition = "2018" license = "MIT OR Apache-2.0" @@ -23,7 +23,7 @@ uuid = { version = "0.8.2", features = ["v4"] } log = "0.4.14" serde_json = "1.0.64" serde = "1.0.124" -sqlxmq_macros = { version = "0.3.2", path = "sqlxmq_macros" } +sqlxmq_macros = { version = "0.3.3", path = "sqlxmq_macros" } anymap2 = "0.13.0" [features] diff --git a/sqlxmq_macros/Cargo.toml b/sqlxmq_macros/Cargo.toml index 6b904e5..c53035e 100644 --- a/sqlxmq_macros/Cargo.toml +++ b/sqlxmq_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlxmq_macros" -version = "0.3.2" +version = "0.3.3" authors = ["Diggory Blake "] edition = "2018" license = "MIT OR Apache-2.0" @@ -14,5 +14,6 @@ documentation = "https://docs.rs/sqlxmq" proc-macro = true [dependencies] -syn = { version = "1.0.64", features = ["full"] } -quote = "1.0.9" +syn = { version = "1.0.80", features = ["full"] } +quote = "1.0.10" +proc-macro2 = "1.0.30" diff --git a/sqlxmq_macros/src/lib.rs b/sqlxmq_macros/src/lib.rs index f21071a..b0452ad 100644 --- a/sqlxmq_macros/src/lib.rs +++ b/sqlxmq_macros/src/lib.rs @@ -6,10 +6,12 @@ use std::mem; use proc_macro::TokenStream; -use quote::quote; +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens, TokenStreamExt}; use syn::{ - parse_macro_input, parse_quote, AttributeArgs, Error, ItemFn, Lit, Meta, NestedMeta, Path, - Result, Visibility, + parse::{Parse, ParseStream}, + parse_macro_input, parse_quote, AttrStyle, Attribute, AttributeArgs, Error, Lit, Meta, + NestedMeta, Path, Result, Signature, Visibility, }; #[derive(Default)] @@ -90,6 +92,44 @@ fn interpret_job_arg(options: &mut JobOptions, arg: NestedMeta) -> Result<()> { Ok(()) } +#[derive(Clone)] +struct MaybeItemFn { + attrs: Vec, + vis: Visibility, + sig: Signature, + block: TokenStream2, +} + +/// This parses a `TokenStream` into a `MaybeItemFn` +/// (just like `ItemFn`, but skips parsing the body). +impl Parse for MaybeItemFn { + fn parse(input: ParseStream<'_>) -> syn::Result { + let attrs = input.call(syn::Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + let sig: Signature = input.parse()?; + let block: TokenStream2 = input.parse()?; + Ok(Self { + attrs, + vis, + sig, + block, + }) + } +} + +impl ToTokens for MaybeItemFn { + fn to_tokens(&self, tokens: &mut TokenStream2) { + tokens.append_all( + self.attrs + .iter() + .filter(|attr| matches!(attr.style, AttrStyle::Outer)), + ); + self.vis.to_tokens(tokens); + self.sig.to_tokens(tokens); + self.block.to_tokens(tokens); + } +} + /// Marks a function as being a background job. /// /// The first argument to the function must have type `CurrentJob`. @@ -181,7 +221,7 @@ fn interpret_job_arg(options: &mut JobOptions, arg: NestedMeta) -> Result<()> { #[proc_macro_attribute] pub fn job(attr: TokenStream, item: TokenStream) -> TokenStream { let args = parse_macro_input!(attr as AttributeArgs); - let mut inner_fn = parse_macro_input!(item as ItemFn); + let mut inner_fn = parse_macro_input!(item as MaybeItemFn); let mut options = JobOptions::default(); let mut errors = Vec::new();