feat(ast): remove explicit untagged marker on enums (#6915)

This assumes that any enums with exactly one field in each variant are untagged, and they're tagged otherwise.
This commit is contained in:
ottomated 2024-10-26 08:21:40 +00:00
parent 2c7ac29ece
commit ce5b609514
8 changed files with 9 additions and 58 deletions

View file

@ -55,7 +55,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum Expression<'a> {
/// See [`BooleanLiteral`] for AST node details.
BooleanLiteral(Box<'a, BooleanLiteral>) = 0,
@ -312,7 +311,7 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged, custom_ts_def)]
#[estree(custom_ts_def)]
pub enum ArrayExpressionElement<'a> {
/// `...[3, 4]` in `const array = [1, 2, ...[3, 4], null];`
SpreadElement(Box<'a, SpreadElement<'a>>) = 64,
@ -356,7 +355,6 @@ pub struct ObjectExpression<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ObjectPropertyKind<'a> {
/// `a: 1` in `const obj = { a: 1 };`
ObjectProperty(Box<'a, ObjectProperty<'a>>) = 0,
@ -391,7 +389,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum PropertyKey<'a> {
/// `a` in `const obj = { a: 1 }; obj.a;`
StaticIdentifier(Box<'a, IdentifierName<'a>>) = 64,
@ -479,7 +476,6 @@ pub struct TemplateElementValue<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum MemberExpression<'a> {
/// `ar[0]` in `const ar = [1, 2]; ar[0];`
ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>) = 48,
@ -628,7 +624,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum Argument<'a> {
/// `...[1, 2]` in `const arr = [...[1, 2]];`
SpreadElement(Box<'a, SpreadElement<'a>>) = 64,
@ -744,7 +739,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum AssignmentTarget<'a> {
// `SimpleAssignmentTarget` variants added here by `inherit_variants!` macro
@inherit SimpleAssignmentTarget
@ -762,7 +756,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum SimpleAssignmentTarget<'a> {
AssignmentTargetIdentifier(Box<'a, IdentifierReference<'a>>) = 0,
TSAsExpression(Box<'a, TSAsExpression<'a>>) = 1,
@ -816,7 +809,6 @@ pub use match_simple_assignment_target;
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum AssignmentTargetPattern<'a> {
ArrayAssignmentTarget(Box<'a, ArrayAssignmentTarget<'a>>) = 8,
ObjectAssignmentTarget(Box<'a, ObjectAssignmentTarget<'a>>) = 9,
@ -888,7 +880,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum AssignmentTargetMaybeDefault<'a> {
AssignmentTargetWithDefault(Box<'a, AssignmentTargetWithDefault<'a>>) = 16,
// `AssignmentTarget` variants added here by `inherit_variants!` macro
@ -909,7 +900,6 @@ pub struct AssignmentTargetWithDefault<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum AssignmentTargetProperty<'a> {
AssignmentTargetPropertyIdentifier(Box<'a, AssignmentTargetPropertyIdentifier<'a>>) = 0,
AssignmentTargetPropertyProperty(Box<'a, AssignmentTargetPropertyProperty<'a>>) = 1,
@ -997,7 +987,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ChainElement<'a> {
CallExpression(Box<'a, CallExpression<'a>>) = 0,
// `MemberExpression` variants added here by `inherit_variants!` macro
@ -1027,7 +1016,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum Statement<'a> {
// Statements
BlockStatement(Box<'a, BlockStatement<'a>>) = 0,
@ -1102,7 +1090,6 @@ pub struct BlockStatement<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum Declaration<'a> {
VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 32,
#[visit(args(flags = ScopeFlags::Function))]
@ -1259,7 +1246,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ForStatementInit<'a> {
VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 64,
// `Expression` variants added here by `inherit_variants!` macro
@ -1292,7 +1278,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ForStatementLeft<'a> {
VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 16,
// `AssignmentTarget` variants added here by `inherit_variants!` macro
@ -1525,7 +1510,6 @@ pub struct BindingPattern<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum BindingPatternKind<'a> {
/// `const a = 1`
BindingIdentifier(Box<'a, BindingIdentifier<'a>>) = 0,
@ -1928,7 +1912,6 @@ pub struct ClassBody<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ClassElement<'a> {
StaticBlock(Box<'a, StaticBlock<'a>>) = 0,
/// Class Methods
@ -2150,7 +2133,6 @@ pub struct StaticBlock<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ModuleDeclaration<'a> {
/// `import hello from './world.js';`
/// `import * as t from './world.js';`
@ -2269,7 +2251,6 @@ pub struct ImportDeclaration<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ImportDeclarationSpecifier<'a> {
/// import {imported} from "source"
/// import {imported as local} from "source"
@ -2359,7 +2340,6 @@ pub struct ImportAttribute<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ImportAttributeKey<'a> {
Identifier(IdentifierName<'a>) = 0,
StringLiteral(StringLiteral<'a>) = 1,
@ -2464,7 +2444,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ExportDefaultDeclarationKind<'a> {
#[visit(args(flags = ScopeFlags::Function))]
FunctionDeclaration(Box<'a, Function<'a>>) = 64,
@ -2487,7 +2466,6 @@ pub enum ExportDefaultDeclarationKind<'a> {
#[ast(visit)]
#[derive(Debug, Clone)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum ModuleExportName<'a> {
IdentifierName(IdentifierName<'a>) = 0,
/// For `local` in `ExportSpecifier`: `foo` in `export { foo }`

View file

@ -152,7 +152,6 @@ pub struct JSXClosingFragment {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
#[estree(untagged)]
pub enum JSXElementName<'a> {
/// `<div />`
Identifier(Box<'a, JSXIdentifier<'a>>) = 0,
@ -233,7 +232,6 @@ pub struct JSXMemberExpression<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
#[estree(untagged)]
pub enum JSXMemberExpressionObject<'a> {
/// `<Apple.Orange />`
IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0,
@ -277,7 +275,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum JSXExpression<'a> {
/// An empty expression
///
@ -316,7 +313,6 @@ pub struct JSXEmptyExpression {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum JSXAttributeItem<'a> {
/// A `key="value"` attribute
Attribute(Box<'a, JSXAttribute<'a>>) = 0,
@ -386,7 +382,6 @@ pub struct JSXSpreadAttribute<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum JSXAttributeName<'a> {
/// An attribute name without a namespace prefix, e.g. `foo` in `foo="bar"`.
Identifier(Box<'a, JSXIdentifier<'a>>) = 0,
@ -415,7 +410,6 @@ pub enum JSXAttributeName<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum JSXAttributeValue<'a> {
/// `<Component foo="bar" />`
StringLiteral(Box<'a, StringLiteral<'a>>) = 0,
@ -451,7 +445,6 @@ pub struct JSXIdentifier<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum JSXChild<'a> {
/// `<Foo>Some Text</Foo>`
Text(Box<'a, JSXText<'a>>) = 0,

View file

@ -115,7 +115,6 @@ pub struct RegExp<'a> {
#[ast]
#[derive(Debug)]
#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum RegExpPattern<'a> {
/// Unparsed pattern. Contains string slice of the pattern.
/// Pattern was not parsed, so may be valid or invalid.

View file

@ -114,7 +114,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSEnumMemberName<'a> {
StaticIdentifier(Box<'a, IdentifierName<'a>>) = 64,
StaticStringLiteral(Box<'a, StringLiteral<'a>>) = 65,
@ -177,7 +176,6 @@ pub struct TSLiteralType<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSLiteral<'a> {
BooleanLiteral(Box<'a, BooleanLiteral>) = 0,
NullLiteral(Box<'a, NullLiteral>) = 1,
@ -203,7 +201,6 @@ pub enum TSLiteral<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSType<'a> {
// Keyword
TSAnyKeyword(Box<'a, TSAnyKeyword>) = 0,
@ -545,7 +542,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSTupleElement<'a> {
// Discriminants start at 64, so that `TSTupleElement::is_ts_type` is a single
// bitwise AND operation on the discriminant (`discriminant & 63 != 0`).
@ -781,7 +777,6 @@ pub struct TSTypeReference<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSTypeName<'a> {
IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0,
QualifiedName(Box<'a, TSQualifiedName<'a>>) = 1,
@ -1003,7 +998,6 @@ pub struct TSPropertySignature<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSSignature<'a> {
TSIndexSignature(Box<'a, TSIndexSignature<'a>>) = 0,
TSPropertySignature(Box<'a, TSPropertySignature<'a>>) = 1,
@ -1165,7 +1159,6 @@ pub struct TSTypePredicate<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSTypePredicateName<'a> {
Identifier(Box<'a, IdentifierName<'a>>) = 0,
This(TSThisType) = 1,
@ -1269,7 +1262,6 @@ pub enum TSModuleDeclarationKind {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSModuleDeclarationName<'a> {
Identifier(BindingIdentifier<'a>) = 0,
StringLiteral(StringLiteral<'a>) = 1,
@ -1278,7 +1270,6 @@ pub enum TSModuleDeclarationName<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSModuleDeclarationBody<'a> {
TSModuleDeclaration(Box<'a, TSModuleDeclaration<'a>>) = 0,
TSModuleBlock(Box<'a, TSModuleBlock<'a>>) = 1,
@ -1357,7 +1348,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSTypeQueryExprName<'a> {
TSImportType(Box<'a, TSImportType<'a>>) = 2,
// `TSTypeName` variants added here by `inherit_variants!` macro
@ -1402,7 +1392,6 @@ pub struct TSImportAttribute<'a> {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSImportAttributeName<'a> {
Identifier(IdentifierName<'a>) = 0,
StringLiteral(StringLiteral<'a>) = 1,
@ -1623,7 +1612,6 @@ inherit_variants! {
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum TSModuleReference<'a> {
ExternalModuleReference(Box<'a, TSExternalModuleReference<'a>>) = 2,
// `TSTypeName` variants added here by `inherit_variants!` macro

View file

@ -37,7 +37,6 @@ pub struct Alternative<'a> {
#[ast]
#[derive(Debug)]
#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum Term<'a> {
// Assertion, QuantifiableAssertion
BoundaryAssertion(Box<'a, BoundaryAssertion>) = 0,
@ -246,7 +245,6 @@ pub enum CharacterClassContentsKind {
#[ast]
#[derive(Debug)]
#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)]
#[estree(untagged)]
pub enum CharacterClassContents<'a> {
CharacterClassRange(Box<'a, CharacterClassRange>) = 0,
CharacterClassEscape(Box<'a, CharacterClassEscape>) = 1,

View file

@ -117,10 +117,12 @@ fn serialize_struct(def: &StructDef) -> TokenStream {
// 3. All other enums, which are camelCased.
fn serialize_enum(def: &EnumDef) -> TokenStream {
let ident = def.ident();
if def.markers.estree.untagged {
let is_untagged = def.all_variants().all(|var| var.fields.len() == 1);
if is_untagged {
let match_branches = def.all_variants().map(|var| {
let var_ident = var.ident();
assert!(var.fields.len() == 1, "Each variant of an untagged enum must have exactly one inner field (on {ident}::{var_ident})");
quote! {
#ident::#var_ident(x) => {
Serialize::serialize(x, serializer)

View file

@ -48,7 +48,9 @@ fn typescript_enum(def: &EnumDef) -> Option<String> {
return None;
}
let union = if def.markers.estree.untagged {
let is_untagged = def.all_variants().all(|var| var.fields.len() == 1);
let union = if is_untagged {
def.all_variants().map(|var| type_to_string(var.fields[0].typ.name())).join(" | ")
} else {
def.all_variants().map(|var| format!("'{}'", enum_variant_name(var, def))).join(" | ")

View file

@ -125,14 +125,12 @@ impl Parse for ESTreeStructAttribute {
#[derive(Debug, Serialize, Default)]
pub struct ESTreeEnumAttribute {
pub rename_all: Option<String>,
pub untagged: bool,
pub custom_ts_def: bool,
}
impl Parse for ESTreeEnumAttribute {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
let mut rename_all = None;
let mut untagged = false;
let mut custom_ts_def = false;
loop {
@ -145,13 +143,6 @@ impl Parse for ESTreeEnumAttribute {
"Duplicate estree(rename_all)"
);
}
"untagged" => {
if untagged {
panic!("Duplicate estree(untagged)");
} else {
untagged = true;
}
}
"custom_ts_def" => {
if custom_ts_def {
panic!("Duplicate estree(custom_ts_def)");
@ -168,7 +159,7 @@ impl Parse for ESTreeEnumAttribute {
break;
}
}
Ok(Self { rename_all, untagged, custom_ts_def })
Ok(Self { rename_all, custom_ts_def })
}
}