Skip to content

Commit

Permalink
feat: add dummy variants to the enum ast nodes. [no ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Apr 15, 2024
1 parent add6be0 commit 4790898
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 20 deletions.
5 changes: 5 additions & 0 deletions crates/oxc_ast/src/ast_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ macro_rules! ast_kinds {
{ $($ident:ident($type:ty),)* } => (
#[derive(Debug, Clone, Copy)]
pub enum AstType {
Dummy,
$($ident,)*
}

/// Untyped AST Node Kind
#[derive(Debug, Clone, Copy)]
pub enum AstKind<'a> {
Dummy,
$($ident($type),)*
}
)
Expand Down Expand Up @@ -307,6 +309,7 @@ impl<'a> AstKind<'a> {

pub fn from_expression(e: &'a Expression<'a>) -> Self {
match e {
Expression::Dummy => Self::Dummy,
Expression::BooleanLiteral(e) => Self::BooleanLiteral(e),
Expression::NullLiteral(e) => Self::NullLiteral(e),
Expression::NumericLiteral(e) => Self::NumericLiteral(e),
Expand Down Expand Up @@ -355,6 +358,7 @@ impl<'a> GetSpan for AstKind<'a> {
#[allow(clippy::match_same_arms)]
fn span(&self) -> Span {
match self {
Self::Dummy => Span::default(),
Self::Program(x) => x.span,
Self::Directive(x) => x.span,
Self::Hashbang(x) => x.span,
Expand Down Expand Up @@ -732,6 +736,7 @@ impl<'a> AstKind<'a> {
Self::TSNamedTupleMember(_) => "TSNamedTupleMember".into(),

Self::TSPropertySignature(_) => "TSPropertySignature".into(),
Self::Dummy => "Dummy".into(),
}
}
}
1 change: 1 addition & 0 deletions crates/oxc_ast/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl<'a> GetSpan for Expression<'a> {
Self::TSTypeAssertion(e) => e.span,
Self::TSNonNullExpression(e) => e.span,
Self::TSInstantiationExpression(e) => e.span,
Self::Dummy => Span::default(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_ast/src/visit/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@ pub mod walk {
Expression::TSInstantiationExpression(expr) => {
visitor.visit_ts_instantiation_expression(expr);
}
Expression::Dummy => { /* ignore */ }
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/oxc_ast/src/visit/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ pub mod walk_mut {
Expression::TSInstantiationExpression(expr) => {
visitor.visit_ts_instantiation_expression(expr);
}
Expression::Dummy => { /* ignore */ }
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for Expression<'a> {
Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx),
Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSInstantiationExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::Dummy => unreachable!("Dummy should never reach the Codegen."),
}
}
}
Expand Down
47 changes: 27 additions & 20 deletions crates/oxc_macros/src/ast_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{
parse_quote, punctuated::Punctuated, Attribute, Generics, Ident, Item, ItemEnum, ItemStruct,
Meta, Token,
Meta, Token, Variant,
};

pub fn ast_node(mut item: Item) -> TokenStream2 {
Expand All @@ -24,57 +24,64 @@ pub fn ast_node(mut item: Item) -> TokenStream2 {
}

fn modify_struct(item: &mut ItemStruct) -> NodeData {
validate_struct_attributes(&item.attrs);
item.attrs.iter().for_each(validate_struct_attribute);
// add the correct representation
item.attrs.push(parse_quote!(#[repr(C)]));
NodeData { ident: &item.ident, generics: &item.generics }
}

fn modify_enum(item: &mut ItemEnum) -> NodeData {
validate_enum_attributes(&item.attrs);
item.attrs.iter().for_each(validate_enum_attribute);
item.variants.iter().for_each(validate_enum_variant);
// add the correct representation
item.attrs.push(parse_quote!(#[repr(C, u8)]));
// add the dummy variant
item.variants.insert(0, parse_quote!(Dummy));
NodeData { ident: &item.ident, generics: &item.generics }
}

fn validate_struct_attributes<I>(attrs: &I)
where
for<'a> &'a I: IntoIterator<Item = &'a Attribute>,
{
// validators

fn validate_struct_attribute(attr: &Attribute) {
// make sure that no structure derives Clone/Copy traits.
// TODO: It will fail if there is a manual Clone/Copy traits implemented for the struct.
// Negative traits (!Copy and !Clone) are nightly so I'm not sure how we can fully enforce it.
assert!(
!attrs.into_iter().any(|attr| {
!{
let args = attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated);
attr.path().is_ident("derive")
&& args.is_ok_and(|args| {
args.iter()
.any(|arg| arg.path().is_ident("Clone") || arg.path().is_ident("Copy"))
})
}),
},
"`ast_node` can't have Clone or Copy traits"
);

validate_attributes(attrs);
validate_attribute(attr);
}

fn validate_enum_attributes<I>(attrs: &I)
where
for<'a> &'a I: IntoIterator<Item = &'a Attribute>,
{
fn validate_enum_attribute(attr: &Attribute) {
// TODO: Later on we may want to enforce deriving clone and copy traits for all enum types
validate_attributes(attrs);
validate_attribute(attr);
}

fn validate_attributes<I>(attrs: &I)
where
for<'a> &'a I: IntoIterator<Item = &'a Attribute>,
{
fn validate_attribute(attr: &Attribute) {
assert!(
!attrs.into_iter().any(|attr| attr.path().is_ident("repr")),
!attr.path().is_ident("repr"),
"using `repr` attribute is not allowed with `ast_node`."
);
}

fn validate_enum_variant(var: &Variant) {
assert_ne!(
var.ident, "Dummy",
r#"Found a variant called `Dummy`,\
Please use another name,\
This variant identifier is reserved by `ast_node` attribute."#
);
}

fn impl_traversable_test_trait(node: &NodeData) -> TokenStream2 {
let ident = node.ident;
let generics = node.generics;
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_prettier/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,7 @@ impl<'a> Format<'a> for Expression<'a> {
Self::TSTypeAssertion(expr) => expr.expression.format(p),
Self::TSNonNullExpression(expr) => expr.expression.format(p),
Self::TSInstantiationExpression(expr) => expr.expression.format(p),
Self::Dummy => unreachable!("Dummy should never reach the Format."),
}
}
}
Expand Down

0 comments on commit 4790898

Please sign in to comment.