Skip to content

Commit

Permalink
feat(macros): add boilerplate for type transformation. [no ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Apr 15, 2024
1 parent 7f36824 commit db59c2b
Showing 1 changed file with 33 additions and 6 deletions.
39 changes: 33 additions & 6 deletions crates/oxc_macros/src/ast_node.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use proc_macro2::TokenStream as TokenStream2;

use quote::{format_ident, quote};
use quote::{format_ident, quote, ToTokens};
use syn::{
parse_quote, punctuated::Punctuated, AttrStyle, Attribute, Field, Fields, Generics, Ident,
Item, ItemEnum, ItemStruct, Meta, Token, Variant,
parse_quote, punctuated::Punctuated, AngleBracketedGenericArguments, AttrStyle, Attribute,
Field, Fields, GenericArgument, Generics, Ident, Item, ItemEnum, ItemStruct, Meta,
PathArguments, Token, Type, Variant,
};

pub fn ast_node(mut item: Item) -> TokenStream2 {
Expand Down Expand Up @@ -36,6 +37,7 @@ pub fn ast_node(mut item: Item) -> TokenStream2 {

fn modify_struct(item: &mut ItemStruct) -> NodeData {
item.attrs.iter().for_each(validate_struct_attribute);
item.fields.iter().for_each(validate_field);
// add the correct representation
item.attrs.push(parse_quote!(#[repr(C)]));
NodeData {
Expand All @@ -52,7 +54,7 @@ fn modify_enum(item: &mut ItemEnum) -> NodeData {
item.variants.len() < 256,
"`ast_node` enums are limited to the maximum of 256 variants."
);
item.variants.iter().for_each(validate_enum_variant);
item.variants.iter().for_each(validate_variant);

// add the correct representation
item.attrs.push(parse_quote!(#[repr(C, u8)]));
Expand Down Expand Up @@ -101,7 +103,14 @@ fn validate_attribute(attr: &Attribute) {
);
}

fn validate_enum_variant(var: &Variant) {
fn validate_field(field: &Field) {
assert!(
matches!(&field.ty, Type::Path(ty) if ty.path.segments.len() == 1),
"Currently `ast_node` attribute only supports single segment type paths."
)
}

fn validate_variant(var: &Variant) {
assert_ne!(
var.ident, "Dummy",
r#"Found a variant called `Dummy`,\
Expand Down Expand Up @@ -152,7 +161,25 @@ fn transform_struct_fields(fields: &Fields) -> Punctuated<Field, Token![,]> {
}

fn transform_struct_field(field: &Field) -> Field {
let field = field.clone();
let mut field = field.clone();

let Type::Path(ty) = field.ty else {
unreachable!("Should have been asserted at this point.");
};

let ty_path_first = ty.path.segments.first().expect("already asserted");
let ty = match &ty_path_first.arguments {
PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. })
if args.iter().any(|arg| matches!(arg, GenericArgument::Lifetime(_))) =>
{
// as the rule of thumb; if a type has lifetimes we should transform it to a traversable type.
println!("Transform type here");
ty
}
_ => ty,
};

field.ty = Type::Path(ty);

field
}
Expand Down

0 comments on commit db59c2b

Please sign in to comment.