From 2b0a69fb6b1bab1f90b2c1aa507d4d0611ef42dc Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Fri, 16 May 2025 03:43:22 +0000 Subject: [PATCH] perf(ast): re-order struct fields to reduce padding (#11056) All our AST structs are `#[repr(C)]`, which gives us guaranteed stable memory layouts. This is essential for raw transfer, and helpful for other purposes too. However, the downside is that we lose out on the automatic field-reordering that default `#[repr(Rust)]` provides, where structs are packed to minimize padding bytes. This PR implements a similar field-reordering scheme, to get the same effect. * `oxc_ast_tools` determines optimal field order for compact memory layout. * `oxc_ast_tools` generates a file (`structs.rs`) which details the desired field order for each type. * `#[ast]` proc macro follows the instructions in `structs.rs` and re-orders the fields. This reduces the size of various AST types by 8 bytes. No type now has more than 7 padding bytes (previously e.g. `Function` had 15 bytes of padding). Possible future improvements: 1. Get Rust Analyser to display original field order. 2. Remove `syn` dependency from `oxc_ast_macros` crate, to improve compile times. It should be possible to do all the AST manipulation using just `proc_macro` crate, by generating more code in `oxc_ast_tools`, so the macro's logic can be simpler. Note: This PR doesn't add `syn` dependency, it was already there. But it makes it easier to remove it. --- .github/generated/ast_changes_watch_list.yml | 1 + Cargo.lock | 12 + Cargo.toml | 1 + .../oxc_ast/src/generated/assert_layouts.rs | 664 +++++++++--------- crates/oxc_ast/src/generated/ast_builder.rs | 2 +- crates/oxc_ast/src/generated/derive_dummy.rs | 4 +- crates/oxc_ast_macros/Cargo.toml | 1 + crates/oxc_ast_macros/src/ast.rs | 107 ++- .../oxc_ast_macros/src/generated/structs.rs | 302 ++++++++ crates/oxc_ast_macros/src/lib.rs | 8 +- .../src/generated/assert_layouts.rs | 72 +- .../src/generated/assert_layouts.rs | 16 +- crates/oxc_syntax/src/module_record.rs | 2 +- napi/parser/generated/deserialize/js.js | 234 +++--- napi/parser/generated/deserialize/ts.js | 300 ++++---- napi/parser/src/generated/assert_layouts.rs | 52 +- tasks/ast_tools/Cargo.toml | 1 + .../src/generators/assert_layouts.rs | 196 +++++- tasks/ast_tools/src/generators/ast_builder.rs | 2 +- 19 files changed, 1263 insertions(+), 714 deletions(-) create mode 100644 crates/oxc_ast_macros/src/generated/structs.rs diff --git a/.github/generated/ast_changes_watch_list.yml b/.github/generated/ast_changes_watch_list.yml index 2da86ae011ebe..96738fe0fefb0 100644 --- a/.github/generated/ast_changes_watch_list.yml +++ b/.github/generated/ast_changes_watch_list.yml @@ -27,6 +27,7 @@ src: - 'crates/oxc_ast/src/serialize/mod.rs' - 'crates/oxc_ast/src/serialize/ts.rs' - 'crates/oxc_ast_macros/src/generated/derived_traits.rs' + - 'crates/oxc_ast_macros/src/generated/structs.rs' - 'crates/oxc_ast_macros/src/lib.rs' - 'crates/oxc_ast_visit/src/generated/utf8_to_utf16_converter.rs' - 'crates/oxc_ast_visit/src/generated/visit.rs' diff --git a/Cargo.lock b/Cargo.lock index 3d87fbfbea202..5062406e6932e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1551,6 +1551,7 @@ dependencies = [ name = "oxc_ast_macros" version = "0.70.0" dependencies = [ + "phf", "proc-macro2", "quote", "syn", @@ -1569,6 +1570,7 @@ dependencies = [ "lazy-regex", "oxc_index", "phf", + "phf_codegen", "prettyplease", "proc-macro2", "quote", @@ -2361,6 +2363,16 @@ dependencies = [ "phf_shared", ] +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + [[package]] name = "phf_generator" version = "0.11.3" diff --git a/Cargo.toml b/Cargo.toml index b2bf6646e22f3..1306a2851b596 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -205,6 +205,7 @@ num-traits = "0.2.19" papaya = "0.2.1" petgraph = { version = "0.8.1", default-features = false } phf = "0.11.3" +phf_codegen = "0.11.3" pico-args = "0.5.0" prettyplease = "0.2.32" project-root = "0.2.2" diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index 2bc0ec25352c7..a1f095f74b418 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -9,17 +9,17 @@ use crate::ast::*; #[cfg(target_pointer_width = "64")] const _: () = { - // Padding: 9 bytes - assert!(size_of::() == 136); + // Padding: 1 bytes + assert!(size_of::() == 128); assert!(align_of::() == 8); assert!(offset_of!(Program, span) == 0); - assert!(offset_of!(Program, source_type) == 8); - assert!(offset_of!(Program, source_text) == 16); - assert!(offset_of!(Program, comments) == 32); - assert!(offset_of!(Program, hashbang) == 56); - assert!(offset_of!(Program, directives) == 80); - assert!(offset_of!(Program, body) == 104); - assert!(offset_of!(Program, scope_id) == 128); + assert!(offset_of!(Program, source_type) == 124); + assert!(offset_of!(Program, source_text) == 8); + assert!(offset_of!(Program, comments) == 24); + assert!(offset_of!(Program, hashbang) == 48); + assert!(offset_of!(Program, directives) == 72); + assert!(offset_of!(Program, body) == 96); + assert!(offset_of!(Program, scope_id) == 120); assert!(size_of::() == 16); assert!(align_of::() == 8); @@ -78,16 +78,16 @@ const _: () = { assert!(size_of::() == 16); assert!(align_of::() == 8); - // Padding: 12 bytes - assert!(size_of::() == 56); + // Padding: 4 bytes + assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(ObjectProperty, span) == 0); - assert!(offset_of!(ObjectProperty, kind) == 8); - assert!(offset_of!(ObjectProperty, key) == 16); - assert!(offset_of!(ObjectProperty, value) == 32); - assert!(offset_of!(ObjectProperty, method) == 48); - assert!(offset_of!(ObjectProperty, shorthand) == 49); - assert!(offset_of!(ObjectProperty, computed) == 50); + assert!(offset_of!(ObjectProperty, kind) == 40); + assert!(offset_of!(ObjectProperty, key) == 8); + assert!(offset_of!(ObjectProperty, value) == 24); + assert!(offset_of!(ObjectProperty, method) == 41); + assert!(offset_of!(ObjectProperty, shorthand) == 42); + assert!(offset_of!(ObjectProperty, computed) == 43); assert!(size_of::() == 16); assert!(align_of::() == 8); @@ -190,24 +190,24 @@ const _: () = { assert!(size_of::() == 32); assert!(align_of::() == 8); assert!(offset_of!(UpdateExpression, span) == 0); - assert!(offset_of!(UpdateExpression, operator) == 8); - assert!(offset_of!(UpdateExpression, prefix) == 9); - assert!(offset_of!(UpdateExpression, argument) == 16); + assert!(offset_of!(UpdateExpression, operator) == 24); + assert!(offset_of!(UpdateExpression, prefix) == 25); + assert!(offset_of!(UpdateExpression, argument) == 8); // Padding: 7 bytes assert!(size_of::() == 32); assert!(align_of::() == 8); assert!(offset_of!(UnaryExpression, span) == 0); - assert!(offset_of!(UnaryExpression, operator) == 8); - assert!(offset_of!(UnaryExpression, argument) == 16); + assert!(offset_of!(UnaryExpression, operator) == 24); + assert!(offset_of!(UnaryExpression, argument) == 8); // Padding: 7 bytes assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(BinaryExpression, span) == 0); assert!(offset_of!(BinaryExpression, left) == 8); - assert!(offset_of!(BinaryExpression, operator) == 24); - assert!(offset_of!(BinaryExpression, right) == 32); + assert!(offset_of!(BinaryExpression, operator) == 40); + assert!(offset_of!(BinaryExpression, right) == 24); // Padding: 0 bytes assert!(size_of::() == 48); @@ -221,8 +221,8 @@ const _: () = { assert!(align_of::() == 8); assert!(offset_of!(LogicalExpression, span) == 0); assert!(offset_of!(LogicalExpression, left) == 8); - assert!(offset_of!(LogicalExpression, operator) == 24); - assert!(offset_of!(LogicalExpression, right) == 32); + assert!(offset_of!(LogicalExpression, operator) == 40); + assert!(offset_of!(LogicalExpression, right) == 24); // Padding: 0 bytes assert!(size_of::() == 56); @@ -236,9 +236,9 @@ const _: () = { assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(AssignmentExpression, span) == 0); - assert!(offset_of!(AssignmentExpression, operator) == 8); - assert!(offset_of!(AssignmentExpression, left) == 16); - assert!(offset_of!(AssignmentExpression, right) == 32); + assert!(offset_of!(AssignmentExpression, operator) == 40); + assert!(offset_of!(AssignmentExpression, left) == 8); + assert!(offset_of!(AssignmentExpression, right) == 24); assert!(size_of::() == 16); assert!(align_of::() == 8); @@ -355,25 +355,25 @@ const _: () = { assert!(size_of::() == 16); assert!(align_of::() == 8); - // Padding: 14 bytes - assert!(size_of::() == 48); + // Padding: 6 bytes + assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(VariableDeclaration, span) == 0); - assert!(offset_of!(VariableDeclaration, kind) == 8); - assert!(offset_of!(VariableDeclaration, declarations) == 16); - assert!(offset_of!(VariableDeclaration, declare) == 40); + assert!(offset_of!(VariableDeclaration, kind) == 32); + assert!(offset_of!(VariableDeclaration, declarations) == 8); + assert!(offset_of!(VariableDeclaration, declare) == 33); assert!(size_of::() == 1); assert!(align_of::() == 1); - // Padding: 14 bytes - assert!(size_of::() == 72); + // Padding: 6 bytes + assert!(size_of::() == 64); assert!(align_of::() == 8); assert!(offset_of!(VariableDeclarator, span) == 0); - assert!(offset_of!(VariableDeclarator, kind) == 8); - assert!(offset_of!(VariableDeclarator, id) == 16); - assert!(offset_of!(VariableDeclarator, init) == 48); - assert!(offset_of!(VariableDeclarator, definite) == 64); + assert!(offset_of!(VariableDeclarator, kind) == 56); + assert!(offset_of!(VariableDeclarator, id) == 8); + assert!(offset_of!(VariableDeclarator, init) == 40); + assert!(offset_of!(VariableDeclarator, definite) == 57); // Padding: 0 bytes assert!(size_of::() == 8); @@ -433,15 +433,15 @@ const _: () = { assert!(size_of::() == 16); assert!(align_of::() == 8); - // Padding: 11 bytes - assert!(size_of::() == 72); + // Padding: 3 bytes + assert!(size_of::() == 64); assert!(align_of::() == 8); assert!(offset_of!(ForOfStatement, span) == 0); - assert!(offset_of!(ForOfStatement, r#await) == 8); - assert!(offset_of!(ForOfStatement, left) == 16); - assert!(offset_of!(ForOfStatement, right) == 32); - assert!(offset_of!(ForOfStatement, body) == 48); - assert!(offset_of!(ForOfStatement, scope_id) == 64); + assert!(offset_of!(ForOfStatement, r#await) == 60); + assert!(offset_of!(ForOfStatement, left) == 8); + assert!(offset_of!(ForOfStatement, right) == 24); + assert!(offset_of!(ForOfStatement, body) == 40); + assert!(offset_of!(ForOfStatement, scope_id) == 56); // Padding: 0 bytes assert!(size_of::() == 32); @@ -569,22 +569,22 @@ const _: () = { assert!(offset_of!(BindingRestElement, span) == 0); assert!(offset_of!(BindingRestElement, argument) == 8); - // Padding: 15 bytes - assert!(size_of::() == 104); + // Padding: 7 bytes + assert!(size_of::() == 96); assert!(align_of::() == 8); assert!(offset_of!(Function, span) == 0); - assert!(offset_of!(Function, r#type) == 8); - assert!(offset_of!(Function, id) == 16); - assert!(offset_of!(Function, generator) == 48); - assert!(offset_of!(Function, r#async) == 49); - assert!(offset_of!(Function, declare) == 50); - assert!(offset_of!(Function, type_parameters) == 56); - assert!(offset_of!(Function, this_param) == 64); - assert!(offset_of!(Function, params) == 72); - assert!(offset_of!(Function, return_type) == 80); - assert!(offset_of!(Function, body) == 88); - assert!(offset_of!(Function, scope_id) == 96); - assert!(offset_of!(Function, pure) == 100); + assert!(offset_of!(Function, r#type) == 84); + assert!(offset_of!(Function, id) == 8); + assert!(offset_of!(Function, generator) == 85); + assert!(offset_of!(Function, r#async) == 86); + assert!(offset_of!(Function, declare) == 87); + assert!(offset_of!(Function, type_parameters) == 40); + assert!(offset_of!(Function, this_param) == 48); + assert!(offset_of!(Function, params) == 56); + assert!(offset_of!(Function, return_type) == 64); + assert!(offset_of!(Function, body) == 72); + assert!(offset_of!(Function, scope_id) == 80); + assert!(offset_of!(Function, pure) == 88); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -593,9 +593,9 @@ const _: () = { assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(FormalParameters, span) == 0); - assert!(offset_of!(FormalParameters, kind) == 8); - assert!(offset_of!(FormalParameters, items) == 16); - assert!(offset_of!(FormalParameters, rest) == 40); + assert!(offset_of!(FormalParameters, kind) == 40); + assert!(offset_of!(FormalParameters, items) == 8); + assert!(offset_of!(FormalParameters, rest) == 32); // Padding: 5 bytes assert!(size_of::() == 72); @@ -617,41 +617,41 @@ const _: () = { assert!(offset_of!(FunctionBody, directives) == 8); assert!(offset_of!(FunctionBody, statements) == 32); - // Padding: 9 bytes - assert!(size_of::() == 56); + // Padding: 1 bytes + assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(ArrowFunctionExpression, span) == 0); - assert!(offset_of!(ArrowFunctionExpression, expression) == 8); - assert!(offset_of!(ArrowFunctionExpression, r#async) == 9); - assert!(offset_of!(ArrowFunctionExpression, type_parameters) == 16); - assert!(offset_of!(ArrowFunctionExpression, params) == 24); - assert!(offset_of!(ArrowFunctionExpression, return_type) == 32); - assert!(offset_of!(ArrowFunctionExpression, body) == 40); - assert!(offset_of!(ArrowFunctionExpression, scope_id) == 48); - assert!(offset_of!(ArrowFunctionExpression, pure) == 52); + assert!(offset_of!(ArrowFunctionExpression, expression) == 44); + assert!(offset_of!(ArrowFunctionExpression, r#async) == 45); + assert!(offset_of!(ArrowFunctionExpression, type_parameters) == 8); + assert!(offset_of!(ArrowFunctionExpression, params) == 16); + assert!(offset_of!(ArrowFunctionExpression, return_type) == 24); + assert!(offset_of!(ArrowFunctionExpression, body) == 32); + assert!(offset_of!(ArrowFunctionExpression, scope_id) == 40); + assert!(offset_of!(ArrowFunctionExpression, pure) == 46); // Padding: 7 bytes assert!(size_of::() == 32); assert!(align_of::() == 8); assert!(offset_of!(YieldExpression, span) == 0); - assert!(offset_of!(YieldExpression, delegate) == 8); - assert!(offset_of!(YieldExpression, argument) == 16); + assert!(offset_of!(YieldExpression, delegate) == 24); + assert!(offset_of!(YieldExpression, argument) == 8); - // Padding: 9 bytes - assert!(size_of::() == 144); + // Padding: 1 bytes + assert!(size_of::() == 136); assert!(align_of::() == 8); assert!(offset_of!(Class, span) == 0); - assert!(offset_of!(Class, r#type) == 8); - assert!(offset_of!(Class, decorators) == 16); - assert!(offset_of!(Class, id) == 40); - assert!(offset_of!(Class, type_parameters) == 72); - assert!(offset_of!(Class, super_class) == 80); - assert!(offset_of!(Class, super_type_arguments) == 96); - assert!(offset_of!(Class, implements) == 104); - assert!(offset_of!(Class, body) == 128); - assert!(offset_of!(Class, r#abstract) == 136); - assert!(offset_of!(Class, declare) == 137); - assert!(offset_of!(Class, scope_id) == 140); + assert!(offset_of!(Class, r#type) == 132); + assert!(offset_of!(Class, decorators) == 8); + assert!(offset_of!(Class, id) == 32); + assert!(offset_of!(Class, type_parameters) == 64); + assert!(offset_of!(Class, super_class) == 72); + assert!(offset_of!(Class, super_type_arguments) == 88); + assert!(offset_of!(Class, implements) == 96); + assert!(offset_of!(Class, body) == 120); + assert!(offset_of!(Class, r#abstract) == 133); + assert!(offset_of!(Class, declare) == 134); + assert!(offset_of!(Class, scope_id) == 128); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -665,20 +665,20 @@ const _: () = { assert!(size_of::() == 16); assert!(align_of::() == 8); - // Padding: 9 bytes - assert!(size_of::() == 72); + // Padding: 1 bytes + assert!(size_of::() == 64); assert!(align_of::() == 8); assert!(offset_of!(MethodDefinition, span) == 0); - assert!(offset_of!(MethodDefinition, r#type) == 8); - assert!(offset_of!(MethodDefinition, decorators) == 16); - assert!(offset_of!(MethodDefinition, key) == 40); - assert!(offset_of!(MethodDefinition, value) == 56); - assert!(offset_of!(MethodDefinition, kind) == 64); - assert!(offset_of!(MethodDefinition, computed) == 65); - assert!(offset_of!(MethodDefinition, r#static) == 66); - assert!(offset_of!(MethodDefinition, r#override) == 67); - assert!(offset_of!(MethodDefinition, optional) == 68); - assert!(offset_of!(MethodDefinition, accessibility) == 69); + assert!(offset_of!(MethodDefinition, r#type) == 56); + assert!(offset_of!(MethodDefinition, decorators) == 8); + assert!(offset_of!(MethodDefinition, key) == 32); + assert!(offset_of!(MethodDefinition, value) == 48); + assert!(offset_of!(MethodDefinition, kind) == 57); + assert!(offset_of!(MethodDefinition, computed) == 58); + assert!(offset_of!(MethodDefinition, r#static) == 59); + assert!(offset_of!(MethodDefinition, r#override) == 60); + assert!(offset_of!(MethodDefinition, optional) == 61); + assert!(offset_of!(MethodDefinition, accessibility) == 62); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -687,19 +687,19 @@ const _: () = { assert!(size_of::() == 88); assert!(align_of::() == 8); assert!(offset_of!(PropertyDefinition, span) == 0); - assert!(offset_of!(PropertyDefinition, r#type) == 8); - assert!(offset_of!(PropertyDefinition, decorators) == 16); - assert!(offset_of!(PropertyDefinition, key) == 40); - assert!(offset_of!(PropertyDefinition, type_annotation) == 56); - assert!(offset_of!(PropertyDefinition, value) == 64); - assert!(offset_of!(PropertyDefinition, computed) == 80); - assert!(offset_of!(PropertyDefinition, r#static) == 81); - assert!(offset_of!(PropertyDefinition, declare) == 82); - assert!(offset_of!(PropertyDefinition, r#override) == 83); - assert!(offset_of!(PropertyDefinition, optional) == 84); - assert!(offset_of!(PropertyDefinition, definite) == 85); - assert!(offset_of!(PropertyDefinition, readonly) == 86); - assert!(offset_of!(PropertyDefinition, accessibility) == 87); + assert!(offset_of!(PropertyDefinition, r#type) == 72); + assert!(offset_of!(PropertyDefinition, decorators) == 8); + assert!(offset_of!(PropertyDefinition, key) == 32); + assert!(offset_of!(PropertyDefinition, type_annotation) == 48); + assert!(offset_of!(PropertyDefinition, value) == 56); + assert!(offset_of!(PropertyDefinition, computed) == 73); + assert!(offset_of!(PropertyDefinition, r#static) == 74); + assert!(offset_of!(PropertyDefinition, declare) == 75); + assert!(offset_of!(PropertyDefinition, r#override) == 76); + assert!(offset_of!(PropertyDefinition, optional) == 77); + assert!(offset_of!(PropertyDefinition, definite) == 78); + assert!(offset_of!(PropertyDefinition, readonly) == 79); + assert!(offset_of!(PropertyDefinition, accessibility) == 80); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -726,20 +726,20 @@ const _: () = { assert!(size_of::() == 1); assert!(align_of::() == 1); - // Padding: 10 bytes - assert!(size_of::() == 88); + // Padding: 2 bytes + assert!(size_of::() == 80); assert!(align_of::() == 8); assert!(offset_of!(AccessorProperty, span) == 0); - assert!(offset_of!(AccessorProperty, r#type) == 8); - assert!(offset_of!(AccessorProperty, decorators) == 16); - assert!(offset_of!(AccessorProperty, key) == 40); - assert!(offset_of!(AccessorProperty, type_annotation) == 56); - assert!(offset_of!(AccessorProperty, value) == 64); - assert!(offset_of!(AccessorProperty, computed) == 80); - assert!(offset_of!(AccessorProperty, r#static) == 81); - assert!(offset_of!(AccessorProperty, r#override) == 82); - assert!(offset_of!(AccessorProperty, definite) == 83); - assert!(offset_of!(AccessorProperty, accessibility) == 84); + assert!(offset_of!(AccessorProperty, r#type) == 72); + assert!(offset_of!(AccessorProperty, decorators) == 8); + assert!(offset_of!(AccessorProperty, key) == 32); + assert!(offset_of!(AccessorProperty, type_annotation) == 48); + assert!(offset_of!(AccessorProperty, value) == 56); + assert!(offset_of!(AccessorProperty, computed) == 73); + assert!(offset_of!(AccessorProperty, r#static) == 74); + assert!(offset_of!(AccessorProperty, r#override) == 75); + assert!(offset_of!(AccessorProperty, definite) == 76); + assert!(offset_of!(AccessorProperty, accessibility) == 77); // Padding: 7 bytes assert!(size_of::() == 48); @@ -749,15 +749,15 @@ const _: () = { assert!(offset_of!(ImportExpression, options) == 24); assert!(offset_of!(ImportExpression, phase) == 40); - // Padding: 14 bytes - assert!(size_of::() == 104); + // Padding: 6 bytes + assert!(size_of::() == 96); assert!(align_of::() == 8); assert!(offset_of!(ImportDeclaration, span) == 0); assert!(offset_of!(ImportDeclaration, specifiers) == 8); assert!(offset_of!(ImportDeclaration, source) == 32); - assert!(offset_of!(ImportDeclaration, phase) == 80); - assert!(offset_of!(ImportDeclaration, with_clause) == 88); - assert!(offset_of!(ImportDeclaration, import_kind) == 96); + assert!(offset_of!(ImportDeclaration, phase) == 88); + assert!(offset_of!(ImportDeclaration, with_clause) == 80); + assert!(offset_of!(ImportDeclaration, import_kind) == 89); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -809,8 +809,8 @@ const _: () = { assert!(offset_of!(ExportNamedDeclaration, declaration) == 8); assert!(offset_of!(ExportNamedDeclaration, specifiers) == 24); assert!(offset_of!(ExportNamedDeclaration, source) == 48); - assert!(offset_of!(ExportNamedDeclaration, export_kind) == 96); - assert!(offset_of!(ExportNamedDeclaration, with_clause) == 104); + assert!(offset_of!(ExportNamedDeclaration, export_kind) == 104); + assert!(offset_of!(ExportNamedDeclaration, with_clause) == 96); // Padding: 0 bytes assert!(size_of::() == 80); @@ -1037,9 +1037,9 @@ const _: () = { assert!(offset_of!(TSEnumDeclaration, span) == 0); assert!(offset_of!(TSEnumDeclaration, id) == 8); assert!(offset_of!(TSEnumDeclaration, body) == 40); - assert!(offset_of!(TSEnumDeclaration, r#const) == 72); - assert!(offset_of!(TSEnumDeclaration, declare) == 73); - assert!(offset_of!(TSEnumDeclaration, scope_id) == 76); + assert!(offset_of!(TSEnumDeclaration, r#const) == 76); + assert!(offset_of!(TSEnumDeclaration, declare) == 77); + assert!(offset_of!(TSEnumDeclaration, scope_id) == 72); // Padding: 0 bytes assert!(size_of::() == 32); @@ -1107,8 +1107,8 @@ const _: () = { assert!(size_of::() == 32); assert!(align_of::() == 8); assert!(offset_of!(TSTypeOperator, span) == 0); - assert!(offset_of!(TSTypeOperator, operator) == 8); - assert!(offset_of!(TSTypeOperator, type_annotation) == 16); + assert!(offset_of!(TSTypeOperator, operator) == 24); + assert!(offset_of!(TSTypeOperator, type_annotation) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -1272,8 +1272,8 @@ const _: () = { assert!(offset_of!(TSTypeAliasDeclaration, id) == 8); assert!(offset_of!(TSTypeAliasDeclaration, type_parameters) == 40); assert!(offset_of!(TSTypeAliasDeclaration, type_annotation) == 48); - assert!(offset_of!(TSTypeAliasDeclaration, declare) == 64); - assert!(offset_of!(TSTypeAliasDeclaration, scope_id) == 68); + assert!(offset_of!(TSTypeAliasDeclaration, declare) == 68); + assert!(offset_of!(TSTypeAliasDeclaration, scope_id) == 64); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -1293,8 +1293,8 @@ const _: () = { assert!(offset_of!(TSInterfaceDeclaration, type_parameters) == 40); assert!(offset_of!(TSInterfaceDeclaration, extends) == 48); assert!(offset_of!(TSInterfaceDeclaration, body) == 72); - assert!(offset_of!(TSInterfaceDeclaration, declare) == 80); - assert!(offset_of!(TSInterfaceDeclaration, scope_id) == 84); + assert!(offset_of!(TSInterfaceDeclaration, declare) == 84); + assert!(offset_of!(TSInterfaceDeclaration, scope_id) == 80); // Padding: 0 bytes assert!(size_of::() == 32); @@ -1306,11 +1306,11 @@ const _: () = { assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(TSPropertySignature, span) == 0); - assert!(offset_of!(TSPropertySignature, computed) == 8); - assert!(offset_of!(TSPropertySignature, optional) == 9); - assert!(offset_of!(TSPropertySignature, readonly) == 10); - assert!(offset_of!(TSPropertySignature, key) == 16); - assert!(offset_of!(TSPropertySignature, type_annotation) == 32); + assert!(offset_of!(TSPropertySignature, computed) == 32); + assert!(offset_of!(TSPropertySignature, optional) == 33); + assert!(offset_of!(TSPropertySignature, readonly) == 34); + assert!(offset_of!(TSPropertySignature, key) == 8); + assert!(offset_of!(TSPropertySignature, type_annotation) == 24); assert!(size_of::() == 16); assert!(align_of::() == 8); @@ -1336,19 +1336,19 @@ const _: () = { assert!(size_of::() == 1); assert!(align_of::() == 1); - // Padding: 9 bytes - assert!(size_of::() == 72); + // Padding: 1 bytes + assert!(size_of::() == 64); assert!(align_of::() == 8); assert!(offset_of!(TSMethodSignature, span) == 0); assert!(offset_of!(TSMethodSignature, key) == 8); - assert!(offset_of!(TSMethodSignature, computed) == 24); - assert!(offset_of!(TSMethodSignature, optional) == 25); - assert!(offset_of!(TSMethodSignature, kind) == 26); - assert!(offset_of!(TSMethodSignature, type_parameters) == 32); - assert!(offset_of!(TSMethodSignature, this_param) == 40); - assert!(offset_of!(TSMethodSignature, params) == 48); - assert!(offset_of!(TSMethodSignature, return_type) == 56); - assert!(offset_of!(TSMethodSignature, scope_id) == 64); + assert!(offset_of!(TSMethodSignature, computed) == 60); + assert!(offset_of!(TSMethodSignature, optional) == 61); + assert!(offset_of!(TSMethodSignature, kind) == 62); + assert!(offset_of!(TSMethodSignature, type_parameters) == 24); + assert!(offset_of!(TSMethodSignature, this_param) == 32); + assert!(offset_of!(TSMethodSignature, params) == 40); + assert!(offset_of!(TSMethodSignature, return_type) == 48); + assert!(offset_of!(TSMethodSignature, scope_id) == 56); // Padding: 4 bytes assert!(size_of::() == 40); @@ -1378,8 +1378,8 @@ const _: () = { assert!(align_of::() == 8); assert!(offset_of!(TSTypePredicate, span) == 0); assert!(offset_of!(TSTypePredicate, parameter_name) == 8); - assert!(offset_of!(TSTypePredicate, asserts) == 24); - assert!(offset_of!(TSTypePredicate, type_annotation) == 32); + assert!(offset_of!(TSTypePredicate, asserts) == 32); + assert!(offset_of!(TSTypePredicate, type_annotation) == 24); assert!(size_of::() == 16); assert!(align_of::() == 8); @@ -1390,9 +1390,9 @@ const _: () = { assert!(offset_of!(TSModuleDeclaration, span) == 0); assert!(offset_of!(TSModuleDeclaration, id) == 8); assert!(offset_of!(TSModuleDeclaration, body) == 64); - assert!(offset_of!(TSModuleDeclaration, kind) == 80); - assert!(offset_of!(TSModuleDeclaration, declare) == 81); - assert!(offset_of!(TSModuleDeclaration, scope_id) == 84); + assert!(offset_of!(TSModuleDeclaration, kind) == 84); + assert!(offset_of!(TSModuleDeclaration, declare) == 85); + assert!(offset_of!(TSModuleDeclaration, scope_id) == 80); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -1455,10 +1455,10 @@ const _: () = { assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(TSConstructorType, span) == 0); - assert!(offset_of!(TSConstructorType, r#abstract) == 8); - assert!(offset_of!(TSConstructorType, type_parameters) == 16); - assert!(offset_of!(TSConstructorType, params) == 24); - assert!(offset_of!(TSConstructorType, return_type) == 32); + assert!(offset_of!(TSConstructorType, r#abstract) == 32); + assert!(offset_of!(TSConstructorType, type_parameters) == 8); + assert!(offset_of!(TSConstructorType, params) == 16); + assert!(offset_of!(TSConstructorType, return_type) == 24); // Padding: 2 bytes assert!(size_of::() == 56); @@ -1467,9 +1467,9 @@ const _: () = { assert!(offset_of!(TSMappedType, type_parameter) == 8); assert!(offset_of!(TSMappedType, name_type) == 16); assert!(offset_of!(TSMappedType, type_annotation) == 32); - assert!(offset_of!(TSMappedType, optional) == 48); - assert!(offset_of!(TSMappedType, readonly) == 49); - assert!(offset_of!(TSMappedType, scope_id) == 52); + assert!(offset_of!(TSMappedType, optional) == 52); + assert!(offset_of!(TSMappedType, readonly) == 53); + assert!(offset_of!(TSMappedType, scope_id) == 48); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -1601,13 +1601,13 @@ const _: () = { assert!(size_of::() == 88); assert!(align_of::() == 4); assert!(offset_of!(Program, span) == 0); - assert!(offset_of!(Program, source_type) == 8); - assert!(offset_of!(Program, source_text) == 12); - assert!(offset_of!(Program, comments) == 20); - assert!(offset_of!(Program, hashbang) == 36); - assert!(offset_of!(Program, directives) == 52); - assert!(offset_of!(Program, body) == 68); - assert!(offset_of!(Program, scope_id) == 84); + assert!(offset_of!(Program, source_type) == 84); + assert!(offset_of!(Program, source_text) == 8); + assert!(offset_of!(Program, comments) == 16); + assert!(offset_of!(Program, hashbang) == 32); + assert!(offset_of!(Program, directives) == 48); + assert!(offset_of!(Program, body) == 64); + assert!(offset_of!(Program, scope_id) == 80); assert!(size_of::() == 8); assert!(align_of::() == 4); @@ -1666,16 +1666,16 @@ const _: () = { assert!(size_of::() == 8); assert!(align_of::() == 4); - // Padding: 4 bytes - assert!(size_of::() == 32); + // Padding: 0 bytes + assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(ObjectProperty, span) == 0); - assert!(offset_of!(ObjectProperty, kind) == 8); - assert!(offset_of!(ObjectProperty, key) == 12); - assert!(offset_of!(ObjectProperty, value) == 20); - assert!(offset_of!(ObjectProperty, method) == 28); - assert!(offset_of!(ObjectProperty, shorthand) == 29); - assert!(offset_of!(ObjectProperty, computed) == 30); + assert!(offset_of!(ObjectProperty, kind) == 24); + assert!(offset_of!(ObjectProperty, key) == 8); + assert!(offset_of!(ObjectProperty, value) == 16); + assert!(offset_of!(ObjectProperty, method) == 25); + assert!(offset_of!(ObjectProperty, shorthand) == 26); + assert!(offset_of!(ObjectProperty, computed) == 27); assert!(size_of::() == 8); assert!(align_of::() == 4); @@ -1778,24 +1778,24 @@ const _: () = { assert!(size_of::() == 20); assert!(align_of::() == 4); assert!(offset_of!(UpdateExpression, span) == 0); - assert!(offset_of!(UpdateExpression, operator) == 8); - assert!(offset_of!(UpdateExpression, prefix) == 9); - assert!(offset_of!(UpdateExpression, argument) == 12); + assert!(offset_of!(UpdateExpression, operator) == 16); + assert!(offset_of!(UpdateExpression, prefix) == 17); + assert!(offset_of!(UpdateExpression, argument) == 8); // Padding: 3 bytes assert!(size_of::() == 20); assert!(align_of::() == 4); assert!(offset_of!(UnaryExpression, span) == 0); - assert!(offset_of!(UnaryExpression, operator) == 8); - assert!(offset_of!(UnaryExpression, argument) == 12); + assert!(offset_of!(UnaryExpression, operator) == 16); + assert!(offset_of!(UnaryExpression, argument) == 8); // Padding: 3 bytes assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(BinaryExpression, span) == 0); assert!(offset_of!(BinaryExpression, left) == 8); - assert!(offset_of!(BinaryExpression, operator) == 16); - assert!(offset_of!(BinaryExpression, right) == 20); + assert!(offset_of!(BinaryExpression, operator) == 24); + assert!(offset_of!(BinaryExpression, right) == 16); // Padding: 0 bytes assert!(size_of::() == 32); @@ -1809,8 +1809,8 @@ const _: () = { assert!(align_of::() == 4); assert!(offset_of!(LogicalExpression, span) == 0); assert!(offset_of!(LogicalExpression, left) == 8); - assert!(offset_of!(LogicalExpression, operator) == 16); - assert!(offset_of!(LogicalExpression, right) == 20); + assert!(offset_of!(LogicalExpression, operator) == 24); + assert!(offset_of!(LogicalExpression, right) == 16); // Padding: 0 bytes assert!(size_of::() == 32); @@ -1824,9 +1824,9 @@ const _: () = { assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(AssignmentExpression, span) == 0); - assert!(offset_of!(AssignmentExpression, operator) == 8); - assert!(offset_of!(AssignmentExpression, left) == 12); - assert!(offset_of!(AssignmentExpression, right) == 20); + assert!(offset_of!(AssignmentExpression, operator) == 24); + assert!(offset_of!(AssignmentExpression, left) == 8); + assert!(offset_of!(AssignmentExpression, right) == 16); assert!(size_of::() == 8); assert!(align_of::() == 4); @@ -1943,25 +1943,25 @@ const _: () = { assert!(size_of::() == 8); assert!(align_of::() == 4); - // Padding: 6 bytes - assert!(size_of::() == 32); + // Padding: 2 bytes + assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(VariableDeclaration, span) == 0); - assert!(offset_of!(VariableDeclaration, kind) == 8); - assert!(offset_of!(VariableDeclaration, declarations) == 12); - assert!(offset_of!(VariableDeclaration, declare) == 28); + assert!(offset_of!(VariableDeclaration, kind) == 24); + assert!(offset_of!(VariableDeclaration, declarations) == 8); + assert!(offset_of!(VariableDeclaration, declare) == 25); assert!(size_of::() == 1); assert!(align_of::() == 1); - // Padding: 6 bytes - assert!(size_of::() == 40); + // Padding: 2 bytes + assert!(size_of::() == 36); assert!(align_of::() == 4); assert!(offset_of!(VariableDeclarator, span) == 0); - assert!(offset_of!(VariableDeclarator, kind) == 8); - assert!(offset_of!(VariableDeclarator, id) == 12); - assert!(offset_of!(VariableDeclarator, init) == 28); - assert!(offset_of!(VariableDeclarator, definite) == 36); + assert!(offset_of!(VariableDeclarator, kind) == 32); + assert!(offset_of!(VariableDeclarator, id) == 8); + assert!(offset_of!(VariableDeclarator, init) == 24); + assert!(offset_of!(VariableDeclarator, definite) == 33); // Padding: 0 bytes assert!(size_of::() == 8); @@ -2025,11 +2025,11 @@ const _: () = { assert!(size_of::() == 40); assert!(align_of::() == 4); assert!(offset_of!(ForOfStatement, span) == 0); - assert!(offset_of!(ForOfStatement, r#await) == 8); - assert!(offset_of!(ForOfStatement, left) == 12); - assert!(offset_of!(ForOfStatement, right) == 20); - assert!(offset_of!(ForOfStatement, body) == 28); - assert!(offset_of!(ForOfStatement, scope_id) == 36); + assert!(offset_of!(ForOfStatement, r#await) == 36); + assert!(offset_of!(ForOfStatement, left) == 8); + assert!(offset_of!(ForOfStatement, right) == 16); + assert!(offset_of!(ForOfStatement, body) == 24); + assert!(offset_of!(ForOfStatement, scope_id) == 32); // Padding: 0 bytes assert!(size_of::() == 24); @@ -2157,22 +2157,22 @@ const _: () = { assert!(offset_of!(BindingRestElement, span) == 0); assert!(offset_of!(BindingRestElement, argument) == 8); - // Padding: 7 bytes - assert!(size_of::() == 64); + // Padding: 3 bytes + assert!(size_of::() == 60); assert!(align_of::() == 4); assert!(offset_of!(Function, span) == 0); - assert!(offset_of!(Function, r#type) == 8); - assert!(offset_of!(Function, id) == 12); - assert!(offset_of!(Function, generator) == 32); - assert!(offset_of!(Function, r#async) == 33); - assert!(offset_of!(Function, declare) == 34); - assert!(offset_of!(Function, type_parameters) == 36); - assert!(offset_of!(Function, this_param) == 40); - assert!(offset_of!(Function, params) == 44); - assert!(offset_of!(Function, return_type) == 48); - assert!(offset_of!(Function, body) == 52); - assert!(offset_of!(Function, scope_id) == 56); - assert!(offset_of!(Function, pure) == 60); + assert!(offset_of!(Function, r#type) == 52); + assert!(offset_of!(Function, id) == 8); + assert!(offset_of!(Function, generator) == 53); + assert!(offset_of!(Function, r#async) == 54); + assert!(offset_of!(Function, declare) == 55); + assert!(offset_of!(Function, type_parameters) == 28); + assert!(offset_of!(Function, this_param) == 32); + assert!(offset_of!(Function, params) == 36); + assert!(offset_of!(Function, return_type) == 40); + assert!(offset_of!(Function, body) == 44); + assert!(offset_of!(Function, scope_id) == 48); + assert!(offset_of!(Function, pure) == 56); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2181,9 +2181,9 @@ const _: () = { assert!(size_of::() == 32); assert!(align_of::() == 4); assert!(offset_of!(FormalParameters, span) == 0); - assert!(offset_of!(FormalParameters, kind) == 8); - assert!(offset_of!(FormalParameters, items) == 12); - assert!(offset_of!(FormalParameters, rest) == 28); + assert!(offset_of!(FormalParameters, kind) == 28); + assert!(offset_of!(FormalParameters, items) == 8); + assert!(offset_of!(FormalParameters, rest) == 24); // Padding: 1 bytes assert!(size_of::() == 44); @@ -2205,41 +2205,41 @@ const _: () = { assert!(offset_of!(FunctionBody, directives) == 8); assert!(offset_of!(FunctionBody, statements) == 24); - // Padding: 5 bytes - assert!(size_of::() == 36); + // Padding: 1 bytes + assert!(size_of::() == 32); assert!(align_of::() == 4); assert!(offset_of!(ArrowFunctionExpression, span) == 0); - assert!(offset_of!(ArrowFunctionExpression, expression) == 8); - assert!(offset_of!(ArrowFunctionExpression, r#async) == 9); - assert!(offset_of!(ArrowFunctionExpression, type_parameters) == 12); - assert!(offset_of!(ArrowFunctionExpression, params) == 16); - assert!(offset_of!(ArrowFunctionExpression, return_type) == 20); - assert!(offset_of!(ArrowFunctionExpression, body) == 24); - assert!(offset_of!(ArrowFunctionExpression, scope_id) == 28); - assert!(offset_of!(ArrowFunctionExpression, pure) == 32); + assert!(offset_of!(ArrowFunctionExpression, expression) == 28); + assert!(offset_of!(ArrowFunctionExpression, r#async) == 29); + assert!(offset_of!(ArrowFunctionExpression, type_parameters) == 8); + assert!(offset_of!(ArrowFunctionExpression, params) == 12); + assert!(offset_of!(ArrowFunctionExpression, return_type) == 16); + assert!(offset_of!(ArrowFunctionExpression, body) == 20); + assert!(offset_of!(ArrowFunctionExpression, scope_id) == 24); + assert!(offset_of!(ArrowFunctionExpression, pure) == 30); // Padding: 3 bytes assert!(size_of::() == 20); assert!(align_of::() == 4); assert!(offset_of!(YieldExpression, span) == 0); - assert!(offset_of!(YieldExpression, delegate) == 8); - assert!(offset_of!(YieldExpression, argument) == 12); + assert!(offset_of!(YieldExpression, delegate) == 16); + assert!(offset_of!(YieldExpression, argument) == 8); - // Padding: 5 bytes - assert!(size_of::() == 92); + // Padding: 1 bytes + assert!(size_of::() == 88); assert!(align_of::() == 4); assert!(offset_of!(Class, span) == 0); - assert!(offset_of!(Class, r#type) == 8); - assert!(offset_of!(Class, decorators) == 12); - assert!(offset_of!(Class, id) == 28); - assert!(offset_of!(Class, type_parameters) == 48); - assert!(offset_of!(Class, super_class) == 52); - assert!(offset_of!(Class, super_type_arguments) == 60); - assert!(offset_of!(Class, implements) == 64); - assert!(offset_of!(Class, body) == 80); - assert!(offset_of!(Class, r#abstract) == 84); - assert!(offset_of!(Class, declare) == 85); - assert!(offset_of!(Class, scope_id) == 88); + assert!(offset_of!(Class, r#type) == 84); + assert!(offset_of!(Class, decorators) == 8); + assert!(offset_of!(Class, id) == 24); + assert!(offset_of!(Class, type_parameters) == 44); + assert!(offset_of!(Class, super_class) == 48); + assert!(offset_of!(Class, super_type_arguments) == 56); + assert!(offset_of!(Class, implements) == 60); + assert!(offset_of!(Class, body) == 76); + assert!(offset_of!(Class, r#abstract) == 85); + assert!(offset_of!(Class, declare) == 86); + assert!(offset_of!(Class, scope_id) == 80); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2253,20 +2253,20 @@ const _: () = { assert!(size_of::() == 8); assert!(align_of::() == 4); - // Padding: 5 bytes - assert!(size_of::() == 48); + // Padding: 1 bytes + assert!(size_of::() == 44); assert!(align_of::() == 4); assert!(offset_of!(MethodDefinition, span) == 0); - assert!(offset_of!(MethodDefinition, r#type) == 8); - assert!(offset_of!(MethodDefinition, decorators) == 12); - assert!(offset_of!(MethodDefinition, key) == 28); - assert!(offset_of!(MethodDefinition, value) == 36); - assert!(offset_of!(MethodDefinition, kind) == 40); - assert!(offset_of!(MethodDefinition, computed) == 41); - assert!(offset_of!(MethodDefinition, r#static) == 42); - assert!(offset_of!(MethodDefinition, r#override) == 43); - assert!(offset_of!(MethodDefinition, optional) == 44); - assert!(offset_of!(MethodDefinition, accessibility) == 45); + assert!(offset_of!(MethodDefinition, r#type) == 36); + assert!(offset_of!(MethodDefinition, decorators) == 8); + assert!(offset_of!(MethodDefinition, key) == 24); + assert!(offset_of!(MethodDefinition, value) == 32); + assert!(offset_of!(MethodDefinition, kind) == 37); + assert!(offset_of!(MethodDefinition, computed) == 38); + assert!(offset_of!(MethodDefinition, r#static) == 39); + assert!(offset_of!(MethodDefinition, r#override) == 40); + assert!(offset_of!(MethodDefinition, optional) == 41); + assert!(offset_of!(MethodDefinition, accessibility) == 42); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2275,19 +2275,19 @@ const _: () = { assert!(size_of::() == 56); assert!(align_of::() == 4); assert!(offset_of!(PropertyDefinition, span) == 0); - assert!(offset_of!(PropertyDefinition, r#type) == 8); - assert!(offset_of!(PropertyDefinition, decorators) == 12); - assert!(offset_of!(PropertyDefinition, key) == 28); - assert!(offset_of!(PropertyDefinition, type_annotation) == 36); - assert!(offset_of!(PropertyDefinition, value) == 40); - assert!(offset_of!(PropertyDefinition, computed) == 48); - assert!(offset_of!(PropertyDefinition, r#static) == 49); - assert!(offset_of!(PropertyDefinition, declare) == 50); - assert!(offset_of!(PropertyDefinition, r#override) == 51); - assert!(offset_of!(PropertyDefinition, optional) == 52); - assert!(offset_of!(PropertyDefinition, definite) == 53); - assert!(offset_of!(PropertyDefinition, readonly) == 54); - assert!(offset_of!(PropertyDefinition, accessibility) == 55); + assert!(offset_of!(PropertyDefinition, r#type) == 44); + assert!(offset_of!(PropertyDefinition, decorators) == 8); + assert!(offset_of!(PropertyDefinition, key) == 24); + assert!(offset_of!(PropertyDefinition, type_annotation) == 32); + assert!(offset_of!(PropertyDefinition, value) == 36); + assert!(offset_of!(PropertyDefinition, computed) == 45); + assert!(offset_of!(PropertyDefinition, r#static) == 46); + assert!(offset_of!(PropertyDefinition, declare) == 47); + assert!(offset_of!(PropertyDefinition, r#override) == 48); + assert!(offset_of!(PropertyDefinition, optional) == 49); + assert!(offset_of!(PropertyDefinition, definite) == 50); + assert!(offset_of!(PropertyDefinition, readonly) == 51); + assert!(offset_of!(PropertyDefinition, accessibility) == 52); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2314,20 +2314,20 @@ const _: () = { assert!(size_of::() == 1); assert!(align_of::() == 1); - // Padding: 6 bytes - assert!(size_of::() == 56); + // Padding: 2 bytes + assert!(size_of::() == 52); assert!(align_of::() == 4); assert!(offset_of!(AccessorProperty, span) == 0); - assert!(offset_of!(AccessorProperty, r#type) == 8); - assert!(offset_of!(AccessorProperty, decorators) == 12); - assert!(offset_of!(AccessorProperty, key) == 28); - assert!(offset_of!(AccessorProperty, type_annotation) == 36); - assert!(offset_of!(AccessorProperty, value) == 40); - assert!(offset_of!(AccessorProperty, computed) == 48); - assert!(offset_of!(AccessorProperty, r#static) == 49); - assert!(offset_of!(AccessorProperty, r#override) == 50); - assert!(offset_of!(AccessorProperty, definite) == 51); - assert!(offset_of!(AccessorProperty, accessibility) == 52); + assert!(offset_of!(AccessorProperty, r#type) == 44); + assert!(offset_of!(AccessorProperty, decorators) == 8); + assert!(offset_of!(AccessorProperty, key) == 24); + assert!(offset_of!(AccessorProperty, type_annotation) == 32); + assert!(offset_of!(AccessorProperty, value) == 36); + assert!(offset_of!(AccessorProperty, computed) == 45); + assert!(offset_of!(AccessorProperty, r#static) == 46); + assert!(offset_of!(AccessorProperty, r#override) == 47); + assert!(offset_of!(AccessorProperty, definite) == 48); + assert!(offset_of!(AccessorProperty, accessibility) == 49); // Padding: 3 bytes assert!(size_of::() == 28); @@ -2337,15 +2337,15 @@ const _: () = { assert!(offset_of!(ImportExpression, options) == 16); assert!(offset_of!(ImportExpression, phase) == 24); - // Padding: 6 bytes - assert!(size_of::() == 64); + // Padding: 2 bytes + assert!(size_of::() == 60); assert!(align_of::() == 4); assert!(offset_of!(ImportDeclaration, span) == 0); assert!(offset_of!(ImportDeclaration, specifiers) == 8); assert!(offset_of!(ImportDeclaration, source) == 24); - assert!(offset_of!(ImportDeclaration, phase) == 52); - assert!(offset_of!(ImportDeclaration, with_clause) == 56); - assert!(offset_of!(ImportDeclaration, import_kind) == 60); + assert!(offset_of!(ImportDeclaration, phase) == 56); + assert!(offset_of!(ImportDeclaration, with_clause) == 52); + assert!(offset_of!(ImportDeclaration, import_kind) == 57); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2397,8 +2397,8 @@ const _: () = { assert!(offset_of!(ExportNamedDeclaration, declaration) == 8); assert!(offset_of!(ExportNamedDeclaration, specifiers) == 16); assert!(offset_of!(ExportNamedDeclaration, source) == 32); - assert!(offset_of!(ExportNamedDeclaration, export_kind) == 60); - assert!(offset_of!(ExportNamedDeclaration, with_clause) == 64); + assert!(offset_of!(ExportNamedDeclaration, export_kind) == 64); + assert!(offset_of!(ExportNamedDeclaration, with_clause) == 60); // Padding: 0 bytes assert!(size_of::() == 48); @@ -2625,9 +2625,9 @@ const _: () = { assert!(offset_of!(TSEnumDeclaration, span) == 0); assert!(offset_of!(TSEnumDeclaration, id) == 8); assert!(offset_of!(TSEnumDeclaration, body) == 28); - assert!(offset_of!(TSEnumDeclaration, r#const) == 52); - assert!(offset_of!(TSEnumDeclaration, declare) == 53); - assert!(offset_of!(TSEnumDeclaration, scope_id) == 56); + assert!(offset_of!(TSEnumDeclaration, r#const) == 56); + assert!(offset_of!(TSEnumDeclaration, declare) == 57); + assert!(offset_of!(TSEnumDeclaration, scope_id) == 52); // Padding: 0 bytes assert!(size_of::() == 24); @@ -2695,8 +2695,8 @@ const _: () = { assert!(size_of::() == 20); assert!(align_of::() == 4); assert!(offset_of!(TSTypeOperator, span) == 0); - assert!(offset_of!(TSTypeOperator, operator) == 8); - assert!(offset_of!(TSTypeOperator, type_annotation) == 12); + assert!(offset_of!(TSTypeOperator, operator) == 16); + assert!(offset_of!(TSTypeOperator, type_annotation) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2860,8 +2860,8 @@ const _: () = { assert!(offset_of!(TSTypeAliasDeclaration, id) == 8); assert!(offset_of!(TSTypeAliasDeclaration, type_parameters) == 28); assert!(offset_of!(TSTypeAliasDeclaration, type_annotation) == 32); - assert!(offset_of!(TSTypeAliasDeclaration, declare) == 40); - assert!(offset_of!(TSTypeAliasDeclaration, scope_id) == 44); + assert!(offset_of!(TSTypeAliasDeclaration, declare) == 44); + assert!(offset_of!(TSTypeAliasDeclaration, scope_id) == 40); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -2881,8 +2881,8 @@ const _: () = { assert!(offset_of!(TSInterfaceDeclaration, type_parameters) == 28); assert!(offset_of!(TSInterfaceDeclaration, extends) == 32); assert!(offset_of!(TSInterfaceDeclaration, body) == 48); - assert!(offset_of!(TSInterfaceDeclaration, declare) == 52); - assert!(offset_of!(TSInterfaceDeclaration, scope_id) == 56); + assert!(offset_of!(TSInterfaceDeclaration, declare) == 56); + assert!(offset_of!(TSInterfaceDeclaration, scope_id) == 52); // Padding: 0 bytes assert!(size_of::() == 24); @@ -2894,11 +2894,11 @@ const _: () = { assert!(size_of::() == 24); assert!(align_of::() == 4); assert!(offset_of!(TSPropertySignature, span) == 0); - assert!(offset_of!(TSPropertySignature, computed) == 8); - assert!(offset_of!(TSPropertySignature, optional) == 9); - assert!(offset_of!(TSPropertySignature, readonly) == 10); - assert!(offset_of!(TSPropertySignature, key) == 12); - assert!(offset_of!(TSPropertySignature, type_annotation) == 20); + assert!(offset_of!(TSPropertySignature, computed) == 20); + assert!(offset_of!(TSPropertySignature, optional) == 21); + assert!(offset_of!(TSPropertySignature, readonly) == 22); + assert!(offset_of!(TSPropertySignature, key) == 8); + assert!(offset_of!(TSPropertySignature, type_annotation) == 16); assert!(size_of::() == 8); assert!(align_of::() == 4); @@ -2929,14 +2929,14 @@ const _: () = { assert!(align_of::() == 4); assert!(offset_of!(TSMethodSignature, span) == 0); assert!(offset_of!(TSMethodSignature, key) == 8); - assert!(offset_of!(TSMethodSignature, computed) == 16); - assert!(offset_of!(TSMethodSignature, optional) == 17); - assert!(offset_of!(TSMethodSignature, kind) == 18); - assert!(offset_of!(TSMethodSignature, type_parameters) == 20); - assert!(offset_of!(TSMethodSignature, this_param) == 24); - assert!(offset_of!(TSMethodSignature, params) == 28); - assert!(offset_of!(TSMethodSignature, return_type) == 32); - assert!(offset_of!(TSMethodSignature, scope_id) == 36); + assert!(offset_of!(TSMethodSignature, computed) == 36); + assert!(offset_of!(TSMethodSignature, optional) == 37); + assert!(offset_of!(TSMethodSignature, kind) == 38); + assert!(offset_of!(TSMethodSignature, type_parameters) == 16); + assert!(offset_of!(TSMethodSignature, this_param) == 20); + assert!(offset_of!(TSMethodSignature, params) == 24); + assert!(offset_of!(TSMethodSignature, return_type) == 28); + assert!(offset_of!(TSMethodSignature, scope_id) == 32); // Padding: 0 bytes assert!(size_of::() == 24); @@ -2966,8 +2966,8 @@ const _: () = { assert!(align_of::() == 4); assert!(offset_of!(TSTypePredicate, span) == 0); assert!(offset_of!(TSTypePredicate, parameter_name) == 8); - assert!(offset_of!(TSTypePredicate, asserts) == 20); - assert!(offset_of!(TSTypePredicate, type_annotation) == 24); + assert!(offset_of!(TSTypePredicate, asserts) == 24); + assert!(offset_of!(TSTypePredicate, type_annotation) == 20); assert!(size_of::() == 12); assert!(align_of::() == 4); @@ -2978,9 +2978,9 @@ const _: () = { assert!(offset_of!(TSModuleDeclaration, span) == 0); assert!(offset_of!(TSModuleDeclaration, id) == 8); assert!(offset_of!(TSModuleDeclaration, body) == 40); - assert!(offset_of!(TSModuleDeclaration, kind) == 48); - assert!(offset_of!(TSModuleDeclaration, declare) == 49); - assert!(offset_of!(TSModuleDeclaration, scope_id) == 52); + assert!(offset_of!(TSModuleDeclaration, kind) == 52); + assert!(offset_of!(TSModuleDeclaration, declare) == 53); + assert!(offset_of!(TSModuleDeclaration, scope_id) == 48); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -3043,10 +3043,10 @@ const _: () = { assert!(size_of::() == 24); assert!(align_of::() == 4); assert!(offset_of!(TSConstructorType, span) == 0); - assert!(offset_of!(TSConstructorType, r#abstract) == 8); - assert!(offset_of!(TSConstructorType, type_parameters) == 12); - assert!(offset_of!(TSConstructorType, params) == 16); - assert!(offset_of!(TSConstructorType, return_type) == 20); + assert!(offset_of!(TSConstructorType, r#abstract) == 20); + assert!(offset_of!(TSConstructorType, type_parameters) == 8); + assert!(offset_of!(TSConstructorType, params) == 12); + assert!(offset_of!(TSConstructorType, return_type) == 16); // Padding: 2 bytes assert!(size_of::() == 36); @@ -3055,9 +3055,9 @@ const _: () = { assert!(offset_of!(TSMappedType, type_parameter) == 8); assert!(offset_of!(TSMappedType, name_type) == 12); assert!(offset_of!(TSMappedType, type_annotation) == 20); - assert!(offset_of!(TSMappedType, optional) == 28); - assert!(offset_of!(TSMappedType, readonly) == 29); - assert!(offset_of!(TSMappedType, scope_id) == 32); + assert!(offset_of!(TSMappedType, optional) == 32); + assert!(offset_of!(TSMappedType, readonly) == 33); + assert!(offset_of!(TSMappedType, scope_id) == 28); assert!(size_of::() == 1); assert!(align_of::() == 1); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 258f4e11f66b6..34d7716fb6654 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -3,7 +3,7 @@ //! AST node factories -#![expect(clippy::default_trait_access)] +#![expect(clippy::default_trait_access, clippy::inconsistent_struct_constructor)] use std::cell::Cell; diff --git a/crates/oxc_ast/src/generated/derive_dummy.rs b/crates/oxc_ast/src/generated/derive_dummy.rs index b77a7dfc288da..0965306dc850d 100644 --- a/crates/oxc_ast/src/generated/derive_dummy.rs +++ b/crates/oxc_ast/src/generated/derive_dummy.rs @@ -651,7 +651,7 @@ impl<'a> Dummy<'a> for BlockStatement<'a> { impl<'a> Dummy<'a> for Declaration<'a> { /// Create a dummy [`Declaration`]. /// - /// Has cost of making 1 allocation (48 bytes). + /// Has cost of making 1 allocation (40 bytes). fn dummy(allocator: &'a Allocator) -> Self { Self::VariableDeclaration(Dummy::dummy(allocator)) } @@ -1210,7 +1210,7 @@ impl<'a> Dummy<'a> for ClassElement<'a> { impl<'a> Dummy<'a> for MethodDefinition<'a> { /// Create a dummy [`MethodDefinition`]. /// - /// Has cost of making 3 allocations (160 bytes). + /// Has cost of making 3 allocations (152 bytes). fn dummy(allocator: &'a Allocator) -> Self { Self { span: Dummy::dummy(allocator), diff --git a/crates/oxc_ast_macros/Cargo.toml b/crates/oxc_ast_macros/Cargo.toml index 9b211d02e7836..8be0a9ae142d2 100644 --- a/crates/oxc_ast_macros/Cargo.toml +++ b/crates/oxc_ast_macros/Cargo.toml @@ -21,6 +21,7 @@ proc-macro = true doctest = false [dependencies] +phf = { workspace = true } proc-macro2 = { workspace = true } quote = { workspace = true } syn = { workspace = true, features = ["full", "parsing", "printing", "proc-macro"] } diff --git a/crates/oxc_ast_macros/src/ast.rs b/crates/oxc_ast_macros/src/ast.rs index 381f4bfd25eac..86fe3341682fa 100644 --- a/crates/oxc_ast_macros/src/ast.rs +++ b/crates/oxc_ast_macros/src/ast.rs @@ -1,31 +1,106 @@ -use proc_macro2::TokenStream; +use std::mem; + +use proc_macro2::{TokenStream, TokenTree}; use quote::quote; -use syn::{Attribute, Fields, Ident, Item, ItemEnum, punctuated::Punctuated, token::Comma}; +use syn::{ + Attribute, Fields, FieldsNamed, Ident, Item, ItemEnum, ItemStruct, parse_quote, + punctuated::Punctuated, token::Comma, +}; -use crate::generated::derived_traits::get_trait_crate_and_generics; +use crate::generated::{derived_traits::get_trait_crate_and_generics, structs::STRUCTS}; -pub fn ast(input: &Item) -> TokenStream { - let (head, tail) = match input { - Item::Enum(enum_) => (enum_repr(enum_), assert_generated_derives(&enum_.attrs)), - Item::Struct(struct_) => (quote!(#[repr(C)]), assert_generated_derives(&struct_.attrs)), +/// `#[ast]` macro. +pub fn ast(item: &mut Item, args: TokenStream) -> TokenStream { + match item { + Item::Enum(item) => modify_enum(item), + Item::Struct(item) => modify_struct(item, args), _ => unreachable!(), + } +} + +/// Add `#[repr(...)]` and `#[derive(::oxc_ast_macros::Ast)]` to enum, +/// and static assertions for `#[generate_derive]`. +fn modify_enum(item: &ItemEnum) -> TokenStream { + // If enum has any non-unit variant, `#[repr(C, u8)]`, otherwise `#[repr(u8)]` + let repr = if item.variants.iter().any(|var| !matches!(var.fields, Fields::Unit)) { + quote!(#[repr(C, u8)]) + } else { + quote!(#[repr(u8)]) }; + let assertions = assert_generated_derives(&item.attrs); + quote! { + #repr #[derive(::oxc_ast_macros::Ast)] - #head - #input - #tail + #item + #assertions } } -/// If `enum_` has any non-unit variant, returns `#[repr(C, u8)]`, otherwise returns `#[repr(u8)]`. -fn enum_repr(enum_: &ItemEnum) -> TokenStream { - if enum_.variants.iter().any(|var| !matches!(var.fields, Fields::Unit)) { - quote!(#[repr(C, u8)]) - } else { - quote!(#[repr(u8)]) +/// Details of how `#[ast]` macro should modify a struct. +pub struct StructDetails { + pub field_order: Option<&'static [u8]>, +} + +/// Add `#[repr(C)]` and `#[derive(::oxc_ast_macros::Ast)]` to struct, +/// and static assertions for `#[generate_derive]`. +/// Re-order struct fields if instructed by `STRUCTS` data. +fn modify_struct(item: &mut ItemStruct, args: TokenStream) -> TokenStream { + let assertions = assert_generated_derives(&item.attrs); + + let item = reorder_struct_fields(item, args).unwrap_or_else(|| quote!(#item)); + + quote! { + #[repr(C)] + #[derive(::oxc_ast_macros::Ast)] + #item + #assertions + } +} + +/// Re-order struct fields, depending on instructions in `STRUCTS` (which is codegen-ed). +fn reorder_struct_fields(item: &mut ItemStruct, args: TokenStream) -> Option { + // Skip foreign types + if let Some(TokenTree::Ident(ident)) = args.into_iter().next() { + if ident == "foreign" { + return None; + } + } + + // Get struct data. Exit if no fields need re-ordering. + let struct_name = item.ident.to_string(); + let field_order = STRUCTS[&struct_name].field_order?; + + // Re-order fields. + // `field_order` contains indexes of fields in the order they should be. + let fields = mem::replace(&mut item.fields, Fields::Unit); + let Fields::Named(FieldsNamed { brace_token, mut named }) = fields else { unreachable!() }; + + assert!( + named.len() == field_order.len(), + "Wrong number of fields for `{struct_name}` in `STRUCTS`" + ); + + // Create 2 sets of fields. + // 1st set are the fields in original order, each prefixed with `#[cfg(doc)]`. + // 2nd set are the fields in new order, each prefixed with `#[cfg(not(doc))]`. + // This is necessary so that fields are listed in original source order in docs. + let mut fields = named.clone().into_pairs().zip(field_order).collect::>(); + fields.sort_unstable_by_key(|(_, index)| **index); + + for field in &mut named { + field.attrs.insert(0, parse_quote!( #[cfg(doc)])); } + + named.extend(fields.into_iter().map(|(mut pair, _)| { + pair.value_mut().attrs.insert(0, parse_quote!( #[cfg(not(doc))])); + pair + })); + + item.fields = Fields::Named(FieldsNamed { brace_token, named }); + + Some(quote!( #item )) } /// Generate assertions that traits used in `#[generate_derive]` are in scope. diff --git a/crates/oxc_ast_macros/src/generated/structs.rs b/crates/oxc_ast_macros/src/generated/structs.rs new file mode 100644 index 0000000000000..f785bc2ac9f64 --- /dev/null +++ b/crates/oxc_ast_macros/src/generated/structs.rs @@ -0,0 +1,302 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/generators/assert_layouts.rs`. + +use crate::ast::StructDetails; + +/// Details of how `#[ast]` macro should modify structs. +#[expect(clippy::unreadable_literal)] +pub static STRUCTS: phf::Map<&'static str, StructDetails> = ::phf::Map { + key: 12913932095322966823, + disps: &[ + (0, 0), + (0, 15), + (0, 140), + (0, 50), + (0, 27), + (0, 26), + (1, 84), + (0, 50), + (0, 17), + (0, 184), + (1, 127), + (6, 133), + (0, 8), + (0, 29), + (2, 45), + (0, 1), + (0, 40), + (0, 0), + (1, 103), + (2, 67), + (3, 95), + (0, 68), + (1, 64), + (0, 139), + (0, 18), + (1, 6), + (0, 18), + (0, 148), + (0, 52), + (0, 22), + (13, 66), + (0, 22), + (1, 122), + (59, 42), + (0, 7), + (6, 26), + (1, 164), + (0, 1), + (0, 14), + (3, 52), + (24, 100), + (0, 130), + (0, 206), + (0, 5), + (0, 1), + (1, 18), + ], + entries: &[ + ("ImportNamespaceSpecifier", StructDetails { field_order: None }), + ("JSXFragment", StructDetails { field_order: None }), + ("JSXOpeningElement", StructDetails { field_order: None }), + ("TSTemplateLiteralType", StructDetails { field_order: None }), + ("ScopeId", StructDetails { field_order: None }), + ("Modifiers", StructDetails { field_order: None }), + ("PrivateIdentifier", StructDetails { field_order: None }), + ("BigIntLiteral", StructDetails { field_order: None }), + ("CatchParameter", StructDetails { field_order: None }), + ("TSAsExpression", StructDetails { field_order: None }), + ("Hashbang", StructDetails { field_order: None }), + ("TSTypeParameter", StructDetails { field_order: None }), + ("ForStatement", StructDetails { field_order: None }), + ("TSTypeAliasDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 3, 5, 4]) }), + ("MetaProperty", StructDetails { field_order: None }), + ("NonMaxU32", StructDetails { field_order: None }), + ("RawTransferData", StructDetails { field_order: None }), + ("JSDocUnknownType", StructDetails { field_order: None }), + ("TSNeverKeyword", StructDetails { field_order: None }), + ("IdentifierName", StructDetails { field_order: None }), + ("StringLiteral", StructDetails { field_order: None }), + ("Error", StructDetails { field_order: Some(&[3, 0, 1, 2]) }), + ("ObjectPattern", StructDetails { field_order: None }), + ("TSNumberKeyword", StructDetails { field_order: None }), + ("EcmaScriptModule", StructDetails { field_order: Some(&[4, 0, 1, 2, 3]) }), + ("TSInstantiationExpression", StructDetails { field_order: None }), + ("CatchClause", StructDetails { field_order: None }), + ("BoundaryAssertion", StructDetails { field_order: None }), + ("TaggedTemplateExpression", StructDetails { field_order: None }), + ("AssignmentTargetPropertyIdentifier", StructDetails { field_order: None }), + ("ObjectProperty", StructDetails { field_order: Some(&[0, 3, 1, 2, 4, 5, 6]) }), + ("TemplateElementValue", StructDetails { field_order: None }), + ("BlockStatement", StructDetails { field_order: None }), + ("TSObjectKeyword", StructDetails { field_order: None }), + ("TSCallSignatureDeclaration", StructDetails { field_order: None }), + ("ConditionalExpression", StructDetails { field_order: None }), + ("TSTypeAssertion", StructDetails { field_order: None }), + ("TemplateLiteral", StructDetails { field_order: None }), + ("TSQualifiedName", StructDetails { field_order: None }), + ("ImportSpecifier", StructDetails { field_order: None }), + ("TryStatement", StructDetails { field_order: None }), + ("TSSymbolKeyword", StructDetails { field_order: None }), + ("UnaryExpression", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("WithStatement", StructDetails { field_order: None }), + ( + "AccessorProperty", + StructDetails { field_order: Some(&[0, 5, 1, 2, 3, 4, 6, 7, 8, 9, 10]) }, + ), + ("ReturnStatement", StructDetails { field_order: None }), + ("AssignmentPattern", StructDetails { field_order: None }), + ("Program", StructDetails { field_order: Some(&[0, 7, 1, 2, 3, 4, 5, 6]) }), + ("TSInterfaceBody", StructDetails { field_order: None }), + ("JSXMemberExpression", StructDetails { field_order: None }), + ("JSXClosingElement", StructDetails { field_order: None }), + ("TSArrayType", StructDetails { field_order: None }), + ("TSIntrinsicKeyword", StructDetails { field_order: None }), + ("StaticImport", StructDetails { field_order: None }), + ("ExportDefaultDeclaration", StructDetails { field_order: None }), + ("ArrayPattern", StructDetails { field_order: None }), + ("SequenceExpression", StructDetails { field_order: None }), + ("CharacterClassRange", StructDetails { field_order: None }), + ("Disjunction", StructDetails { field_order: None }), + ("ThrowStatement", StructDetails { field_order: None }), + ("ForInStatement", StructDetails { field_order: None }), + ( + "ArrowFunctionExpression", + StructDetails { field_order: Some(&[0, 6, 7, 1, 2, 3, 4, 5, 8]) }, + ), + ("IdentifierReference", StructDetails { field_order: None }), + ("TSTypeOperator", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("ErrorLabel", StructDetails { field_order: Some(&[1, 0]) }), + ("AwaitExpression", StructDetails { field_order: None }), + ("Quantifier", StructDetails { field_order: Some(&[0, 1, 2, 4, 3]) }), + ("CharacterClassEscape", StructDetails { field_order: None }), + ("ImportEntry", StructDetails { field_order: None }), + ("FormalParameter", StructDetails { field_order: None }), + ("TSNamespaceExportDeclaration", StructDetails { field_order: None }), + ("BreakStatement", StructDetails { field_order: None }), + ("TSParenthesizedType", StructDetails { field_order: None }), + ("TSLiteralType", StructDetails { field_order: None }), + ("TSVoidKeyword", StructDetails { field_order: None }), + ("StaticExport", StructDetails { field_order: None }), + ("V8IntrinsicExpression", StructDetails { field_order: None }), + ("TSModuleDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 4, 5, 3]) }), + ("NamedReference", StructDetails { field_order: None }), + ("StaticBlock", StructDetails { field_order: None }), + ("TSInferType", StructDetails { field_order: None }), + ("TSMethodSignature", StructDetails { field_order: Some(&[0, 1, 7, 8, 9, 2, 3, 4, 5, 6]) }), + ("Elision", StructDetails { field_order: None }), + ("YieldExpression", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("TSSatisfiesExpression", StructDetails { field_order: None }), + ("ThisExpression", StructDetails { field_order: None }), + ("UnicodePropertyEscape", StructDetails { field_order: Some(&[0, 3, 4, 1, 2]) }), + ("Decorator", StructDetails { field_order: None }), + ("ExportNamedDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 3, 5, 4]) }), + ("VariableDeclaration", StructDetails { field_order: Some(&[0, 2, 1, 3]) }), + ("TSTypeAnnotation", StructDetails { field_order: None }), + ("ImportDefaultSpecifier", StructDetails { field_order: None }), + ("TSNullKeyword", StructDetails { field_order: None }), + ("TSBooleanKeyword", StructDetails { field_order: None }), + ("Comment", StructDetails { field_order: None }), + ("TSAnyKeyword", StructDetails { field_order: None }), + ("DynamicImport", StructDetails { field_order: None }), + ("ObjectExpression", StructDetails { field_order: None }), + ("DoWhileStatement", StructDetails { field_order: None }), + ("SymbolId", StructDetails { field_order: None }), + ("TSTypeReference", StructDetails { field_order: None }), + ("TSIndexedAccessType", StructDetails { field_order: None }), + ("ExportSpecifier", StructDetails { field_order: None }), + ("TSImportEqualsDeclaration", StructDetails { field_order: None }), + ("JSXText", StructDetails { field_order: None }), + ("TSIndexSignature", StructDetails { field_order: None }), + ("RegExpFlags", StructDetails { field_order: None }), + ("EmptyStatement", StructDetails { field_order: None }), + ("TSInterfaceDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 3, 4, 6, 5]) }), + ("FunctionBody", StructDetails { field_order: None }), + ("UpdateExpression", StructDetails { field_order: Some(&[0, 2, 3, 1]) }), + ("Modifier", StructDetails { field_order: None }), + ("Pattern", StructDetails { field_order: None }), + ("TSUndefinedKeyword", StructDetails { field_order: None }), + ("ExpressionStatement", StructDetails { field_order: None }), + ("DebuggerStatement", StructDetails { field_order: None }), + ( + "PropertyDefinition", + StructDetails { field_order: Some(&[0, 5, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13]) }, + ), + ("JSXElement", StructDetails { field_order: None }), + ("IgnoreGroup", StructDetails { field_order: None }), + ("TSClassImplements", StructDetails { field_order: None }), + ("TSNonNullExpression", StructDetails { field_order: None }), + ("AssignmentTargetWithDefault", StructDetails { field_order: None }), + ("TSTypePredicate", StructDetails { field_order: Some(&[0, 1, 3, 2]) }), + ("TSExportAssignment", StructDetails { field_order: None }), + ("Character", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("TSTypeParameterInstantiation", StructDetails { field_order: None }), + ("NewExpression", StructDetails { field_order: None }), + ("JSXOpeningFragment", StructDetails { field_order: None }), + ("ContinueStatement", StructDetails { field_order: None }), + ("SpreadElement", StructDetails { field_order: None }), + ("JSXIdentifier", StructDetails { field_order: None }), + ("PrivateInExpression", StructDetails { field_order: None }), + ("LabeledStatement", StructDetails { field_order: None }), + ("TSInterfaceHeritage", StructDetails { field_order: None }), + ("PrivateFieldExpression", StructDetails { field_order: None }), + ("TSNamedTupleMember", StructDetails { field_order: None }), + ("TSConstructSignatureDeclaration", StructDetails { field_order: None }), + ("LookAroundAssertion", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("BinaryExpression", StructDetails { field_order: Some(&[0, 1, 3, 2]) }), + ("VariableDeclarator", StructDetails { field_order: Some(&[0, 3, 1, 2, 4]) }), + ("CallExpression", StructDetails { field_order: None }), + ("JSXNamespacedName", StructDetails { field_order: None }), + ("ObjectAssignmentTarget", StructDetails { field_order: None }), + ("Span", StructDetails { field_order: None }), + ("BindingIdentifier", StructDetails { field_order: None }), + ("JSXExpressionContainer", StructDetails { field_order: None }), + ("ForOfStatement", StructDetails { field_order: Some(&[0, 5, 1, 2, 3, 4]) }), + ("TSTypeParameterDeclaration", StructDetails { field_order: None }), + ("AssignmentExpression", StructDetails { field_order: Some(&[0, 3, 1, 2]) }), + ("TSOptionalType", StructDetails { field_order: None }), + ("ClassString", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("AssignmentTargetRest", StructDetails { field_order: None }), + ("ChainExpression", StructDetails { field_order: None }), + ("SwitchStatement", StructDetails { field_order: None }), + ("BindingRestElement", StructDetails { field_order: None }), + ("ArrayAssignmentTarget", StructDetails { field_order: None }), + ("SourceType", StructDetails { field_order: None }), + ( + "Function", + StructDetails { field_order: Some(&[0, 8, 1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 12]) }, + ), + ("LabelIdentifier", StructDetails { field_order: None }), + ("FormalParameters", StructDetails { field_order: Some(&[0, 3, 1, 2]) }), + ( + "MethodDefinition", + StructDetails { field_order: Some(&[0, 4, 1, 2, 3, 5, 6, 7, 8, 9, 10]) }, + ), + ("RegExpLiteral", StructDetails { field_order: None }), + ("TSPropertySignature", StructDetails { field_order: Some(&[0, 3, 4, 5, 1, 2]) }), + ("JSXSpreadAttribute", StructDetails { field_order: None }), + ("ClassStringDisjunction", StructDetails { field_order: Some(&[0, 2, 1]) }), + ("BindingPattern", StructDetails { field_order: None }), + ("CapturingGroup", StructDetails { field_order: None }), + ("TSBigIntKeyword", StructDetails { field_order: None }), + ("ReferenceId", StructDetails { field_order: None }), + ("IndexedReference", StructDetails { field_order: None }), + ("RegExp", StructDetails { field_order: None }), + ("TSFunctionType", StructDetails { field_order: None }), + ("TSExternalModuleReference", StructDetails { field_order: None }), + ("JSDocNonNullableType", StructDetails { field_order: None }), + ("WhileStatement", StructDetails { field_order: None }), + ("NullLiteral", StructDetails { field_order: None }), + ("TSStringKeyword", StructDetails { field_order: None }), + ("Alternative", StructDetails { field_order: None }), + ("TSIntersectionType", StructDetails { field_order: None }), + ("NameSpan", StructDetails { field_order: Some(&[1, 0]) }), + ("NumericLiteral", StructDetails { field_order: None }), + ("ImportDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 4, 3, 5]) }), + ("JSXAttribute", StructDetails { field_order: None }), + ("LogicalExpression", StructDetails { field_order: Some(&[0, 1, 3, 2]) }), + ("TSEnumMember", StructDetails { field_order: None }), + ("TSIndexSignatureName", StructDetails { field_order: None }), + ("WithClause", StructDetails { field_order: None }), + ("TSUnionType", StructDetails { field_order: None }), + ("RegExpPattern", StructDetails { field_order: None }), + ("JSXClosingFragment", StructDetails { field_order: None }), + ("Class", StructDetails { field_order: Some(&[0, 9, 1, 2, 3, 4, 5, 6, 7, 10, 11, 8]) }), + ("TSTupleType", StructDetails { field_order: None }), + ("Dot", StructDetails { field_order: None }), + ("JSXEmptyExpression", StructDetails { field_order: None }), + ("TSUnknownKeyword", StructDetails { field_order: None }), + ("SwitchCase", StructDetails { field_order: None }), + ("TSEnumBody", StructDetails { field_order: None }), + ("JSXSpreadChild", StructDetails { field_order: None }), + ("JSDocNullableType", StructDetails { field_order: None }), + ("StaticMemberExpression", StructDetails { field_order: None }), + ("ClassBody", StructDetails { field_order: None }), + ("ArrayExpression", StructDetails { field_order: None }), + ("ParenthesizedExpression", StructDetails { field_order: None }), + ("ExportEntry", StructDetails { field_order: Some(&[1, 0, 2, 3, 4, 5, 6]) }), + ("ImportExpression", StructDetails { field_order: None }), + ("TSModuleBlock", StructDetails { field_order: None }), + ("TSTypeLiteral", StructDetails { field_order: None }), + ("TSTypeQuery", StructDetails { field_order: None }), + ("AssignmentTargetPropertyProperty", StructDetails { field_order: None }), + ("CharacterClass", StructDetails { field_order: Some(&[0, 2, 3, 4, 1]) }), + ("BooleanLiteral", StructDetails { field_order: None }), + ("TSEnumDeclaration", StructDetails { field_order: Some(&[0, 1, 2, 4, 5, 3]) }), + ("TSConditionalType", StructDetails { field_order: None }), + ("TemplateElement", StructDetails { field_order: None }), + ("TSMappedType", StructDetails { field_order: Some(&[0, 1, 2, 3, 5, 6, 4]) }), + ("Directive", StructDetails { field_order: None }), + ("IfStatement", StructDetails { field_order: None }), + ("TSImportType", StructDetails { field_order: None }), + ("TSConstructorType", StructDetails { field_order: Some(&[0, 4, 1, 2, 3]) }), + ("ExportAllDeclaration", StructDetails { field_order: None }), + ("TSRestType", StructDetails { field_order: None }), + ("TSThisType", StructDetails { field_order: None }), + ("ImportAttribute", StructDetails { field_order: None }), + ("Super", StructDetails { field_order: None }), + ("BindingProperty", StructDetails { field_order: None }), + ("ComputedMemberExpression", StructDetails { field_order: None }), + ("TSThisParameter", StructDetails { field_order: None }), + ], +}; diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index a6135f9e6aa28..6f85bac680add 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -1,10 +1,12 @@ use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{Item, parse_macro_input}; mod ast; mod generated { pub mod derived_traits; + pub mod structs; } /// This attribute serves two purposes: @@ -38,9 +40,9 @@ mod generated { /// /// Add assertions that traits used in `#[generate_derive(...)]` are in scope. #[proc_macro_attribute] -pub fn ast(_args: TokenStream, input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as Item); - let expanded = ast::ast(&input); +pub fn ast(args: TokenStream, input: TokenStream) -> TokenStream { + let mut input = parse_macro_input!(input as Item); + let expanded = ast::ast(&mut input, TokenStream2::from(args)); TokenStream::from(expanded) } diff --git a/crates/oxc_regular_expression/src/generated/assert_layouts.rs b/crates/oxc_regular_expression/src/generated/assert_layouts.rs index aa0048f3965e5..ef5de10434a2b 100644 --- a/crates/oxc_regular_expression/src/generated/assert_layouts.rs +++ b/crates/oxc_regular_expression/src/generated/assert_layouts.rs @@ -43,8 +43,8 @@ const _: () = { assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(LookAroundAssertion, span) == 0); - assert!(offset_of!(LookAroundAssertion, kind) == 8); - assert!(offset_of!(LookAroundAssertion, body) == 16); + assert!(offset_of!(LookAroundAssertion, kind) == 40); + assert!(offset_of!(LookAroundAssertion, body) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -55,15 +55,15 @@ const _: () = { assert!(offset_of!(Quantifier, span) == 0); assert!(offset_of!(Quantifier, min) == 8); assert!(offset_of!(Quantifier, max) == 16); - assert!(offset_of!(Quantifier, greedy) == 32); - assert!(offset_of!(Quantifier, body) == 40); + assert!(offset_of!(Quantifier, greedy) == 48); + assert!(offset_of!(Quantifier, body) == 32); // Padding: 3 bytes assert!(size_of::() == 16); assert!(align_of::() == 8); assert!(offset_of!(Character, span) == 0); - assert!(offset_of!(Character, kind) == 8); - assert!(offset_of!(Character, value) == 12); + assert!(offset_of!(Character, kind) == 12); + assert!(offset_of!(Character, value) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -81,10 +81,10 @@ const _: () = { assert!(size_of::() == 48); assert!(align_of::() == 8); assert!(offset_of!(UnicodePropertyEscape, span) == 0); - assert!(offset_of!(UnicodePropertyEscape, negative) == 8); - assert!(offset_of!(UnicodePropertyEscape, strings) == 9); - assert!(offset_of!(UnicodePropertyEscape, name) == 16); - assert!(offset_of!(UnicodePropertyEscape, value) == 32); + assert!(offset_of!(UnicodePropertyEscape, negative) == 40); + assert!(offset_of!(UnicodePropertyEscape, strings) == 41); + assert!(offset_of!(UnicodePropertyEscape, name) == 8); + assert!(offset_of!(UnicodePropertyEscape, value) == 24); // Padding: 0 bytes assert!(size_of::() == 8); @@ -95,10 +95,10 @@ const _: () = { assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(CharacterClass, span) == 0); - assert!(offset_of!(CharacterClass, negative) == 8); - assert!(offset_of!(CharacterClass, strings) == 9); - assert!(offset_of!(CharacterClass, kind) == 10); - assert!(offset_of!(CharacterClass, body) == 16); + assert!(offset_of!(CharacterClass, negative) == 32); + assert!(offset_of!(CharacterClass, strings) == 33); + assert!(offset_of!(CharacterClass, kind) == 34); + assert!(offset_of!(CharacterClass, body) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -117,15 +117,15 @@ const _: () = { assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(ClassStringDisjunction, span) == 0); - assert!(offset_of!(ClassStringDisjunction, strings) == 8); - assert!(offset_of!(ClassStringDisjunction, body) == 16); + assert!(offset_of!(ClassStringDisjunction, strings) == 32); + assert!(offset_of!(ClassStringDisjunction, body) == 8); // Padding: 7 bytes assert!(size_of::() == 40); assert!(align_of::() == 8); assert!(offset_of!(ClassString, span) == 0); - assert!(offset_of!(ClassString, strings) == 8); - assert!(offset_of!(ClassString, body) == 16); + assert!(offset_of!(ClassString, strings) == 32); + assert!(offset_of!(ClassString, body) == 8); // Padding: 0 bytes assert!(size_of::() == 56); @@ -204,8 +204,8 @@ const _: () = { assert!(size_of::() == 36); assert!(align_of::() == 4); assert!(offset_of!(LookAroundAssertion, span) == 0); - assert!(offset_of!(LookAroundAssertion, kind) == 8); - assert!(offset_of!(LookAroundAssertion, body) == 12); + assert!(offset_of!(LookAroundAssertion, kind) == 32); + assert!(offset_of!(LookAroundAssertion, body) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -216,15 +216,15 @@ const _: () = { assert!(offset_of!(Quantifier, span) == 0); assert!(offset_of!(Quantifier, min) == 8); assert!(offset_of!(Quantifier, max) == 16); - assert!(offset_of!(Quantifier, greedy) == 32); - assert!(offset_of!(Quantifier, body) == 36); + assert!(offset_of!(Quantifier, greedy) == 44); + assert!(offset_of!(Quantifier, body) == 32); // Padding: 3 bytes assert!(size_of::() == 16); assert!(align_of::() == 4); assert!(offset_of!(Character, span) == 0); - assert!(offset_of!(Character, kind) == 8); - assert!(offset_of!(Character, value) == 12); + assert!(offset_of!(Character, kind) == 12); + assert!(offset_of!(Character, value) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -242,10 +242,10 @@ const _: () = { assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(UnicodePropertyEscape, span) == 0); - assert!(offset_of!(UnicodePropertyEscape, negative) == 8); - assert!(offset_of!(UnicodePropertyEscape, strings) == 9); - assert!(offset_of!(UnicodePropertyEscape, name) == 12); - assert!(offset_of!(UnicodePropertyEscape, value) == 20); + assert!(offset_of!(UnicodePropertyEscape, negative) == 24); + assert!(offset_of!(UnicodePropertyEscape, strings) == 25); + assert!(offset_of!(UnicodePropertyEscape, name) == 8); + assert!(offset_of!(UnicodePropertyEscape, value) == 16); // Padding: 0 bytes assert!(size_of::() == 8); @@ -256,10 +256,10 @@ const _: () = { assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(CharacterClass, span) == 0); - assert!(offset_of!(CharacterClass, negative) == 8); - assert!(offset_of!(CharacterClass, strings) == 9); - assert!(offset_of!(CharacterClass, kind) == 10); - assert!(offset_of!(CharacterClass, body) == 12); + assert!(offset_of!(CharacterClass, negative) == 24); + assert!(offset_of!(CharacterClass, strings) == 25); + assert!(offset_of!(CharacterClass, kind) == 26); + assert!(offset_of!(CharacterClass, body) == 8); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -278,15 +278,15 @@ const _: () = { assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(ClassStringDisjunction, span) == 0); - assert!(offset_of!(ClassStringDisjunction, strings) == 8); - assert!(offset_of!(ClassStringDisjunction, body) == 12); + assert!(offset_of!(ClassStringDisjunction, strings) == 24); + assert!(offset_of!(ClassStringDisjunction, body) == 8); // Padding: 3 bytes assert!(size_of::() == 28); assert!(align_of::() == 4); assert!(offset_of!(ClassString, span) == 0); - assert!(offset_of!(ClassString, strings) == 8); - assert!(offset_of!(ClassString, body) == 12); + assert!(offset_of!(ClassString, strings) == 24); + assert!(offset_of!(ClassString, body) == 8); // Padding: 0 bytes assert!(size_of::() == 40); diff --git a/crates/oxc_syntax/src/generated/assert_layouts.rs b/crates/oxc_syntax/src/generated/assert_layouts.rs index db4c6fb4795e5..0b05a017c4bf9 100644 --- a/crates/oxc_syntax/src/generated/assert_layouts.rs +++ b/crates/oxc_syntax/src/generated/assert_layouts.rs @@ -18,8 +18,8 @@ const _: () = { // Padding: 0 bytes assert!(size_of::() == 24); assert!(align_of::() == 8); - assert!(offset_of!(NameSpan, name) == 0); - assert!(offset_of!(NameSpan, span) == 16); + assert!(offset_of!(NameSpan, name) == 8); + assert!(offset_of!(NameSpan, span) == 0); // Padding: 7 bytes assert!(size_of::() == 96); @@ -36,8 +36,8 @@ const _: () = { // Padding: 7 bytes assert!(size_of::() == 144); assert!(align_of::() == 8); - assert!(offset_of!(ExportEntry, statement_span) == 0); - assert!(offset_of!(ExportEntry, span) == 8); + assert!(offset_of!(ExportEntry, statement_span) == 8); + assert!(offset_of!(ExportEntry, span) == 0); assert!(offset_of!(ExportEntry, module_request) == 16); assert!(offset_of!(ExportEntry, import_name) == 40); assert!(offset_of!(ExportEntry, export_name) == 72); @@ -102,8 +102,8 @@ const _: () = { // Padding: 0 bytes assert!(size_of::() == 16); assert!(align_of::() == 4); - assert!(offset_of!(NameSpan, name) == 0); - assert!(offset_of!(NameSpan, span) == 8); + assert!(offset_of!(NameSpan, name) == 8); + assert!(offset_of!(NameSpan, span) == 0); // Padding: 3 bytes assert!(size_of::() == 64); @@ -120,8 +120,8 @@ const _: () = { // Padding: 3 bytes assert!(size_of::() == 96); assert!(align_of::() == 4); - assert!(offset_of!(ExportEntry, statement_span) == 0); - assert!(offset_of!(ExportEntry, span) == 8); + assert!(offset_of!(ExportEntry, statement_span) == 8); + assert!(offset_of!(ExportEntry, span) == 0); assert!(offset_of!(ExportEntry, module_request) == 16); assert!(offset_of!(ExportEntry, import_name) == 32); assert!(offset_of!(ExportEntry, export_name) == 52); diff --git a/crates/oxc_syntax/src/module_record.rs b/crates/oxc_syntax/src/module_record.rs index d1ea3ca066e6e..8ff3e99719293 100644 --- a/crates/oxc_syntax/src/module_record.rs +++ b/crates/oxc_syntax/src/module_record.rs @@ -100,7 +100,7 @@ pub struct NameSpan<'a> { impl<'a> NameSpan<'a> { /// Constructor pub fn new(name: Atom<'a>, span: Span) -> Self { - Self { name, span } + Self { span, name } } } diff --git a/napi/parser/generated/deserialize/js.js b/napi/parser/generated/deserialize/js.js index fcc8b9db7445f..0d594d89b8b38 100644 --- a/napi/parser/generated/deserialize/js.js +++ b/napi/parser/generated/deserialize/js.js @@ -35,8 +35,8 @@ function deserialize(buffer, sourceTextInput, sourceLenInput) { } function deserializeProgram(pos) { - const body = deserializeVecDirective(pos + 80); - body.push(...deserializeVecStatement(pos + 104)); + const body = deserializeVecDirective(pos + 72); + body.push(...deserializeVecStatement(pos + 96)); const start = deserializeU32(pos); const end = deserializeU32(pos + 4); @@ -46,8 +46,8 @@ function deserializeProgram(pos) { start, end, body, - sourceType: deserializeModuleKind(pos + 9), - hashbang: deserializeOptionHashbang(pos + 56), + sourceType: deserializeModuleKind(pos + 125), + hashbang: deserializeOptionHashbang(pos + 48), }; return program; } @@ -123,12 +123,12 @@ function deserializeObjectProperty(pos) { type: 'Property', start: deserializeU32(pos), end: deserializeU32(pos + 4), - method: deserializeBool(pos + 48), - shorthand: deserializeBool(pos + 49), - computed: deserializeBool(pos + 50), - key: deserializePropertyKey(pos + 16), - value: deserializeExpression(pos + 32), - kind: deserializePropertyKind(pos + 8), + method: deserializeBool(pos + 41), + shorthand: deserializeBool(pos + 42), + computed: deserializeBool(pos + 43), + key: deserializePropertyKey(pos + 8), + value: deserializeExpression(pos + 24), + kind: deserializePropertyKind(pos + 40), }; } @@ -252,9 +252,9 @@ function deserializeUpdateExpression(pos) { type: 'UpdateExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeUpdateOperator(pos + 8), - prefix: deserializeBool(pos + 9), - argument: deserializeSimpleAssignmentTarget(pos + 16), + operator: deserializeUpdateOperator(pos + 24), + prefix: deserializeBool(pos + 25), + argument: deserializeSimpleAssignmentTarget(pos + 8), }; } @@ -263,9 +263,9 @@ function deserializeUnaryExpression(pos) { type: 'UnaryExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeUnaryOperator(pos + 8), + operator: deserializeUnaryOperator(pos + 24), prefix: true, - argument: deserializeExpression(pos + 16), + argument: deserializeExpression(pos + 8), }; } @@ -275,8 +275,8 @@ function deserializeBinaryExpression(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), left: deserializeExpression(pos + 8), - operator: deserializeBinaryOperator(pos + 24), - right: deserializeExpression(pos + 32), + operator: deserializeBinaryOperator(pos + 40), + right: deserializeExpression(pos + 24), }; } @@ -297,8 +297,8 @@ function deserializeLogicalExpression(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), left: deserializeExpression(pos + 8), - operator: deserializeLogicalOperator(pos + 24), - right: deserializeExpression(pos + 32), + operator: deserializeLogicalOperator(pos + 40), + right: deserializeExpression(pos + 24), }; } @@ -318,9 +318,9 @@ function deserializeAssignmentExpression(pos) { type: 'AssignmentExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeAssignmentOperator(pos + 8), - left: deserializeAssignmentTarget(pos + 16), - right: deserializeExpression(pos + 32), + operator: deserializeAssignmentOperator(pos + 40), + left: deserializeAssignmentTarget(pos + 8), + right: deserializeExpression(pos + 24), }; } @@ -486,8 +486,8 @@ function deserializeVariableDeclaration(pos) { type: 'VariableDeclaration', start: deserializeU32(pos), end: deserializeU32(pos + 4), - declarations: deserializeVecVariableDeclarator(pos + 16), - kind: deserializeVariableDeclarationKind(pos + 8), + declarations: deserializeVecVariableDeclarator(pos + 8), + kind: deserializeVariableDeclarationKind(pos + 32), }; } @@ -496,8 +496,8 @@ function deserializeVariableDeclarator(pos) { type: 'VariableDeclarator', start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeBindingPattern(pos + 16), - init: deserializeOptionExpression(pos + 48), + id: deserializeBindingPattern(pos + 8), + init: deserializeOptionExpression(pos + 40), }; } @@ -577,10 +577,10 @@ function deserializeForOfStatement(pos) { type: 'ForOfStatement', start: deserializeU32(pos), end: deserializeU32(pos + 4), - await: deserializeBool(pos + 8), - left: deserializeForStatementLeft(pos + 16), - right: deserializeExpression(pos + 32), - body: deserializeStatement(pos + 48), + await: deserializeBool(pos + 60), + left: deserializeForStatementLeft(pos + 8), + right: deserializeExpression(pos + 24), + body: deserializeStatement(pos + 40), }; } @@ -759,24 +759,24 @@ function deserializeBindingRestElement(pos) { } function deserializeFunction(pos) { - const params = deserializeBoxFormalParameters(pos + 72); + const params = deserializeBoxFormalParameters(pos + 56); return { - type: deserializeFunctionType(pos + 8), + type: deserializeFunctionType(pos + 84), start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeOptionBindingIdentifier(pos + 16), + id: deserializeOptionBindingIdentifier(pos + 8), expression: false, - generator: deserializeBool(pos + 48), - async: deserializeBool(pos + 49), + generator: deserializeBool(pos + 85), + async: deserializeBool(pos + 86), params, - body: deserializeOptionBoxFunctionBody(pos + 88), + body: deserializeOptionBoxFunctionBody(pos + 72), }; } function deserializeFormalParameters(pos) { - const params = deserializeVecFormalParameter(pos + 16); - if (uint32[(pos + 40) >> 2] !== 0 && uint32[(pos + 44) >> 2] !== 0) { - pos = uint32[(pos + 40) >> 2]; + const params = deserializeVecFormalParameter(pos + 8); + if (uint32[(pos + 32) >> 2] !== 0 && uint32[(pos + 36) >> 2] !== 0) { + pos = uint32[(pos + 32) >> 2]; params.push({ type: 'RestElement', start: deserializeU32(pos), @@ -803,8 +803,8 @@ function deserializeFunctionBody(pos) { } function deserializeArrowFunctionExpression(pos) { - const expression = deserializeBool(pos + 8); - let body = deserializeBoxFunctionBody(pos + 40); + const expression = deserializeBool(pos + 44); + let body = deserializeBoxFunctionBody(pos + 32); return { type: 'ArrowFunctionExpression', start: deserializeU32(pos), @@ -812,8 +812,8 @@ function deserializeArrowFunctionExpression(pos) { id: null, expression, generator: false, - async: deserializeBool(pos + 9), - params: deserializeBoxFormalParameters(pos + 24), + async: deserializeBool(pos + 45), + params: deserializeBoxFormalParameters(pos + 16), body: expression ? body.body[0].expression : body, }; } @@ -823,19 +823,19 @@ function deserializeYieldExpression(pos) { type: 'YieldExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - delegate: deserializeBool(pos + 8), - argument: deserializeOptionExpression(pos + 16), + delegate: deserializeBool(pos + 24), + argument: deserializeOptionExpression(pos + 8), }; } function deserializeClass(pos) { return { - type: deserializeClassType(pos + 8), + type: deserializeClassType(pos + 132), start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeOptionBindingIdentifier(pos + 40), - superClass: deserializeOptionExpression(pos + 80), - body: deserializeBoxClassBody(pos + 128), + id: deserializeOptionBindingIdentifier(pos + 32), + superClass: deserializeOptionExpression(pos + 72), + body: deserializeBoxClassBody(pos + 120), }; } @@ -850,26 +850,26 @@ function deserializeClassBody(pos) { function deserializeMethodDefinition(pos) { return { - type: deserializeMethodDefinitionType(pos + 8), + type: deserializeMethodDefinitionType(pos + 56), start: deserializeU32(pos), end: deserializeU32(pos + 4), - static: deserializeBool(pos + 66), - computed: deserializeBool(pos + 65), - key: deserializePropertyKey(pos + 40), - kind: deserializeMethodDefinitionKind(pos + 64), - value: deserializeBoxFunction(pos + 56), + static: deserializeBool(pos + 59), + computed: deserializeBool(pos + 58), + key: deserializePropertyKey(pos + 32), + kind: deserializeMethodDefinitionKind(pos + 57), + value: deserializeBoxFunction(pos + 48), }; } function deserializePropertyDefinition(pos) { return { - type: deserializePropertyDefinitionType(pos + 8), + type: deserializePropertyDefinitionType(pos + 72), start: deserializeU32(pos), end: deserializeU32(pos + 4), - static: deserializeBool(pos + 81), - computed: deserializeBool(pos + 80), - key: deserializePropertyKey(pos + 40), - value: deserializeOptionExpression(pos + 64), + static: deserializeBool(pos + 74), + computed: deserializeBool(pos + 73), + key: deserializePropertyKey(pos + 32), + value: deserializeOptionExpression(pos + 56), }; } @@ -893,13 +893,13 @@ function deserializeStaticBlock(pos) { function deserializeAccessorProperty(pos) { return { - type: deserializeAccessorPropertyType(pos + 8), + type: deserializeAccessorPropertyType(pos + 72), start: deserializeU32(pos), end: deserializeU32(pos + 4), - key: deserializePropertyKey(pos + 40), - value: deserializeOptionExpression(pos + 64), - computed: deserializeBool(pos + 80), - static: deserializeBool(pos + 81), + key: deserializePropertyKey(pos + 32), + value: deserializeOptionExpression(pos + 56), + computed: deserializeBool(pos + 73), + static: deserializeBool(pos + 74), }; } @@ -916,7 +916,7 @@ function deserializeImportExpression(pos) { function deserializeImportDeclaration(pos) { let specifiers = deserializeOptionVecImportDeclarationSpecifier(pos + 8); if (specifiers === null) specifiers = []; - const withClause = deserializeOptionBoxWithClause(pos + 88); + const withClause = deserializeOptionBoxWithClause(pos + 80); return { type: 'ImportDeclaration', start: deserializeU32(pos), @@ -972,7 +972,7 @@ function deserializeImportAttribute(pos) { } function deserializeExportNamedDeclaration(pos) { - const withClause = deserializeOptionBoxWithClause(pos + 104); + const withClause = deserializeOptionBoxWithClause(pos + 96); return { type: 'ExportNamedDeclaration', start: deserializeU32(pos), @@ -1298,8 +1298,8 @@ function deserializeTSEnumDeclaration(pos) { end: deserializeU32(pos + 4), id: deserializeBindingIdentifier(pos + 8), body: deserializeTSEnumBody(pos + 40), - const: deserializeBool(pos + 72), - declare: deserializeBool(pos + 73), + const: deserializeBool(pos + 76), + declare: deserializeBool(pos + 77), }; } @@ -1385,8 +1385,8 @@ function deserializeTSTypeOperator(pos) { type: 'TSTypeOperator', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeTSTypeOperatorOperator(pos + 8), - typeAnnotation: deserializeTSType(pos + 16), + operator: deserializeTSTypeOperatorOperator(pos + 24), + typeAnnotation: deserializeTSType(pos + 8), }; } @@ -1619,7 +1619,7 @@ function deserializeTSTypeAliasDeclaration(pos) { id: deserializeBindingIdentifier(pos + 8), typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 40), typeAnnotation: deserializeTSType(pos + 48), - declare: deserializeBool(pos + 64), + declare: deserializeBool(pos + 68), }; } @@ -1667,7 +1667,7 @@ function deserializeTSInterfaceDeclaration(pos) { typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 40), extends: deserializeVecTSInterfaceHeritage(pos + 48), body: deserializeBoxTSInterfaceBody(pos + 72), - declare: deserializeBool(pos + 80), + declare: deserializeBool(pos + 84), }; } @@ -1685,11 +1685,11 @@ function deserializeTSPropertySignature(pos) { type: 'TSPropertySignature', start: deserializeU32(pos), end: deserializeU32(pos + 4), - computed: deserializeBool(pos + 8), - optional: deserializeBool(pos + 9), - readonly: deserializeBool(pos + 10), - key: deserializePropertyKey(pos + 16), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 32), + computed: deserializeBool(pos + 32), + optional: deserializeBool(pos + 33), + readonly: deserializeBool(pos + 34), + key: deserializePropertyKey(pos + 8), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 24), accessibility: null, static: false, }; @@ -1723,20 +1723,20 @@ function deserializeTSCallSignatureDeclaration(pos) { } function deserializeTSMethodSignature(pos) { - const params = deserializeBoxFormalParameters(pos + 48); - const thisParam = deserializeOptionBoxTSThisParameter(pos + 40); + const params = deserializeBoxFormalParameters(pos + 40); + const thisParam = deserializeOptionBoxTSThisParameter(pos + 32); if (thisParam !== null) params.unshift(thisParam); return { type: 'TSMethodSignature', start: deserializeU32(pos), end: deserializeU32(pos + 4), key: deserializePropertyKey(pos + 8), - computed: deserializeBool(pos + 24), - optional: deserializeBool(pos + 25), - kind: deserializeTSMethodSignatureKind(pos + 26), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 32), + computed: deserializeBool(pos + 60), + optional: deserializeBool(pos + 61), + kind: deserializeTSMethodSignatureKind(pos + 62), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 24), params, - returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56), + returnType: deserializeOptionBoxTSTypeAnnotation(pos + 48), accessibility: null, readonly: false, static: false, @@ -1782,17 +1782,17 @@ function deserializeTSTypePredicate(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), parameterName: deserializeTSTypePredicateName(pos + 8), - asserts: deserializeBool(pos + 24), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 32), + asserts: deserializeBool(pos + 32), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 24), }; } function deserializeTSModuleDeclaration(pos) { - const kind = deserializeTSModuleDeclarationKind(pos + 80), + const kind = deserializeTSModuleDeclarationKind(pos + 84), global = kind === 'global', start = deserializeU32(pos), end = deserializeU32(pos + 4), - declare = deserializeBool(pos + 81); + declare = deserializeBool(pos + 85); let id = deserializeTSModuleDeclarationName(pos + 8), body = deserializeOptionTSModuleDeclarationBody(pos + 64); @@ -1904,15 +1904,15 @@ function deserializeTSConstructorType(pos) { type: 'TSConstructorType', start: deserializeU32(pos), end: deserializeU32(pos + 4), - abstract: deserializeBool(pos + 8), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 16), - params: deserializeBoxFormalParameters(pos + 24), - returnType: deserializeBoxTSTypeAnnotation(pos + 32), + abstract: deserializeBool(pos + 32), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8), + params: deserializeBoxFormalParameters(pos + 16), + returnType: deserializeBoxTSTypeAnnotation(pos + 24), }; } function deserializeTSMappedType(pos) { - let optional = deserializeOptionTSMappedTypeModifierOperator(pos + 48); + let optional = deserializeOptionTSMappedTypeModifierOperator(pos + 52); if (optional === null) optional = false; const typeParameter = deserializeBoxTSTypeParameter(pos + 8); return { @@ -1922,7 +1922,7 @@ function deserializeTSMappedType(pos) { nameType: deserializeOptionTSType(pos + 16), typeAnnotation: deserializeOptionTSType(pos + 32), optional, - readonly: deserializeOptionTSMappedTypeModifierOperator(pos + 49), + readonly: deserializeOptionTSMappedTypeModifierOperator(pos + 53), key: typeParameter.name, constraint: typeParameter.constraint, }; @@ -2077,9 +2077,9 @@ function deserializeComment(pos) { function deserializeNameSpan(pos) { return { - value: deserializeStr(pos), - start: deserializeU32(pos + 16), - end: deserializeU32(pos + 20), + value: deserializeStr(pos + 8), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), }; } @@ -2093,8 +2093,8 @@ function deserializeImportEntry(pos) { function deserializeExportEntry(pos) { return { - start: deserializeU32(pos + 8), - end: deserializeU32(pos + 12), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), moduleRequest: deserializeOptionNameSpan(pos + 16), importName: deserializeExportImportName(pos + 40), exportName: deserializeExportExportName(pos + 72), @@ -2127,36 +2127,36 @@ function deserializeSourceType(pos) { function deserializeRawTransferData(pos) { return { program: deserializeProgram(pos), - comments: deserializeVecComment(pos + 136), - module: deserializeEcmaScriptModule(pos + 160), - errors: deserializeVecError(pos + 264), + comments: deserializeVecComment(pos + 128), + module: deserializeEcmaScriptModule(pos + 152), + errors: deserializeVecError(pos + 256), }; } function deserializeError(pos) { return { - severity: deserializeErrorSeverity(pos), - message: deserializeStr(pos + 8), - labels: deserializeVecErrorLabel(pos + 24), - helpMessage: deserializeOptionStr(pos + 48), + severity: deserializeErrorSeverity(pos + 56), + message: deserializeStr(pos), + labels: deserializeVecErrorLabel(pos + 16), + helpMessage: deserializeOptionStr(pos + 40), }; } function deserializeErrorLabel(pos) { return { - message: deserializeOptionStr(pos), - start: deserializeU32(pos + 16), - end: deserializeU32(pos + 20), + message: deserializeOptionStr(pos + 8), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), }; } function deserializeEcmaScriptModule(pos) { return { - hasModuleSyntax: deserializeBool(pos), - staticImports: deserializeVecStaticImport(pos + 8), - staticExports: deserializeVecStaticExport(pos + 32), - dynamicImports: deserializeVecDynamicImport(pos + 56), - importMetas: deserializeVecSpan(pos + 80), + hasModuleSyntax: deserializeBool(pos + 96), + staticImports: deserializeVecStaticImport(pos), + staticExports: deserializeVecStaticExport(pos + 24), + dynamicImports: deserializeVecDynamicImport(pos + 48), + importMetas: deserializeVecSpan(pos + 72), }; } @@ -4532,7 +4532,7 @@ function deserializeVecVariableDeclarator(pos) { pos = uint32[pos32]; for (let i = 0; i < len; i++) { arr.push(deserializeVariableDeclarator(pos)); - pos += 72; + pos += 64; } return arr; } @@ -5262,7 +5262,7 @@ function deserializeU32(pos) { } function deserializeOptionNameSpan(pos) { - if (uint32[pos >> 2] === 0 && uint32[(pos + 4) >> 2] === 0) return null; + if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null; return deserializeNameSpan(pos); } diff --git a/napi/parser/generated/deserialize/ts.js b/napi/parser/generated/deserialize/ts.js index 0e9bd8bea13a6..7547afab6f25c 100644 --- a/napi/parser/generated/deserialize/ts.js +++ b/napi/parser/generated/deserialize/ts.js @@ -35,8 +35,8 @@ function deserialize(buffer, sourceTextInput, sourceLenInput) { } function deserializeProgram(pos) { - const body = deserializeVecDirective(pos + 80); - body.push(...deserializeVecStatement(pos + 104)); + const body = deserializeVecDirective(pos + 72); + body.push(...deserializeVecStatement(pos + 96)); const end = deserializeU32(pos + 4); @@ -62,8 +62,8 @@ function deserializeProgram(pos) { start, end, body, - sourceType: deserializeModuleKind(pos + 9), - hashbang: deserializeOptionHashbang(pos + 56), + sourceType: deserializeModuleKind(pos + 125), + hashbang: deserializeOptionHashbang(pos + 48), }; return program; } @@ -151,12 +151,12 @@ function deserializeObjectProperty(pos) { type: 'Property', start: deserializeU32(pos), end: deserializeU32(pos + 4), - method: deserializeBool(pos + 48), - shorthand: deserializeBool(pos + 49), - computed: deserializeBool(pos + 50), - key: deserializePropertyKey(pos + 16), - value: deserializeExpression(pos + 32), - kind: deserializePropertyKind(pos + 8), + method: deserializeBool(pos + 41), + shorthand: deserializeBool(pos + 42), + computed: deserializeBool(pos + 43), + key: deserializePropertyKey(pos + 8), + value: deserializeExpression(pos + 24), + kind: deserializePropertyKind(pos + 40), optional: false, }; } @@ -284,9 +284,9 @@ function deserializeUpdateExpression(pos) { type: 'UpdateExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeUpdateOperator(pos + 8), - prefix: deserializeBool(pos + 9), - argument: deserializeSimpleAssignmentTarget(pos + 16), + operator: deserializeUpdateOperator(pos + 24), + prefix: deserializeBool(pos + 25), + argument: deserializeSimpleAssignmentTarget(pos + 8), }; } @@ -295,9 +295,9 @@ function deserializeUnaryExpression(pos) { type: 'UnaryExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeUnaryOperator(pos + 8), + operator: deserializeUnaryOperator(pos + 24), prefix: true, - argument: deserializeExpression(pos + 16), + argument: deserializeExpression(pos + 8), }; } @@ -307,8 +307,8 @@ function deserializeBinaryExpression(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), left: deserializeExpression(pos + 8), - operator: deserializeBinaryOperator(pos + 24), - right: deserializeExpression(pos + 32), + operator: deserializeBinaryOperator(pos + 40), + right: deserializeExpression(pos + 24), }; } @@ -329,8 +329,8 @@ function deserializeLogicalExpression(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), left: deserializeExpression(pos + 8), - operator: deserializeLogicalOperator(pos + 24), - right: deserializeExpression(pos + 32), + operator: deserializeLogicalOperator(pos + 40), + right: deserializeExpression(pos + 24), }; } @@ -350,9 +350,9 @@ function deserializeAssignmentExpression(pos) { type: 'AssignmentExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeAssignmentOperator(pos + 8), - left: deserializeAssignmentTarget(pos + 16), - right: deserializeExpression(pos + 32), + operator: deserializeAssignmentOperator(pos + 40), + left: deserializeAssignmentTarget(pos + 8), + right: deserializeExpression(pos + 24), }; } @@ -536,9 +536,9 @@ function deserializeVariableDeclaration(pos) { type: 'VariableDeclaration', start: deserializeU32(pos), end: deserializeU32(pos + 4), - declarations: deserializeVecVariableDeclarator(pos + 16), - kind: deserializeVariableDeclarationKind(pos + 8), - declare: deserializeBool(pos + 40), + declarations: deserializeVecVariableDeclarator(pos + 8), + kind: deserializeVariableDeclarationKind(pos + 32), + declare: deserializeBool(pos + 33), }; } @@ -547,9 +547,9 @@ function deserializeVariableDeclarator(pos) { type: 'VariableDeclarator', start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeBindingPattern(pos + 16), - init: deserializeOptionExpression(pos + 48), - definite: deserializeBool(pos + 64), + id: deserializeBindingPattern(pos + 8), + init: deserializeOptionExpression(pos + 40), + definite: deserializeBool(pos + 57), }; } @@ -630,10 +630,10 @@ function deserializeForOfStatement(pos) { type: 'ForOfStatement', start: deserializeU32(pos), end: deserializeU32(pos + 4), - await: deserializeBool(pos + 8), - left: deserializeForStatementLeft(pos + 16), - right: deserializeExpression(pos + 32), - body: deserializeStatement(pos + 48), + await: deserializeBool(pos + 60), + left: deserializeForStatementLeft(pos + 8), + right: deserializeExpression(pos + 24), + body: deserializeStatement(pos + 40), }; } @@ -830,29 +830,29 @@ function deserializeBindingRestElement(pos) { } function deserializeFunction(pos) { - const params = deserializeBoxFormalParameters(pos + 72); - const thisParam = deserializeOptionBoxTSThisParameter(pos + 64); + const params = deserializeBoxFormalParameters(pos + 56); + const thisParam = deserializeOptionBoxTSThisParameter(pos + 48); if (thisParam !== null) params.unshift(thisParam); return { - type: deserializeFunctionType(pos + 8), + type: deserializeFunctionType(pos + 84), start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeOptionBindingIdentifier(pos + 16), + id: deserializeOptionBindingIdentifier(pos + 8), expression: false, - generator: deserializeBool(pos + 48), - async: deserializeBool(pos + 49), + generator: deserializeBool(pos + 85), + async: deserializeBool(pos + 86), params, - body: deserializeOptionBoxFunctionBody(pos + 88), - declare: deserializeBool(pos + 50), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 56), - returnType: deserializeOptionBoxTSTypeAnnotation(pos + 80), + body: deserializeOptionBoxFunctionBody(pos + 72), + declare: deserializeBool(pos + 87), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 40), + returnType: deserializeOptionBoxTSTypeAnnotation(pos + 64), }; } function deserializeFormalParameters(pos) { - const params = deserializeVecFormalParameter(pos + 16); - if (uint32[(pos + 40) >> 2] !== 0 && uint32[(pos + 44) >> 2] !== 0) { - pos = uint32[(pos + 40) >> 2]; + const params = deserializeVecFormalParameter(pos + 8); + if (uint32[(pos + 32) >> 2] !== 0 && uint32[(pos + 36) >> 2] !== 0) { + pos = uint32[(pos + 32) >> 2]; params.push({ type: 'RestElement', start: deserializeU32(pos), @@ -909,8 +909,8 @@ function deserializeFunctionBody(pos) { } function deserializeArrowFunctionExpression(pos) { - const expression = deserializeBool(pos + 8); - let body = deserializeBoxFunctionBody(pos + 40); + const expression = deserializeBool(pos + 44); + let body = deserializeBoxFunctionBody(pos + 32); return { type: 'ArrowFunctionExpression', start: deserializeU32(pos), @@ -918,11 +918,11 @@ function deserializeArrowFunctionExpression(pos) { id: null, expression, generator: false, - async: deserializeBool(pos + 9), - params: deserializeBoxFormalParameters(pos + 24), + async: deserializeBool(pos + 45), + params: deserializeBoxFormalParameters(pos + 16), body: expression ? body.body[0].expression : body, - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 16), - returnType: deserializeOptionBoxTSTypeAnnotation(pos + 32), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8), + returnType: deserializeOptionBoxTSTypeAnnotation(pos + 24), }; } @@ -931,25 +931,25 @@ function deserializeYieldExpression(pos) { type: 'YieldExpression', start: deserializeU32(pos), end: deserializeU32(pos + 4), - delegate: deserializeBool(pos + 8), - argument: deserializeOptionExpression(pos + 16), + delegate: deserializeBool(pos + 24), + argument: deserializeOptionExpression(pos + 8), }; } function deserializeClass(pos) { return { - type: deserializeClassType(pos + 8), + type: deserializeClassType(pos + 132), start: deserializeU32(pos), end: deserializeU32(pos + 4), - id: deserializeOptionBindingIdentifier(pos + 40), - superClass: deserializeOptionExpression(pos + 80), - body: deserializeBoxClassBody(pos + 128), - decorators: deserializeVecDecorator(pos + 16), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 72), - superTypeArguments: deserializeOptionBoxTSTypeParameterInstantiation(pos + 96), - implements: deserializeVecTSClassImplements(pos + 104), - abstract: deserializeBool(pos + 136), - declare: deserializeBool(pos + 137), + id: deserializeOptionBindingIdentifier(pos + 32), + superClass: deserializeOptionExpression(pos + 72), + body: deserializeBoxClassBody(pos + 120), + decorators: deserializeVecDecorator(pos + 8), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 64), + superTypeArguments: deserializeOptionBoxTSTypeParameterInstantiation(pos + 88), + implements: deserializeVecTSClassImplements(pos + 96), + abstract: deserializeBool(pos + 133), + declare: deserializeBool(pos + 134), }; } @@ -963,8 +963,8 @@ function deserializeClassBody(pos) { } function deserializeMethodDefinition(pos) { - const kind = deserializeMethodDefinitionKind(pos + 64); - let key = deserializePropertyKey(pos + 40); + const kind = deserializeMethodDefinitionKind(pos + 57); + let key = deserializePropertyKey(pos + 32); if (kind === 'constructor') { key = { type: 'Identifier', @@ -977,38 +977,38 @@ function deserializeMethodDefinition(pos) { }; } return { - type: deserializeMethodDefinitionType(pos + 8), + type: deserializeMethodDefinitionType(pos + 56), start: deserializeU32(pos), end: deserializeU32(pos + 4), - static: deserializeBool(pos + 66), - computed: deserializeBool(pos + 65), + static: deserializeBool(pos + 59), + computed: deserializeBool(pos + 58), key, kind, - value: deserializeBoxFunction(pos + 56), - decorators: deserializeVecDecorator(pos + 16), - override: deserializeBool(pos + 67), - optional: deserializeBool(pos + 68), - accessibility: deserializeOptionTSAccessibility(pos + 69), + value: deserializeBoxFunction(pos + 48), + decorators: deserializeVecDecorator(pos + 8), + override: deserializeBool(pos + 60), + optional: deserializeBool(pos + 61), + accessibility: deserializeOptionTSAccessibility(pos + 62), }; } function deserializePropertyDefinition(pos) { return { - type: deserializePropertyDefinitionType(pos + 8), + type: deserializePropertyDefinitionType(pos + 72), start: deserializeU32(pos), end: deserializeU32(pos + 4), - static: deserializeBool(pos + 81), - computed: deserializeBool(pos + 80), - key: deserializePropertyKey(pos + 40), - value: deserializeOptionExpression(pos + 64), - decorators: deserializeVecDecorator(pos + 16), - declare: deserializeBool(pos + 82), - override: deserializeBool(pos + 83), - optional: deserializeBool(pos + 84), - definite: deserializeBool(pos + 85), - readonly: deserializeBool(pos + 86), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 56), - accessibility: deserializeOptionTSAccessibility(pos + 87), + static: deserializeBool(pos + 74), + computed: deserializeBool(pos + 73), + key: deserializePropertyKey(pos + 32), + value: deserializeOptionExpression(pos + 56), + decorators: deserializeVecDecorator(pos + 8), + declare: deserializeBool(pos + 75), + override: deserializeBool(pos + 76), + optional: deserializeBool(pos + 77), + definite: deserializeBool(pos + 78), + readonly: deserializeBool(pos + 79), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 48), + accessibility: deserializeOptionTSAccessibility(pos + 80), }; } @@ -1032,19 +1032,19 @@ function deserializeStaticBlock(pos) { function deserializeAccessorProperty(pos) { return { - type: deserializeAccessorPropertyType(pos + 8), + type: deserializeAccessorPropertyType(pos + 72), start: deserializeU32(pos), end: deserializeU32(pos + 4), - key: deserializePropertyKey(pos + 40), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 56), - value: deserializeOptionExpression(pos + 64), - computed: deserializeBool(pos + 80), - static: deserializeBool(pos + 81), - decorators: deserializeVecDecorator(pos + 16), - definite: deserializeBool(pos + 83), - accessibility: deserializeOptionTSAccessibility(pos + 84), + key: deserializePropertyKey(pos + 32), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 48), + value: deserializeOptionExpression(pos + 56), + computed: deserializeBool(pos + 73), + static: deserializeBool(pos + 74), + decorators: deserializeVecDecorator(pos + 8), + definite: deserializeBool(pos + 76), + accessibility: deserializeOptionTSAccessibility(pos + 77), optional: false, - override: deserializeBool(pos + 82), + override: deserializeBool(pos + 75), readonly: false, declare: false, }; @@ -1063,7 +1063,7 @@ function deserializeImportExpression(pos) { function deserializeImportDeclaration(pos) { let specifiers = deserializeOptionVecImportDeclarationSpecifier(pos + 8); if (specifiers === null) specifiers = []; - const withClause = deserializeOptionBoxWithClause(pos + 88); + const withClause = deserializeOptionBoxWithClause(pos + 80); return { type: 'ImportDeclaration', start: deserializeU32(pos), @@ -1071,7 +1071,7 @@ function deserializeImportDeclaration(pos) { specifiers, source: deserializeStringLiteral(pos + 32), attributes: withClause === null ? [] : withClause.attributes, - importKind: deserializeImportOrExportKind(pos + 96), + importKind: deserializeImportOrExportKind(pos + 89), }; } @@ -1121,7 +1121,7 @@ function deserializeImportAttribute(pos) { } function deserializeExportNamedDeclaration(pos) { - const withClause = deserializeOptionBoxWithClause(pos + 104); + const withClause = deserializeOptionBoxWithClause(pos + 96); return { type: 'ExportNamedDeclaration', start: deserializeU32(pos), @@ -1130,7 +1130,7 @@ function deserializeExportNamedDeclaration(pos) { specifiers: deserializeVecExportSpecifier(pos + 24), source: deserializeOptionStringLiteral(pos + 48), attributes: withClause === null ? [] : withClause.attributes, - exportKind: deserializeImportOrExportKind(pos + 96), + exportKind: deserializeImportOrExportKind(pos + 104), }; } @@ -1450,8 +1450,8 @@ function deserializeTSEnumDeclaration(pos) { end: deserializeU32(pos + 4), id: deserializeBindingIdentifier(pos + 8), body: deserializeTSEnumBody(pos + 40), - const: deserializeBool(pos + 72), - declare: deserializeBool(pos + 73), + const: deserializeBool(pos + 76), + declare: deserializeBool(pos + 77), }; } @@ -1537,8 +1537,8 @@ function deserializeTSTypeOperator(pos) { type: 'TSTypeOperator', start: deserializeU32(pos), end: deserializeU32(pos + 4), - operator: deserializeTSTypeOperatorOperator(pos + 8), - typeAnnotation: deserializeTSType(pos + 16), + operator: deserializeTSTypeOperatorOperator(pos + 24), + typeAnnotation: deserializeTSType(pos + 8), }; } @@ -1771,7 +1771,7 @@ function deserializeTSTypeAliasDeclaration(pos) { id: deserializeBindingIdentifier(pos + 8), typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 40), typeAnnotation: deserializeTSType(pos + 48), - declare: deserializeBool(pos + 64), + declare: deserializeBool(pos + 68), }; } @@ -1819,7 +1819,7 @@ function deserializeTSInterfaceDeclaration(pos) { typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 40), extends: deserializeVecTSInterfaceHeritage(pos + 48), body: deserializeBoxTSInterfaceBody(pos + 72), - declare: deserializeBool(pos + 80), + declare: deserializeBool(pos + 84), }; } @@ -1837,11 +1837,11 @@ function deserializeTSPropertySignature(pos) { type: 'TSPropertySignature', start: deserializeU32(pos), end: deserializeU32(pos + 4), - computed: deserializeBool(pos + 8), - optional: deserializeBool(pos + 9), - readonly: deserializeBool(pos + 10), - key: deserializePropertyKey(pos + 16), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 32), + computed: deserializeBool(pos + 32), + optional: deserializeBool(pos + 33), + readonly: deserializeBool(pos + 34), + key: deserializePropertyKey(pos + 8), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 24), accessibility: null, static: false, }; @@ -1875,20 +1875,20 @@ function deserializeTSCallSignatureDeclaration(pos) { } function deserializeTSMethodSignature(pos) { - const params = deserializeBoxFormalParameters(pos + 48); - const thisParam = deserializeOptionBoxTSThisParameter(pos + 40); + const params = deserializeBoxFormalParameters(pos + 40); + const thisParam = deserializeOptionBoxTSThisParameter(pos + 32); if (thisParam !== null) params.unshift(thisParam); return { type: 'TSMethodSignature', start: deserializeU32(pos), end: deserializeU32(pos + 4), key: deserializePropertyKey(pos + 8), - computed: deserializeBool(pos + 24), - optional: deserializeBool(pos + 25), - kind: deserializeTSMethodSignatureKind(pos + 26), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 32), + computed: deserializeBool(pos + 60), + optional: deserializeBool(pos + 61), + kind: deserializeTSMethodSignatureKind(pos + 62), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 24), params, - returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56), + returnType: deserializeOptionBoxTSTypeAnnotation(pos + 48), accessibility: null, readonly: false, static: false, @@ -1934,17 +1934,17 @@ function deserializeTSTypePredicate(pos) { start: deserializeU32(pos), end: deserializeU32(pos + 4), parameterName: deserializeTSTypePredicateName(pos + 8), - asserts: deserializeBool(pos + 24), - typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 32), + asserts: deserializeBool(pos + 32), + typeAnnotation: deserializeOptionBoxTSTypeAnnotation(pos + 24), }; } function deserializeTSModuleDeclaration(pos) { - const kind = deserializeTSModuleDeclarationKind(pos + 80), + const kind = deserializeTSModuleDeclarationKind(pos + 84), global = kind === 'global', start = deserializeU32(pos), end = deserializeU32(pos + 4), - declare = deserializeBool(pos + 81); + declare = deserializeBool(pos + 85); let id = deserializeTSModuleDeclarationName(pos + 8), body = deserializeOptionTSModuleDeclarationBody(pos + 64); @@ -2056,15 +2056,15 @@ function deserializeTSConstructorType(pos) { type: 'TSConstructorType', start: deserializeU32(pos), end: deserializeU32(pos + 4), - abstract: deserializeBool(pos + 8), - typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 16), - params: deserializeBoxFormalParameters(pos + 24), - returnType: deserializeBoxTSTypeAnnotation(pos + 32), + abstract: deserializeBool(pos + 32), + typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8), + params: deserializeBoxFormalParameters(pos + 16), + returnType: deserializeBoxTSTypeAnnotation(pos + 24), }; } function deserializeTSMappedType(pos) { - let optional = deserializeOptionTSMappedTypeModifierOperator(pos + 48); + let optional = deserializeOptionTSMappedTypeModifierOperator(pos + 52); if (optional === null) optional = false; const typeParameter = deserializeBoxTSTypeParameter(pos + 8); return { @@ -2074,7 +2074,7 @@ function deserializeTSMappedType(pos) { nameType: deserializeOptionTSType(pos + 16), typeAnnotation: deserializeOptionTSType(pos + 32), optional, - readonly: deserializeOptionTSMappedTypeModifierOperator(pos + 49), + readonly: deserializeOptionTSMappedTypeModifierOperator(pos + 53), key: typeParameter.name, constraint: typeParameter.constraint, }; @@ -2229,9 +2229,9 @@ function deserializeComment(pos) { function deserializeNameSpan(pos) { return { - value: deserializeStr(pos), - start: deserializeU32(pos + 16), - end: deserializeU32(pos + 20), + value: deserializeStr(pos + 8), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), }; } @@ -2245,8 +2245,8 @@ function deserializeImportEntry(pos) { function deserializeExportEntry(pos) { return { - start: deserializeU32(pos + 8), - end: deserializeU32(pos + 12), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), moduleRequest: deserializeOptionNameSpan(pos + 16), importName: deserializeExportImportName(pos + 40), exportName: deserializeExportExportName(pos + 72), @@ -2279,36 +2279,36 @@ function deserializeSourceType(pos) { function deserializeRawTransferData(pos) { return { program: deserializeProgram(pos), - comments: deserializeVecComment(pos + 136), - module: deserializeEcmaScriptModule(pos + 160), - errors: deserializeVecError(pos + 264), + comments: deserializeVecComment(pos + 128), + module: deserializeEcmaScriptModule(pos + 152), + errors: deserializeVecError(pos + 256), }; } function deserializeError(pos) { return { - severity: deserializeErrorSeverity(pos), - message: deserializeStr(pos + 8), - labels: deserializeVecErrorLabel(pos + 24), - helpMessage: deserializeOptionStr(pos + 48), + severity: deserializeErrorSeverity(pos + 56), + message: deserializeStr(pos), + labels: deserializeVecErrorLabel(pos + 16), + helpMessage: deserializeOptionStr(pos + 40), }; } function deserializeErrorLabel(pos) { return { - message: deserializeOptionStr(pos), - start: deserializeU32(pos + 16), - end: deserializeU32(pos + 20), + message: deserializeOptionStr(pos + 8), + start: deserializeU32(pos), + end: deserializeU32(pos + 4), }; } function deserializeEcmaScriptModule(pos) { return { - hasModuleSyntax: deserializeBool(pos), - staticImports: deserializeVecStaticImport(pos + 8), - staticExports: deserializeVecStaticExport(pos + 32), - dynamicImports: deserializeVecDynamicImport(pos + 56), - importMetas: deserializeVecSpan(pos + 80), + hasModuleSyntax: deserializeBool(pos + 96), + staticImports: deserializeVecStaticImport(pos), + staticExports: deserializeVecStaticExport(pos + 24), + dynamicImports: deserializeVecDynamicImport(pos + 48), + importMetas: deserializeVecSpan(pos + 72), }; } @@ -4684,7 +4684,7 @@ function deserializeVecVariableDeclarator(pos) { pos = uint32[pos32]; for (let i = 0; i < len; i++) { arr.push(deserializeVariableDeclarator(pos)); - pos += 72; + pos += 64; } return arr; } @@ -5414,7 +5414,7 @@ function deserializeU32(pos) { } function deserializeOptionNameSpan(pos) { - if (uint32[pos >> 2] === 0 && uint32[(pos + 4) >> 2] === 0) return null; + if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null; return deserializeNameSpan(pos); } diff --git a/napi/parser/src/generated/assert_layouts.rs b/napi/parser/src/generated/assert_layouts.rs index 90f16fad16cf1..adc7edf6ad48b 100644 --- a/napi/parser/src/generated/assert_layouts.rs +++ b/napi/parser/src/generated/assert_layouts.rs @@ -10,20 +10,20 @@ use crate::raw_transfer_types::*; #[cfg(target_pointer_width = "64")] const _: () = { // Padding: 0 bytes - assert!(size_of::() == 288); + assert!(size_of::() == 280); assert!(align_of::() == 8); assert!(offset_of!(RawTransferData, program) == 0); - assert!(offset_of!(RawTransferData, comments) == 136); - assert!(offset_of!(RawTransferData, module) == 160); - assert!(offset_of!(RawTransferData, errors) == 264); + assert!(offset_of!(RawTransferData, comments) == 128); + assert!(offset_of!(RawTransferData, module) == 152); + assert!(offset_of!(RawTransferData, errors) == 256); // Padding: 7 bytes assert!(size_of::() == 64); assert!(align_of::() == 8); - assert!(offset_of!(Error, severity) == 0); - assert!(offset_of!(Error, message) == 8); - assert!(offset_of!(Error, labels) == 24); - assert!(offset_of!(Error, help_message) == 48); + assert!(offset_of!(Error, severity) == 56); + assert!(offset_of!(Error, message) == 0); + assert!(offset_of!(Error, labels) == 16); + assert!(offset_of!(Error, help_message) == 40); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -31,17 +31,17 @@ const _: () = { // Padding: 0 bytes assert!(size_of::() == 24); assert!(align_of::() == 8); - assert!(offset_of!(ErrorLabel, message) == 0); - assert!(offset_of!(ErrorLabel, span) == 16); + assert!(offset_of!(ErrorLabel, message) == 8); + assert!(offset_of!(ErrorLabel, span) == 0); // Padding: 7 bytes assert!(size_of::() == 104); assert!(align_of::() == 8); - assert!(offset_of!(EcmaScriptModule, has_module_syntax) == 0); - assert!(offset_of!(EcmaScriptModule, static_imports) == 8); - assert!(offset_of!(EcmaScriptModule, static_exports) == 32); - assert!(offset_of!(EcmaScriptModule, dynamic_imports) == 56); - assert!(offset_of!(EcmaScriptModule, import_metas) == 80); + assert!(offset_of!(EcmaScriptModule, has_module_syntax) == 96); + assert!(offset_of!(EcmaScriptModule, static_imports) == 0); + assert!(offset_of!(EcmaScriptModule, static_exports) == 24); + assert!(offset_of!(EcmaScriptModule, dynamic_imports) == 48); + assert!(offset_of!(EcmaScriptModule, import_metas) == 72); // Padding: 0 bytes assert!(size_of::() == 56); @@ -70,10 +70,10 @@ const _: () = { // Padding: 3 bytes assert!(size_of::() == 36); assert!(align_of::() == 4); - assert!(offset_of!(Error, severity) == 0); - assert!(offset_of!(Error, message) == 4); - assert!(offset_of!(Error, labels) == 12); - assert!(offset_of!(Error, help_message) == 28); + assert!(offset_of!(Error, severity) == 32); + assert!(offset_of!(Error, message) == 0); + assert!(offset_of!(Error, labels) == 8); + assert!(offset_of!(Error, help_message) == 24); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -81,17 +81,17 @@ const _: () = { // Padding: 0 bytes assert!(size_of::() == 16); assert!(align_of::() == 4); - assert!(offset_of!(ErrorLabel, message) == 0); - assert!(offset_of!(ErrorLabel, span) == 8); + assert!(offset_of!(ErrorLabel, message) == 8); + assert!(offset_of!(ErrorLabel, span) == 0); // Padding: 3 bytes assert!(size_of::() == 68); assert!(align_of::() == 4); - assert!(offset_of!(EcmaScriptModule, has_module_syntax) == 0); - assert!(offset_of!(EcmaScriptModule, static_imports) == 4); - assert!(offset_of!(EcmaScriptModule, static_exports) == 20); - assert!(offset_of!(EcmaScriptModule, dynamic_imports) == 36); - assert!(offset_of!(EcmaScriptModule, import_metas) == 52); + assert!(offset_of!(EcmaScriptModule, has_module_syntax) == 64); + assert!(offset_of!(EcmaScriptModule, static_imports) == 0); + assert!(offset_of!(EcmaScriptModule, static_exports) == 16); + assert!(offset_of!(EcmaScriptModule, dynamic_imports) == 32); + assert!(offset_of!(EcmaScriptModule, import_metas) == 48); // Padding: 0 bytes assert!(size_of::() == 40); diff --git a/tasks/ast_tools/Cargo.toml b/tasks/ast_tools/Cargo.toml index 62665a6311e7d..c67dc1f8533ca 100644 --- a/tasks/ast_tools/Cargo.toml +++ b/tasks/ast_tools/Cargo.toml @@ -23,6 +23,7 @@ itertools = { workspace = true } lazy-regex = { workspace = true } oxc_index = { workspace = true } phf = { workspace = true, features = ["macros"] } +phf_codegen = { workspace = true } prettyplease = { workspace = true } proc-macro2 = { workspace = true } quote = { workspace = true } diff --git a/tasks/ast_tools/src/generators/assert_layouts.rs b/tasks/ast_tools/src/generators/assert_layouts.rs index 16e9d3306cd1e..fe5b03751cd31 100644 --- a/tasks/ast_tools/src/generators/assert_layouts.rs +++ b/tasks/ast_tools/src/generators/assert_layouts.rs @@ -6,17 +6,18 @@ use std::{ borrow::Cow, - cmp::{max, min}, + cmp::{Ordering, max, min}, num, }; +use phf_codegen::Map as PhfMapGen; use proc_macro2::TokenStream; use quote::quote; use rustc_hash::FxHashMap; -use syn::Ident; +use syn::{Expr, Ident, parse_str}; use crate::{ - Codegen, Generator, + AST_MACROS_CRATE_PATH, Codegen, Generator, output::{Output, output_path}, schema::{ Def, Discriminant, EnumDef, PrimitiveDef, Schema, StructDef, TypeDef, TypeId, Visibility, @@ -40,9 +41,12 @@ impl Generator for AssertLayouts { } } - /// Generate assertions that calculated layouts are correct. + /// Generate assertions that calculated layouts are correct, + /// and struct layout data for `oxc_ast_macros` crate. fn generate_many(&self, schema: &Schema, _codegen: &Codegen) -> Vec { - generate_assertions(schema) + let mut outputs = generate_assertions(schema); + outputs.push(generate_struct_details(schema)); + outputs } } @@ -55,12 +59,14 @@ fn calculate_layout(type_id: TypeId, schema: &mut Schema) -> &Layout { layout.layout_64.align == 0 } + let span_type_id = schema.type_names["Span"]; + let type_def = &schema.types[type_id]; match type_def { TypeDef::Struct(struct_def) => { if is_not_calculated(&struct_def.layout) { schema.struct_def_mut(type_id).layout = - calculate_layout_for_struct(type_id, schema); + calculate_layout_for_struct(type_id, span_type_id, schema); } &schema.struct_def(type_id).layout } @@ -110,26 +116,110 @@ fn calculate_layout(type_id: TypeId, schema: &mut Schema) -> &Layout { /// All structs in AST are `#[repr(C)]`. In a `#[repr(C)]` struct, compiler does not re-order the fields, /// so they are stored in memory in same order as they're defined. /// -/// Each field is aligned to the alignment of the field type. Padding bytes are added between fields -/// as necessary to ensure this. +/// So we determine a field order here which avoids excess padding. [`generate_struct_details`] generates +/// code describing this field order, and `#[ast]` macro re-orders the fields. +/// +/// This gives us the stability guarantees of `#[repr(C)]` without the downside of structs which are +/// larger than they need to be due to excess padding. /// /// Alignment of the struct is the highest alignment of its fields (or 1 if no fields). /// Size of struct is a multiple of its alignment. /// /// A struct has a niche if any of its fields has a niche. The niche will be the largest niche /// in any of its fields. Padding bytes are not used as niches. -fn calculate_layout_for_struct(type_id: TypeId, schema: &mut Schema) -> Layout { +/// +/// # Field order +/// +/// Fields are ordered according to the following rules, in order: +/// +/// 1. If field is `span: Span` it goes first. +/// 2. If field is ZST, it goes last. +/// 3. Fields with higher alignment on 64-bit systems go first. +/// 4. Fields with higher alignment on 32-bit systems go first. +/// 5. Otherwise, retain original field order. +/// +/// This ordering scheme does not match `#[repr(Rust)]`, but is equally efficient in terms of packing +/// structs into as few bytes as possible. +/// +/// `#[repr(Rust)]` would move fields with niches (e.g. `Expression`) earlier than fields without +/// niches (e.g. `Option>`), but we don't do that. AST is generally visited in source order, +/// so keeping fields in original order as much as possible is preferable for CPU caching. +/// +/// `span: Span` is always first to make `Expression::get_span` etc branchless, because the `span` field +/// is in the same position for all of `Expression`'s variants. +/// +/// Ordering by 64-bit alignment first, then 32-alignment creates a layout that is optimally packed +/// on both platforms. Fields will be ordered `u64`, `usize`, `u32`, so `usize` will have same alignment +/// as `u64` fields that come before it on 64-bit systems, and will have same alignment as +/// `u32`s that come after it on 32-bit systems. So it never results in padding on either platform. +/// +/// Note: "usize" here also includes pointer-aligned types e.g. `Box`, `Vec`, `Atom`, `&str`. +/// "u64" includes other 8-byte aligned types e.g. `f64`, `Span`. +/// +/// ZSTs need to go last so that they don't have same offset as another sized field. +/// If they did, this would screw up sorting the fields in `generate_struct_details`. +fn calculate_layout_for_struct( + type_id: TypeId, + span_type_id: TypeId, + schema: &mut Schema, +) -> Layout { + // Get layout of fields' types and calculate optimal field order + struct FieldData { + index: usize, + layout: Layout, + is_span: bool, + is_zst: bool, + } + + let mut field_order = schema + .struct_def(type_id) + .field_indices() + .map(|index| { + let field = &schema.struct_def(type_id).fields[index]; + let is_span = field.type_id == span_type_id && field.name() == "span"; + let layout = calculate_layout(field.type_id, schema); + let is_zst = layout.layout_64.size == 0 && layout.layout_32.size == 0; + FieldData { index, layout: layout.clone(), is_span, is_zst } + }) + .collect::>(); + + field_order.sort_unstable_by(|f1, f2| { + let mut order = f1.is_span.cmp(&f2.is_span).reverse(); + if order == Ordering::Equal { + order = f1.is_zst.cmp(&f2.is_zst); + if order == Ordering::Equal { + order = f1.layout.layout_64.align.cmp(&f2.layout.layout_64.align).reverse(); + if order == Ordering::Equal { + order = f1.layout.layout_32.align.cmp(&f2.layout.layout_32.align).reverse(); + if order == Ordering::Equal { + order = f1.index.cmp(&f2.index); + } + } + } + } + order + }); + + // Calculate offset of each field, and size + alignment of struct let mut layout_64 = PlatformLayout::from_size_align(0, 1); let mut layout_32 = PlatformLayout::from_size_align(0, 1); - for field_index in schema.struct_def(type_id).field_indices() { - let field_type_id = schema.struct_def(type_id).fields[field_index].type_id; - let field_layout = calculate_layout(field_type_id, schema); - - #[expect(clippy::items_after_statements)] - fn update(layout: &mut PlatformLayout, field_layout: &PlatformLayout) -> u32 { - // Field needs to be aligned - let offset = layout.size.next_multiple_of(field_layout.align); + let struct_def = schema.struct_def_mut(type_id); + for field_data in &field_order { + fn update( + layout: &mut PlatformLayout, + field_layout: &PlatformLayout, + struct_name: &str, + ) -> u32 { + // Field should already be aligned as we've re-ordered fields to ensure they're tightly packed. + // This shouldn't break as long as all fields are aligned on `< 16`. + // If we introduce a `u128` into AST, we might need to change the field ordering algorithm + // to fill in the gap between `span` and the `u128` field. + let offset = layout.size; + assert!( + offset % field_layout.align == 0, + "Incorrect alignment for struct fields in `{struct_name}`" + ); // Update alignment layout.align = max(layout.align, field_layout.align); @@ -138,7 +228,7 @@ fn calculate_layout_for_struct(type_id: TypeId, schema: &mut Schema) -> Layout { // Take the largest niche. Preference for (in order): // * Largest single range of niche values. // * Largest number of niche values at start of range. - // * Earlier field. + // * Earlier field (earlier after re-ordering). if let Some(field_niche) = &field_layout.niche { if layout.niche.as_ref().is_none_or(|niche| { field_niche.count_max() > niche.count_max() @@ -158,11 +248,11 @@ fn calculate_layout_for_struct(type_id: TypeId, schema: &mut Schema) -> Layout { offset } - let offset_64 = update(&mut layout_64, &field_layout.layout_64); - let offset_32 = update(&mut layout_32, &field_layout.layout_32); + let offset_64 = update(&mut layout_64, &field_data.layout.layout_64, struct_def.name()); + let offset_32 = update(&mut layout_32, &field_data.layout.layout_32, struct_def.name()); // Store offset on `field` - let field = &mut schema.struct_def_mut(type_id).fields[field_index]; + let field = &mut struct_def.fields[field_data.index]; field.offset = Offset { offset_64, offset_32 }; } @@ -566,6 +656,70 @@ fn template(krate: &str, assertions_64: &TokenStream, assertions_32: &TokenStrea } } +/// Generate struct field orders for `oxc_ast_macros` crate. +/// +/// `#[ast]` macro will re-order struct fields in order we provide here. +fn generate_struct_details(schema: &Schema) -> Output { + let mut map = PhfMapGen::new(); + for type_def in &schema.types { + let TypeDef::Struct(struct_def) = type_def else { continue }; + + // Get indexes of fields in ascending order of offset. + // Field index is included in sorting so any ZST fields remain in same order as in source + // (multiple ZST fields will have same offset as each other). + // + // If struct as written already has all fields in offset order then no-reordering is required, + // in which case output `None`. + let mut field_offsets_and_source_indexes = struct_def + .fields + .iter() + .enumerate() + .map(|(index, field)| (field.offset.offset_64, index)) + .collect::>(); + field_offsets_and_source_indexes.sort_unstable(); + + let field_order = if field_offsets_and_source_indexes + .iter() + .enumerate() + .any(|(new_index, &(_, source_index))| source_index != new_index) + { + // Field order needs to change from source order. + // Remap to `Vec` indexed by source field index, + // with each entry containing the new index after re-ordering + let mut source_and_new_indexes = field_offsets_and_source_indexes + .into_iter() + .enumerate() + .map(|(new_index, (_, source_index))| (source_index, new_index)) + .collect::>(); + source_and_new_indexes.sort_unstable_by_key(|&(source_index, _)| source_index); + let new_indexes = source_and_new_indexes + .into_iter() + .map(|(_, new_index)| number_lit(u8::try_from(new_index).unwrap())); + quote!(Some(&[#(#new_indexes),*])) + } else { + // Field order stays as it is in source + quote!(None) + }; + + let details = quote!( StructDetails { field_order: #field_order } ); + + map.entry(struct_def.name(), &details.to_string()); + } + let map = parse_str::(&map.build().to_string()).unwrap(); + + let code = quote! { + use crate::ast::StructDetails; + + ///@@line_break + /// Details of how `#[ast]` macro should modify structs. + #[expect(clippy::unreadable_literal)] + pub static STRUCTS: phf::Map<&'static str, StructDetails> = #map; + }; + + Output::Rust { path: output_path(AST_MACROS_CRATE_PATH, "structs.rs"), tokens: code } +} + +/// Add a line break to [`TokenStream`]. fn add_line_break(tokens: &mut TokenStream) { tokens.extend(quote! { ///@@line_break diff --git a/tasks/ast_tools/src/generators/ast_builder.rs b/tasks/ast_tools/src/generators/ast_builder.rs index 88db52a1bb0af..10ffd31f86622 100644 --- a/tasks/ast_tools/src/generators/ast_builder.rs +++ b/tasks/ast_tools/src/generators/ast_builder.rs @@ -69,7 +69,7 @@ impl Generator for AstBuilderGenerator { //! AST node factories //!@@line_break - #![expect(clippy::default_trait_access)] + #![expect(clippy::default_trait_access, clippy::inconsistent_struct_constructor)] ///@@line_break use std::cell::Cell;