Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

validate macro input at entry point #57

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions bilge-impl/src/bitsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ struct ItemIr {
expanded: TokenStream,
}

pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
let (item, declared_bitsize) = parse(item, args);
pub(super) fn bitsize(args: TokenStream, item: Item) -> TokenStream {
let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args);
let attrs = SplitAttributes::from_item(&item);
let ir = match item {
Item::Struct(mut item) => {
Expand All @@ -33,17 +33,6 @@ pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
generate_common(ir, attrs, declared_bitsize)
}

fn parse(item: TokenStream, args: TokenStream) -> (Item, BitSize) {
let item = syn::parse2(item).unwrap_or_else(unreachable);

if args.is_empty() {
abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`")
}

let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args);
(item, declared_bitsize)
}

fn check_type_is_supported(ty: &Type) {
use Type::*;
match ty {
Expand Down
7 changes: 1 addition & 6 deletions bilge-impl/src/fmt_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{Data, DeriveInput, Fields, Variant, punctuated::Iter};

pub(crate) fn binary(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(crate) fn binary(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, bitsize, ..) = analyze(&derive_input);

match derive_data {
Expand Down Expand Up @@ -86,10 +85,6 @@ fn generate_to_int_match_arms(variants: Iter<Variant>, enum_name: &Ident, bitsiz
.collect()
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, false)
}
7 changes: 1 addition & 6 deletions bilge-impl/src/from_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use quote::quote;
use syn::{Type, Fields, DeriveInput, Data, punctuated::Iter, Variant};
use crate::shared::{fallback::Fallback, self, BitSize, unreachable, discriminant_assigner::DiscriminantAssigner, enum_fills_bitsize};

pub(super) fn from_bits(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(super) fn from_bits(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, internal_bitsize, fallback) = analyze(&derive_input);
let expanded = match &derive_data {
Data::Struct(struct_data) => {
Expand All @@ -22,10 +21,6 @@ pub(super) fn from_bits(item: TokenStream) -> TokenStream {
generate_common(expanded)
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, false)
}
Expand Down
33 changes: 23 additions & 10 deletions bilge-impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
use syn::parse_macro_input;

mod bitsize;
mod bitsize_internal;
Expand All @@ -19,15 +20,19 @@ mod shared;
#[proc_macro_error]
#[proc_macro_attribute]
pub fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
bitsize::bitsize(args.into(), item.into()).into()
let item = parse_macro_input!(item);

bitsize::bitsize(args.into(), item).into()
}

/// This is internally used, not to be used by anything besides `bitsize`.
/// No guarantees are given.
#[proc_macro_error]
#[proc_macro_attribute]
pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
bitsize_internal::bitsize_internal(args.into(), item.into()).into()
let item = parse_macro_input!(item);

bitsize_internal::bitsize_internal(args.into(), item).into()
}

/// Generate an `impl TryFrom<uN>` for unfilled bitfields.
Expand All @@ -36,8 +41,10 @@ pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
/// a struct don't fill their given `bitsize`.
#[proc_macro_error]
#[proc_macro_derive(TryFromBits, attributes(bitsize_internal, fallback))]
pub fn derive_try_from_bits(item: TokenStream) -> TokenStream {
try_from_bits::try_from_bits(item.into()).into()
pub fn derive_try_from_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

try_from_bits::try_from_bits(derive_input).into()
}

/// Generate an `impl From<uN>` for filled bitfields.
Expand All @@ -47,22 +54,28 @@ pub fn derive_try_from_bits(item: TokenStream) -> TokenStream {
/// using enums.
#[proc_macro_error]
#[proc_macro_derive(FromBits, attributes(bitsize_internal, fallback))]
pub fn derive_from_bits(item: TokenStream) -> TokenStream {
from_bits::from_bits(item.into()).into()
pub fn derive_from_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

from_bits::from_bits(derive_input).into()
}

/// Generate an `impl Debug` for bitfield structs.
///
/// Please use normal #[derive(Debug)] for enums.
#[proc_macro_error]
#[proc_macro_derive(DebugBits, attributes(bitsize_internal))]
pub fn debug_bits(item: TokenStream) -> TokenStream {
debug_bits::debug_bits(item.into()).into()
pub fn debug_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

debug_bits::debug_bits(derive_input).into()
}

/// Generate an `impl core::fmt::Binary` for bitfields.
#[proc_macro_error]
#[proc_macro_derive(BinaryBits)]
pub fn derive_binary_bits(item: TokenStream) -> TokenStream {
fmt_bits::binary(item.into()).into()
pub fn derive_binary_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

fmt_bits::binary(derive_input).into()
}
4 changes: 4 additions & 0 deletions bilge-impl/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ pub(crate) fn analyze_derive(derive_input: &DeriveInput, try_from: bool) -> (&sy

// If we want to support bitsize(u4) besides bitsize(4), do that here.
pub fn bitsize_and_arbitrary_int_from(bitsize_arg: TokenStream) -> (BitSize, TokenStream) {
if bitsize_arg.is_empty() {
abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`")
}

let bitsize: LitInt = syn::parse2(bitsize_arg.clone()).unwrap_or_else(|_|
abort!(bitsize_arg, "attribute value is not a number"; help = "you need to define the size like this: `#[bitsize(32)]`")
);
Expand Down
7 changes: 1 addition & 6 deletions bilge-impl/src/try_from_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use syn::{DeriveInput, Data, punctuated::Iter, Variant, Type, Fields};
use crate::shared::{last_ident_of_path, bitsize_from_type_ident};
use crate::shared::{fallback::Fallback, self, BitSize, unreachable, enum_fills_bitsize, discriminant_assigner::DiscriminantAssigner};

pub(super) fn try_from_bits(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(super) fn try_from_bits(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, internal_bitsize, ..) = analyze(&derive_input);
match derive_data {
Data::Struct(ref data) => {
Expand All @@ -21,10 +20,6 @@ pub(super) fn try_from_bits(item: TokenStream) -> TokenStream {
}
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, true)
}
Expand Down