From e8206c45d6cc832c0217137fb8c56e310eab8e51 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Fri, 18 Oct 2024 22:05:54 +0200 Subject: [PATCH 01/25] refactor!: replaced dependency `bumpalo` with `bump-scope` --- Cargo.lock | 21 +++++++++++++++---- Cargo.toml | 2 +- crates/oxc_allocator/Cargo.toml | 2 +- crates/oxc_allocator/src/boxed.rs | 4 ++-- crates/oxc_allocator/src/clone_in.rs | 2 +- crates/oxc_allocator/src/convert.rs | 2 +- crates/oxc_allocator/src/lib.rs | 15 ++++++++++--- crates/oxc_allocator/src/vec.rs | 2 +- crates/oxc_ast/src/ast_builder_impl.rs | 4 ++-- crates/oxc_parser/src/lexer/identifier.rs | 2 +- crates/oxc_parser/src/lexer/string.rs | 2 +- crates/oxc_parser/src/lexer/template.rs | 2 +- crates/oxc_prettier/src/doc.rs | 2 +- crates/oxc_prettier/src/format/string.rs | 2 +- crates/oxc_span/src/atom.rs | 4 +++- .../src/common/helper_loader.rs | 2 +- .../src/plugins/replace_global_defines.rs | 2 +- 17 files changed, 48 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8214921227c8e..c10baf55bd95d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,14 +179,21 @@ dependencies = [ ] [[package]] -name = "bumpalo" -version = "3.16.0" +name = "bump-scope" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "0f6696006b61de8209f071acd6fc40e1acdd10bb7a7e9f5d117a1944fbb62a5c" dependencies = [ "allocator-api2", + "sptr", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -1434,7 +1441,7 @@ name = "oxc_allocator" version = "0.31.0" dependencies = [ "allocator-api2", - "bumpalo", + "bump-scope", "serde", "serde_json", ] @@ -2864,6 +2871,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index 27c34a29cce6e..a0029cfac186d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ base64 = "0.22.1" base64-simd = "0.8" bitflags = "2.6.0" bpaf = "0.9.15" -bumpalo = "3.16.0" +bump-scope = "0.10.3" cfg-if = "1.0.0" compact_str = "0.8.0" console = "0.15.8" diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index cf8d1284a5df9..59708f3a30204 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -20,7 +20,7 @@ doctest = false [dependencies] allocator-api2 = { workspace = true } -bumpalo = { workspace = true, features = ["allocator-api2", "collections"] } +bump-scope = { workspace = true } serde = { workspace = true, optional = true } diff --git a/crates/oxc_allocator/src/boxed.rs b/crates/oxc_allocator/src/boxed.rs index 4e74ba9df6e5f..d057fa6810c50 100644 --- a/crates/oxc_allocator/src/boxed.rs +++ b/crates/oxc_allocator/src/boxed.rs @@ -68,7 +68,7 @@ impl<'alloc, T> Box<'alloc, T> { /// let in_arena: Box = Box::new_in(5, &arena); /// ``` pub fn new_in(value: T, allocator: &Allocator) -> Self { - Self(NonNull::from(allocator.alloc(value)), PhantomData) + Self(allocator.alloc(value).into_raw(), PhantomData) } /// Create a fake [`Box`] with a dangling pointer. @@ -192,7 +192,7 @@ mod test { let allocator = Allocator::default(); let mut b = Box::new_in("x", &allocator); let b = &mut *b; - *b = allocator.alloc("v"); + *b = allocator.alloc("v").into_ref(); assert_eq!(*b, "v"); } diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index 3610bd7a1edc2..7e8098433d0a4 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -75,7 +75,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for &'old_alloc str { type Cloned = &'new_alloc str; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { - allocator.alloc_str(self) + allocator.alloc_str(self).into_ref() } } diff --git a/crates/oxc_allocator/src/convert.rs b/crates/oxc_allocator/src/convert.rs index 2f9122b817a0e..d00d9d63785a3 100644 --- a/crates/oxc_allocator/src/convert.rs +++ b/crates/oxc_allocator/src/convert.rs @@ -49,7 +49,7 @@ impl<'a> FromIn<'a, String> for crate::String<'a> { impl<'a> FromIn<'a, String> for &'a str { #[inline(always)] fn from_in(value: String, allocator: &'a Allocator) -> Self { - crate::String::from_str_in(value.as_str(), allocator).into_bump_str() + crate::String::from_str_in(value.as_str(), allocator).into_fixed_string().into_str() } } diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 90460f81ead9a..6958e2b4b8fdb 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -44,8 +44,11 @@ use std::{ ops::{Deref, DerefMut}, }; -pub use bumpalo::collections::String; -use bumpalo::Bump; +use bump_scope::Bump; + +/// A bump-allocated string. +pub type String<'a> = bump_scope::BumpString<'a, 'a>; +type BumpScope<'a> = bump_scope::BumpScope<'a>; mod boxed; mod clone_in; @@ -69,6 +72,12 @@ pub struct Allocator { bump: Bump, } +impl<'a> From<&'a Allocator> for &'a BumpScope<'a> { + fn from(value: &'a Allocator) -> Self { + value.bump.as_scope() + } +} + impl From for Allocator { fn from(bump: Bump) -> Self { Self { bump } @@ -93,7 +102,7 @@ impl DerefMut for Allocator { mod test { use std::ops::Deref; - use bumpalo::Bump; + use bump_scope::Bump; use crate::Allocator; diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 653fc0e928cd5..bea2ed7289a7c 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -11,7 +11,7 @@ use std::{ }; use allocator_api2::vec; -use bumpalo::Bump; +use bump_scope::Bump; #[cfg(any(feature = "serialize", test))] use serde::{ser::SerializeSeq, Serialize, Serializer}; diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index 1c4e7e1aa9a71..3b8c48b5e192b 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -61,12 +61,12 @@ impl<'a> AstBuilder<'a> { #[inline] pub fn str(self, value: &str) -> &'a str { - String::from_str_in(value, self.allocator).into_bump_str() + String::from_str_in(value, self.allocator).into_fixed_string().into_str() } #[inline] pub fn atom(self, value: &str) -> Atom<'a> { - Atom::from(String::from_str_in(value, self.allocator).into_bump_str()) + Atom::from(&*String::from_str_in(value, self.allocator).into_fixed_string().into_str()) } /// # SAFETY diff --git a/crates/oxc_parser/src/lexer/identifier.rs b/crates/oxc_parser/src/lexer/identifier.rs index 961af1da57170..f6567369030d3 100644 --- a/crates/oxc_parser/src/lexer/identifier.rs +++ b/crates/oxc_parser/src/lexer/identifier.rs @@ -199,7 +199,7 @@ impl<'a> Lexer<'a> { } // Convert `str` to arena slice and save to `escaped_strings` - let id = str.into_bump_str(); + let id = str.into_fixed_string().into_str(); self.save_string(true, id); id } diff --git a/crates/oxc_parser/src/lexer/string.rs b/crates/oxc_parser/src/lexer/string.rs index 73c9635c83040..f136aea8249fc 100644 --- a/crates/oxc_parser/src/lexer/string.rs +++ b/crates/oxc_parser/src/lexer/string.rs @@ -146,7 +146,7 @@ macro_rules! handle_string_literal_escape { } // Convert `str` to arena slice and save to `escaped_strings` - $lexer.save_string(true, str.into_bump_str()); + $lexer.save_string(true, str.into_fixed_string().into_str()); Kind::Str }}; diff --git a/crates/oxc_parser/src/lexer/template.rs b/crates/oxc_parser/src/lexer/template.rs index ea672dfa5bb27..02e5c5f1dfc77 100644 --- a/crates/oxc_parser/src/lexer/template.rs +++ b/crates/oxc_parser/src/lexer/template.rs @@ -300,7 +300,7 @@ impl<'a> Lexer<'a> { }, }; - self.save_template_string(is_valid_escape_sequence, str.into_bump_str()); + self.save_template_string(is_valid_escape_sequence, str.into_fixed_string().into_str()); ret } diff --git a/crates/oxc_prettier/src/doc.rs b/crates/oxc_prettier/src/doc.rs index 417d7a3e78fc9..b5b45161625e4 100644 --- a/crates/oxc_prettier/src/doc.rs +++ b/crates/oxc_prettier/src/doc.rs @@ -188,7 +188,7 @@ pub trait DocBuilder<'a> { #[inline] fn str(&self, s: &str) -> Doc<'a> { - Doc::Str(String::from_str_in(s, self.allocator()).into_bump_str()) + Doc::Str(String::from_str_in(s, self.allocator()).into_fixed_string().into_str()) } #[inline] diff --git a/crates/oxc_prettier/src/format/string.rs b/crates/oxc_prettier/src/format/string.rs index 56f8f92b17419..92377e68aeb30 100644 --- a/crates/oxc_prettier/src/format/string.rs +++ b/crates/oxc_prettier/src/format/string.rs @@ -61,5 +61,5 @@ pub(super) fn print_string<'a>( prefer_single_quote: bool, ) -> &'a str { let enclosing_quote = get_preferred_quote(raw_text, prefer_single_quote); - make_string(p, raw_text, enclosing_quote).into_bump_str() + make_string(p, raw_text, enclosing_quote).into_fixed_string().into_str() } diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index b9363cc4e5efb..c3bc6a4538906 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -79,7 +79,9 @@ impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> { impl<'alloc> FromIn<'alloc, &str> for Atom<'alloc> { fn from_in(s: &str, allocator: &'alloc Allocator) -> Self { - Self::from(oxc_allocator::String::from_str_in(s, allocator).into_bump_str()) + Self::from( + &*oxc_allocator::String::from_str_in(s, allocator).into_fixed_string().into_str(), + ) } } diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 7169223514624..8a643632d55b1 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -251,7 +251,7 @@ impl<'a> HelperLoaderStore<'a> { source.push_str(&self.module_name); source.push_str("/helpers/"); source.push_str(helper_name); - let source = Atom::from(source.into_bump_str()); + let source = Atom::from(&*source.into_fixed_string().into_str()); let binding = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import); diff --git a/crates/oxc_transformer/src/plugins/replace_global_defines.rs b/crates/oxc_transformer/src/plugins/replace_global_defines.rs index 74c28656bd08d..1ce131a51ab6e 100644 --- a/crates/oxc_transformer/src/plugins/replace_global_defines.rs +++ b/crates/oxc_transformer/src/plugins/replace_global_defines.rs @@ -229,7 +229,7 @@ impl<'a> ReplaceGlobalDefines<'a> { // Construct a new expression because we don't have ast clone right now. fn parse_value(&self, source_text: &str) -> Expression<'a> { // Allocate the string lazily because replacement happens rarely. - let source_text = self.allocator.alloc_str(source_text); + let source_text = self.allocator.alloc_str(source_text).into_ref(); // Unwrapping here, it should already be checked by [ReplaceGlobalDefinesConfig::new]. Parser::new(self.allocator, source_text, SourceType::default()).parse_expression().unwrap() } From d3e64cb57bda14d8bec801e6913d1c7749ca0e2f Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:14:34 +0200 Subject: [PATCH 02/25] refactor: update `bump-scope` to version `0.10.4` --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c10baf55bd95d..1d6762ab35c20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "bump-scope" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6696006b61de8209f071acd6fc40e1acdd10bb7a7e9f5d117a1944fbb62a5c" +checksum = "1edd128ed0b76d06446c9ac0ae855201f0464df8eaa42e7e8f0bf92d179129de" dependencies = [ "allocator-api2", "sptr", diff --git a/Cargo.toml b/Cargo.toml index a0029cfac186d..e736f2fc7311a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ base64 = "0.22.1" base64-simd = "0.8" bitflags = "2.6.0" bpaf = "0.9.15" -bump-scope = "0.10.3" +bump-scope = "0.10.4" cfg-if = "1.0.0" compact_str = "0.8.0" console = "0.15.8" From 27d43bb5eeaaa1b4d58d4ae7c08247c988e4909d Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 19 Oct 2024 02:34:14 +0200 Subject: [PATCH 03/25] refactor: create a wrapper type for bump allocated strings --- crates/oxc_allocator/src/convert.rs | 2 +- crates/oxc_allocator/src/lib.rs | 3 +- crates/oxc_allocator/src/string.rs | 51 +++++++++++++++++++ crates/oxc_ast/src/ast_builder_impl.rs | 4 +- crates/oxc_parser/src/lexer/identifier.rs | 2 +- crates/oxc_parser/src/lexer/string.rs | 2 +- crates/oxc_parser/src/lexer/template.rs | 2 +- crates/oxc_prettier/src/doc.rs | 2 +- crates/oxc_prettier/src/format/string.rs | 2 +- crates/oxc_span/src/atom.rs | 4 +- .../src/common/helper_loader.rs | 2 +- 11 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 crates/oxc_allocator/src/string.rs diff --git a/crates/oxc_allocator/src/convert.rs b/crates/oxc_allocator/src/convert.rs index d00d9d63785a3..05f3c30223a54 100644 --- a/crates/oxc_allocator/src/convert.rs +++ b/crates/oxc_allocator/src/convert.rs @@ -49,7 +49,7 @@ impl<'a> FromIn<'a, String> for crate::String<'a> { impl<'a> FromIn<'a, String> for &'a str { #[inline(always)] fn from_in(value: String, allocator: &'a Allocator) -> Self { - crate::String::from_str_in(value.as_str(), allocator).into_fixed_string().into_str() + crate::String::from_str_in(value.as_str(), allocator).into_str() } } diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 6958e2b4b8fdb..03af509e5ac54 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -47,17 +47,18 @@ use std::{ use bump_scope::Bump; /// A bump-allocated string. -pub type String<'a> = bump_scope::BumpString<'a, 'a>; type BumpScope<'a> = bump_scope::BumpScope<'a>; mod boxed; mod clone_in; mod convert; +mod string; mod vec; pub use boxed::{Address, Box}; pub use clone_in::CloneIn; pub use convert::{FromIn, IntoIn}; +pub use string::String; pub use vec::Vec; /// A bump-allocated memory arena based on [bumpalo]. diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs new file mode 100644 index 0000000000000..3d658bc5f3ea4 --- /dev/null +++ b/crates/oxc_allocator/src/string.rs @@ -0,0 +1,51 @@ +use bump_scope::BumpString as StringImpl; + +use crate::Allocator; + +/// A bump-allocated string. +pub struct String<'a>(StringImpl<'a, 'a>); + +impl<'a> String<'a> { + /// Constructs a new empty `String`. + #[inline] + pub fn new_in(allocator: &'a Allocator) -> Self { + Self(StringImpl::new_in(allocator)) + } + + /// Constructs a `String` from a `&str`. + #[inline] + pub fn from_str_in(string: &str, allocator: &'a Allocator) -> Self { + Self(StringImpl::from_str_in(string, allocator)) + } + + /// Constructs a new empty `String` with the specified capacity. + #[inline] + pub fn with_capacity_in(capacity: usize, allocator: &'a Allocator) -> Self { + Self(StringImpl::with_capacity_in(capacity, allocator)) + } + + /// Converts a `String` into a `&str`. + #[inline] + pub fn into_str(self) -> &'a str { + // First converts it to a `FixedBumpString` to suppress it trying to shrink its allocation. + self.0.into_fixed_string().into_str() + } + + /// Appends a given string slice to the end of this string. + #[inline] + pub fn push_str(&mut self, string: &str) { + self.0.push_str(string); + } + + /// Appends a given `char` to the end of this string. + #[inline] + pub fn push(&mut self, c: char) { + self.0.push(c); + } + + /// Extracts a string slice containing the entire `String`. + #[inline] + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index 3b8c48b5e192b..a82dc485d9ebb 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -61,12 +61,12 @@ impl<'a> AstBuilder<'a> { #[inline] pub fn str(self, value: &str) -> &'a str { - String::from_str_in(value, self.allocator).into_fixed_string().into_str() + String::from_str_in(value, self.allocator).into_str() } #[inline] pub fn atom(self, value: &str) -> Atom<'a> { - Atom::from(&*String::from_str_in(value, self.allocator).into_fixed_string().into_str()) + Atom::from(String::from_str_in(value, self.allocator).into_str()) } /// # SAFETY diff --git a/crates/oxc_parser/src/lexer/identifier.rs b/crates/oxc_parser/src/lexer/identifier.rs index f6567369030d3..0f25883af9c90 100644 --- a/crates/oxc_parser/src/lexer/identifier.rs +++ b/crates/oxc_parser/src/lexer/identifier.rs @@ -199,7 +199,7 @@ impl<'a> Lexer<'a> { } // Convert `str` to arena slice and save to `escaped_strings` - let id = str.into_fixed_string().into_str(); + let id = str.into_str(); self.save_string(true, id); id } diff --git a/crates/oxc_parser/src/lexer/string.rs b/crates/oxc_parser/src/lexer/string.rs index f136aea8249fc..e12d579236058 100644 --- a/crates/oxc_parser/src/lexer/string.rs +++ b/crates/oxc_parser/src/lexer/string.rs @@ -146,7 +146,7 @@ macro_rules! handle_string_literal_escape { } // Convert `str` to arena slice and save to `escaped_strings` - $lexer.save_string(true, str.into_fixed_string().into_str()); + $lexer.save_string(true, str.into_str()); Kind::Str }}; diff --git a/crates/oxc_parser/src/lexer/template.rs b/crates/oxc_parser/src/lexer/template.rs index 02e5c5f1dfc77..9ff416104121f 100644 --- a/crates/oxc_parser/src/lexer/template.rs +++ b/crates/oxc_parser/src/lexer/template.rs @@ -300,7 +300,7 @@ impl<'a> Lexer<'a> { }, }; - self.save_template_string(is_valid_escape_sequence, str.into_fixed_string().into_str()); + self.save_template_string(is_valid_escape_sequence, str.into_str()); ret } diff --git a/crates/oxc_prettier/src/doc.rs b/crates/oxc_prettier/src/doc.rs index b5b45161625e4..c753a19dec367 100644 --- a/crates/oxc_prettier/src/doc.rs +++ b/crates/oxc_prettier/src/doc.rs @@ -188,7 +188,7 @@ pub trait DocBuilder<'a> { #[inline] fn str(&self, s: &str) -> Doc<'a> { - Doc::Str(String::from_str_in(s, self.allocator()).into_fixed_string().into_str()) + Doc::Str(String::from_str_in(s, self.allocator()).into_str()) } #[inline] diff --git a/crates/oxc_prettier/src/format/string.rs b/crates/oxc_prettier/src/format/string.rs index 92377e68aeb30..f24070d6c9a6a 100644 --- a/crates/oxc_prettier/src/format/string.rs +++ b/crates/oxc_prettier/src/format/string.rs @@ -61,5 +61,5 @@ pub(super) fn print_string<'a>( prefer_single_quote: bool, ) -> &'a str { let enclosing_quote = get_preferred_quote(raw_text, prefer_single_quote); - make_string(p, raw_text, enclosing_quote).into_fixed_string().into_str() + make_string(p, raw_text, enclosing_quote).into_str() } diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index c3bc6a4538906..7e21a6edbfb91 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -79,9 +79,7 @@ impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> { impl<'alloc> FromIn<'alloc, &str> for Atom<'alloc> { fn from_in(s: &str, allocator: &'alloc Allocator) -> Self { - Self::from( - &*oxc_allocator::String::from_str_in(s, allocator).into_fixed_string().into_str(), - ) + Self::from(&*oxc_allocator::String::from_str_in(s, allocator).into_str()) } } diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 8a643632d55b1..f495e64b72f7d 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -251,7 +251,7 @@ impl<'a> HelperLoaderStore<'a> { source.push_str(&self.module_name); source.push_str("/helpers/"); source.push_str(helper_name); - let source = Atom::from(&*source.into_fixed_string().into_str()); + let source = Atom::from(source.into_str()); let binding = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import); From a8c4b08ffe310c179c800021a8dd63eced5daecb Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:22:23 +0200 Subject: [PATCH 04/25] refactor(allocator): implement `Vec` using `bump_scope::BumpVec` --- crates/oxc_allocator/src/vec.rs | 339 ++++++++++++++++++++++++++++---- 1 file changed, 303 insertions(+), 36 deletions(-) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index bea2ed7289a7c..a33e9313ba402 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -6,20 +6,17 @@ use std::{ self, fmt::Debug, hash::{Hash, Hasher}, - ops, - ptr::NonNull, + ops::{self, RangeBounds}, }; -use allocator_api2::vec; -use bump_scope::Bump; -#[cfg(any(feature = "serialize", test))] -use serde::{ser::SerializeSeq, Serialize, Serializer}; - use crate::{Allocator, Box}; +type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T>; + /// Bumpalo Vec -#[derive(Debug, PartialEq, Eq)] -pub struct Vec<'alloc, T>(vec::Vec); +#[derive(Debug, PartialEq)] +#[cfg_attr(any(feature = "serialize", test), derive(serde::Serialize))] +pub struct Vec<'alloc, T>(VecImpl<'alloc, T>); impl<'alloc, T> Vec<'alloc, T> { /// Constructs a new, empty `Vec`. @@ -38,7 +35,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline] pub fn new_in(allocator: &'alloc Allocator) -> Self { - Self(vec::Vec::new_in(allocator)) + Self(VecImpl::new_in(allocator)) } /// Constructs a new, empty `Vec` with at least the specified capacity @@ -90,19 +87,19 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline] pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self { - Self(vec::Vec::with_capacity_in(capacity, allocator)) + Self(VecImpl::with_capacity_in(capacity, allocator)) } /// Create a new [`Vec`] whose elements are taken from an iterator and /// allocated in the given `allocator`. /// - /// This is behaviorially identical to [`FromIterator::from_iter`]. + /// This is behaviorally identical to [`FromIterator::from_iter`]. #[inline] pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { let iter = iter.into_iter(); let hint = iter.size_hint(); let capacity = hint.1.unwrap_or(hint.0); - let mut vec = vec::Vec::with_capacity_in(capacity, &**allocator); + let mut vec = VecImpl::with_capacity_in(capacity, &**allocator); vec.extend(iter); Self(vec) } @@ -128,10 +125,8 @@ impl<'alloc, T> Vec<'alloc, T> { /// /// [owned slice]: Box pub fn into_boxed_slice(self) -> Box<'alloc, [T]> { - let slice = self.0.leak(); - let ptr = NonNull::from(slice); + let ptr = self.0.into_fixed_vec().into_boxed_slice().into_raw(); // SAFETY: `ptr` points to a valid slice `[T]`. - // `allocator_api2::vec::Vec::leak` consumes the inner `Vec` without dropping it. // Lifetime of returned `Box<'alloc, [T]>` is same as lifetime of consumed `Vec<'alloc, T>`, // so data in the `Box` must be valid for its lifetime. // `Vec` uniquely owned the data, and we have consumed the `Vec`, so the new `Box` has @@ -139,10 +134,225 @@ impl<'alloc, T> Vec<'alloc, T> { // `ptr` was created from a `&mut [T]`. unsafe { Box::from_non_null(ptr) } } + + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); + /// let mut vec2 = Vec::from_iter_in([4, 5, 6], &allocator); + /// vec.append(&mut vec2); + /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(vec2, []); + /// ``` + pub fn append(&mut self, other: &mut Self) { + self.reserve(other.len()); + + unsafe { + other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr().add(self.len()), other.len()); + + let self_len = self.len(); + self.set_len(self_len + other.len()); + + other.set_len(0); + } + } + + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); + /// let mut vec2 = Vec::from_iter_in([4, 5, 6], &allocator); + /// vec.append(&mut vec2); + /// assert_eq!(vec, [4, 5, 6, 1, 2, 3]); + /// assert_eq!(vec2, []); + /// ``` + pub fn prepend(&mut self, other: &mut Self) { + self.reserve(other.len()); + + unsafe { + // copy existing content forward to make space + self.as_mut_ptr() + .copy_to_nonoverlapping(self.as_mut_ptr().add(self.len()), other.len()); + + // copy other + other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr(), other.len()); + + let self_len = self.len(); + self.set_len(self_len + other.len()); + + other.set_len(0); + } + } + + /// Creates a splicing iterator that replaces the specified range in the vector + /// with the given `replace_with` iterator and yields the removed items. + /// `replace_with` does not need to be the same length as `range`. + /// + /// `range` is removed even if the iterator is not consumed until the end. + /// + /// It is unspecified how many elements are removed from the vector + /// if the `Splice` value is leaked. + /// + /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped. + /// + /// This is optimal if: + /// + /// * The tail (elements in the vector after `range`) is empty, + /// * or `replace_with` yields fewer or equal elements than `range`’s length + /// * or the lower bound of its `size_hint()` is exact. + /// + /// Otherwise, a temporary vector is allocated and the tail is moved twice. + /// + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + /// + /// # Examples + /// + /// ``` + /// use crate::{ Allocator, Vec }; + /// let allocator: Allocator = Allocator::default(); + /// let mut v = Vec::from_iter_in([1, 2, 3, 4], &allocator); + /// let new = [7, 8, 9]; + /// let u = bump.alloc_iter(v.splice(1..3, new)); + /// assert_eq!(v, &[1, 7, 8, 9, 4]); + /// assert_eq!(u, &[2, 3]); + /// ``` + #[inline] + pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> + where + R: RangeBounds, + I: IntoIterator, + { + _ = (range, replace_with); + todo!() + } + + /// Retains only the elements specified by the predicate, passing a mutable reference to it. + /// + /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// use crate::{ Allocator, Vec }; + /// let allocator = Allocator::default() + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &allocator); + /// + /// vec.retain_mut(|x| if *x <= 3 { + /// *x += 1; + /// true + /// } else { + /// false + /// }); + /// + /// assert_eq!(vec, [2, 3, 4]); + /// ``` + #[allow(clippy::pedantic)] + pub fn retain_mut(&mut self, f: F) + where + F: FnMut(&mut T) -> bool, + { + self.0.retain(f) + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// in the given `Vec`. The collection may reserve more space to + /// speculatively avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1], &allocator); + /// vec.reserve_exact(10); + /// assert!(vec.capacity() >= 11); + /// ``` + #[inline] + pub fn reserve(&mut self, additional: usize) { + // self.buf.reserve(self.len, additional); + let _ = additional; + todo!() + } + + /// Reserves the minimum capacity for at least `additional` more elements to + /// be inserted in the given `Vec`. Unlike [`reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `reserve_exact`, capacity will be greater than or equal to + /// `self.len() + additional`. Does nothing if the capacity is already + /// sufficient. + /// + /// Note that the allocator may give the collection more space than it + /// requests. Therefore, capacity can not be relied upon to be precisely + /// minimal. Prefer [`reserve`] if future insertions are expected. + /// + /// [`reserve`]: Vec::reserve + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1], &allocator); + /// vec.reserve_exact(10); + /// assert!(vec.capacity() >= 11); + /// ``` + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + // self.0.reserve_exact(self.len, additional); + let _ = additional; + todo!() + } } +pub struct Splice<'a, I: Iterator>(std::vec::Splice<'a, I>); + +impl Iterator for Splice<'_, I> { + type Item = I::Item; + + fn next(&mut self) -> Option { + todo!() + } + + fn size_hint(&self) -> (usize, Option) { + todo!() + } +} + +impl<'alloc, T> Eq for Vec<'alloc, T> where T: Eq {} + impl<'alloc, T> ops::Deref for Vec<'alloc, T> { - type Target = vec::Vec; + type Target = VecImpl<'alloc, T>; fn deref(&self) -> &Self::Target { &self.0 @@ -150,13 +360,13 @@ impl<'alloc, T> ops::Deref for Vec<'alloc, T> { } impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { - fn deref_mut(&mut self) -> &mut vec::Vec { + fn deref_mut(&mut self) -> &mut VecImpl<'alloc, T> { &mut self.0 } } impl<'alloc, T> IntoIterator for Vec<'alloc, T> { - type IntoIter = as IntoIterator>::IntoIter; + type IntoIter = as IntoIterator>::IntoIter; type Item = T; fn into_iter(self) -> Self::IntoIter { @@ -188,23 +398,6 @@ impl<'alloc, T> ops::Index for Vec<'alloc, T> { // } // } -#[cfg(any(feature = "serialize", test))] -impl<'alloc, T> Serialize for Vec<'alloc, T> -where - T: Serialize, -{ - fn serialize(&self, s: S) -> Result - where - S: Serializer, - { - let mut seq = s.serialize_seq(Some(self.0.len()))?; - for e in &self.0 { - seq.serialize_element(e)?; - } - seq.end() - } -} - impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { fn hash(&self, state: &mut H) { for e in &self.0 { @@ -264,4 +457,78 @@ mod test { // Check length of slice is equal to what `v.len()` was, not `v.capacity()` assert_eq!(b.len(), 3); } + + #[test] + fn append() { + let allocator = Allocator::default(); + + { + let mut v = Vec::new_in(&allocator); + let mut other = Vec::::new_in(&allocator); + v.append(&mut other); + assert!(v.is_empty()); + assert!(other.is_empty()); + } + + { + let mut v = Vec::new_in(&allocator); + let mut other = Vec::from_iter_in([1, 2, 3], &allocator); + v.append(&mut other); + assert_eq!(v.as_slice(), &[1, 2, 3]); + assert!(other.is_empty()); + } + + { + let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + let mut other = Vec::new_in(&allocator); + v.append(&mut other); + assert_eq!(v.as_slice(), &[1, 2, 3]); + assert!(other.is_empty()); + } + + { + let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + let mut other = Vec::from_iter_in([4, 5, 6], &allocator); + v.append(&mut other); + assert_eq!(v.as_slice(), &[1, 2, 3, 4, 5, 6]); + assert!(other.is_empty()); + } + } + + #[test] + fn prepend() { + let allocator = Allocator::default(); + + { + let mut v = Vec::new_in(&allocator); + let mut other = Vec::::new_in(&allocator); + v.prepend(&mut other); + assert!(v.is_empty()); + assert!(other.is_empty()); + } + + { + let mut v = Vec::new_in(&allocator); + let mut other = Vec::from_iter_in([1, 2, 3], &allocator); + v.prepend(&mut other); + assert_eq!(v.as_slice(), &[1, 2, 3]); + assert!(other.is_empty()); + } + + { + let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + let mut other = Vec::new_in(&allocator); + v.prepend(&mut other); + assert_eq!(v.as_slice(), &[1, 2, 3]); + assert!(other.is_empty()); + } + + { + let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + let mut other = Vec::from_iter_in([4, 5, 6], &allocator); + v.prepend(&mut other); + assert_eq!(v.as_slice(), &[4, 5, 6, 1, 2, 3]); + assert!(other.is_empty()); + } + } } From 3575befa632db43608e681cf6de9cb37e34b799c Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:23:34 +0200 Subject: [PATCH 05/25] fix(allocator): serde support for string --- Cargo.lock | 1 + crates/oxc_allocator/Cargo.toml | 2 +- crates/oxc_allocator/src/string.rs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 1d6762ab35c20..8e9ca5a207dbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,6 +185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1edd128ed0b76d06446c9ac0ae855201f0464df8eaa42e7e8f0bf92d179129de" dependencies = [ "allocator-api2", + "serde", "sptr", ] diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index 59708f3a30204..facc6c2e61164 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -29,4 +29,4 @@ serde = { workspace = true } serde_json = { workspace = true } [features] -serialize = ["dep:serde"] +serialize = ["dep:serde", "bump-scope/serde"] diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index 3d658bc5f3ea4..81196eca32671 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -3,6 +3,7 @@ use bump_scope::BumpString as StringImpl; use crate::Allocator; /// A bump-allocated string. +#[cfg_attr(any(feature = "serialize", test), derive(serde::Serialize))] pub struct String<'a>(StringImpl<'a, 'a>); impl<'a> String<'a> { From 15d2be8e32245df648473ad62001261d0aea4622 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:23:58 +0200 Subject: [PATCH 06/25] doc(allocator): replace `bumpalo` with `bump-scope` --- crates/oxc_allocator/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 03af509e5ac54..77d281aa3f1e3 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -61,7 +61,7 @@ pub use convert::{FromIn, IntoIn}; pub use string::String; pub use vec::Vec; -/// A bump-allocated memory arena based on [bumpalo]. +/// A bump-allocated memory arena based on [bump-scope]. /// /// ## No `Drop`s /// From 425ee2901d4718bb354c5b67f6290305936946e2 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sun, 20 Oct 2024 00:37:52 +0200 Subject: [PATCH 07/25] feat(allocator): complete `Vec` abstraction --- Cargo.lock | 4 +- Cargo.toml | 2 +- crates/oxc_allocator/Cargo.toml | 5 +- crates/oxc_allocator/src/clone_in.rs | 2 +- crates/oxc_allocator/src/lib.rs | 4 +- crates/oxc_allocator/src/vec.rs | 398 ++++++++++++++++++++++++--- 6 files changed, 369 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e9ca5a207dbb..43580793108fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "bump-scope" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edd128ed0b76d06446c9ac0ae855201f0464df8eaa42e7e8f0bf92d179129de" +checksum = "f2611a1654ad8eaf7a7ec539964b3fd39e746c2a60a0fc558ec238689a04dcd0" dependencies = [ "allocator-api2", "serde", diff --git a/Cargo.toml b/Cargo.toml index e736f2fc7311a..970f331dd6af4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ base64 = "0.22.1" base64-simd = "0.8" bitflags = "2.6.0" bpaf = "0.9.15" -bump-scope = "0.10.4" +bump-scope = "0.10.5" cfg-if = "1.0.0" compact_str = "0.8.0" console = "0.15.8" diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index facc6c2e61164..9aa40a5c9fde7 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -22,11 +22,12 @@ doctest = false allocator-api2 = { workspace = true } bump-scope = { workspace = true } -serde = { workspace = true, optional = true } +serde = { workspace = true, optional = true, features = ["derive"] } [dev-dependencies] -serde = { workspace = true } +serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } +bump-scope = { workspace = true, features = ["serde"] } [features] serialize = ["dep:serde", "bump-scope/serde"] diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index 7e8098433d0a4..711cbc6901498 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -7,7 +7,7 @@ use crate::{Allocator, Box, Vec}; /// As a convention `Cloned` associated type should always be the same as `Self`, /// It'd only differ in the lifetime, Here's an example: /// -/// ``` +/// ```ignore /// impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Struct<'old_alloc> { /// type Cloned = Struct<'new_alloc>; /// fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 77d281aa3f1e3..2b51e660251f3 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -31,10 +31,10 @@ //! Consumers of the [`oxc` umbrella crate](https://crates.io/crates/oxc) pass //! [`Allocator`] references to other tools. //! -//! ``` +//! ```ignore //! use oxc::{allocator::Allocator, parser::Parser, span::SourceType}; //! -//! let allocator = Allocator::default() +//! let allocator = Allocator::default(); //! let parsed = Parser::new(&allocator, "let x = 1;", SourceType::default()); //! assert!(parsed.errors.is_empty()); //! ``` diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index a33e9313ba402..077418b193ad4 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -4,18 +4,23 @@ use std::{ self, + borrow::Cow, fmt::Debug, hash::{Hash, Hasher}, - ops::{self, RangeBounds}, + iter::FusedIterator, + ops::{self, Index, RangeBounds}, + slice::SliceIndex, }; +use allocator_api2::alloc::Global; + use crate::{Allocator, Box}; type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T>; -/// Bumpalo Vec -#[derive(Debug, PartialEq)] +/// A bump-allocated vector. #[cfg_attr(any(feature = "serialize", test), derive(serde::Serialize))] +#[derive(Debug)] pub struct Vec<'alloc, T>(VecImpl<'alloc, T>); impl<'alloc, T> Vec<'alloc, T> { @@ -33,7 +38,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// let mut vec: Vec = Vec::new_in(&arena); /// assert!(vec.is_empty()); /// ``` - #[inline] + #[inline(always)] pub fn new_in(allocator: &'alloc Allocator) -> Self { Self(VecImpl::new_in(allocator)) } @@ -85,7 +90,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// let vec_units = Vec::<()>::with_capacity_in(10, &arena); /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` - #[inline] + #[inline(always)] pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self { Self(VecImpl::with_capacity_in(capacity, allocator)) } @@ -94,7 +99,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// allocated in the given `allocator`. /// /// This is behaviorally identical to [`FromIterator::from_iter`]. - #[inline] + #[inline(always)] pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { let iter = iter.into_iter(); let hint = iter.size_hint(); @@ -104,6 +109,170 @@ impl<'alloc, T> Vec<'alloc, T> { Self(vec) } + /// Returns the total number of elements the vector can hold without + /// reallocating. + /// + /// # Examples + /// + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let vec = Vec::::with_capacity_in(2048, &allocator); + /// assert!(vec.capacity() >= 2048); + /// ``` + #[must_use] + #[inline(always)] + pub const fn capacity(&self) -> usize { + self.0.capacity() + } + + /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. + #[must_use] + #[inline(always)] + pub const fn as_slice(&self) -> &[T] { + self.0.as_slice() + } + + /// Extracts a mutable slice containing the entire vector. + /// + /// Equivalent to `&mut s[..]`. + #[must_use] + #[inline(always)] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.0.as_mut_slice() + } + + /// Appends an element to the back of a collection. + #[inline(always)] + pub fn push(&mut self, value: T) { + self.0.push(value) + } + + /// Removes the last element from a vector and returns it, or [`None`] if it + /// is empty. + #[inline(always)] + pub fn pop(&mut self) -> Option { + self.0.pop() + } + + /// Inserts an element at position `index` within the vector, shifting all elements after it to the right. + /// + /// # Panics + /// Panics if `index > len`. + /// + /// # Examples + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); + /// vec.insert(1, 4); + /// assert_eq!(vec, [1, 4, 2, 3]); + /// vec.insert(4, 5); + /// assert_eq!(vec, [1, 4, 2, 3, 5]); + /// ``` + #[inline(always)] + pub fn insert(&mut self, index: usize, element: T) { + self.0.insert(index, element) + } + + /// Removes and returns the element at position `index` within the vector, + /// shifting all elements after it to the left. + /// + /// Note: Because this shifts over the remaining elements, it has a + /// worst-case performance of *O*(*n*). If you don't need the order of elements + /// to be preserved, use [`swap_remove`] instead. + /// + /// # Panics + /// Panics if `index` is out of bounds. + /// + /// [`swap_remove`]: Self::swap_remove + /// + /// # Examples + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + /// assert_eq!(v.remove(1), 2); + /// assert_eq!(v, [1, 3]); + /// ``` + #[track_caller] + pub fn remove(&mut self, index: usize) -> T { + self.0.remove(index) + } + + /// Shortens the vector, keeping the first `len` elements and dropping + /// the rest. + /// + /// If `len` is greater than the vector's current length, this has no + /// effect. + /// + /// The [`drain`] method can emulate `truncate`, but causes the excess + /// elements to be returned instead of dropped. + /// + /// Note that this method has no effect on the allocated capacity + /// of the vector. + /// + /// # Examples + /// + /// Truncating a five element vector to two elements: + /// + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// # + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4, 5], &allocator); + /// vec.truncate(2); + /// assert_eq!(vec, [1, 2]); + /// ``` + /// + /// No truncation occurs when `len` is greater than the vector's current + /// length: + /// + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// # + /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); + /// vec.truncate(8); + /// assert_eq!(vec, [1, 2, 3]); + /// ``` + /// + /// Truncating when `len == 0` is equivalent to calling the [`clear`] + /// method. + /// + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// # + /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); + /// vec.truncate(0); + /// assert_eq!(vec, []); + /// ``` + /// + /// [`clear`]: BumpVec::clear + /// [`drain`]: BumpVec::drain + #[inline(always)] + pub fn truncate(&mut self, len: usize) { + self.0.truncate(len); + } + + /// Clears the vector, removing all values. + /// + /// # Examples + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4, 5], &allocator); + /// vec.clear(); + /// assert!(vec.is_empty()); + /// ``` + #[inline(always)] + pub fn clear(&mut self) { + self.0.clear(); + } + /// Converts the vector into [`Box<[T]>`][owned slice]. /// /// Any excess capacity the vector has will not be included in the slice. @@ -124,6 +293,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` /// /// [owned slice]: Box + #[inline(always)] pub fn into_boxed_slice(self) -> Box<'alloc, [T]> { let ptr = self.0.into_fixed_vec().into_boxed_slice().into_raw(); // SAFETY: `ptr` points to a valid slice `[T]`. @@ -152,6 +322,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); /// assert_eq!(vec2, []); /// ``` + #[inline(always)] pub fn append(&mut self, other: &mut Self) { self.reserve(other.len()); @@ -178,17 +349,17 @@ impl<'alloc, T> Vec<'alloc, T> { /// let allocator = Allocator::default(); /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); /// let mut vec2 = Vec::from_iter_in([4, 5, 6], &allocator); - /// vec.append(&mut vec2); + /// vec.prepend(&mut vec2); /// assert_eq!(vec, [4, 5, 6, 1, 2, 3]); /// assert_eq!(vec2, []); /// ``` + #[inline(always)] pub fn prepend(&mut self, other: &mut Self) { self.reserve(other.len()); unsafe { // copy existing content forward to make space - self.as_mut_ptr() - .copy_to_nonoverlapping(self.as_mut_ptr().add(self.len()), other.len()); + self.as_mut_ptr().copy_to(self.as_mut_ptr().add(other.len()), self.len()); // copy other other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr(), other.len()); @@ -200,6 +371,45 @@ impl<'alloc, T> Vec<'alloc, T> { } } + /// Removes the specified range from the vector in bulk, returning all + /// removed elements as an iterator. If the iterator is dropped before + /// being fully consumed, it drops the remaining removed elements. + /// + /// The returned iterator keeps a mutable borrow on the vector to optimize + /// its implementation. + /// + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + /// + /// # Leaking + /// + /// If the returned iterator goes out of scope without being dropped (due to + /// [`mem::forget`](core::mem::forget), for example), the vector may have lost and leaked + /// elements arbitrarily, including elements outside the range. + /// + /// # Examples + /// + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let mut v = Vec::from_iter_in([1, 2, 3], &allocator); + /// let u = Vec::from_iter_in(v.drain(1..), &allocator); + /// assert_eq!(v, [1]); + /// assert_eq!(u, [2, 3]); + /// + /// // A full range clears the vector, like `clear()` does + /// v.drain(..); + /// assert_eq!(v, []); + /// ``` + pub fn drain(&mut self, range: R) -> Drain<'_, T> + where + R: RangeBounds, + { + Drain(self.0.drain(range)) + } + /// Creates a splicing iterator that replaces the specified range in the vector /// with the given `replace_with` iterator and yields the removed items. /// `replace_with` does not need to be the same length as `range`. @@ -227,22 +437,21 @@ impl<'alloc, T> Vec<'alloc, T> { /// # Examples /// /// ``` - /// use crate::{ Allocator, Vec }; + /// use oxc_allocator::{ Allocator, Vec }; /// let allocator: Allocator = Allocator::default(); /// let mut v = Vec::from_iter_in([1, 2, 3, 4], &allocator); /// let new = [7, 8, 9]; - /// let u = bump.alloc_iter(v.splice(1..3, new)); + /// let u = Vec::from_iter_in(v.splice(1..3, new), &allocator); /// assert_eq!(v, &[1, 7, 8, 9, 4]); /// assert_eq!(u, &[2, 3]); /// ``` - #[inline] + #[inline(always)] pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> where R: RangeBounds, I: IntoIterator, { - _ = (range, replace_with); - todo!() + Splice(self.0.splice(range, replace_with)) } /// Retains only the elements specified by the predicate, passing a mutable reference to it. @@ -254,8 +463,8 @@ impl<'alloc, T> Vec<'alloc, T> { /// # Examples /// /// ``` - /// use crate::{ Allocator, Vec }; - /// let allocator = Allocator::default() + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &allocator); /// /// vec.retain_mut(|x| if *x <= 3 { @@ -267,7 +476,37 @@ impl<'alloc, T> Vec<'alloc, T> { /// /// assert_eq!(vec, [2, 3, 4]); /// ``` - #[allow(clippy::pedantic)] + #[inline(always)] + pub fn retain(&mut self, mut f: F) + where + F: FnMut(&T) -> bool, + { + self.retain_mut(|elem| f(elem)) + } + + /// Retains only the elements specified by the predicate, passing a mutable reference to it. + /// + /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// use oxc_allocator::{ Allocator, Vec }; + /// let allocator = Allocator::default(); + /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &allocator); + /// + /// vec.retain_mut(|x| if *x <= 3 { + /// *x += 1; + /// true + /// } else { + /// false + /// }); + /// + /// assert_eq!(vec, [2, 3, 4]); + /// ``` + #[inline(always)] pub fn retain_mut(&mut self, f: F) where F: FnMut(&mut T) -> bool, @@ -291,14 +530,12 @@ impl<'alloc, T> Vec<'alloc, T> { /// use oxc_allocator::{ Allocator, Vec }; /// let allocator = Allocator::default(); /// let mut vec = Vec::from_iter_in([1], &allocator); - /// vec.reserve_exact(10); + /// vec.reserve(10); /// assert!(vec.capacity() >= 11); /// ``` - #[inline] + #[inline(always)] pub fn reserve(&mut self, additional: usize) { - // self.buf.reserve(self.len, additional); - let _ = additional; - todo!() + self.0.reserve(additional); } /// Reserves the minimum capacity for at least `additional` more elements to @@ -327,40 +564,116 @@ impl<'alloc, T> Vec<'alloc, T> { /// vec.reserve_exact(10); /// assert!(vec.capacity() >= 11); /// ``` - #[inline] + #[inline(always)] pub fn reserve_exact(&mut self, additional: usize) { - // self.0.reserve_exact(self.len, additional); - let _ = additional; - todo!() + self.0.reserve_exact(additional); + } + + /// Forces the length of the vector to `new_len`. + /// + /// This is a low-level operation that maintains none of the normal + /// invariants of the type. Normally changing the length of a vector + /// is done using one of the safe operations instead, such as + /// [`resize`], [`truncate`], [`extend`], or [`clear`]. + /// + /// # Safety + /// - `new_len` must be less than or equal to the [`capacity`]. + /// - The elements at `old_len..new_len` must be initialized. + /// + /// [`resize`]: BumpVec::resize + /// [`truncate`]: BumpVec::truncate + /// [`extend`]: BumpVec::extend + /// [`clear`]: BumpVec::clear + /// [`capacity`]: BumpVec::capacity + #[inline(always)] + pub unsafe fn set_len(&mut self, new_len: usize) { + self.0.set_len(new_len); } } -pub struct Splice<'a, I: Iterator>(std::vec::Splice<'a, I>); +macro_rules! impl_slice_eq1 { + ([$($($vars:tt)+)?] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => { + impl<$($($vars)+,)? T, U> PartialEq<$rhs> for $lhs + where + T: PartialEq, + $($ty: $bound)? + { + #[inline] + fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } + #[inline] + fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] } + } + } +} + +impl_slice_eq1! { ['t, 'u] Vec<'t, T>, Vec<'u, U> } +impl_slice_eq1! { ['t] Vec<'t, T>, &[U] } +impl_slice_eq1! { [] Vec<'_, T>, &mut [U] } +impl_slice_eq1! { [] &[T], Vec<'_, U> } +impl_slice_eq1! { [] &mut [T], Vec<'_, U> } +impl_slice_eq1! { [] Vec<'_, T>, [U] } +impl_slice_eq1! { [] [T], Vec<'_, U> } +impl_slice_eq1! { ['t] Cow<'_, [T]>, Vec<'t, U> where T: Clone } +impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, [U; N] } +impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, &[U; N] } + +pub struct Drain<'a, T>(bump_scope::owned_slice::Drain<'a, T>); + +impl Iterator for Drain<'_, T> { + type Item = T; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl DoubleEndedIterator for Drain<'_, T> { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + +impl ExactSizeIterator for Drain<'_, T> {} + +impl FusedIterator for Drain<'_, T> {} + +pub struct Splice<'a, I: Iterator>(bump_scope::bump_vec::Splice<'a, I, Global>); impl Iterator for Splice<'_, I> { type Item = I::Item; + #[inline(always)] fn next(&mut self) -> Option { - todo!() + self.0.next() } + #[inline(always)] fn size_hint(&self) -> (usize, Option) { - todo!() + self.0.size_hint() } } impl<'alloc, T> Eq for Vec<'alloc, T> where T: Eq {} impl<'alloc, T> ops::Deref for Vec<'alloc, T> { - type Target = VecImpl<'alloc, T>; + type Target = [T]; + #[inline(always)] fn deref(&self) -> &Self::Target { &self.0 } } impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { - fn deref_mut(&mut self) -> &mut VecImpl<'alloc, T> { + #[inline(always)] + fn deref_mut(&mut self) -> &mut [T] { &mut self.0 } } @@ -369,6 +682,7 @@ impl<'alloc, T> IntoIterator for Vec<'alloc, T> { type IntoIter = as IntoIterator>::IntoIter; type Item = T; + #[inline(always)] fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } @@ -378,16 +692,18 @@ impl<'alloc, T> IntoIterator for &'alloc Vec<'alloc, T> { type IntoIter = std::slice::Iter<'alloc, T>; type Item = &'alloc T; + #[inline(always)] fn into_iter(self) -> Self::IntoIter { self.0.iter() } } -impl<'alloc, T> ops::Index for Vec<'alloc, T> { - type Output = T; +impl> Index for Vec<'_, T> { + type Output = I::Output; - fn index(&self, index: usize) -> &Self::Output { - self.0.index(index) + #[inline] + fn index(&self, index: I) -> &Self::Output { + Index::index(&**self, index) } } @@ -399,10 +715,16 @@ impl<'alloc, T> ops::Index for Vec<'alloc, T> { // } impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { + #[inline(always)] fn hash(&self, state: &mut H) { - for e in &self.0 { - e.hash(state); - } + self.0.hash(state) + } +} + +impl Extend for Vec<'_, T> { + #[inline(always)] + fn extend>(&mut self, iter: I) { + self.0.extend(iter) } } From 0497f135c37b816e1f8daca5257bd40a0890ba15 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sun, 20 Oct 2024 00:40:07 +0200 Subject: [PATCH 08/25] refactor(allocator): use the `from_iter_in` provided by `bump-scope` --- crates/oxc_allocator/src/vec.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 077418b193ad4..2bebecb15fcd6 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -101,12 +101,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// This is behaviorally identical to [`FromIterator::from_iter`]. #[inline(always)] pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { - let iter = iter.into_iter(); - let hint = iter.size_hint(); - let capacity = hint.1.unwrap_or(hint.0); - let mut vec = VecImpl::with_capacity_in(capacity, &**allocator); - vec.extend(iter); - Self(vec) + Self(VecImpl::from_iter_in(iter, allocator)) } /// Returns the total number of elements the vector can hold without From 315153e6ba1c9e8016ebbd3249ad4712835e2a2d Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sun, 20 Oct 2024 01:09:04 +0200 Subject: [PATCH 09/25] chore: merge branch 'main' into replace-bumpalo-with-bump-scope --- .github/.generated_ast_watch_list.yml | 4 + Cargo.lock | 62 +- Cargo.toml | 47 +- apps/oxlint/CHANGELOG.md | 7 + apps/oxlint/Cargo.toml | 2 +- crates/oxc/CHANGELOG.md | 11 + crates/oxc/Cargo.toml | 2 +- crates/oxc_allocator/CHANGELOG.md | 11 + crates/oxc_allocator/Cargo.toml | 6 +- crates/oxc_allocator/src/vec.rs | 67 +- crates/oxc_ast/CHANGELOG.md | 24 + crates/oxc_ast/Cargo.toml | 6 +- crates/oxc_ast/src/ast/js.rs | 776 ++-- crates/oxc_ast/src/ast/jsx.rs | 127 +- crates/oxc_ast/src/ast/literal.rs | 60 +- crates/oxc_ast/src/ast/mod.rs | 2 - crates/oxc_ast/src/ast/ts.rs | 564 +-- crates/oxc_ast/src/ast_impl/js.rs | 17 - crates/oxc_ast/src/ast_impl/literal.rs | 3 - crates/oxc_ast/src/generated/derive_estree.rs | 4072 +++++++++++++++++ crates/oxc_ast/src/lib.rs | 2 + crates/oxc_ast/src/serialize.rs | 14 + crates/oxc_ast_macros/CHANGELOG.md | 6 + crates/oxc_ast_macros/Cargo.toml | 2 +- crates/oxc_ast_macros/src/ast.rs | 2 + crates/oxc_ast_macros/src/lib.rs | 2 +- crates/oxc_cfg/Cargo.toml | 2 +- crates/oxc_codegen/CHANGELOG.md | 59 + crates/oxc_codegen/Cargo.toml | 2 +- crates/oxc_codegen/src/gen.rs | 73 +- crates/oxc_data_structures/CHANGELOG.md | 10 + crates/oxc_data_structures/Cargo.toml | 2 +- crates/oxc_diagnostics/Cargo.toml | 2 +- crates/oxc_ecmascript/CHANGELOG.md | 22 + crates/oxc_ecmascript/Cargo.toml | 2 +- crates/oxc_estree/CHANGELOG.md | 12 + crates/oxc_estree/Cargo.toml | 18 + crates/oxc_estree/src/lib.rs | 3 + crates/oxc_index/Cargo.toml | 2 +- crates/oxc_isolated_declarations/CHANGELOG.md | 22 + crates/oxc_isolated_declarations/Cargo.toml | 2 +- crates/oxc_linter/CHANGELOG.md | 85 + crates/oxc_linter/Cargo.toml | 2 +- crates/oxc_linter/src/disable_directives.rs | 7 +- .../src/rules/eslint/no_cond_assign.rs | 68 +- .../src/rules/eslint/no_unused_labels.rs | 7 +- .../src/rules/jest/no_untyped_mock_factory.rs | 8 +- .../src/rules/typescript/no_namespace.rs | 7 +- .../src/snapshots/no_cond_assign.snap | 7 - crates/oxc_mangler/Cargo.toml | 2 +- crates/oxc_minifier/CHANGELOG.md | 52 + crates/oxc_minifier/Cargo.toml | 2 +- .../src/ast_passes/peephole_fold_constants.rs | 2 +- .../ast_passes/peephole_remove_dead_code.rs | 34 +- crates/oxc_module_lexer/Cargo.toml | 2 +- crates/oxc_parser/CHANGELOG.md | 25 + crates/oxc_parser/Cargo.toml | 2 +- crates/oxc_prettier/src/lib.rs | 2 +- crates/oxc_regular_expression/CHANGELOG.md | 21 + crates/oxc_regular_expression/Cargo.toml | 11 +- crates/oxc_regular_expression/src/ast.rs | 132 +- .../src/generated/derive_estree.rs | 468 ++ crates/oxc_regular_expression/src/lib.rs | 2 + crates/oxc_semantic/CHANGELOG.md | 19 + crates/oxc_semantic/Cargo.toml | 2 +- crates/oxc_semantic/src/symbol.rs | 1 + crates/oxc_sourcemap/Cargo.toml | 2 +- crates/oxc_span/CHANGELOG.md | 16 + crates/oxc_span/Cargo.toml | 6 +- crates/oxc_span/src/atom.rs | 6 - crates/oxc_span/src/compact_str.rs | 6 - .../oxc_span/src/generated/derive_estree.rs | 90 + crates/oxc_span/src/lib.rs | 5 + crates/oxc_span/src/source_type/mod.rs | 25 +- crates/oxc_span/src/span/mod.rs | 2 +- crates/oxc_span/src/span/types.rs | 9 +- crates/oxc_syntax/CHANGELOG.md | 19 + crates/oxc_syntax/Cargo.toml | 6 +- .../oxc_syntax/src/generated/derive_estree.rs | 204 + crates/oxc_syntax/src/identifier.rs | 13 +- crates/oxc_syntax/src/lib.rs | 2 + crates/oxc_syntax/src/operator.rs | 123 +- crates/oxc_transformer/CHANGELOG.md | 56 + crates/oxc_transformer/Cargo.toml | 2 +- crates/oxc_traverse/CHANGELOG.md | 20 + crates/oxc_traverse/Cargo.toml | 2 +- editors/vscode/CHANGELOG.md | 13 + editors/vscode/package.json | 2 +- napi/transform/CHANGELOG.md | 11 + napi/transform/Cargo.toml | 2 +- npm/oxc-parser/package.json | 2 +- npm/oxc-transform/package.json | 2 +- npm/oxlint/CHANGELOG.md | 6 + npm/oxlint/package.json | 2 +- tasks/ast_tools/src/derives/estree.rs | 229 + tasks/ast_tools/src/derives/mod.rs | 15 +- tasks/ast_tools/src/main.rs | 6 +- tasks/ast_tools/src/markers.rs | 180 +- tasks/ast_tools/src/passes/linker.rs | 4 +- tasks/ast_tools/src/schema/defs.rs | 17 +- tasks/ast_tools/src/schema/mod.rs | 20 +- tasks/ast_tools/src/schema/serialize.rs | 32 + wasm/parser/package.json | 2 +- 103 files changed, 6869 insertions(+), 1391 deletions(-) create mode 100644 crates/oxc_ast/src/generated/derive_estree.rs create mode 100644 crates/oxc_estree/CHANGELOG.md create mode 100644 crates/oxc_estree/Cargo.toml create mode 100644 crates/oxc_estree/src/lib.rs create mode 100644 crates/oxc_regular_expression/src/generated/derive_estree.rs create mode 100644 crates/oxc_span/src/generated/derive_estree.rs create mode 100644 crates/oxc_syntax/src/generated/derive_estree.rs create mode 100644 tasks/ast_tools/src/derives/estree.rs create mode 100644 tasks/ast_tools/src/schema/serialize.rs diff --git a/.github/.generated_ast_watch_list.yml b/.github/.generated_ast_watch_list.yml index b801c6d9f9d89..542c3a26c2b48 100644 --- a/.github/.generated_ast_watch_list.yml +++ b/.github/.generated_ast_watch_list.yml @@ -23,6 +23,10 @@ src: - 'crates/oxc_ast/src/generated/derive_content_hash.rs' - 'crates/oxc_regular_expression/src/generated/derive_content_hash.rs' - 'crates/oxc_syntax/src/generated/derive_content_hash.rs' + - 'crates/oxc_ast/src/generated/derive_estree.rs' + - 'crates/oxc_regular_expression/src/generated/derive_estree.rs' + - 'crates/oxc_span/src/generated/derive_estree.rs' + - 'crates/oxc_syntax/src/generated/derive_estree.rs' - 'crates/oxc_ast/src/generated/assert_layouts.rs' - 'crates/oxc_ast/src/generated/ast_kind.rs' - 'crates/oxc_ast/src/generated/ast_builder.rs' diff --git a/Cargo.lock b/Cargo.lock index 43580793108fc..3b8dc0d06792c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1397,7 +1397,7 @@ checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "oxc" -version = "0.31.0" +version = "0.32.0" dependencies = [ "napi", "napi-derive", @@ -1439,7 +1439,7 @@ dependencies = [ [[package]] name = "oxc_allocator" -version = "0.31.0" +version = "0.32.0" dependencies = [ "allocator-api2", "bump-scope", @@ -1449,24 +1449,24 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.31.0" +version = "0.32.0" dependencies = [ "bitflags 2.6.0", "num-bigint", "oxc_allocator", "oxc_ast_macros", + "oxc_estree", "oxc_regular_expression", "oxc_span", "oxc_syntax", "serde", "serde_json", - "tsify", "wasm-bindgen", ] [[package]] name = "oxc_ast_macros" -version = "0.31.0" +version = "0.32.0" dependencies = [ "proc-macro2", "quote", @@ -1514,7 +1514,7 @@ dependencies = [ [[package]] name = "oxc_cfg" -version = "0.31.0" +version = "0.32.0" dependencies = [ "bitflags 2.6.0", "itertools", @@ -1527,7 +1527,7 @@ dependencies = [ [[package]] name = "oxc_codegen" -version = "0.31.0" +version = "0.32.0" dependencies = [ "assert-unchecked", "base64", @@ -1577,14 +1577,14 @@ dependencies = [ [[package]] name = "oxc_data_structures" -version = "0.31.0" +version = "0.32.0" dependencies = [ "assert-unchecked", ] [[package]] name = "oxc_diagnostics" -version = "0.31.0" +version = "0.32.0" dependencies = [ "miette", "owo-colors", @@ -1595,7 +1595,7 @@ dependencies = [ [[package]] name = "oxc_ecmascript" -version = "0.31.0" +version = "0.32.0" dependencies = [ "num-bigint", "num-traits", @@ -1604,9 +1604,13 @@ dependencies = [ "oxc_syntax", ] +[[package]] +name = "oxc_estree" +version = "0.32.0" + [[package]] name = "oxc_index" -version = "0.31.0" +version = "0.32.0" dependencies = [ "rayon", "serde", @@ -1614,7 +1618,7 @@ dependencies = [ [[package]] name = "oxc_isolated_declarations" -version = "0.31.0" +version = "0.32.0" dependencies = [ "bitflags 2.6.0", "insta", @@ -1655,7 +1659,7 @@ dependencies = [ [[package]] name = "oxc_linter" -version = "0.9.10" +version = "0.10.0" dependencies = [ "aho-corasick", "bitflags 2.6.0", @@ -1712,7 +1716,7 @@ dependencies = [ [[package]] name = "oxc_mangler" -version = "0.31.0" +version = "0.32.0" dependencies = [ "itertools", "oxc_ast", @@ -1723,7 +1727,7 @@ dependencies = [ [[package]] name = "oxc_minifier" -version = "0.31.0" +version = "0.32.0" dependencies = [ "cow-utils", "insta", @@ -1773,7 +1777,7 @@ dependencies = [ [[package]] name = "oxc_module_lexer" -version = "0.31.0" +version = "0.32.0" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1784,7 +1788,7 @@ dependencies = [ [[package]] name = "oxc_parser" -version = "0.31.0" +version = "0.32.0" dependencies = [ "assert-unchecked", "bitflags 2.6.0", @@ -1860,16 +1864,16 @@ dependencies = [ [[package]] name = "oxc_regular_expression" -version = "0.31.0" +version = "0.32.0" dependencies = [ "oxc_allocator", "oxc_ast_macros", "oxc_diagnostics", + "oxc_estree", "oxc_span", "phf 0.11.2", "rustc-hash", "serde", - "tsify", "unicode-id-start", "wasm-bindgen", ] @@ -1896,7 +1900,7 @@ dependencies = [ [[package]] name = "oxc_semantic" -version = "0.31.0" +version = "0.32.0" dependencies = [ "assert-unchecked", "indexmap", @@ -1921,7 +1925,7 @@ dependencies = [ [[package]] name = "oxc_sourcemap" -version = "0.31.0" +version = "0.32.0" dependencies = [ "base64-simd", "cfg-if", @@ -1934,21 +1938,21 @@ dependencies = [ [[package]] name = "oxc_span" -version = "0.31.0" +version = "0.32.0" dependencies = [ "compact_str", "miette", "oxc_allocator", "oxc_ast_macros", + "oxc_estree", "schemars", "serde", - "tsify", "wasm-bindgen", ] [[package]] name = "oxc_syntax" -version = "0.31.0" +version = "0.32.0" dependencies = [ "assert-unchecked", "bitflags 2.6.0", @@ -1956,13 +1960,13 @@ dependencies = [ "nonmax", "oxc_allocator", "oxc_ast_macros", + "oxc_estree", "oxc_index", "oxc_span", "phf 0.11.2", "rustc-hash", "ryu-js", "serde", - "tsify", "unicode-id-start", "wasm-bindgen", ] @@ -2007,7 +2011,7 @@ dependencies = [ [[package]] name = "oxc_transform_napi" -version = "0.31.0" +version = "0.32.0" dependencies = [ "napi", "napi-build", @@ -2017,7 +2021,7 @@ dependencies = [ [[package]] name = "oxc_transformer" -version = "0.31.0" +version = "0.32.0" dependencies = [ "base64", "cow-utils", @@ -2046,7 +2050,7 @@ dependencies = [ [[package]] name = "oxc_traverse" -version = "0.31.0" +version = "0.32.0" dependencies = [ "compact_str", "itoa", @@ -2078,7 +2082,7 @@ dependencies = [ [[package]] name = "oxlint" -version = "0.9.10" +version = "0.10.0" dependencies = [ "bpaf", "glob", diff --git a/Cargo.toml b/Cargo.toml index 970f331dd6af4..91307bd1912aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,29 +76,30 @@ doc_lazy_continuation = "allow" # FIXME [workspace.dependencies] # publish = true -oxc = { version = "0.31.0", path = "crates/oxc" } -oxc_allocator = { version = "0.31.0", path = "crates/oxc_allocator" } -oxc_ast = { version = "0.31.0", path = "crates/oxc_ast" } -oxc_ast_macros = { version = "0.31.0", path = "crates/oxc_ast_macros" } -oxc_cfg = { version = "0.31.0", path = "crates/oxc_cfg" } -oxc_codegen = { version = "0.31.0", path = "crates/oxc_codegen" } -oxc_data_structures = { version = "0.31.0", path = "crates/oxc_data_structures" } -oxc_diagnostics = { version = "0.31.0", path = "crates/oxc_diagnostics" } -oxc_ecmascript = { version = "0.31.0", path = "crates/oxc_ecmascript" } -oxc_index = { version = "0.31.0", path = "crates/oxc_index" } -oxc_isolated_declarations = { version = "0.31.0", path = "crates/oxc_isolated_declarations" } -oxc_mangler = { version = "0.31.0", path = "crates/oxc_mangler" } -oxc_minifier = { version = "0.31.0", path = "crates/oxc_minifier" } -oxc_module_lexer = { version = "0.31.0", path = "crates/oxc_module_lexer" } -oxc_parser = { version = "0.31.0", path = "crates/oxc_parser" } -oxc_regular_expression = { version = "0.31.0", path = "crates/oxc_regular_expression" } -oxc_semantic = { version = "0.31.0", path = "crates/oxc_semantic" } -oxc_sourcemap = { version = "0.31.0", path = "crates/oxc_sourcemap" } -oxc_span = { version = "0.31.0", path = "crates/oxc_span" } -oxc_syntax = { version = "0.31.0", path = "crates/oxc_syntax" } -oxc_transform_napi = { version = "0.31.0", path = "napi/transform" } -oxc_transformer = { version = "0.31.0", path = "crates/oxc_transformer" } -oxc_traverse = { version = "0.31.0", path = "crates/oxc_traverse" } +oxc = { version = "0.32.0", path = "crates/oxc" } +oxc_allocator = { version = "0.32.0", path = "crates/oxc_allocator" } +oxc_ast = { version = "0.32.0", path = "crates/oxc_ast" } +oxc_ast_macros = { version = "0.32.0", path = "crates/oxc_ast_macros" } +oxc_cfg = { version = "0.32.0", path = "crates/oxc_cfg" } +oxc_codegen = { version = "0.32.0", path = "crates/oxc_codegen" } +oxc_data_structures = { version = "0.32.0", path = "crates/oxc_data_structures" } +oxc_diagnostics = { version = "0.32.0", path = "crates/oxc_diagnostics" } +oxc_ecmascript = { version = "0.32.0", path = "crates/oxc_ecmascript" } +oxc_estree = { version = "0.32.0", path = "crates/oxc_estree" } +oxc_index = { version = "0.32.0", path = "crates/oxc_index" } +oxc_isolated_declarations = { version = "0.32.0", path = "crates/oxc_isolated_declarations" } +oxc_mangler = { version = "0.32.0", path = "crates/oxc_mangler" } +oxc_minifier = { version = "0.32.0", path = "crates/oxc_minifier" } +oxc_module_lexer = { version = "0.32.0", path = "crates/oxc_module_lexer" } +oxc_parser = { version = "0.32.0", path = "crates/oxc_parser" } +oxc_regular_expression = { version = "0.32.0", path = "crates/oxc_regular_expression" } +oxc_semantic = { version = "0.32.0", path = "crates/oxc_semantic" } +oxc_sourcemap = { version = "0.32.0", path = "crates/oxc_sourcemap" } +oxc_span = { version = "0.32.0", path = "crates/oxc_span" } +oxc_syntax = { version = "0.32.0", path = "crates/oxc_syntax" } +oxc_transform_napi = { version = "0.32.0", path = "napi/transform" } +oxc_transformer = { version = "0.32.0", path = "crates/oxc_transformer" } +oxc_traverse = { version = "0.32.0", path = "crates/oxc_traverse" } # publish = false oxc_linter = { path = "crates/oxc_linter" } diff --git a/apps/oxlint/CHANGELOG.md b/apps/oxlint/CHANGELOG.md index ca7dca7ed32dc..6951b69bf1840 100644 --- a/apps/oxlint/CHANGELOG.md +++ b/apps/oxlint/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.10.0] - 2024-10-18 + +- 80266d8 linter: [**BREAKING**] Support plugins in oxlint config files (#6088) (DonIsaac) + +### Features + + ## [0.9.10] - 2024-10-07 ### Bug Fixes diff --git a/apps/oxlint/Cargo.toml b/apps/oxlint/Cargo.toml index 51e39c05c5612..67e74196daa44 100644 --- a/apps/oxlint/Cargo.toml +++ b/apps/oxlint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxlint" -version = "0.9.10" +version = "0.10.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc/CHANGELOG.md b/crates/oxc/CHANGELOG.md index 814969382827a..beeb3618d806c 100644 --- a/crates/oxc/CHANGELOG.md +++ b/crates/oxc/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 91c87dd codegen: [**BREAKING**] Remove `Codegen::enableSourceMap` API (#6452) (Boshen) + +- 7645e5c codegen: [**BREAKING**] Remove CommentOptions API (#6451) (Boshen) + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +### Refactor + + ## [0.31.0] - 2024-10-08 - 020bb80 codegen: [**BREAKING**] Change to `CodegenReturn::code` and `CodegenReturn::map` (#6310) (Boshen) diff --git a/crates/oxc/Cargo.toml b/crates/oxc/Cargo.toml index 7cc5ec89a4c3e..158ebf85e3439 100644 --- a/crates/oxc/Cargo.toml +++ b/crates/oxc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_allocator/CHANGELOG.md b/crates/oxc_allocator/CHANGELOG.md index 01d92b48beaf4..54b6f355ff763 100644 --- a/crates/oxc_allocator/CHANGELOG.md +++ b/crates/oxc_allocator/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- 5ee1ef3 allocator: Add `Vec::into_boxed_slice` (#6195) (DonIsaac) + +### Documentation + +- 9f555d7 allocator: Clarify docs for `Box` (#6625) (overlookmotel) +- 06e75b0 allocator: Enable lint warnings on missing docs, and add missing doc comments (#6613) (DonIsaac) + ## [0.31.0] - 2024-10-08 ### Performance diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index 9aa40a5c9fde7..2e11d20d3cf02 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_allocator" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true @@ -22,10 +22,10 @@ doctest = false allocator-api2 = { workspace = true } bump-scope = { workspace = true } -serde = { workspace = true, optional = true, features = ["derive"] } +serde = { workspace = true, optional = true } [dev-dependencies] -serde = { workspace = true, features = ["derive"] } +serde = { workspace = true } serde_json = { workspace = true } bump-scope = { workspace = true, features = ["serde"] } diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 2bebecb15fcd6..8ed6cc9ff7aeb 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -2,26 +2,38 @@ //! //! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) +use core::fmt; use std::{ self, borrow::Cow, fmt::Debug, hash::{Hash, Hasher}, iter::FusedIterator, + mem::ManuallyDrop, ops::{self, Index, RangeBounds}, slice::SliceIndex, }; use allocator_api2::alloc::Global; +#[cfg(any(feature = "serialize", test))] +use serde::{ser::SerializeSeq, Serialize, Serializer}; + use crate::{Allocator, Box}; type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T>; -/// A bump-allocated vector. -#[cfg_attr(any(feature = "serialize", test), derive(serde::Serialize))] -#[derive(Debug)] -pub struct Vec<'alloc, T>(VecImpl<'alloc, T>); +/// A `Vec` without [`Drop`], which stores its data in the arena allocator. +/// +/// Should only be used for storing AST types. +/// +/// Must NOT be used to store types which have a [`Drop`] implementation. +/// `T::drop` will NOT be called on the `Vec`'s contents when the `Vec` is dropped. +/// If `T` owns memory outside of the arena, this will be a memory leak. +/// +/// Note: This is not a soundness issue, as Rust does not support relying on `drop` +/// being called to guarantee soundness. +pub struct Vec<'alloc, T>(ManuallyDrop>); impl<'alloc, T> Vec<'alloc, T> { /// Constructs a new, empty `Vec`. @@ -40,7 +52,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline(always)] pub fn new_in(allocator: &'alloc Allocator) -> Self { - Self(VecImpl::new_in(allocator)) + Self(ManuallyDrop::new(VecImpl::new_in(allocator))) } /// Constructs a new, empty `Vec` with at least the specified capacity @@ -92,7 +104,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline(always)] pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self { - Self(VecImpl::with_capacity_in(capacity, allocator)) + Self(ManuallyDrop::new(VecImpl::with_capacity_in(capacity, allocator))) } /// Create a new [`Vec`] whose elements are taken from an iterator and @@ -101,7 +113,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// This is behaviorally identical to [`FromIterator::from_iter`]. #[inline(always)] pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { - Self(VecImpl::from_iter_in(iter, allocator)) + Self(ManuallyDrop::new(VecImpl::from_iter_in(iter, allocator))) } /// Returns the total number of elements the vector can hold without @@ -117,7 +129,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[must_use] #[inline(always)] - pub const fn capacity(&self) -> usize { + pub fn capacity(&self) -> usize { self.0.capacity() } @@ -126,7 +138,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// Equivalent to `&s[..]`. #[must_use] #[inline(always)] - pub const fn as_slice(&self) -> &[T] { + pub fn as_slice(&self) -> &[T] { self.0.as_slice() } @@ -290,7 +302,8 @@ impl<'alloc, T> Vec<'alloc, T> { /// [owned slice]: Box #[inline(always)] pub fn into_boxed_slice(self) -> Box<'alloc, [T]> { - let ptr = self.0.into_fixed_vec().into_boxed_slice().into_raw(); + // By first calling `into_fixed_vec` we don't shrink the allocation. + let ptr = ManuallyDrop::into_inner(self.0).into_fixed_vec().into_boxed_slice().into_raw(); // SAFETY: `ptr` points to a valid slice `[T]`. // Lifetime of returned `Box<'alloc, [T]>` is same as lifetime of consumed `Vec<'alloc, T>`, // so data in the `Box` must be valid for its lifetime. @@ -586,6 +599,30 @@ impl<'alloc, T> Vec<'alloc, T> { } } +impl<'alloc, T: Debug> Debug for Vec<'alloc, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let inner = &*self.0; + f.debug_tuple("Vec").field(inner).finish() + } +} + +#[cfg(any(feature = "serialize", test))] +impl<'alloc, T> Serialize for Vec<'alloc, T> +where + T: Serialize, +{ + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let mut seq = s.serialize_seq(Some(self.0.len()))?; + for e in self.0.iter() { + seq.serialize_element(e)?; + } + seq.end() + } +} + macro_rules! impl_slice_eq1 { ([$($($vars:tt)+)?] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => { impl<$($($vars)+,)? T, U> PartialEq<$rhs> for $lhs @@ -679,7 +716,10 @@ impl<'alloc, T> IntoIterator for Vec<'alloc, T> { #[inline(always)] fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() + let inner = ManuallyDrop::into_inner(self.0); + // TODO: `allocator_api2::vec::Vec::IntoIter` is `Drop`. + // Wrap it in `ManuallyDrop` to prevent that. + inner.into_iter() } } @@ -710,9 +750,10 @@ impl> Index for Vec<'_, T> { // } impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { - #[inline(always)] fn hash(&self, state: &mut H) { - self.0.hash(state) + for e in self.0.iter() { + e.hash(state); + } } } diff --git a/crates/oxc_ast/CHANGELOG.md b/crates/oxc_ast/CHANGELOG.md index 0e428acaeb070..d2e74ce5d2e5d 100644 --- a/crates/oxc_ast/CHANGELOG.md +++ b/crates/oxc_ast/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +- 2808973 ast: [**BREAKING**] Add `Program::comments` (#6445) (Boshen) + +### Features + +- 6f22538 ecmascript: Add `ToBoolean`, `ToNumber`, `ToString` (#6502) (Boshen) +- 590925a minifier: Finish implementing folding array expressions (#6575) (camc314) +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) +- b5b0af9 regular_expression: Support RegExp Modifiers (#6410) (leaysgur) + +### Bug Fixes + +- 02bfbfe codegen: Preserve parenthesis for `ChainExpression` (#6430) (Dunqing) +- a71e8a0 minifier: Preserve init variable declarations when removing `for` statements during DCE (#6551) (magic-akari) +- 834ee2a semantic: `TSConditionalType` scope enter/exit locations (#6351) (DonIsaac) + +### Refactor + +- 073b02a ast: Type params field before params in TS function declaration types (#6391) (overlookmotel) +- 458f8f3 ast_tools: Consistent comments on `AstBuilder` methods (#6664) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 01b878e parser: [**BREAKING**] Use `BindingIdentifier` for `namespace` declaration names (#6003) (DonIsaac) diff --git a/crates/oxc_ast/Cargo.toml b/crates/oxc_ast/Cargo.toml index 8680c7e2a1325..5a3752ebc68d5 100644 --- a/crates/oxc_ast/Cargo.toml +++ b/crates/oxc_ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_ast" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true @@ -21,6 +21,7 @@ doctest = false [dependencies] oxc_allocator = { workspace = true } oxc_ast_macros = { workspace = true } +oxc_estree = { workspace = true } oxc_regular_expression = { workspace = true } oxc_span = { workspace = true } oxc_syntax = { workspace = true } @@ -30,8 +31,6 @@ num-bigint = { workspace = true } serde = { workspace = true, features = ["derive"], optional = true } serde_json = { workspace = true, optional = true } - -tsify = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } [features] @@ -39,7 +38,6 @@ default = [] serialize = [ "dep:serde", "dep:serde_json", - "dep:tsify", "dep:wasm-bindgen", "oxc_allocator/serialize", "oxc_regular_expression/serialize", diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 719e69c543ba7..2ee58141e8d61 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -2,13 +2,11 @@ // They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates. // Read [`macro@oxc_ast_macros::ast`] for more information. -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use std::cell::Cell; use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, SourceType, Span}; use oxc_syntax::{ operator::{ @@ -18,10 +16,6 @@ use oxc_syntax::{ scope::ScopeId, symbol::SymbolId, }; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; use super::{macros::inherit_variants, *}; @@ -32,22 +26,20 @@ use super::{macros::inherit_variants, *}; strict_if(self.source_type.is_strict() || self.directives.iter().any(Directive::is_use_strict)), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Program<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub source_type: SourceType, - #[serde(skip)] + #[estree(skip)] pub source_text: &'a str, /// Sorted comments - #[serde(skip)] + #[estree(skip)] pub comments: Vec<'a, Comment>, pub hashbang: Option>, pub directives: Vec<'a, Directive<'a>>, pub body: Vec<'a, Statement<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -60,9 +52,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum Expression<'a> { /// See [`BooleanLiteral`] for AST node details. BooleanLiteral(Box<'a, BooleanLiteral>) = 0, @@ -210,11 +201,10 @@ pub use match_expression; /// Fundamental syntactic structure used for naming variables, functions, and properties. It must start with a Unicode letter (including $ and _) and can be followed by Unicode letters, digits, $, or _. #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "Identifier")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Identifier")] pub struct IdentifierName<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: Atom<'a>, } @@ -226,11 +216,10 @@ pub struct IdentifierName<'a> { /// See: [13.1 Identifiers](https://tc39.es/ecma262/#sec-identifiers) #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "Identifier")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Identifier")] pub struct IdentifierReference<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the identifier being referenced. pub name: Atom<'a>, @@ -239,7 +228,7 @@ pub struct IdentifierReference<'a> { /// Identifies what identifier this refers to, and how it is used. This is /// set in the bind step of semantic analysis, and will always be [`None`] /// immediately after parsing. - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub reference_id: Cell>, } @@ -251,11 +240,10 @@ pub struct IdentifierReference<'a> { /// See: [13.1 Identifiers](https://tc39.es/ecma262/#sec-identifiers) #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "Identifier")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Identifier")] pub struct BindingIdentifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The identifier name being bound. pub name: Atom<'a>, @@ -265,7 +253,7 @@ pub struct BindingIdentifier<'a> { /// you choose to skip semantic analysis, this will always be [`None`]. /// /// [`semantic analysis`]: - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub symbol_id: Cell>, } @@ -277,11 +265,10 @@ pub struct BindingIdentifier<'a> { /// See: [13.1 Identifiers](https://tc39.es/ecma262/#sec-identifiers) #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "Identifier")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Identifier")] pub struct LabelIdentifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: Atom<'a>, } @@ -291,11 +278,9 @@ pub struct LabelIdentifier<'a> { /// Represents a `this` expression, which is a reference to the current object. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ThisExpression { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -304,17 +289,15 @@ pub struct ThisExpression { /// Represents an array literal, which can include elements, spread elements, or null values. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ArrayExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, #[tsify(type = "Array")] pub elements: Vec<'a, ArrayExpressionElement<'a>>, /// Array trailing comma /// - #[serde(skip)] + #[estree(skip)] pub trailing_comma: Option, } @@ -326,9 +309,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ArrayExpressionElement<'a> { /// `...[3, 4]` in `const array = [1, 2, ...[3, 4], null];` SpreadElement(Box<'a, SpreadElement<'a>>) = 64, @@ -358,24 +340,21 @@ pub struct Elision { /// Represents an object literal, which can include properties, spread properties, or computed properties and trailing comma. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ObjectExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Properties declared in the object pub properties: Vec<'a, ObjectPropertyKind<'a>>, - #[serde(skip)] + #[estree(skip)] pub trailing_comma: Option, } /// Represents a property in an object literal. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ObjectPropertyKind<'a> { /// `a: 1` in `const obj = { a: 1 };` ObjectProperty(Box<'a, ObjectProperty<'a>>) = 0, @@ -388,11 +367,9 @@ pub enum ObjectPropertyKind<'a> { /// Represents a property in an object literal. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ObjectProperty<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: PropertyKind, pub key: PropertyKey<'a>, @@ -411,9 +388,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum PropertyKey<'a> { /// `a` in `const obj = { a: 1 }; obj.a;` StaticIdentifier(Box<'a, IdentifierName<'a>>) = 64, @@ -427,9 +403,8 @@ pub enum PropertyKey<'a> { /// Represents the kind of property in an object literal or class. #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum PropertyKind { /// `a: 1` in `const obj = { a: 1 };` Init = 0, @@ -444,11 +419,9 @@ pub enum PropertyKind { /// Represents a template literal, which can include quasi elements and expression elements. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TemplateLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub quasis: Vec<'a, TemplateElement<'a>>, pub expressions: Vec<'a, Expression<'a>>, @@ -459,11 +432,9 @@ pub struct TemplateLiteral<'a> { /// Represents a tagged template expression, which can include a tag and a quasi. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TaggedTemplateExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub tag: Expression<'a>, pub quasi: TemplateLiteral<'a>, @@ -475,11 +446,9 @@ pub struct TaggedTemplateExpression<'a> { /// Represents a quasi element in a template literal. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TemplateElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub tail: bool, pub value: TemplateElementValue<'a>, @@ -488,8 +457,8 @@ pub struct TemplateElement<'a> { /// See [template-strings-cooked-vs-raw](https://exploringjs.com/js/book/ch_template-literals.html#template-strings-cooked-vs-raw) #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(no_type)] pub struct TemplateElementValue<'a> { /// A raw interpretation where backslashes do not have special meaning. /// For example, \t produces two characters – a backslash and a t. @@ -507,9 +476,8 @@ pub struct TemplateElementValue<'a> { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum MemberExpression<'a> { /// `ar[0]` in `const ar = [1, 2]; ar[0];` ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>) = 48, @@ -535,11 +503,9 @@ pub use match_member_expression; /// Represents a computed member access expression, which can include an object and an expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ComputedMemberExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub object: Expression<'a>, pub expression: Expression<'a>, @@ -551,11 +517,9 @@ pub struct ComputedMemberExpression<'a> { /// Represents a static member access expression, which can include an object and a property. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct StaticMemberExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub object: Expression<'a>, pub property: IdentifierName<'a>, @@ -567,11 +531,9 @@ pub struct StaticMemberExpression<'a> { /// Represents a private field access expression, which can include an object and a private identifier. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct PrivateFieldExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub object: Expression<'a>, pub field: PrivateIdentifier<'a>, @@ -596,11 +558,9 @@ pub struct PrivateFieldExpression<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct CallExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub callee: Expression<'a>, pub type_parameters: Option>>, @@ -622,11 +582,9 @@ pub struct CallExpression<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct NewExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub callee: Expression<'a>, pub arguments: Vec<'a, Argument<'a>>, @@ -638,11 +596,9 @@ pub struct NewExpression<'a> { /// Represents a meta property. The following syntaxes are supported. `import.meta`, `new.target`. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct MetaProperty<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub meta: IdentifierName<'a>, pub property: IdentifierName<'a>, @@ -653,11 +609,9 @@ pub struct MetaProperty<'a> { /// Represents a spread element, which can include an argument. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct SpreadElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The expression being spread. pub argument: Expression<'a>, @@ -671,9 +625,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum Argument<'a> { /// `...[1, 2]` in `const arr = [...[1, 2]];` SpreadElement(Box<'a, SpreadElement<'a>>) = 64, @@ -687,11 +640,9 @@ pub enum Argument<'a> { /// Represents an update expression, which can include an operator and an argument. The following syntaxes are supported. `++a`, `a++`, `--a`, `a--` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct UpdateExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub operator: UpdateOperator, pub prefix: bool, @@ -703,11 +654,9 @@ pub struct UpdateExpression<'a> { /// Represents a unary expression, which can include an operator and an argument. The following syntaxes are supported. `+a`, `-a`, `~a`, `!a`, `delete a`, `void a`, `typeof a` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct UnaryExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub operator: UnaryOperator, pub argument: Expression<'a>, @@ -718,11 +667,9 @@ pub struct UnaryExpression<'a> { /// Represents a binary expression, which can include a left expression, an operator, and a right expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BinaryExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: Expression<'a>, pub operator: BinaryOperator, @@ -734,11 +681,9 @@ pub struct BinaryExpression<'a> { /// Represents a private in expression, which can include a private identifier, an operator, and a expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct PrivateInExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: PrivateIdentifier<'a>, pub operator: BinaryOperator, // BinaryOperator::In @@ -750,11 +695,9 @@ pub struct PrivateInExpression<'a> { /// Represents a logical expression, which can include a left expression, an operator, and a right expression. The following syntaxes are supported. `||`, `&&` and `??` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct LogicalExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: Expression<'a>, pub operator: LogicalOperator, @@ -766,11 +709,9 @@ pub struct LogicalExpression<'a> { /// Represents a conditional expression, which can include a test, a consequent, and an alternate. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ConditionalExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub test: Expression<'a>, pub consequent: Expression<'a>, @@ -782,11 +723,9 @@ pub struct ConditionalExpression<'a> { /// Represents an assignment expression, which can include an operator, a target, and a expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AssignmentExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub operator: AssignmentOperator, pub left: AssignmentTarget<'a>, @@ -802,9 +741,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum AssignmentTarget<'a> { // `SimpleAssignmentTarget` variants added here by `inherit_variants!` macro @inherit SimpleAssignmentTarget @@ -821,9 +759,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum SimpleAssignmentTarget<'a> { AssignmentTargetIdentifier(Box<'a, IdentifierReference<'a>>) = 0, TSAsExpression(Box<'a, TSAsExpression<'a>>) = 1, @@ -876,9 +813,8 @@ pub use match_simple_assignment_target; #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum AssignmentTargetPattern<'a> { ArrayAssignmentTarget(Box<'a, ArrayAssignmentTarget<'a>>) = 8, ObjectAssignmentTarget(Box<'a, ObjectAssignmentTarget<'a>>) = 9, @@ -898,17 +834,16 @@ pub use match_assignment_target_pattern; /// Represents an array assignment target, which can include elements and a rest element. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct ArrayAssignmentTarget<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, #[tsify(type = "Array")] pub elements: Vec<'a, Option>>, - #[serde(skip)] + #[estree(skip)] pub rest: Option>, - #[serde(skip)] + #[estree(skip)] pub trailing_comma: Option, } @@ -917,15 +852,14 @@ pub struct ArrayAssignmentTarget<'a> { /// Represents an object assignment target, which can include properties and a rest element. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct ObjectAssignmentTarget<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, #[tsify(type = "Array")] pub properties: Vec<'a, AssignmentTargetProperty<'a>>, - #[serde(skip)] + #[estree(skip)] pub rest: Option>, } @@ -934,13 +868,12 @@ pub struct ObjectAssignmentTarget<'a> { /// Represents a rest element in an array assignment target, which can include a target. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "RestElement")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "RestElement")] pub struct AssignmentTargetRest<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, - #[serde(rename = "argument")] + #[estree(rename = "argument")] pub target: AssignmentTarget<'a>, } @@ -952,9 +885,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum AssignmentTargetMaybeDefault<'a> { AssignmentTargetWithDefault(Box<'a, AssignmentTargetWithDefault<'a>>) = 16, // `AssignmentTarget` variants added here by `inherit_variants!` macro @@ -964,11 +896,9 @@ pub enum AssignmentTargetMaybeDefault<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AssignmentTargetWithDefault<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub binding: AssignmentTarget<'a>, pub init: Expression<'a>, @@ -976,9 +906,8 @@ pub struct AssignmentTargetWithDefault<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum AssignmentTargetProperty<'a> { AssignmentTargetPropertyIdentifier(Box<'a, AssignmentTargetPropertyIdentifier<'a>>) = 0, AssignmentTargetPropertyProperty(Box<'a, AssignmentTargetPropertyProperty<'a>>) = 1, @@ -989,11 +918,9 @@ pub enum AssignmentTargetProperty<'a> { /// Represents an assignment target property identifier, which can include a binding and an init expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AssignmentTargetPropertyIdentifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub binding: IdentifierReference<'a>, pub init: Option>, @@ -1004,11 +931,9 @@ pub struct AssignmentTargetPropertyIdentifier<'a> { /// Represents an assignment target property property, which can include a name and a binding. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AssignmentTargetPropertyProperty<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: PropertyKey<'a>, pub binding: AssignmentTargetMaybeDefault<'a>, @@ -1019,11 +944,9 @@ pub struct AssignmentTargetPropertyProperty<'a> { /// Represents a sequence expression, which can include expressions. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct SequenceExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expressions: Vec<'a, Expression<'a>>, } @@ -1033,11 +956,9 @@ pub struct SequenceExpression<'a> { /// Represents a super expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Super { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -1046,11 +967,9 @@ pub struct Super { /// Represents an await expression, which can include an argument. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AwaitExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub argument: Expression<'a>, } @@ -1060,11 +979,9 @@ pub struct AwaitExpression<'a> { /// Represents a chain expression, which can include an expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ChainExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: ChainElement<'a>, } @@ -1077,9 +994,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ChainElement<'a> { CallExpression(Box<'a, CallExpression<'a>>) = 0, // `MemberExpression` variants added here by `inherit_variants!` macro @@ -1092,11 +1008,9 @@ pub enum ChainElement<'a> { /// Represents a parenthesized expression, which can include an expression. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ParenthesizedExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, } @@ -1110,9 +1024,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum Statement<'a> { // Statements BlockStatement(Box<'a, BlockStatement<'a>>) = 0, @@ -1145,11 +1058,9 @@ pub enum Statement<'a> { /// Represents a directive statement, which can include a string literal. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Directive<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Directive with any escapes unescaped pub expression: StringLiteral<'a>, @@ -1162,11 +1073,9 @@ pub struct Directive<'a> { /// Represents a hashbang directive, which can include a value. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Hashbang<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub value: Atom<'a>, } @@ -1177,14 +1086,12 @@ pub struct Hashbang<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BlockStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, Statement<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1192,9 +1099,8 @@ pub struct BlockStatement<'a> { /// Declarations and the Variable Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum Declaration<'a> { VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 32, #[visit(args(flags = ScopeFlags::Function))] @@ -1229,11 +1135,9 @@ pub use match_declaration; /// Represents a variable declaration, which can include a kind, declarations, and modifiers. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct VariableDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: VariableDeclarationKind, pub declarations: Vec<'a, VariableDeclarator<'a>>, @@ -1242,15 +1146,14 @@ pub struct VariableDeclaration<'a> { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum VariableDeclarationKind { Var = 0, Const = 1, Let = 2, Using = 3, - #[serde(rename = "await using")] + #[estree(rename = "await using")] AwaitUsing = 4, } @@ -1264,13 +1167,11 @@ pub enum VariableDeclarationKind { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct VariableDeclarator<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, - #[serde(skip)] + #[estree(skip)] pub kind: VariableDeclarationKind, pub id: BindingPattern<'a>, pub init: Option>, @@ -1280,22 +1181,18 @@ pub struct VariableDeclarator<'a> { /// Empty Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct EmptyStatement { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } /// Expression Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ExpressionStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, } @@ -1303,11 +1200,9 @@ pub struct ExpressionStatement<'a> { /// If Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct IfStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub test: Expression<'a>, pub consequent: Statement<'a>, @@ -1317,11 +1212,9 @@ pub struct IfStatement<'a> { /// Do-While Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct DoWhileStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Statement<'a>, pub test: Expression<'a>, @@ -1330,11 +1223,9 @@ pub struct DoWhileStatement<'a> { /// While Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct WhileStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub test: Expression<'a>, pub body: Statement<'a>, @@ -1344,17 +1235,15 @@ pub struct WhileStatement<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ForStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub init: Option>, pub test: Option>, pub update: Option>, pub body: Statement<'a>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1367,9 +1256,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ForStatementInit<'a> { VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 64, // `Expression` variants added here by `inherit_variants!` macro @@ -1381,16 +1269,14 @@ pub enum ForStatementInit<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ForInStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: ForStatementLeft<'a>, pub right: Expression<'a>, pub body: Statement<'a>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1403,9 +1289,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ForStatementLeft<'a> { VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 16, // `AssignmentTarget` variants added here by `inherit_variants!` macro @@ -1416,17 +1301,15 @@ pub enum ForStatementLeft<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ForOfStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub r#await: bool, pub left: ForStatementLeft<'a>, pub right: Expression<'a>, pub body: Statement<'a>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1434,11 +1317,9 @@ pub struct ForOfStatement<'a> { /// Continue Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ContinueStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub label: Option>, } @@ -1446,11 +1327,9 @@ pub struct ContinueStatement<'a> { /// Break Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BreakStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub label: Option>, } @@ -1458,11 +1337,9 @@ pub struct BreakStatement<'a> { /// Return Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ReturnStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub argument: Option>, } @@ -1470,11 +1347,9 @@ pub struct ReturnStatement<'a> { /// With Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct WithStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub object: Expression<'a>, pub body: Statement<'a>, @@ -1484,27 +1359,23 @@ pub struct WithStatement<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct SwitchStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub discriminant: Expression<'a>, #[scope(enter_before)] pub cases: Vec<'a, SwitchCase<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct SwitchCase<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub test: Option>, pub consequent: Vec<'a, Statement<'a>>, @@ -1513,11 +1384,9 @@ pub struct SwitchCase<'a> { /// Labelled Statement #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct LabeledStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub label: LabelIdentifier<'a>, pub body: Statement<'a>, @@ -1532,11 +1401,9 @@ pub struct LabeledStatement<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ThrowStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The expression being thrown, e.g. `err` in `throw err;` pub argument: Expression<'a>, @@ -1559,11 +1426,9 @@ pub struct ThrowStatement<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TryStatement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Statements in the `try` block pub block: Box<'a, BlockStatement<'a>>, @@ -1589,17 +1454,15 @@ pub struct TryStatement<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::CatchClause))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct CatchClause<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The caught error parameter, e.g. `e` in `catch (e) {}` pub param: Option>, /// The statements run when an error is caught pub body: Box<'a, BlockStatement<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1619,11 +1482,9 @@ pub struct CatchClause<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct CatchParameter<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The bound error pub pattern: BindingPattern<'a>, @@ -1638,11 +1499,9 @@ pub struct CatchParameter<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct DebuggerStatement { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -1650,12 +1509,11 @@ pub struct DebuggerStatement { /// * #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(no_type)] pub struct BindingPattern<'a> { // serde(flatten) the attributes because estree has no `BindingPattern` - #[serde(flatten)] + #[estree(flatten)] #[tsify(type = "(BindingIdentifier | ObjectPattern | ArrayPattern | AssignmentPattern)")] #[span] pub kind: BindingPatternKind<'a>, @@ -1665,9 +1523,8 @@ pub struct BindingPattern<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum BindingPatternKind<'a> { /// `const a = 1` BindingIdentifier(Box<'a, BindingIdentifier<'a>>) = 0, @@ -1684,11 +1541,9 @@ pub enum BindingPatternKind<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AssignmentPattern<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: BindingPattern<'a>, pub right: Expression<'a>, @@ -1697,25 +1552,22 @@ pub struct AssignmentPattern<'a> { // See serializer in serialize.rs #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct ObjectPattern<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, #[tsify(type = "Array")] pub properties: Vec<'a, BindingProperty<'a>>, - #[serde(skip)] + #[estree(skip)] pub rest: Option>>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BindingProperty<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub key: PropertyKey<'a>, pub value: BindingPattern<'a>, @@ -1726,15 +1578,14 @@ pub struct BindingProperty<'a> { // See serializer in serialize.rs #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct ArrayPattern<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, #[tsify(type = "Array")] pub elements: Vec<'a, Option>>, - #[serde(skip)] + #[estree(skip)] pub rest: Option>>, } @@ -1749,11 +1600,10 @@ pub struct ArrayPattern<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "RestElement")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "RestElement")] pub struct BindingRestElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub argument: BindingPattern<'a>, } @@ -1800,12 +1650,10 @@ pub struct BindingRestElement<'a> { strict_if(self.is_strict()), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Function<'a> { pub r#type: FunctionType, - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The function identifier. [`None`] for anonymous function expressions. pub id: Option>, @@ -1855,15 +1703,14 @@ pub struct Function<'a> { /// } /// ``` pub body: Option>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum FunctionType { FunctionDeclaration = 0, FunctionExpression = 1, @@ -1876,26 +1723,23 @@ pub enum FunctionType { // See serializer in serialize.rs #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct FormalParameters<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: FormalParameterKind, #[tsify(type = "Array")] pub items: Vec<'a, FormalParameter<'a>>, - #[serde(skip)] + #[estree(skip)] pub rest: Option>>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct FormalParameter<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub decorators: Vec<'a, Decorator<'a>>, pub pattern: BindingPattern<'a>, @@ -1906,8 +1750,7 @@ pub struct FormalParameter<'a> { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum FormalParameterKind { /// FormalParameter = 0, @@ -1922,11 +1765,9 @@ pub enum FormalParameterKind { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct FunctionBody<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub directives: Vec<'a, Directive<'a>>, pub statements: Vec<'a, Statement<'a>>, @@ -1939,11 +1780,9 @@ pub struct FunctionBody<'a> { strict_if(self.body.has_use_strict_directive()), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ArrowFunctionExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Is the function body an arrow expression? i.e. `() => expr` instead of `() => {}` pub expression: bool, @@ -1953,7 +1792,7 @@ pub struct ArrowFunctionExpression<'a> { pub return_type: Option>>, /// See `expression` for whether this arrow expression returns an expression. pub body: Box<'a, FunctionBody<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1961,11 +1800,9 @@ pub struct ArrowFunctionExpression<'a> { /// Generator Function Definitions #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct YieldExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub delegate: bool, pub argument: Option>, @@ -1975,12 +1812,10 @@ pub struct YieldExpression<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::StrictMode))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Class<'a> { pub r#type: ClassType, - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Decorators applied to the class. /// @@ -2041,15 +1876,14 @@ pub struct Class<'a> { pub declare: bool, /// Id of the scope created by the [`Class`], including type parameters and /// statements within the [`ClassBody`]. - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum ClassType { /// Class declaration statement /// ```ts @@ -2066,11 +1900,9 @@ pub enum ClassType { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ClassBody<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, ClassElement<'a>>, } @@ -2095,9 +1927,8 @@ pub struct ClassBody<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ClassElement<'a> { StaticBlock(Box<'a, StaticBlock<'a>>) = 0, /// Class Methods @@ -2119,15 +1950,13 @@ pub enum ClassElement<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct MethodDefinition<'a> { /// Method definition type /// /// This will always be true when an `abstract` modifier is used on the method. pub r#type: MethodDefinitionType, - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub decorators: Vec<'a, Decorator<'a>>, pub key: PropertyKey<'a>, @@ -2148,8 +1977,7 @@ pub struct MethodDefinition<'a> { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum MethodDefinitionType { MethodDefinition = 0, TSAbstractMethodDefinition = 1, @@ -2157,12 +1985,10 @@ pub enum MethodDefinitionType { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct PropertyDefinition<'a> { pub r#type: PropertyDefinitionType, - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Decorators applied to the property. /// @@ -2239,8 +2065,7 @@ pub struct PropertyDefinition<'a> { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum PropertyDefinitionType { PropertyDefinition = 0, TSAbstractPropertyDefinition = 1, @@ -2248,9 +2073,8 @@ pub enum PropertyDefinitionType { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum MethodDefinitionKind { /// Class constructor Constructor = 0, @@ -2267,11 +2091,9 @@ pub enum MethodDefinitionKind { /// See: [MDN - Private class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields) #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct PrivateIdentifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: Atom<'a>, } @@ -2292,14 +2114,12 @@ pub struct PrivateIdentifier<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::ClassStaticBlock))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct StaticBlock<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, Statement<'a>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -2329,9 +2149,8 @@ pub struct StaticBlock<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ModuleDeclaration<'a> { /// `import hello from './world.js';` /// `import * as t from './world.js';` @@ -2366,8 +2185,7 @@ pub use match_module_declaration; #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub enum AccessorPropertyType { AccessorProperty = 0, TSAbstractAccessorProperty = 1, @@ -2383,12 +2201,10 @@ pub enum AccessorPropertyType { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct AccessorProperty<'a> { pub r#type: AccessorPropertyType, - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Decorators applied to the accessor property. /// @@ -2427,11 +2243,9 @@ pub struct AccessorProperty<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub source: Expression<'a>, pub arguments: Vec<'a, Expression<'a>>, @@ -2439,11 +2253,9 @@ pub struct ImportExpression<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// `None` for `import 'foo'`, `Some([])` for `import {} from 'foo'` pub specifiers: Option>>, @@ -2456,9 +2268,8 @@ pub struct ImportDeclaration<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ImportDeclarationSpecifier<'a> { /// import {imported} from "source" /// import {imported as local} from "source" @@ -2473,11 +2284,9 @@ pub enum ImportDeclarationSpecifier<'a> { // import {imported as local} from "source" #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportSpecifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub imported: ModuleExportName<'a>, /// The name of the imported symbol. @@ -2504,11 +2313,9 @@ pub struct ImportSpecifier<'a> { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportDefaultSpecifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the imported symbol. pub local: BindingIdentifier<'a>, @@ -2522,22 +2329,18 @@ pub struct ImportDefaultSpecifier<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportNamespaceSpecifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub local: BindingIdentifier<'a>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct WithClause<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub attributes_keyword: IdentifierName<'a>, // `with` or `assert` pub with_entries: Vec<'a, ImportAttribute<'a>>, @@ -2545,11 +2348,9 @@ pub struct WithClause<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ImportAttribute<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub key: ImportAttributeKey<'a>, pub value: StringLiteral<'a>, @@ -2557,9 +2358,8 @@ pub struct ImportAttribute<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ImportAttributeKey<'a> { Identifier(IdentifierName<'a>) = 0, StringLiteral(StringLiteral<'a>) = 1, @@ -2578,11 +2378,9 @@ pub enum ImportAttributeKey<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ExportNamedDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub declaration: Option>, pub specifiers: Vec<'a, ExportSpecifier<'a>>, @@ -2604,11 +2402,9 @@ pub struct ExportNamedDeclaration<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ExportDefaultDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub declaration: ExportDefaultDeclarationKind<'a>, pub exported: ModuleExportName<'a>, // the `default` Keyword @@ -2625,11 +2421,9 @@ pub struct ExportDefaultDeclaration<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ExportAllDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// If this declaration is re-named pub exported: Option>, @@ -2652,11 +2446,9 @@ pub struct ExportAllDeclaration<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct ExportSpecifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub local: ModuleExportName<'a>, pub exported: ModuleExportName<'a>, @@ -2671,9 +2463,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ExportDefaultDeclarationKind<'a> { #[visit(args(flags = ScopeFlags::Function))] FunctionDeclaration(Box<'a, Function<'a>>) = 64, @@ -2695,9 +2486,8 @@ pub enum ExportDefaultDeclarationKind<'a> { /// * #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum ModuleExportName<'a> { IdentifierName(IdentifierName<'a>) = 0, /// For `local` in `ExportSpecifier`: `foo` in `export { foo }` diff --git a/crates/oxc_ast/src/ast/jsx.rs b/crates/oxc_ast/src/ast/jsx.rs index ce4f04831e8b2..289be4f57b4ff 100644 --- a/crates/oxc_ast/src/ast/jsx.rs +++ b/crates/oxc_ast/src/ast/jsx.rs @@ -4,16 +4,10 @@ // They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates. // Read [`macro@oxc_ast_macros::ast`] for more information. -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; use super::{inherit_variants, js::*, literal::*, ts::*}; @@ -38,11 +32,9 @@ use super::{inherit_variants, js::*, literal::*, ts::*}; /// See: [JSX Syntax](https://facebook.github.io/jsx/) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Opening tag of the element. pub opening_element: Box<'a, JSXOpeningElement<'a>>, @@ -69,11 +61,9 @@ pub struct JSXElement<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXOpeningElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Is this tag self-closing? /// @@ -103,11 +93,9 @@ pub struct JSXOpeningElement<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXClosingElement<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: JSXElementName<'a>, } @@ -122,11 +110,9 @@ pub struct JSXClosingElement<'a> { /// See: [`React.Fragment`](https://react.dev/reference/react/Fragment) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXFragment<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// `<>` pub opening_fragment: JSXOpeningFragment, @@ -139,22 +125,18 @@ pub struct JSXFragment<'a> { /// JSX Opening Fragment (`<>`) #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXOpeningFragment { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } /// JSX Closing Fragment (``) #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXClosingFragment { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -162,7 +144,7 @@ pub struct JSXClosingFragment { #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[serde(untagged)] +#[estree(untagged)] pub enum JSXElementName<'a> { /// `
` Identifier(Box<'a, JSXIdentifier<'a>>) = 0, @@ -185,11 +167,9 @@ pub enum JSXElementName<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXNamespacedName<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Namespace portion of the name, e.g. `Apple` in `` pub namespace: JSXIdentifier<'a>, @@ -214,11 +194,9 @@ pub struct JSXNamespacedName<'a> { /// [`member expression`]: JSXMemberExpressionObject::MemberExpression #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXMemberExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The object being accessed. This is everything before the last `.`. pub object: JSXMemberExpressionObject<'a>, @@ -229,7 +207,7 @@ pub struct JSXMemberExpression<'a> { #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[serde(untagged)] +#[estree(untagged)] pub enum JSXMemberExpressionObject<'a> { IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0, MemberExpression(Box<'a, JSXMemberExpression<'a>>) = 1, @@ -251,11 +229,9 @@ pub enum JSXMemberExpressionObject<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXExpressionContainer<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The expression inside the container. pub expression: JSXExpression<'a>, @@ -270,9 +246,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum JSXExpression<'a> { EmptyExpression(JSXEmptyExpression) = 64, // `Expression` variants added here by `inherit_variants!` macro @@ -283,11 +258,9 @@ pub enum JSXExpression<'a> { /// An empty JSX expression (`{}`) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXEmptyExpression { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -304,9 +277,8 @@ pub struct JSXEmptyExpression { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum JSXAttributeItem<'a> { /// A `key="value"` attribute Attribute(Box<'a, JSXAttribute<'a>>) = 0, @@ -327,11 +299,9 @@ pub enum JSXAttributeItem<'a> { /// // name ^^^ ^^^^ value #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXAttribute<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the attribute. This is a prop in React-like applications. pub name: JSXAttributeName<'a>, @@ -350,11 +320,9 @@ pub struct JSXAttribute<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXSpreadAttribute<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub argument: Expression<'a>, } @@ -376,9 +344,8 @@ pub struct JSXSpreadAttribute<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum JSXAttributeName<'a> { /// An attribute name without a namespace prefix, e.g. `foo` in `foo="bar"`. Identifier(Box<'a, JSXIdentifier<'a>>) = 0, @@ -406,9 +373,8 @@ pub enum JSXAttributeName<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum JSXAttributeValue<'a> { StringLiteral(Box<'a, StringLiteral<'a>>) = 0, ExpressionContainer(Box<'a, JSXExpressionContainer<'a>>) = 1, @@ -423,11 +389,9 @@ pub enum JSXAttributeValue<'a> { /// [`IdentifierName`]: super::IdentifierName #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXIdentifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the identifier. pub name: Atom<'a>, @@ -440,9 +404,8 @@ pub struct JSXIdentifier<'a> { /// Part of a [`JSXElement`]. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum JSXChild<'a> { /// `Some Text` Text(Box<'a, JSXText<'a>>) = 0, @@ -461,11 +424,9 @@ pub enum JSXChild<'a> { /// Variant of [`JSXChild`] that represents an object spread (`{...expression}`). #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXSpreadChild<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The expression being spread. pub expression: Expression<'a>, @@ -483,11 +444,9 @@ pub struct JSXSpreadChild<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSXText<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The text content. pub value: Atom<'a>, diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index c4fe6200de64f..04da8bc414388 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -4,32 +4,24 @@ // They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates. // Read [`macro@oxc_ast_macros::ast`] for more information. -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use std::hash::Hash; use bitflags::bitflags; use oxc_allocator::{Box, CloneIn}; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_regular_expression::ast::Pattern; use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; use oxc_syntax::number::{BigintBase, NumberBase}; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; /// Boolean literal /// /// #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BooleanLiteral { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub value: bool, } @@ -39,11 +31,9 @@ pub struct BooleanLiteral { /// #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)] pub struct NullLiteral { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -52,34 +42,30 @@ pub struct NullLiteral { /// #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)] pub struct NumericLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The value of the number, converted into base 10 pub value: f64, /// The number as it appears in the source code pub raw: &'a str, /// The base representation used by the literal in the source code - #[serde(skip)] + #[estree(skip)] pub base: NumberBase, } /// BigInt literal #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct BigIntLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The bigint as it appears in the source code pub raw: Atom<'a>, /// The base representation used by the literal in the source code - #[serde(skip)] + #[estree(skip)] pub base: BigintBase, } @@ -88,11 +74,9 @@ pub struct BigIntLiteral<'a> { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct RegExpLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, // valid regex is printed as {} // invalid regex is printed as null, which we can't implement yet @@ -105,8 +89,8 @@ pub struct RegExpLiteral<'a> { /// #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(no_type)] pub struct RegExp<'a> { /// The regex pattern between the slashes pub pattern: RegExpPattern<'a>, @@ -119,8 +103,8 @@ pub struct RegExp<'a> { /// This pattern may or may not be parsed. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum RegExpPattern<'a> { /// Unparsed pattern. Contains string slice of the pattern. /// Pattern was not parsed, so may be valid or invalid. @@ -135,8 +119,8 @@ pub enum RegExpPattern<'a> { #[ast] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(no_type)] pub struct EmptyObject; /// String literal @@ -144,11 +128,9 @@ pub struct EmptyObject; /// #[ast(visit)] #[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct StringLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub value: Atom<'a>, } diff --git a/crates/oxc_ast/src/ast/mod.rs b/crates/oxc_ast/src/ast/mod.rs index 19a3c0b505cbe..25fe7c3092598 100644 --- a/crates/oxc_ast/src/ast/mod.rs +++ b/crates/oxc_ast/src/ast/mod.rs @@ -1,5 +1,3 @@ -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] //! AST Definitions //! //! # Enum inheritance diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 1555888052394..97ae5f09c4bbb 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -7,32 +7,16 @@ // They are purely markers for codegen used in `tasks/ast_tools` and `crates/oxc_traverse/scripts`. See docs in those crates. // Read [`macro@oxc_ast_macros::ast`] for more information. -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use std::cell::Cell; use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; use oxc_syntax::scope::ScopeId; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; use super::{inherit_variants, js::*, jsx::*, literal::*}; -#[cfg(feature = "serialize")] -#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] -const TS_APPEND_CONTENT: &'static str = r#" -export interface TSIndexSignatureName extends Span { - type: "Identifier", - name: Atom, - typeAnnotation: TSTypeAnnotation, -} -"#; - /// TypeScript `this` parameter /// /// ## Example @@ -45,11 +29,9 @@ export interface TSIndexSignatureName extends Span { /// * [TypeScript Handbook - `this` parameters](https://www.typescriptlang.org/docs/handbook/2/functions.html#this-parameters) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSThisParameter<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub this_span: Span, /// Type type the `this` keyword will have in the function @@ -79,11 +61,9 @@ pub struct TSThisParameter<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSEnumDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub id: BindingIdentifier<'a>, #[scope(enter_before)] @@ -91,7 +71,7 @@ pub struct TSEnumDeclaration<'a> { /// `true` for const enums pub r#const: bool, pub declare: bool, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -115,11 +95,9 @@ pub struct TSEnumDeclaration<'a> { /// * [TypeScript Handbook - Enums](https://www.typescriptlang.org/docs/handbook/enums.html) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSEnumMember<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub id: TSEnumMemberName<'a>, pub initializer: Option>, @@ -134,9 +112,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSEnumMemberName<'a> { StaticIdentifier(Box<'a, IdentifierName<'a>>) = 64, StaticStringLiteral(Box<'a, StringLiteral<'a>>) = 65, @@ -163,11 +140,9 @@ pub enum TSEnumMemberName<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeAnnotation<'a> { - #[serde(flatten)] + #[estree(flatten)] /// starts at the `:` token and ends at the end of the type annotation pub span: Span, /// The actual type in the annotation @@ -190,11 +165,9 @@ pub struct TSTypeAnnotation<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSLiteralType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub literal: TSLiteral<'a>, } @@ -202,9 +175,8 @@ pub struct TSLiteralType<'a> { /// A literal in a [`TSLiteralType`]. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSLiteral<'a> { BooleanLiteral(Box<'a, BooleanLiteral>) = 0, NullLiteral(Box<'a, NullLiteral>) = 1, @@ -229,9 +201,8 @@ pub enum TSLiteral<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSType<'a> { // Keyword TSAnyKeyword(Box<'a, TSAnyKeyword>) = 0, @@ -338,11 +309,9 @@ pub use match_ts_type; #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSConditionalType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The type before `extends` in the test expression. pub check_type: TSType<'a>, @@ -354,7 +323,7 @@ pub struct TSConditionalType<'a> { /// The type evaluated to if the test is false. #[scope(exit_before)] pub false_type: TSType<'a>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -370,11 +339,9 @@ pub struct TSConditionalType<'a> { /// * [TypeScript Handbook - Union Types](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#unions) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSUnionType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The types in the union. pub types: Vec<'a, TSType<'a>>, @@ -395,11 +362,9 @@ pub struct TSUnionType<'a> { /// * [TypeScript Handbook - Intersection Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSIntersectionType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub types: Vec<'a, TSType<'a>>, } @@ -415,11 +380,9 @@ pub struct TSIntersectionType<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSParenthesizedType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_annotation: TSType<'a>, } @@ -435,11 +398,9 @@ pub struct TSParenthesizedType<'a> { /// * [TypeScript Handbook - Keyof Types](https://www.typescriptlang.org/docs/handbook/2/keyof-types.html) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeOperator<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub operator: TSTypeOperatorOperator, /// The type being operated on @@ -449,9 +410,8 @@ pub struct TSTypeOperator<'a> { /// Operator in a [`TSTypeOperator`]. #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum TSTypeOperatorOperator { Keyof = 0, Unique = 1, @@ -471,11 +431,9 @@ pub enum TSTypeOperatorOperator { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSArrayType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub element_type: TSType<'a>, } @@ -493,11 +451,9 @@ pub struct TSArrayType<'a> { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSIndexedAccessType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub object_type: TSType<'a>, pub index_type: TSType<'a>, @@ -514,11 +470,9 @@ pub struct TSIndexedAccessType<'a> { /// #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTupleType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub element_types: Vec<'a, TSTupleElement<'a>>, } @@ -535,11 +489,9 @@ pub struct TSTupleType<'a> { /// * [TypeScript Handbook - Tuple Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNamedTupleMember<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub element_type: TSTupleElement<'a>, pub label: IdentifierName<'a>, @@ -557,11 +509,9 @@ pub struct TSNamedTupleMember<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSOptionalType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_annotation: TSType<'a>, } @@ -576,11 +526,9 @@ pub struct TSOptionalType<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSRestType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_annotation: TSType<'a>, } @@ -595,9 +543,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSTupleElement<'a> { // Discriminants start at 64, so that `TSTupleElement::is_ts_type` is a single // bitwise AND operation on the discriminant (`discriminant & 63 != 0`). @@ -619,11 +566,9 @@ pub enum TSTupleElement<'a> { /// * [TypeScript Handbook - Any Type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSAnyKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -638,11 +583,9 @@ pub struct TSAnyKeyword { /// * [TypeScript Handbook - Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#the-primitives-string-number-and-boolean) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSStringKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -657,11 +600,9 @@ pub struct TSStringKeyword { /// * [TypeScript Handbook - Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#the-primitives-string-number-and-boolean) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSBooleanKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -676,11 +617,9 @@ pub struct TSBooleanKeyword { /// * [TypeScript Handbook - Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#the-primitives-string-number-and-boolean) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNumberKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -696,11 +635,9 @@ pub struct TSNumberKeyword { /// * [TypeScript Handbook - Advanced Topics](https://www.typescriptlang.org/docs/handbook/type-compatibility.html#advanced-topics) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNeverKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -716,11 +653,9 @@ pub struct TSNeverKeyword { /// * [microsoft/TypeScript #40580](https://github.com/microsoft/TypeScript/pull/40580) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSIntrinsicKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -737,11 +672,9 @@ pub struct TSIntrinsicKeyword { /// * [TypeScript Handbook - Advanced Topics](https://www.typescriptlang.org/docs/handbook/type-compatibility.html#advanced-topics) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSUnknownKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -757,11 +690,9 @@ pub struct TSUnknownKeyword { /// * [TypeScript Handbook - Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#null-and-undefined) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNullKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -779,61 +710,49 @@ pub struct TSNullKeyword { /// * [TypeScript Handbook - Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#null-and-undefined) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSUndefinedKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSVoidKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSSymbolKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSThisType { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSObjectKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSBigIntKeyword { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -847,11 +766,9 @@ pub struct TSBigIntKeyword { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeReference<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_name: TSTypeName<'a>, pub type_parameters: Option>>, @@ -862,9 +779,8 @@ pub struct TSTypeReference<'a> { /// NamespaceName . IdentifierReference #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSTypeName<'a> { IdentifierReference(Box<'a, IdentifierReference<'a>>) = 0, QualifiedName(Box<'a, TSQualifiedName<'a>>) = 1, @@ -889,11 +805,9 @@ pub use match_ts_type_name; /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSQualifiedName<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub left: TSTypeName<'a>, pub right: IdentifierName<'a>, @@ -901,11 +815,9 @@ pub struct TSQualifiedName<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeParameterInstantiation<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub params: Vec<'a, TSType<'a>>, } @@ -929,11 +841,9 @@ pub struct TSTypeParameterInstantiation<'a> { /// * [TypeScript Handbook - Variance Annotations](https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeParameter<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the parameter, e.g. `T` in `type Foo = ...`. pub name: BindingIdentifier<'a>, @@ -951,11 +861,9 @@ pub struct TSTypeParameter<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeParameterDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub params: Vec<'a, TSTypeParameter<'a>>, } @@ -971,11 +879,9 @@ pub struct TSTypeParameterDeclaration<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeAliasDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Type alias's identifier, e.g. `Foo` in `type Foo = number`. pub id: BindingIdentifier<'a>, @@ -983,16 +889,15 @@ pub struct TSTypeAliasDeclaration<'a> { pub type_parameters: Option>>, pub type_annotation: TSType<'a>, pub declare: bool, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum TSAccessibility { Private = 0, Protected = 1, @@ -1011,11 +916,9 @@ pub enum TSAccessibility { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSClassImplements<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: TSTypeName<'a>, pub type_parameters: Option>>, @@ -1039,11 +942,9 @@ pub struct TSClassImplements<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSInterfaceDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The identifier (name) of the interface. pub id: BindingIdentifier<'a>, @@ -1055,7 +956,7 @@ pub struct TSInterfaceDeclaration<'a> { pub body: Box<'a, TSInterfaceBody<'a>>, /// `true` for `declare interface Foo {}` pub declare: bool, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1063,11 +964,9 @@ pub struct TSInterfaceDeclaration<'a> { /// Body of a [`TSInterfaceDeclaration`]. #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSInterfaceBody<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, TSSignature<'a>>, } @@ -1089,11 +988,9 @@ pub struct TSInterfaceBody<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSPropertySignature<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub computed: bool, pub optional: bool, @@ -1104,9 +1001,8 @@ pub struct TSPropertySignature<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSSignature<'a> { TSIndexSignature(Box<'a, TSIndexSignature<'a>>) = 0, TSPropertySignature(Box<'a, TSPropertySignature<'a>>) = 1, @@ -1128,11 +1024,9 @@ pub enum TSSignature<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSIndexSignature<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub parameters: Vec<'a, TSIndexSignatureName<'a>>, pub type_annotation: Box<'a, TSTypeAnnotation<'a>>, @@ -1141,11 +1035,9 @@ pub struct TSIndexSignature<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSCallSignatureDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_parameters: Option>>, pub this_param: Option>, @@ -1155,9 +1047,8 @@ pub struct TSCallSignatureDeclaration<'a> { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum TSMethodSignatureKind { Method = 0, Get = 1, @@ -1178,11 +1069,9 @@ pub enum TSMethodSignatureKind { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSMethodSignature<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub key: PropertyKey<'a>, pub computed: bool, @@ -1192,7 +1081,7 @@ pub struct TSMethodSignature<'a> { pub this_param: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub return_type: Option>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } @@ -1201,27 +1090,24 @@ pub struct TSMethodSignature<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSConstructSignatureDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_parameters: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub return_type: Option>>, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[serde(tag = "type", rename = "Identifier", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Identifier")] pub struct TSIndexSignatureName<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: Atom<'a>, pub type_annotation: Box<'a, TSTypeAnnotation<'a>>, @@ -1229,11 +1115,9 @@ pub struct TSIndexSignatureName<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSInterfaceHeritage<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, pub type_parameters: Option>>, @@ -1261,11 +1145,9 @@ pub struct TSInterfaceHeritage<'a> { /// * [TypeScript Handbook - Assertion Functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypePredicate<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The identifier the predicate operates on pub parameter_name: TSTypePredicateName<'a>, @@ -1281,9 +1163,8 @@ pub struct TSTypePredicate<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSTypePredicateName<'a> { Identifier(Box<'a, IdentifierName<'a>>) = 0, This(TSThisType) = 1, @@ -1321,11 +1202,9 @@ pub enum TSTypePredicateName<'a> { strict_if(self.body.as_ref().is_some_and(TSModuleDeclarationBody::is_strict)), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSModuleDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The name of the module/namespace being declared. /// @@ -1348,16 +1227,15 @@ pub struct TSModuleDeclaration<'a> { /// ``` pub kind: TSModuleDeclarationKind, pub declare: bool, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum TSModuleDeclarationKind { /// `declare global {}` Global = 0, @@ -1389,9 +1267,8 @@ pub enum TSModuleDeclarationKind { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSModuleDeclarationName<'a> { Identifier(BindingIdentifier<'a>) = 0, StringLiteral(StringLiteral<'a>) = 1, @@ -1399,9 +1276,8 @@ pub enum TSModuleDeclarationName<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSModuleDeclarationBody<'a> { TSModuleDeclaration(Box<'a, TSModuleDeclaration<'a>>) = 0, TSModuleBlock(Box<'a, TSModuleBlock<'a>>) = 1, @@ -1410,24 +1286,21 @@ pub enum TSModuleDeclarationBody<'a> { // See serializer in serialize.rs #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(custom_serialize)] pub struct TSModuleBlock<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, - #[serde(skip)] + #[estree(skip)] pub directives: Vec<'a, Directive<'a>>, pub body: Vec<'a, Statement<'a>>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeLiteral<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub members: Vec<'a, TSSignature<'a>>, } @@ -1447,11 +1320,9 @@ pub struct TSTypeLiteral<'a> { /// * [TypeScript Handbook - Inferring With Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSInferType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The type bound when the pub type_parameter: Box<'a, TSTypeParameter<'a>>, @@ -1468,11 +1339,9 @@ pub struct TSInferType<'a> { /// * [TypeScript Handbook - Typeof Type Operator](https://www.typescriptlang.org/docs/handbook/2/typeof-types.html) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeQuery<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expr_name: TSTypeQueryExprName<'a>, pub type_parameters: Option>>, @@ -1486,9 +1355,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSTypeQueryExprName<'a> { TSImportType(Box<'a, TSImportType<'a>>) = 2, // `TSTypeName` variants added here by `inherit_variants!` macro @@ -1498,11 +1366,9 @@ pub enum TSTypeQueryExprName<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSImportType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// `true` for `typeof import("foo")` pub is_type_of: bool, @@ -1514,11 +1380,9 @@ pub struct TSImportType<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSImportAttributes<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub attributes_keyword: IdentifierName<'a>, // `with` or `assert` pub elements: Vec<'a, TSImportAttribute<'a>>, @@ -1526,11 +1390,9 @@ pub struct TSImportAttributes<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSImportAttribute<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: TSImportAttributeName<'a>, pub value: Expression<'a>, @@ -1538,9 +1400,8 @@ pub struct TSImportAttribute<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSImportAttributeName<'a> { Identifier(IdentifierName<'a>) = 0, StringLiteral(StringLiteral<'a>) = 1, @@ -1556,11 +1417,9 @@ pub enum TSImportAttributeName<'a> { /// ``` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSFunctionType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Generic type parameters /// @@ -1588,11 +1447,9 @@ pub struct TSFunctionType<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSConstructorType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub r#abstract: bool, pub type_parameters: Option>>, @@ -1624,11 +1481,9 @@ pub struct TSConstructorType<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSMappedType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Key type parameter, e.g. `P` in `[P in keyof T]`. pub type_parameter: Box<'a, TSTypeParameter<'a>>, @@ -1658,24 +1513,23 @@ pub struct TSMappedType<'a> { /// type Qux = { [P in keyof T]: T[P] } // None /// ``` pub readonly: TSMappedTypeModifierOperator, - #[serde(skip)] + #[estree(skip)] #[clone_in(default)] pub scope_id: Cell>, } #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum TSMappedTypeModifierOperator { /// e.g. `?` in `{ [P in K]?: T }` True = 0, /// e.g. `+?` in `{ [P in K]+?: T }` - #[serde(rename = "+")] + #[estree(rename = "+")] Plus = 1, /// e.g. `-?` in `{ [P in K]-?: T }` - #[serde(rename = "-")] + #[estree(rename = "-")] Minus = 2, /// No modifier present None = 3, @@ -1694,11 +1548,9 @@ pub enum TSMappedTypeModifierOperator { /// * [TypeScript Handbook - Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#handbook-content) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTemplateLiteralType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The string parts of the template literal. pub quasis: Vec<'a, TemplateElement<'a>>, @@ -1708,11 +1560,9 @@ pub struct TSTemplateLiteralType<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSAsExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, pub type_annotation: TSType<'a>, @@ -1732,11 +1582,9 @@ pub struct TSAsExpression<'a> { /// * [TypeScript Handbook - The `satisfies` Operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator) #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSSatisfiesExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// The value expression being constrained. pub expression: Expression<'a>, @@ -1746,11 +1594,9 @@ pub struct TSSatisfiesExpression<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSTypeAssertion<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, pub type_annotation: TSType<'a>, @@ -1758,11 +1604,9 @@ pub struct TSTypeAssertion<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSImportEqualsDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub id: BindingIdentifier<'a>, pub module_reference: TSModuleReference<'a>, @@ -1777,9 +1621,8 @@ inherit_variants! { /// [`ast` module docs]: `super` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(untagged, rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum TSModuleReference<'a> { ExternalModuleReference(Box<'a, TSExternalModuleReference<'a>>) = 2, // `TSTypeName` variants added here by `inherit_variants!` macro @@ -1789,22 +1632,18 @@ pub enum TSModuleReference<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSExternalModuleReference<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: StringLiteral<'a>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNonNullExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, } @@ -1835,11 +1674,9 @@ pub struct TSNonNullExpression<'a> { /// [`CallExpression`]: crate::ast::js::CallExpression #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct Decorator<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, } @@ -1849,11 +1686,9 @@ pub struct Decorator<'a> { /// `export = foo` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSExportAssignment<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, } @@ -1863,22 +1698,18 @@ pub struct TSExportAssignment<'a> { /// `export as namespace foo` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSNamespaceExportDeclaration<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub id: IdentifierName<'a>, } #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct TSInstantiationExpression<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub expression: Expression<'a>, pub type_parameters: Box<'a, TSTypeParameterInstantiation<'a>>, @@ -1887,9 +1718,8 @@ pub struct TSInstantiationExpression<'a> { /// See [TypeScript - Type-Only Imports and Exports](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum ImportOrExportKind { /// `import { foo } from './foo'`; Value = 0, @@ -1902,11 +1732,9 @@ pub enum ImportOrExportKind { /// `type foo = ty?` or `type foo = ?ty` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSDocNullableType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_annotation: TSType<'a>, /// Was `?` after the type annotation? @@ -1916,11 +1744,9 @@ pub struct JSDocNullableType<'a> { /// `type foo = ty!` or `type foo = !ty` #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSDocNonNullableType<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub type_annotation: TSType<'a>, pub postfix: bool, @@ -1928,10 +1754,8 @@ pub struct JSDocNonNullableType<'a> { #[ast(visit)] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(tag = "type", rename_all = "camelCase")] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] pub struct JSDocUnknownType { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index 7ec9a77ec9bbd..7f98292edf9e6 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -11,23 +11,6 @@ use oxc_syntax::{ use crate::ast::*; -#[cfg(feature = "serialize")] -#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] -const TS_APPEND_CONTENT: &'static str = r#" -export interface BindingIdentifier extends Span { type: "Identifier", name: Atom } -export interface IdentifierReference extends Span { type: "Identifier", name: Atom } -export interface IdentifierName extends Span { type: "Identifier", name: Atom } -export interface LabelIdentifier extends Span { type: "Identifier", name: Atom } -export interface AssignmentTargetRest extends Span { type: "RestElement", argument: AssignmentTarget } -export interface BindingRestElement extends Span { type: "RestElement", argument: BindingPattern } -export interface FormalParameterRest extends Span { - type: "RestElement", - argument: BindingPatternKind, - typeAnnotation?: TSTypeAnnotation, - optional: boolean, -} -"#; - impl<'a> Program<'a> { pub fn is_empty(&self) -> bool { self.body.is_empty() && self.directives.is_empty() diff --git a/crates/oxc_ast/src/ast_impl/literal.rs b/crates/oxc_ast/src/ast_impl/literal.rs index 982fecdaed1d6..5f70ab317ab63 100644 --- a/crates/oxc_ast/src/ast_impl/literal.rs +++ b/crates/oxc_ast/src/ast_impl/literal.rs @@ -1,8 +1,5 @@ //! Literals -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use std::{ borrow::Cow, fmt, diff --git a/crates/oxc_ast/src/generated/derive_estree.rs b/crates/oxc_ast/src/generated/derive_estree.rs new file mode 100644 index 0000000000000..a844d63bb53a3 --- /dev/null +++ b/crates/oxc_ast/src/generated/derive_estree.rs @@ -0,0 +1,4072 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/estree.rs` + +#![allow(unused_imports, unused_mut, clippy::match_same_arms)] + +use serde::{ser::SerializeMap, Serialize, Serializer}; + +#[allow(clippy::wildcard_imports)] +use crate::ast::js::*; + +#[allow(clippy::wildcard_imports)] +use crate::ast::jsx::*; + +#[allow(clippy::wildcard_imports)] +use crate::ast::literal::*; + +#[allow(clippy::wildcard_imports)] +use crate::ast::ts::*; + +impl Serialize for BooleanLiteral { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BooleanLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type BooleanLiteral = ({\n\ttype: 'BooleanLiteral';\n\tvalue: boolean;\n}) & Span;"; + +impl Serialize for NullLiteral { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "NullLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type NullLiteral = ({\n\ttype: 'NullLiteral';\n}) & Span;"; + +impl<'a> Serialize for NumericLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "NumericLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("raw", &self.raw)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type NumericLiteral = ({\n\ttype: 'NumericLiteral';\n\tvalue: number;\n\traw: string;\n}) & Span;"; + +impl<'a> Serialize for BigIntLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BigIntLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("raw", &self.raw)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type BigIntLiteral = ({\n\ttype: 'BigIntLiteral';\n\traw: string;\n}) & Span;"; + +impl<'a> Serialize for RegExpLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "RegExpLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("regex", &self.regex)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type RegExpLiteral = ({\n\ttype: 'RegExpLiteral';\n\tvalue: EmptyObject;\n\tregex: RegExp;\n}) & Span;"; + +impl<'a> Serialize for RegExp<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("pattern", &self.pattern)?; + map.serialize_entry("flags", &self.flags)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type RegExp = ({\n\tpattern: RegExpPattern;\n\tflags: RegExpFlags;\n});"; + +impl<'a> Serialize for RegExpPattern<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + RegExpPattern::Raw(x) => Serialize::serialize(x, serializer), + RegExpPattern::Invalid(x) => Serialize::serialize(x, serializer), + RegExpPattern::Pattern(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type RegExpPattern = string | string | Pattern;"; + +impl Serialize for EmptyObject { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type EmptyObject = ({\n});"; + +impl<'a> Serialize for StringLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "StringLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type StringLiteral = ({\n\ttype: 'StringLiteral';\n\tvalue: string;\n}) & Span;"; + +impl<'a> Serialize for Program<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Program")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("sourceType", &self.source_type)?; + map.serialize_entry("hashbang", &self.hashbang)?; + map.serialize_entry("directives", &self.directives)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Program = ({\n\ttype: 'Program';\n\tsourceType: SourceType;\n\thashbang: (Hashbang) | null;\n\tdirectives: Array;\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for Expression<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + Expression::BooleanLiteral(x) => Serialize::serialize(x, serializer), + Expression::NullLiteral(x) => Serialize::serialize(x, serializer), + Expression::NumericLiteral(x) => Serialize::serialize(x, serializer), + Expression::BigIntLiteral(x) => Serialize::serialize(x, serializer), + Expression::RegExpLiteral(x) => Serialize::serialize(x, serializer), + Expression::StringLiteral(x) => Serialize::serialize(x, serializer), + Expression::TemplateLiteral(x) => Serialize::serialize(x, serializer), + Expression::Identifier(x) => Serialize::serialize(x, serializer), + Expression::MetaProperty(x) => Serialize::serialize(x, serializer), + Expression::Super(x) => Serialize::serialize(x, serializer), + Expression::ArrayExpression(x) => Serialize::serialize(x, serializer), + Expression::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + Expression::AssignmentExpression(x) => Serialize::serialize(x, serializer), + Expression::AwaitExpression(x) => Serialize::serialize(x, serializer), + Expression::BinaryExpression(x) => Serialize::serialize(x, serializer), + Expression::CallExpression(x) => Serialize::serialize(x, serializer), + Expression::ChainExpression(x) => Serialize::serialize(x, serializer), + Expression::ClassExpression(x) => Serialize::serialize(x, serializer), + Expression::ConditionalExpression(x) => Serialize::serialize(x, serializer), + Expression::FunctionExpression(x) => Serialize::serialize(x, serializer), + Expression::ImportExpression(x) => Serialize::serialize(x, serializer), + Expression::LogicalExpression(x) => Serialize::serialize(x, serializer), + Expression::NewExpression(x) => Serialize::serialize(x, serializer), + Expression::ObjectExpression(x) => Serialize::serialize(x, serializer), + Expression::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + Expression::SequenceExpression(x) => Serialize::serialize(x, serializer), + Expression::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + Expression::ThisExpression(x) => Serialize::serialize(x, serializer), + Expression::UnaryExpression(x) => Serialize::serialize(x, serializer), + Expression::UpdateExpression(x) => Serialize::serialize(x, serializer), + Expression::YieldExpression(x) => Serialize::serialize(x, serializer), + Expression::PrivateInExpression(x) => Serialize::serialize(x, serializer), + Expression::JSXElement(x) => Serialize::serialize(x, serializer), + Expression::JSXFragment(x) => Serialize::serialize(x, serializer), + Expression::TSAsExpression(x) => Serialize::serialize(x, serializer), + Expression::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + Expression::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + Expression::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + Expression::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + Expression::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + Expression::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + Expression::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Expression = BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for IdentifierName<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Identifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type IdentifierName = ({\n\ttype: 'Identifier';\n\tname: string;\n}) & Span;"; + +impl<'a> Serialize for IdentifierReference<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Identifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type IdentifierReference = ({\n\ttype: 'Identifier';\n\tname: string;\n}) & Span;"; + +impl<'a> Serialize for BindingIdentifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Identifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type BindingIdentifier = ({\n\ttype: 'Identifier';\n\tname: string;\n}) & Span;"; + +impl<'a> Serialize for LabelIdentifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Identifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type LabelIdentifier = ({\n\ttype: 'Identifier';\n\tname: string;\n}) & Span;"; + +impl Serialize for ThisExpression { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ThisExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ThisExpression = ({\n\ttype: 'ThisExpression';\n}) & Span;"; + +impl<'a> Serialize for ArrayExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ArrayExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("elements", &self.elements)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ArrayExpression = ({\n\ttype: 'ArrayExpression';\n\telements: Array;\n}) & Span;"; + +impl<'a> Serialize for ArrayExpressionElement<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ArrayExpressionElement::SpreadElement(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::Elision(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::BooleanLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::NullLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::NumericLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::BigIntLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::RegExpLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::StringLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TemplateLiteral(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::Identifier(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::MetaProperty(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::Super(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ArrayExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ArrowFunctionExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::AssignmentExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::AwaitExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::BinaryExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::CallExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ChainExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ClassExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ConditionalExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::FunctionExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ImportExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::LogicalExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::NewExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ObjectExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::ParenthesizedExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::SequenceExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TaggedTemplateExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::ThisExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::UnaryExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::UpdateExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::YieldExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::PrivateInExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::JSXElement(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::JSXFragment(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TSAsExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + ArrayExpressionElement::TSInstantiationExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::ComputedMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::StaticMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + ArrayExpressionElement::PrivateFieldExpression(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ArrayExpressionElement = SpreadElement | Elision | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for ObjectExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ObjectExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("properties", &self.properties)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ObjectExpression = ({\n\ttype: 'ObjectExpression';\n\tproperties: Array;\n}) & Span;"; + +impl<'a> Serialize for ObjectPropertyKind<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ObjectPropertyKind::ObjectProperty(x) => Serialize::serialize(x, serializer), + ObjectPropertyKind::SpreadProperty(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ObjectPropertyKind = ObjectProperty | SpreadElement;"; + +impl<'a> Serialize for ObjectProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ObjectProperty")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("init", &self.init)?; + map.serialize_entry("method", &self.method)?; + map.serialize_entry("shorthand", &self.shorthand)?; + map.serialize_entry("computed", &self.computed)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ObjectProperty = ({\n\ttype: 'ObjectProperty';\n\tkind: PropertyKind;\n\tkey: PropertyKey;\n\tvalue: Expression;\n\tinit: (Expression) | null;\n\tmethod: boolean;\n\tshorthand: boolean;\n\tcomputed: boolean;\n}) & Span;"; + +impl<'a> Serialize for PropertyKey<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + PropertyKey::StaticIdentifier(x) => Serialize::serialize(x, serializer), + PropertyKey::PrivateIdentifier(x) => Serialize::serialize(x, serializer), + PropertyKey::BooleanLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::NullLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::NumericLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::BigIntLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::RegExpLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::StringLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::TemplateLiteral(x) => Serialize::serialize(x, serializer), + PropertyKey::Identifier(x) => Serialize::serialize(x, serializer), + PropertyKey::MetaProperty(x) => Serialize::serialize(x, serializer), + PropertyKey::Super(x) => Serialize::serialize(x, serializer), + PropertyKey::ArrayExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::AssignmentExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::AwaitExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::BinaryExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::CallExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ChainExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ClassExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ConditionalExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::FunctionExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ImportExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::LogicalExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::NewExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ObjectExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::SequenceExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ThisExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::UnaryExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::UpdateExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::YieldExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::PrivateInExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::JSXElement(x) => Serialize::serialize(x, serializer), + PropertyKey::JSXFragment(x) => Serialize::serialize(x, serializer), + PropertyKey::TSAsExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + PropertyKey::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + PropertyKey::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type PropertyKey = IdentifierName | PrivateIdentifier | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl Serialize for PropertyKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + PropertyKind::Init => serializer.serialize_unit_variant("PropertyKind", 0u32, "init"), + PropertyKind::Get => serializer.serialize_unit_variant("PropertyKind", 1u32, "get"), + PropertyKind::Set => serializer.serialize_unit_variant("PropertyKind", 2u32, "set"), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type PropertyKind = 'init' | 'get' | 'set';"; + +impl<'a> Serialize for TemplateLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TemplateLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("quasis", &self.quasis)?; + map.serialize_entry("expressions", &self.expressions)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TemplateLiteral = ({\n\ttype: 'TemplateLiteral';\n\tquasis: Array;\n\texpressions: Array;\n}) & Span;"; + +impl<'a> Serialize for TaggedTemplateExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TaggedTemplateExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("tag", &self.tag)?; + map.serialize_entry("quasi", &self.quasi)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TaggedTemplateExpression = ({\n\ttype: 'TaggedTemplateExpression';\n\ttag: Expression;\n\tquasi: TemplateLiteral;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TemplateElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TemplateElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("tail", &self.tail)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TemplateElement = ({\n\ttype: 'TemplateElement';\n\ttail: boolean;\n\tvalue: TemplateElementValue;\n}) & Span;"; + +impl<'a> Serialize for TemplateElementValue<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("raw", &self.raw)?; + map.serialize_entry("cooked", &self.cooked)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TemplateElementValue = ({\n\traw: string;\n\tcooked: (string) | null;\n});"; + +impl<'a> Serialize for MemberExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + MemberExpression::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + MemberExpression::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + MemberExpression::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type MemberExpression = ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for ComputedMemberExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ComputedMemberExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("object", &self.object)?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ComputedMemberExpression = ({\n\ttype: 'ComputedMemberExpression';\n\tobject: Expression;\n\texpression: Expression;\n\toptional: boolean;\n}) & Span;"; + +impl<'a> Serialize for StaticMemberExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "StaticMemberExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("object", &self.object)?; + map.serialize_entry("property", &self.property)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type StaticMemberExpression = ({\n\ttype: 'StaticMemberExpression';\n\tobject: Expression;\n\tproperty: IdentifierName;\n\toptional: boolean;\n}) & Span;"; + +impl<'a> Serialize for PrivateFieldExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "PrivateFieldExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("object", &self.object)?; + map.serialize_entry("field", &self.field)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type PrivateFieldExpression = ({\n\ttype: 'PrivateFieldExpression';\n\tobject: Expression;\n\tfield: PrivateIdentifier;\n\toptional: boolean;\n}) & Span;"; + +impl<'a> Serialize for CallExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CallExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("callee", &self.callee)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("arguments", &self.arguments)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CallExpression = ({\n\ttype: 'CallExpression';\n\tcallee: Expression;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n\targuments: Array;\n\toptional: boolean;\n}) & Span;"; + +impl<'a> Serialize for NewExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "NewExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("callee", &self.callee)?; + map.serialize_entry("arguments", &self.arguments)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type NewExpression = ({\n\ttype: 'NewExpression';\n\tcallee: Expression;\n\targuments: Array;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for MetaProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "MetaProperty")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("meta", &self.meta)?; + map.serialize_entry("property", &self.property)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type MetaProperty = ({\n\ttype: 'MetaProperty';\n\tmeta: IdentifierName;\n\tproperty: IdentifierName;\n}) & Span;"; + +impl<'a> Serialize for SpreadElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "SpreadElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type SpreadElement = ({\n\ttype: 'SpreadElement';\n\targument: Expression;\n}) & Span;"; + +impl<'a> Serialize for Argument<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + Argument::SpreadElement(x) => Serialize::serialize(x, serializer), + Argument::BooleanLiteral(x) => Serialize::serialize(x, serializer), + Argument::NullLiteral(x) => Serialize::serialize(x, serializer), + Argument::NumericLiteral(x) => Serialize::serialize(x, serializer), + Argument::BigIntLiteral(x) => Serialize::serialize(x, serializer), + Argument::RegExpLiteral(x) => Serialize::serialize(x, serializer), + Argument::StringLiteral(x) => Serialize::serialize(x, serializer), + Argument::TemplateLiteral(x) => Serialize::serialize(x, serializer), + Argument::Identifier(x) => Serialize::serialize(x, serializer), + Argument::MetaProperty(x) => Serialize::serialize(x, serializer), + Argument::Super(x) => Serialize::serialize(x, serializer), + Argument::ArrayExpression(x) => Serialize::serialize(x, serializer), + Argument::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + Argument::AssignmentExpression(x) => Serialize::serialize(x, serializer), + Argument::AwaitExpression(x) => Serialize::serialize(x, serializer), + Argument::BinaryExpression(x) => Serialize::serialize(x, serializer), + Argument::CallExpression(x) => Serialize::serialize(x, serializer), + Argument::ChainExpression(x) => Serialize::serialize(x, serializer), + Argument::ClassExpression(x) => Serialize::serialize(x, serializer), + Argument::ConditionalExpression(x) => Serialize::serialize(x, serializer), + Argument::FunctionExpression(x) => Serialize::serialize(x, serializer), + Argument::ImportExpression(x) => Serialize::serialize(x, serializer), + Argument::LogicalExpression(x) => Serialize::serialize(x, serializer), + Argument::NewExpression(x) => Serialize::serialize(x, serializer), + Argument::ObjectExpression(x) => Serialize::serialize(x, serializer), + Argument::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + Argument::SequenceExpression(x) => Serialize::serialize(x, serializer), + Argument::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + Argument::ThisExpression(x) => Serialize::serialize(x, serializer), + Argument::UnaryExpression(x) => Serialize::serialize(x, serializer), + Argument::UpdateExpression(x) => Serialize::serialize(x, serializer), + Argument::YieldExpression(x) => Serialize::serialize(x, serializer), + Argument::PrivateInExpression(x) => Serialize::serialize(x, serializer), + Argument::JSXElement(x) => Serialize::serialize(x, serializer), + Argument::JSXFragment(x) => Serialize::serialize(x, serializer), + Argument::TSAsExpression(x) => Serialize::serialize(x, serializer), + Argument::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + Argument::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + Argument::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + Argument::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + Argument::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + Argument::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + Argument::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Argument = SpreadElement | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for UpdateExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "UpdateExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("prefix", &self.prefix)?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type UpdateExpression = ({\n\ttype: 'UpdateExpression';\n\toperator: UpdateOperator;\n\tprefix: boolean;\n\targument: SimpleAssignmentTarget;\n}) & Span;"; + +impl<'a> Serialize for UnaryExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "UnaryExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type UnaryExpression = ({\n\ttype: 'UnaryExpression';\n\toperator: UnaryOperator;\n\targument: Expression;\n}) & Span;"; + +impl<'a> Serialize for BinaryExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BinaryExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BinaryExpression = ({\n\ttype: 'BinaryExpression';\n\tleft: Expression;\n\toperator: BinaryOperator;\n\tright: Expression;\n}) & Span;"; + +impl<'a> Serialize for PrivateInExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "PrivateInExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type PrivateInExpression = ({\n\ttype: 'PrivateInExpression';\n\tleft: PrivateIdentifier;\n\toperator: BinaryOperator;\n\tright: Expression;\n}) & Span;"; + +impl<'a> Serialize for LogicalExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "LogicalExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LogicalExpression = ({\n\ttype: 'LogicalExpression';\n\tleft: Expression;\n\toperator: LogicalOperator;\n\tright: Expression;\n}) & Span;"; + +impl<'a> Serialize for ConditionalExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ConditionalExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("test", &self.test)?; + map.serialize_entry("consequent", &self.consequent)?; + map.serialize_entry("alternate", &self.alternate)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ConditionalExpression = ({\n\ttype: 'ConditionalExpression';\n\ttest: Expression;\n\tconsequent: Expression;\n\talternate: Expression;\n}) & Span;"; + +impl<'a> Serialize for AssignmentExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AssignmentExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentExpression = ({\n\ttype: 'AssignmentExpression';\n\toperator: AssignmentOperator;\n\tleft: AssignmentTarget;\n\tright: Expression;\n}) & Span;"; + +impl<'a> Serialize for AssignmentTarget<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + AssignmentTarget::AssignmentTargetIdentifier(x) => Serialize::serialize(x, serializer), + AssignmentTarget::TSAsExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + AssignmentTarget::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + AssignmentTarget::ArrayAssignmentTarget(x) => Serialize::serialize(x, serializer), + AssignmentTarget::ObjectAssignmentTarget(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTarget = IdentifierReference | TSAsExpression | TSSatisfiesExpression | TSNonNullExpression | TSTypeAssertion | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression | ArrayAssignmentTarget | ObjectAssignmentTarget;"; + +impl<'a> Serialize for SimpleAssignmentTarget<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + SimpleAssignmentTarget::AssignmentTargetIdentifier(x) => { + Serialize::serialize(x, serializer) + } + SimpleAssignmentTarget::TSAsExpression(x) => Serialize::serialize(x, serializer), + SimpleAssignmentTarget::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + SimpleAssignmentTarget::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + SimpleAssignmentTarget::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + SimpleAssignmentTarget::TSInstantiationExpression(x) => { + Serialize::serialize(x, serializer) + } + SimpleAssignmentTarget::ComputedMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + SimpleAssignmentTarget::StaticMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + SimpleAssignmentTarget::PrivateFieldExpression(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type SimpleAssignmentTarget = IdentifierReference | TSAsExpression | TSSatisfiesExpression | TSNonNullExpression | TSTypeAssertion | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for AssignmentTargetPattern<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + AssignmentTargetPattern::ArrayAssignmentTarget(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetPattern::ObjectAssignmentTarget(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type AssignmentTargetPattern = ArrayAssignmentTarget | ObjectAssignmentTarget;"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ArrayAssignmentTarget = ({\n\ttype: 'ArrayAssignmentTarget';\n\telements: Array;\n}) & Span;"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ObjectAssignmentTarget = ({\n\ttype: 'ObjectAssignmentTarget';\n\tproperties: Array;\n}) & Span;"; + +impl<'a> Serialize for AssignmentTargetRest<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "RestElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.target)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetRest = ({\n\ttype: 'RestElement';\n\targument: AssignmentTarget;\n}) & Span;"; + +impl<'a> Serialize for AssignmentTargetMaybeDefault<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::AssignmentTargetIdentifier(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::TSAsExpression(x) => Serialize::serialize(x, serializer), + AssignmentTargetMaybeDefault::TSSatisfiesExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::TSNonNullExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + AssignmentTargetMaybeDefault::TSInstantiationExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::ComputedMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::StaticMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::PrivateFieldExpression(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::ArrayAssignmentTarget(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetMaybeDefault::ObjectAssignmentTarget(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetMaybeDefault = AssignmentTargetWithDefault | IdentifierReference | TSAsExpression | TSSatisfiesExpression | TSNonNullExpression | TSTypeAssertion | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression | ArrayAssignmentTarget | ObjectAssignmentTarget;"; + +impl<'a> Serialize for AssignmentTargetWithDefault<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AssignmentTargetWithDefault")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("binding", &self.binding)?; + map.serialize_entry("init", &self.init)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetWithDefault = ({\n\ttype: 'AssignmentTargetWithDefault';\n\tbinding: AssignmentTarget;\n\tinit: Expression;\n}) & Span;"; + +impl<'a> Serialize for AssignmentTargetProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(x) => { + Serialize::serialize(x, serializer) + } + AssignmentTargetProperty::AssignmentTargetPropertyProperty(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetProperty = AssignmentTargetPropertyIdentifier | AssignmentTargetPropertyProperty;"; + +impl<'a> Serialize for AssignmentTargetPropertyIdentifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AssignmentTargetPropertyIdentifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("binding", &self.binding)?; + map.serialize_entry("init", &self.init)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetPropertyIdentifier = ({\n\ttype: 'AssignmentTargetPropertyIdentifier';\n\tbinding: IdentifierReference;\n\tinit: (Expression) | null;\n}) & Span;"; + +impl<'a> Serialize for AssignmentTargetPropertyProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AssignmentTargetPropertyProperty")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("binding", &self.binding)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentTargetPropertyProperty = ({\n\ttype: 'AssignmentTargetPropertyProperty';\n\tname: PropertyKey;\n\tbinding: AssignmentTargetMaybeDefault;\n}) & Span;"; + +impl<'a> Serialize for SequenceExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "SequenceExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expressions", &self.expressions)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type SequenceExpression = ({\n\ttype: 'SequenceExpression';\n\texpressions: Array;\n}) & Span;"; + +impl Serialize for Super { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Super")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Super = ({\n\ttype: 'Super';\n}) & Span;"; + +impl<'a> Serialize for AwaitExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AwaitExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AwaitExpression = ({\n\ttype: 'AwaitExpression';\n\targument: Expression;\n}) & Span;"; + +impl<'a> Serialize for ChainExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ChainExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ChainExpression = ({\n\ttype: 'ChainExpression';\n\texpression: ChainElement;\n}) & Span;"; + +impl<'a> Serialize for ChainElement<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ChainElement::CallExpression(x) => Serialize::serialize(x, serializer), + ChainElement::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + ChainElement::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + ChainElement::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ChainElement = CallExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for ParenthesizedExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ParenthesizedExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ParenthesizedExpression = ({\n\ttype: 'ParenthesizedExpression';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for Statement<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + Statement::BlockStatement(x) => Serialize::serialize(x, serializer), + Statement::BreakStatement(x) => Serialize::serialize(x, serializer), + Statement::ContinueStatement(x) => Serialize::serialize(x, serializer), + Statement::DebuggerStatement(x) => Serialize::serialize(x, serializer), + Statement::DoWhileStatement(x) => Serialize::serialize(x, serializer), + Statement::EmptyStatement(x) => Serialize::serialize(x, serializer), + Statement::ExpressionStatement(x) => Serialize::serialize(x, serializer), + Statement::ForInStatement(x) => Serialize::serialize(x, serializer), + Statement::ForOfStatement(x) => Serialize::serialize(x, serializer), + Statement::ForStatement(x) => Serialize::serialize(x, serializer), + Statement::IfStatement(x) => Serialize::serialize(x, serializer), + Statement::LabeledStatement(x) => Serialize::serialize(x, serializer), + Statement::ReturnStatement(x) => Serialize::serialize(x, serializer), + Statement::SwitchStatement(x) => Serialize::serialize(x, serializer), + Statement::ThrowStatement(x) => Serialize::serialize(x, serializer), + Statement::TryStatement(x) => Serialize::serialize(x, serializer), + Statement::WhileStatement(x) => Serialize::serialize(x, serializer), + Statement::WithStatement(x) => Serialize::serialize(x, serializer), + Statement::VariableDeclaration(x) => Serialize::serialize(x, serializer), + Statement::FunctionDeclaration(x) => Serialize::serialize(x, serializer), + Statement::ClassDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSTypeAliasDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSInterfaceDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSEnumDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSModuleDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSImportEqualsDeclaration(x) => Serialize::serialize(x, serializer), + Statement::ImportDeclaration(x) => Serialize::serialize(x, serializer), + Statement::ExportAllDeclaration(x) => Serialize::serialize(x, serializer), + Statement::ExportDefaultDeclaration(x) => Serialize::serialize(x, serializer), + Statement::ExportNamedDeclaration(x) => Serialize::serialize(x, serializer), + Statement::TSExportAssignment(x) => Serialize::serialize(x, serializer), + Statement::TSNamespaceExportDeclaration(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Statement = BlockStatement | BreakStatement | ContinueStatement | DebuggerStatement | DoWhileStatement | EmptyStatement | ExpressionStatement | ForInStatement | ForOfStatement | ForStatement | IfStatement | LabeledStatement | ReturnStatement | SwitchStatement | ThrowStatement | TryStatement | WhileStatement | WithStatement | VariableDeclaration | Function | Class | TSTypeAliasDeclaration | TSInterfaceDeclaration | TSEnumDeclaration | TSModuleDeclaration | TSImportEqualsDeclaration | ImportDeclaration | ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | TSExportAssignment | TSNamespaceExportDeclaration;"; + +impl<'a> Serialize for Directive<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Directive")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("directive", &self.directive)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Directive = ({\n\ttype: 'Directive';\n\texpression: StringLiteral;\n\tdirective: string;\n}) & Span;"; + +impl<'a> Serialize for Hashbang<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Hashbang")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Hashbang = ({\n\ttype: 'Hashbang';\n\tvalue: string;\n}) & Span;"; + +impl<'a> Serialize for BlockStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BlockStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BlockStatement = ({\n\ttype: 'BlockStatement';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for Declaration<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + Declaration::VariableDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::FunctionDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::ClassDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::TSTypeAliasDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::TSInterfaceDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::TSEnumDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::TSModuleDeclaration(x) => Serialize::serialize(x, serializer), + Declaration::TSImportEqualsDeclaration(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Declaration = VariableDeclaration | Function | Class | TSTypeAliasDeclaration | TSInterfaceDeclaration | TSEnumDeclaration | TSModuleDeclaration | TSImportEqualsDeclaration;"; + +impl<'a> Serialize for VariableDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "VariableDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("declarations", &self.declarations)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type VariableDeclaration = ({\n\ttype: 'VariableDeclaration';\n\tkind: VariableDeclarationKind;\n\tdeclarations: Array;\n\tdeclare: boolean;\n}) & Span;"; + +impl Serialize for VariableDeclarationKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + VariableDeclarationKind::Var => { + serializer.serialize_unit_variant("VariableDeclarationKind", 0u32, "var") + } + VariableDeclarationKind::Const => { + serializer.serialize_unit_variant("VariableDeclarationKind", 1u32, "const") + } + VariableDeclarationKind::Let => { + serializer.serialize_unit_variant("VariableDeclarationKind", 2u32, "let") + } + VariableDeclarationKind::Using => { + serializer.serialize_unit_variant("VariableDeclarationKind", 3u32, "using") + } + VariableDeclarationKind::AwaitUsing => { + serializer.serialize_unit_variant("VariableDeclarationKind", 4u32, "await using") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type VariableDeclarationKind = 'var' | 'const' | 'let' | 'using' | 'await using';"; + +impl<'a> Serialize for VariableDeclarator<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "VariableDeclarator")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("init", &self.init)?; + map.serialize_entry("definite", &self.definite)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type VariableDeclarator = ({\n\ttype: 'VariableDeclarator';\n\tid: BindingPattern;\n\tinit: (Expression) | null;\n\tdefinite: boolean;\n}) & Span;"; + +impl Serialize for EmptyStatement { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "EmptyStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type EmptyStatement = ({\n\ttype: 'EmptyStatement';\n}) & Span;"; + +impl<'a> Serialize for ExpressionStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ExpressionStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExpressionStatement = ({\n\ttype: 'ExpressionStatement';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for IfStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "IfStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("test", &self.test)?; + map.serialize_entry("consequent", &self.consequent)?; + map.serialize_entry("alternate", &self.alternate)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type IfStatement = ({\n\ttype: 'IfStatement';\n\ttest: Expression;\n\tconsequent: Statement;\n\talternate: (Statement) | null;\n}) & Span;"; + +impl<'a> Serialize for DoWhileStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "DoWhileStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.serialize_entry("test", &self.test)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type DoWhileStatement = ({\n\ttype: 'DoWhileStatement';\n\tbody: Statement;\n\ttest: Expression;\n}) & Span;"; + +impl<'a> Serialize for WhileStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "WhileStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("test", &self.test)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type WhileStatement = ({\n\ttype: 'WhileStatement';\n\ttest: Expression;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for ForStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ForStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("init", &self.init)?; + map.serialize_entry("test", &self.test)?; + map.serialize_entry("update", &self.update)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ForStatement = ({\n\ttype: 'ForStatement';\n\tinit: (ForStatementInit) | null;\n\ttest: (Expression) | null;\n\tupdate: (Expression) | null;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for ForStatementInit<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ForStatementInit::VariableDeclaration(x) => Serialize::serialize(x, serializer), + ForStatementInit::BooleanLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::NullLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::NumericLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::BigIntLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::RegExpLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::StringLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::TemplateLiteral(x) => Serialize::serialize(x, serializer), + ForStatementInit::Identifier(x) => Serialize::serialize(x, serializer), + ForStatementInit::MetaProperty(x) => Serialize::serialize(x, serializer), + ForStatementInit::Super(x) => Serialize::serialize(x, serializer), + ForStatementInit::ArrayExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::AssignmentExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::AwaitExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::BinaryExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::CallExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ChainExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ClassExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ConditionalExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::FunctionExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ImportExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::LogicalExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::NewExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ObjectExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::SequenceExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ThisExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::UnaryExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::UpdateExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::YieldExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::PrivateInExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::JSXElement(x) => Serialize::serialize(x, serializer), + ForStatementInit::JSXFragment(x) => Serialize::serialize(x, serializer), + ForStatementInit::TSAsExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + ForStatementInit::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + ForStatementInit::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ForStatementInit = VariableDeclaration | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for ForInStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ForInStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("right", &self.right)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ForInStatement = ({\n\ttype: 'ForInStatement';\n\tleft: ForStatementLeft;\n\tright: Expression;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for ForStatementLeft<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ForStatementLeft::VariableDeclaration(x) => Serialize::serialize(x, serializer), + ForStatementLeft::AssignmentTargetIdentifier(x) => Serialize::serialize(x, serializer), + ForStatementLeft::TSAsExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + ForStatementLeft::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + ForStatementLeft::ArrayAssignmentTarget(x) => Serialize::serialize(x, serializer), + ForStatementLeft::ObjectAssignmentTarget(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ForStatementLeft = VariableDeclaration | IdentifierReference | TSAsExpression | TSSatisfiesExpression | TSNonNullExpression | TSTypeAssertion | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression | ArrayAssignmentTarget | ObjectAssignmentTarget;"; + +impl<'a> Serialize for ForOfStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ForOfStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("await", &self.r#await)?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("right", &self.right)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ForOfStatement = ({\n\ttype: 'ForOfStatement';\n\tawait: boolean;\n\tleft: ForStatementLeft;\n\tright: Expression;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for ContinueStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ContinueStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("label", &self.label)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ContinueStatement = ({\n\ttype: 'ContinueStatement';\n\tlabel: (LabelIdentifier) | null;\n}) & Span;"; + +impl<'a> Serialize for BreakStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BreakStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("label", &self.label)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BreakStatement = ({\n\ttype: 'BreakStatement';\n\tlabel: (LabelIdentifier) | null;\n}) & Span;"; + +impl<'a> Serialize for ReturnStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ReturnStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ReturnStatement = ({\n\ttype: 'ReturnStatement';\n\targument: (Expression) | null;\n}) & Span;"; + +impl<'a> Serialize for WithStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "WithStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("object", &self.object)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type WithStatement = ({\n\ttype: 'WithStatement';\n\tobject: Expression;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for SwitchStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "SwitchStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("discriminant", &self.discriminant)?; + map.serialize_entry("cases", &self.cases)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type SwitchStatement = ({\n\ttype: 'SwitchStatement';\n\tdiscriminant: Expression;\n\tcases: Array;\n}) & Span;"; + +impl<'a> Serialize for SwitchCase<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "SwitchCase")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("test", &self.test)?; + map.serialize_entry("consequent", &self.consequent)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type SwitchCase = ({\n\ttype: 'SwitchCase';\n\ttest: (Expression) | null;\n\tconsequent: Array;\n}) & Span;"; + +impl<'a> Serialize for LabeledStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "LabeledStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("label", &self.label)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LabeledStatement = ({\n\ttype: 'LabeledStatement';\n\tlabel: LabelIdentifier;\n\tbody: Statement;\n}) & Span;"; + +impl<'a> Serialize for ThrowStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ThrowStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ThrowStatement = ({\n\ttype: 'ThrowStatement';\n\targument: Expression;\n}) & Span;"; + +impl<'a> Serialize for TryStatement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TryStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("block", &self.block)?; + map.serialize_entry("handler", &self.handler)?; + map.serialize_entry("finalizer", &self.finalizer)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TryStatement = ({\n\ttype: 'TryStatement';\n\tblock: BlockStatement;\n\thandler: (CatchClause) | null;\n\tfinalizer: (BlockStatement) | null;\n}) & Span;"; + +impl<'a> Serialize for CatchClause<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CatchClause")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("param", &self.param)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CatchClause = ({\n\ttype: 'CatchClause';\n\tparam: (CatchParameter) | null;\n\tbody: BlockStatement;\n}) & Span;"; + +impl<'a> Serialize for CatchParameter<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CatchParameter")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("pattern", &self.pattern)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CatchParameter = ({\n\ttype: 'CatchParameter';\n\tpattern: BindingPattern;\n}) & Span;"; + +impl Serialize for DebuggerStatement { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "DebuggerStatement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type DebuggerStatement = ({\n\ttype: 'DebuggerStatement';\n}) & Span;"; + +impl<'a> Serialize for BindingPattern<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + self.kind.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BindingPattern = ({\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n\toptional: boolean;\n}) & (BindingIdentifier | ObjectPattern | ArrayPattern | AssignmentPattern);"; + +impl<'a> Serialize for BindingPatternKind<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + BindingPatternKind::BindingIdentifier(x) => Serialize::serialize(x, serializer), + BindingPatternKind::ObjectPattern(x) => Serialize::serialize(x, serializer), + BindingPatternKind::ArrayPattern(x) => Serialize::serialize(x, serializer), + BindingPatternKind::AssignmentPattern(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BindingPatternKind = BindingIdentifier | ObjectPattern | ArrayPattern | AssignmentPattern;"; + +impl<'a> Serialize for AssignmentPattern<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "AssignmentPattern")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentPattern = ({\n\ttype: 'AssignmentPattern';\n\tleft: BindingPattern;\n\tright: Expression;\n}) & Span;"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ObjectPattern = ({\n\ttype: 'ObjectPattern';\n\tproperties: Array;\n}) & Span;"; + +impl<'a> Serialize for BindingProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BindingProperty")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("shorthand", &self.shorthand)?; + map.serialize_entry("computed", &self.computed)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BindingProperty = ({\n\ttype: 'BindingProperty';\n\tkey: PropertyKey;\n\tvalue: BindingPattern;\n\tshorthand: boolean;\n\tcomputed: boolean;\n}) & Span;"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ArrayPattern = ({\n\ttype: 'ArrayPattern';\n\telements: Array;\n}) & Span;"; + +impl<'a> Serialize for BindingRestElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "RestElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BindingRestElement = ({\n\ttype: 'RestElement';\n\targument: BindingPattern;\n}) & Span;"; + +impl<'a> Serialize for Function<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", &self.r#type)?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("generator", &self.generator)?; + map.serialize_entry("async", &self.r#async)?; + map.serialize_entry("declare", &self.declare)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("thisParam", &self.this_param)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Function = ({\n\ttype: FunctionType;\n\tid: (BindingIdentifier) | null;\n\tgenerator: boolean;\n\tasync: boolean;\n\tdeclare: boolean;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tthisParam: (TSThisParameter) | null;\n\tparams: FormalParameters;\n\treturnType: (TSTypeAnnotation) | null;\n\tbody: (FunctionBody) | null;\n}) & Span;"; + +impl Serialize for FunctionType { + fn serialize(&self, serializer: S) -> Result { + match *self { + FunctionType::FunctionDeclaration => { + serializer.serialize_unit_variant("FunctionType", 0u32, "FunctionDeclaration") + } + FunctionType::FunctionExpression => { + serializer.serialize_unit_variant("FunctionType", 1u32, "FunctionExpression") + } + FunctionType::TSDeclareFunction => { + serializer.serialize_unit_variant("FunctionType", 2u32, "TSDeclareFunction") + } + FunctionType::TSEmptyBodyFunctionExpression => serializer.serialize_unit_variant( + "FunctionType", + 3u32, + "TSEmptyBodyFunctionExpression", + ), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type FunctionType = 'FunctionDeclaration' | 'FunctionExpression' | 'TSDeclareFunction' | 'TSEmptyBodyFunctionExpression';"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type FormalParameters = ({\n\ttype: 'FormalParameters';\n\tkind: FormalParameterKind;\n\titems: Array;\n}) & Span;"; + +impl<'a> Serialize for FormalParameter<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "FormalParameter")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("decorators", &self.decorators)?; + map.serialize_entry("pattern", &self.pattern)?; + map.serialize_entry("accessibility", &self.accessibility)?; + map.serialize_entry("readonly", &self.readonly)?; + map.serialize_entry("override", &self.r#override)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type FormalParameter = ({\n\ttype: 'FormalParameter';\n\tdecorators: Array;\n\tpattern: BindingPattern;\n\taccessibility: (TSAccessibility) | null;\n\treadonly: boolean;\n\toverride: boolean;\n}) & Span;"; + +impl Serialize for FormalParameterKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + FormalParameterKind::FormalParameter => { + serializer.serialize_unit_variant("FormalParameterKind", 0u32, "FormalParameter") + } + FormalParameterKind::UniqueFormalParameters => serializer.serialize_unit_variant( + "FormalParameterKind", + 1u32, + "UniqueFormalParameters", + ), + FormalParameterKind::ArrowFormalParameters => serializer.serialize_unit_variant( + "FormalParameterKind", + 2u32, + "ArrowFormalParameters", + ), + FormalParameterKind::Signature => { + serializer.serialize_unit_variant("FormalParameterKind", 3u32, "Signature") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type FormalParameterKind = 'FormalParameter' | 'UniqueFormalParameters' | 'ArrowFormalParameters' | 'Signature';"; + +impl<'a> Serialize for FunctionBody<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "FunctionBody")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("directives", &self.directives)?; + map.serialize_entry("statements", &self.statements)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type FunctionBody = ({\n\ttype: 'FunctionBody';\n\tdirectives: Array;\n\tstatements: Array;\n}) & Span;"; + +impl<'a> Serialize for ArrowFunctionExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ArrowFunctionExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("async", &self.r#async)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ArrowFunctionExpression = ({\n\ttype: 'ArrowFunctionExpression';\n\texpression: boolean;\n\tasync: boolean;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tparams: FormalParameters;\n\treturnType: (TSTypeAnnotation) | null;\n\tbody: FunctionBody;\n}) & Span;"; + +impl<'a> Serialize for YieldExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "YieldExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("delegate", &self.delegate)?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type YieldExpression = ({\n\ttype: 'YieldExpression';\n\tdelegate: boolean;\n\targument: (Expression) | null;\n}) & Span;"; + +impl<'a> Serialize for Class<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", &self.r#type)?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("decorators", &self.decorators)?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("superClass", &self.super_class)?; + map.serialize_entry("superTypeParameters", &self.super_type_parameters)?; + map.serialize_entry("implements", &self.implements)?; + map.serialize_entry("body", &self.body)?; + map.serialize_entry("abstract", &self.r#abstract)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Class = ({\n\ttype: ClassType;\n\tdecorators: Array;\n\tid: (BindingIdentifier) | null;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tsuperClass: (Expression) | null;\n\tsuperTypeParameters: (TSTypeParameterInstantiation) | null;\n\timplements: (Array) | null;\n\tbody: ClassBody;\n\tabstract: boolean;\n\tdeclare: boolean;\n}) & Span;"; + +impl Serialize for ClassType { + fn serialize(&self, serializer: S) -> Result { + match *self { + ClassType::ClassDeclaration => { + serializer.serialize_unit_variant("ClassType", 0u32, "ClassDeclaration") + } + ClassType::ClassExpression => { + serializer.serialize_unit_variant("ClassType", 1u32, "ClassExpression") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ClassType = 'ClassDeclaration' | 'ClassExpression';"; + +impl<'a> Serialize for ClassBody<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ClassBody")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ClassBody = ({\n\ttype: 'ClassBody';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for ClassElement<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ClassElement::StaticBlock(x) => Serialize::serialize(x, serializer), + ClassElement::MethodDefinition(x) => Serialize::serialize(x, serializer), + ClassElement::PropertyDefinition(x) => Serialize::serialize(x, serializer), + ClassElement::AccessorProperty(x) => Serialize::serialize(x, serializer), + ClassElement::TSIndexSignature(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ClassElement = StaticBlock | MethodDefinition | PropertyDefinition | AccessorProperty | TSIndexSignature;"; + +impl<'a> Serialize for MethodDefinition<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", &self.r#type)?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("decorators", &self.decorators)?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("computed", &self.computed)?; + map.serialize_entry("static", &self.r#static)?; + map.serialize_entry("override", &self.r#override)?; + map.serialize_entry("optional", &self.optional)?; + map.serialize_entry("accessibility", &self.accessibility)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type MethodDefinition = ({\n\ttype: MethodDefinitionType;\n\tdecorators: Array;\n\tkey: PropertyKey;\n\tvalue: Function;\n\tkind: MethodDefinitionKind;\n\tcomputed: boolean;\n\tstatic: boolean;\n\toverride: boolean;\n\toptional: boolean;\n\taccessibility: (TSAccessibility) | null;\n}) & Span;"; + +impl Serialize for MethodDefinitionType { + fn serialize(&self, serializer: S) -> Result { + match *self { + MethodDefinitionType::MethodDefinition => { + serializer.serialize_unit_variant("MethodDefinitionType", 0u32, "MethodDefinition") + } + MethodDefinitionType::TSAbstractMethodDefinition => serializer.serialize_unit_variant( + "MethodDefinitionType", + 1u32, + "TSAbstractMethodDefinition", + ), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type MethodDefinitionType = 'MethodDefinition' | 'TSAbstractMethodDefinition';"; + +impl<'a> Serialize for PropertyDefinition<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", &self.r#type)?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("decorators", &self.decorators)?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("computed", &self.computed)?; + map.serialize_entry("static", &self.r#static)?; + map.serialize_entry("declare", &self.declare)?; + map.serialize_entry("override", &self.r#override)?; + map.serialize_entry("optional", &self.optional)?; + map.serialize_entry("definite", &self.definite)?; + map.serialize_entry("readonly", &self.readonly)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("accessibility", &self.accessibility)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type PropertyDefinition = ({\n\ttype: PropertyDefinitionType;\n\tdecorators: Array;\n\tkey: PropertyKey;\n\tvalue: (Expression) | null;\n\tcomputed: boolean;\n\tstatic: boolean;\n\tdeclare: boolean;\n\toverride: boolean;\n\toptional: boolean;\n\tdefinite: boolean;\n\treadonly: boolean;\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n\taccessibility: (TSAccessibility) | null;\n}) & Span;"; + +impl Serialize for PropertyDefinitionType { + fn serialize(&self, serializer: S) -> Result { + match *self { + PropertyDefinitionType::PropertyDefinition => serializer.serialize_unit_variant( + "PropertyDefinitionType", + 0u32, + "PropertyDefinition", + ), + PropertyDefinitionType::TSAbstractPropertyDefinition => serializer + .serialize_unit_variant( + "PropertyDefinitionType", + 1u32, + "TSAbstractPropertyDefinition", + ), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type PropertyDefinitionType = 'PropertyDefinition' | 'TSAbstractPropertyDefinition';"; + +impl Serialize for MethodDefinitionKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + MethodDefinitionKind::Constructor => { + serializer.serialize_unit_variant("MethodDefinitionKind", 0u32, "constructor") + } + MethodDefinitionKind::Method => { + serializer.serialize_unit_variant("MethodDefinitionKind", 1u32, "method") + } + MethodDefinitionKind::Get => { + serializer.serialize_unit_variant("MethodDefinitionKind", 2u32, "get") + } + MethodDefinitionKind::Set => { + serializer.serialize_unit_variant("MethodDefinitionKind", 3u32, "set") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type MethodDefinitionKind = 'constructor' | 'method' | 'get' | 'set';"; + +impl<'a> Serialize for PrivateIdentifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "PrivateIdentifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type PrivateIdentifier = ({\n\ttype: 'PrivateIdentifier';\n\tname: string;\n}) & Span;"; + +impl<'a> Serialize for StaticBlock<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "StaticBlock")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type StaticBlock = ({\n\ttype: 'StaticBlock';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for ModuleDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ModuleDeclaration::ImportDeclaration(x) => Serialize::serialize(x, serializer), + ModuleDeclaration::ExportAllDeclaration(x) => Serialize::serialize(x, serializer), + ModuleDeclaration::ExportDefaultDeclaration(x) => Serialize::serialize(x, serializer), + ModuleDeclaration::ExportNamedDeclaration(x) => Serialize::serialize(x, serializer), + ModuleDeclaration::TSExportAssignment(x) => Serialize::serialize(x, serializer), + ModuleDeclaration::TSNamespaceExportDeclaration(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ModuleDeclaration = ImportDeclaration | ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | TSExportAssignment | TSNamespaceExportDeclaration;"; + +impl Serialize for AccessorPropertyType { + fn serialize(&self, serializer: S) -> Result { + match *self { + AccessorPropertyType::AccessorProperty => { + serializer.serialize_unit_variant("AccessorPropertyType", 0u32, "AccessorProperty") + } + AccessorPropertyType::TSAbstractAccessorProperty => serializer.serialize_unit_variant( + "AccessorPropertyType", + 1u32, + "TSAbstractAccessorProperty", + ), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type AccessorPropertyType = 'AccessorProperty' | 'TSAbstractAccessorProperty';"; + +impl<'a> Serialize for AccessorProperty<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", &self.r#type)?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("decorators", &self.decorators)?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.serialize_entry("computed", &self.computed)?; + map.serialize_entry("static", &self.r#static)?; + map.serialize_entry("definite", &self.definite)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("accessibility", &self.accessibility)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AccessorProperty = ({\n\ttype: AccessorPropertyType;\n\tdecorators: Array;\n\tkey: PropertyKey;\n\tvalue: (Expression) | null;\n\tcomputed: boolean;\n\tstatic: boolean;\n\tdefinite: boolean;\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n\taccessibility: (TSAccessibility) | null;\n}) & Span;"; + +impl<'a> Serialize for ImportExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("source", &self.source)?; + map.serialize_entry("arguments", &self.arguments)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportExpression = ({\n\ttype: 'ImportExpression';\n\tsource: Expression;\n\targuments: Array;\n}) & Span;"; + +impl<'a> Serialize for ImportDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("specifiers", &self.specifiers)?; + map.serialize_entry("source", &self.source)?; + map.serialize_entry("withClause", &self.with_clause)?; + map.serialize_entry("importKind", &self.import_kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportDeclaration = ({\n\ttype: 'ImportDeclaration';\n\tspecifiers: (Array) | null;\n\tsource: StringLiteral;\n\twithClause: (WithClause) | null;\n\timportKind: ImportOrExportKind;\n}) & Span;"; + +impl<'a> Serialize for ImportDeclarationSpecifier<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ImportDeclarationSpecifier::ImportSpecifier(x) => Serialize::serialize(x, serializer), + ImportDeclarationSpecifier::ImportDefaultSpecifier(x) => { + Serialize::serialize(x, serializer) + } + ImportDeclarationSpecifier::ImportNamespaceSpecifier(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportDeclarationSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier;"; + +impl<'a> Serialize for ImportSpecifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportSpecifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("imported", &self.imported)?; + map.serialize_entry("local", &self.local)?; + map.serialize_entry("importKind", &self.import_kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportSpecifier = ({\n\ttype: 'ImportSpecifier';\n\timported: ModuleExportName;\n\tlocal: BindingIdentifier;\n\timportKind: ImportOrExportKind;\n}) & Span;"; + +impl<'a> Serialize for ImportDefaultSpecifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportDefaultSpecifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("local", &self.local)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportDefaultSpecifier = ({\n\ttype: 'ImportDefaultSpecifier';\n\tlocal: BindingIdentifier;\n}) & Span;"; + +impl<'a> Serialize for ImportNamespaceSpecifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportNamespaceSpecifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("local", &self.local)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportNamespaceSpecifier = ({\n\ttype: 'ImportNamespaceSpecifier';\n\tlocal: BindingIdentifier;\n}) & Span;"; + +impl<'a> Serialize for WithClause<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "WithClause")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("attributesKeyword", &self.attributes_keyword)?; + map.serialize_entry("withEntries", &self.with_entries)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type WithClause = ({\n\ttype: 'WithClause';\n\tattributesKeyword: IdentifierName;\n\twithEntries: Array;\n}) & Span;"; + +impl<'a> Serialize for ImportAttribute<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ImportAttribute")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportAttribute = ({\n\ttype: 'ImportAttribute';\n\tkey: ImportAttributeKey;\n\tvalue: StringLiteral;\n}) & Span;"; + +impl<'a> Serialize for ImportAttributeKey<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ImportAttributeKey::Identifier(x) => Serialize::serialize(x, serializer), + ImportAttributeKey::StringLiteral(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ImportAttributeKey = IdentifierName | StringLiteral;"; + +impl<'a> Serialize for ExportNamedDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ExportNamedDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("declaration", &self.declaration)?; + map.serialize_entry("specifiers", &self.specifiers)?; + map.serialize_entry("source", &self.source)?; + map.serialize_entry("exportKind", &self.export_kind)?; + map.serialize_entry("withClause", &self.with_clause)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExportNamedDeclaration = ({\n\ttype: 'ExportNamedDeclaration';\n\tdeclaration: (Declaration) | null;\n\tspecifiers: Array;\n\tsource: (StringLiteral) | null;\n\texportKind: ImportOrExportKind;\n\twithClause: (WithClause) | null;\n}) & Span;"; + +impl<'a> Serialize for ExportDefaultDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ExportDefaultDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("declaration", &self.declaration)?; + map.serialize_entry("exported", &self.exported)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExportDefaultDeclaration = ({\n\ttype: 'ExportDefaultDeclaration';\n\tdeclaration: ExportDefaultDeclarationKind;\n\texported: ModuleExportName;\n}) & Span;"; + +impl<'a> Serialize for ExportAllDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ExportAllDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("exported", &self.exported)?; + map.serialize_entry("source", &self.source)?; + map.serialize_entry("withClause", &self.with_clause)?; + map.serialize_entry("exportKind", &self.export_kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExportAllDeclaration = ({\n\ttype: 'ExportAllDeclaration';\n\texported: (ModuleExportName) | null;\n\tsource: StringLiteral;\n\twithClause: (WithClause) | null;\n\texportKind: ImportOrExportKind;\n}) & Span;"; + +impl<'a> Serialize for ExportSpecifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ExportSpecifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("local", &self.local)?; + map.serialize_entry("exported", &self.exported)?; + map.serialize_entry("exportKind", &self.export_kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExportSpecifier = ({\n\ttype: 'ExportSpecifier';\n\tlocal: ModuleExportName;\n\texported: ModuleExportName;\n\texportKind: ImportOrExportKind;\n}) & Span;"; + +impl<'a> Serialize for ExportDefaultDeclarationKind<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ExportDefaultDeclarationKind::FunctionDeclaration(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::ClassDeclaration(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::TSInterfaceDeclaration(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::BooleanLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::NullLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::NumericLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::BigIntLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::RegExpLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::StringLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::TemplateLiteral(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::Identifier(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::MetaProperty(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::Super(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ArrayExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ArrowFunctionExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::AssignmentExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::AwaitExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::BinaryExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::CallExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ChainExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ClassExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ConditionalExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::FunctionExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::ImportExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::LogicalExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::NewExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::ObjectExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::ParenthesizedExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::SequenceExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::TaggedTemplateExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::ThisExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::UnaryExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::UpdateExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::YieldExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::PrivateInExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::JSXElement(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::JSXFragment(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::TSAsExpression(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::TSSatisfiesExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + ExportDefaultDeclarationKind::TSNonNullExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::TSInstantiationExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::ComputedMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::StaticMemberExpression(x) => { + Serialize::serialize(x, serializer) + } + ExportDefaultDeclarationKind::PrivateFieldExpression(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ExportDefaultDeclarationKind = Function | Class | TSInterfaceDeclaration | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for ModuleExportName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + ModuleExportName::IdentifierName(x) => Serialize::serialize(x, serializer), + ModuleExportName::IdentifierReference(x) => Serialize::serialize(x, serializer), + ModuleExportName::StringLiteral(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ModuleExportName = IdentifierName | IdentifierReference | StringLiteral;"; + +impl<'a> Serialize for TSThisParameter<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSThisParameter")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("thisSpan", &self.this_span)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSThisParameter = ({\n\ttype: 'TSThisParameter';\n\tthisSpan: Span;\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSEnumDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSEnumDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("members", &self.members)?; + map.serialize_entry("const", &self.r#const)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSEnumDeclaration = ({\n\ttype: 'TSEnumDeclaration';\n\tid: BindingIdentifier;\n\tmembers: Array;\n\tconst: boolean;\n\tdeclare: boolean;\n}) & Span;"; + +impl<'a> Serialize for TSEnumMember<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSEnumMember")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("initializer", &self.initializer)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSEnumMember = ({\n\ttype: 'TSEnumMember';\n\tid: TSEnumMemberName;\n\tinitializer: (Expression) | null;\n}) & Span;"; + +impl<'a> Serialize for TSEnumMemberName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSEnumMemberName::StaticIdentifier(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::StaticStringLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::StaticTemplateLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::StaticNumericLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::BooleanLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::NullLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::NumericLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::BigIntLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::RegExpLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::StringLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TemplateLiteral(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::Identifier(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::MetaProperty(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::Super(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ArrayExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::AssignmentExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::AwaitExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::BinaryExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::CallExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ChainExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ClassExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ConditionalExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::FunctionExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ImportExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::LogicalExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::NewExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ObjectExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::SequenceExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ThisExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::UnaryExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::UpdateExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::YieldExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::PrivateInExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::JSXElement(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::JSXFragment(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TSAsExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + TSEnumMemberName::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSEnumMemberName = IdentifierName | StringLiteral | TemplateLiteral | NumericLiteral | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl<'a> Serialize for TSTypeAnnotation<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeAnnotation")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeAnnotation = ({\n\ttype: 'TSTypeAnnotation';\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSLiteralType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSLiteralType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("literal", &self.literal)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSLiteralType = ({\n\ttype: 'TSLiteralType';\n\tliteral: TSLiteral;\n}) & Span;"; + +impl<'a> Serialize for TSLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSLiteral::BooleanLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::NullLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::NumericLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::BigIntLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::RegExpLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::StringLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::TemplateLiteral(x) => Serialize::serialize(x, serializer), + TSLiteral::UnaryExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSLiteral = BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | UnaryExpression;"; + +impl<'a> Serialize for TSType<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSType::TSAnyKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSBigIntKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSBooleanKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSIntrinsicKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSNeverKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSNullKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSNumberKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSObjectKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSStringKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSSymbolKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSUndefinedKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSUnknownKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSVoidKeyword(x) => Serialize::serialize(x, serializer), + TSType::TSArrayType(x) => Serialize::serialize(x, serializer), + TSType::TSConditionalType(x) => Serialize::serialize(x, serializer), + TSType::TSConstructorType(x) => Serialize::serialize(x, serializer), + TSType::TSFunctionType(x) => Serialize::serialize(x, serializer), + TSType::TSImportType(x) => Serialize::serialize(x, serializer), + TSType::TSIndexedAccessType(x) => Serialize::serialize(x, serializer), + TSType::TSInferType(x) => Serialize::serialize(x, serializer), + TSType::TSIntersectionType(x) => Serialize::serialize(x, serializer), + TSType::TSLiteralType(x) => Serialize::serialize(x, serializer), + TSType::TSMappedType(x) => Serialize::serialize(x, serializer), + TSType::TSNamedTupleMember(x) => Serialize::serialize(x, serializer), + TSType::TSQualifiedName(x) => Serialize::serialize(x, serializer), + TSType::TSTemplateLiteralType(x) => Serialize::serialize(x, serializer), + TSType::TSThisType(x) => Serialize::serialize(x, serializer), + TSType::TSTupleType(x) => Serialize::serialize(x, serializer), + TSType::TSTypeLiteral(x) => Serialize::serialize(x, serializer), + TSType::TSTypeOperatorType(x) => Serialize::serialize(x, serializer), + TSType::TSTypePredicate(x) => Serialize::serialize(x, serializer), + TSType::TSTypeQuery(x) => Serialize::serialize(x, serializer), + TSType::TSTypeReference(x) => Serialize::serialize(x, serializer), + TSType::TSUnionType(x) => Serialize::serialize(x, serializer), + TSType::TSParenthesizedType(x) => Serialize::serialize(x, serializer), + TSType::JSDocNullableType(x) => Serialize::serialize(x, serializer), + TSType::JSDocNonNullableType(x) => Serialize::serialize(x, serializer), + TSType::JSDocUnknownType(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSType = TSAnyKeyword | TSBigIntKeyword | TSBooleanKeyword | TSIntrinsicKeyword | TSNeverKeyword | TSNullKeyword | TSNumberKeyword | TSObjectKeyword | TSStringKeyword | TSSymbolKeyword | TSUndefinedKeyword | TSUnknownKeyword | TSVoidKeyword | TSArrayType | TSConditionalType | TSConstructorType | TSFunctionType | TSImportType | TSIndexedAccessType | TSInferType | TSIntersectionType | TSLiteralType | TSMappedType | TSNamedTupleMember | TSQualifiedName | TSTemplateLiteralType | TSThisType | TSTupleType | TSTypeLiteral | TSTypeOperator | TSTypePredicate | TSTypeQuery | TSTypeReference | TSUnionType | TSParenthesizedType | JSDocNullableType | JSDocNonNullableType | JSDocUnknownType;"; + +impl<'a> Serialize for TSConditionalType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSConditionalType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("checkType", &self.check_type)?; + map.serialize_entry("extendsType", &self.extends_type)?; + map.serialize_entry("trueType", &self.true_type)?; + map.serialize_entry("falseType", &self.false_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSConditionalType = ({\n\ttype: 'TSConditionalType';\n\tcheckType: TSType;\n\textendsType: TSType;\n\ttrueType: TSType;\n\tfalseType: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSUnionType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSUnionType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("types", &self.types)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSUnionType = ({\n\ttype: 'TSUnionType';\n\ttypes: Array;\n}) & Span;"; + +impl<'a> Serialize for TSIntersectionType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSIntersectionType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("types", &self.types)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSIntersectionType = ({\n\ttype: 'TSIntersectionType';\n\ttypes: Array;\n}) & Span;"; + +impl<'a> Serialize for TSParenthesizedType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSParenthesizedType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSParenthesizedType = ({\n\ttype: 'TSParenthesizedType';\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSTypeOperator<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeOperator")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("operator", &self.operator)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeOperator = ({\n\ttype: 'TSTypeOperator';\n\toperator: TSTypeOperatorOperator;\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl Serialize for TSTypeOperatorOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + TSTypeOperatorOperator::Keyof => { + serializer.serialize_unit_variant("TSTypeOperatorOperator", 0u32, "keyof") + } + TSTypeOperatorOperator::Unique => { + serializer.serialize_unit_variant("TSTypeOperatorOperator", 1u32, "unique") + } + TSTypeOperatorOperator::Readonly => { + serializer.serialize_unit_variant("TSTypeOperatorOperator", 2u32, "readonly") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSTypeOperatorOperator = 'keyof' | 'unique' | 'readonly';"; + +impl<'a> Serialize for TSArrayType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSArrayType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("elementType", &self.element_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSArrayType = ({\n\ttype: 'TSArrayType';\n\telementType: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSIndexedAccessType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSIndexedAccessType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("objectType", &self.object_type)?; + map.serialize_entry("indexType", &self.index_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSIndexedAccessType = ({\n\ttype: 'TSIndexedAccessType';\n\tobjectType: TSType;\n\tindexType: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSTupleType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTupleType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("elementTypes", &self.element_types)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTupleType = ({\n\ttype: 'TSTupleType';\n\telementTypes: Array;\n}) & Span;"; + +impl<'a> Serialize for TSNamedTupleMember<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNamedTupleMember")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("elementType", &self.element_type)?; + map.serialize_entry("label", &self.label)?; + map.serialize_entry("optional", &self.optional)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSNamedTupleMember = ({\n\ttype: 'TSNamedTupleMember';\n\telementType: TSTupleElement;\n\tlabel: IdentifierName;\n\toptional: boolean;\n}) & Span;"; + +impl<'a> Serialize for TSOptionalType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSOptionalType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSOptionalType = ({\n\ttype: 'TSOptionalType';\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSRestType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSRestType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSRestType = ({\n\ttype: 'TSRestType';\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSTupleElement<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSTupleElement::TSOptionalType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSRestType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSAnyKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSBigIntKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSBooleanKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSIntrinsicKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSNeverKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSNullKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSNumberKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSObjectKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSStringKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSSymbolKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSUndefinedKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSUnknownKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSVoidKeyword(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSArrayType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSConditionalType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSConstructorType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSFunctionType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSImportType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSIndexedAccessType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSInferType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSIntersectionType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSLiteralType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSMappedType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSNamedTupleMember(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSQualifiedName(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTemplateLiteralType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSThisType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTupleType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTypeLiteral(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTypeOperatorType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTypePredicate(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTypeQuery(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSTypeReference(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSUnionType(x) => Serialize::serialize(x, serializer), + TSTupleElement::TSParenthesizedType(x) => Serialize::serialize(x, serializer), + TSTupleElement::JSDocNullableType(x) => Serialize::serialize(x, serializer), + TSTupleElement::JSDocNonNullableType(x) => Serialize::serialize(x, serializer), + TSTupleElement::JSDocUnknownType(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTupleElement = TSOptionalType | TSRestType | TSAnyKeyword | TSBigIntKeyword | TSBooleanKeyword | TSIntrinsicKeyword | TSNeverKeyword | TSNullKeyword | TSNumberKeyword | TSObjectKeyword | TSStringKeyword | TSSymbolKeyword | TSUndefinedKeyword | TSUnknownKeyword | TSVoidKeyword | TSArrayType | TSConditionalType | TSConstructorType | TSFunctionType | TSImportType | TSIndexedAccessType | TSInferType | TSIntersectionType | TSLiteralType | TSMappedType | TSNamedTupleMember | TSQualifiedName | TSTemplateLiteralType | TSThisType | TSTupleType | TSTypeLiteral | TSTypeOperator | TSTypePredicate | TSTypeQuery | TSTypeReference | TSUnionType | TSParenthesizedType | JSDocNullableType | JSDocNonNullableType | JSDocUnknownType;"; + +impl Serialize for TSAnyKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSAnyKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSAnyKeyword = ({\n\ttype: 'TSAnyKeyword';\n}) & Span;"; + +impl Serialize for TSStringKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSStringKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSStringKeyword = ({\n\ttype: 'TSStringKeyword';\n}) & Span;"; + +impl Serialize for TSBooleanKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSBooleanKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSBooleanKeyword = ({\n\ttype: 'TSBooleanKeyword';\n}) & Span;"; + +impl Serialize for TSNumberKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNumberKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSNumberKeyword = ({\n\ttype: 'TSNumberKeyword';\n}) & Span;"; + +impl Serialize for TSNeverKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNeverKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSNeverKeyword = ({\n\ttype: 'TSNeverKeyword';\n}) & Span;"; + +impl Serialize for TSIntrinsicKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSIntrinsicKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSIntrinsicKeyword = ({\n\ttype: 'TSIntrinsicKeyword';\n}) & Span;"; + +impl Serialize for TSUnknownKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSUnknownKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSUnknownKeyword = ({\n\ttype: 'TSUnknownKeyword';\n}) & Span;"; + +impl Serialize for TSNullKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNullKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSNullKeyword = ({\n\ttype: 'TSNullKeyword';\n}) & Span;"; + +impl Serialize for TSUndefinedKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSUndefinedKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSUndefinedKeyword = ({\n\ttype: 'TSUndefinedKeyword';\n}) & Span;"; + +impl Serialize for TSVoidKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSVoidKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSVoidKeyword = ({\n\ttype: 'TSVoidKeyword';\n}) & Span;"; + +impl Serialize for TSSymbolKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSSymbolKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSSymbolKeyword = ({\n\ttype: 'TSSymbolKeyword';\n}) & Span;"; + +impl Serialize for TSThisType { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSThisType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSThisType = ({\n\ttype: 'TSThisType';\n}) & Span;"; + +impl Serialize for TSObjectKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSObjectKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSObjectKeyword = ({\n\ttype: 'TSObjectKeyword';\n}) & Span;"; + +impl Serialize for TSBigIntKeyword { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSBigIntKeyword")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSBigIntKeyword = ({\n\ttype: 'TSBigIntKeyword';\n}) & Span;"; + +impl<'a> Serialize for TSTypeReference<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeReference")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeName", &self.type_name)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeReference = ({\n\ttype: 'TSTypeReference';\n\ttypeName: TSTypeName;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSTypeName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSTypeName::IdentifierReference(x) => Serialize::serialize(x, serializer), + TSTypeName::QualifiedName(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSTypeName = IdentifierReference | TSQualifiedName;"; + +impl<'a> Serialize for TSQualifiedName<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSQualifiedName")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("left", &self.left)?; + map.serialize_entry("right", &self.right)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSQualifiedName = ({\n\ttype: 'TSQualifiedName';\n\tleft: TSTypeName;\n\tright: IdentifierName;\n}) & Span;"; + +impl<'a> Serialize for TSTypeParameterInstantiation<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeParameterInstantiation")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("params", &self.params)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeParameterInstantiation = ({\n\ttype: 'TSTypeParameterInstantiation';\n\tparams: Array;\n}) & Span;"; + +impl<'a> Serialize for TSTypeParameter<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeParameter")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("constraint", &self.constraint)?; + map.serialize_entry("default", &self.default)?; + map.serialize_entry("in", &self.r#in)?; + map.serialize_entry("out", &self.out)?; + map.serialize_entry("const", &self.r#const)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeParameter = ({\n\ttype: 'TSTypeParameter';\n\tname: BindingIdentifier;\n\tconstraint: (TSType) | null;\n\tdefault: (TSType) | null;\n\tin: boolean;\n\tout: boolean;\n\tconst: boolean;\n}) & Span;"; + +impl<'a> Serialize for TSTypeParameterDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeParameterDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("params", &self.params)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeParameterDeclaration = ({\n\ttype: 'TSTypeParameterDeclaration';\n\tparams: Array;\n}) & Span;"; + +impl<'a> Serialize for TSTypeAliasDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeAliasDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeAliasDeclaration = ({\n\ttype: 'TSTypeAliasDeclaration';\n\tid: BindingIdentifier;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\ttypeAnnotation: TSType;\n\tdeclare: boolean;\n}) & Span;"; + +impl Serialize for TSAccessibility { + fn serialize(&self, serializer: S) -> Result { + match *self { + TSAccessibility::Private => { + serializer.serialize_unit_variant("TSAccessibility", 0u32, "private") + } + TSAccessibility::Protected => { + serializer.serialize_unit_variant("TSAccessibility", 1u32, "protected") + } + TSAccessibility::Public => { + serializer.serialize_unit_variant("TSAccessibility", 2u32, "public") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSAccessibility = 'private' | 'protected' | 'public';"; + +impl<'a> Serialize for TSClassImplements<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSClassImplements")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSClassImplements = ({\n\ttype: 'TSClassImplements';\n\texpression: TSTypeName;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSInterfaceDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSInterfaceDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("extends", &self.extends)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("body", &self.body)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSInterfaceDeclaration = ({\n\ttype: 'TSInterfaceDeclaration';\n\tid: BindingIdentifier;\n\textends: (Array) | null;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tbody: TSInterfaceBody;\n\tdeclare: boolean;\n}) & Span;"; + +impl<'a> Serialize for TSInterfaceBody<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSInterfaceBody")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSInterfaceBody = ({\n\ttype: 'TSInterfaceBody';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for TSPropertySignature<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSPropertySignature")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("computed", &self.computed)?; + map.serialize_entry("optional", &self.optional)?; + map.serialize_entry("readonly", &self.readonly)?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSPropertySignature = ({\n\ttype: 'TSPropertySignature';\n\tcomputed: boolean;\n\toptional: boolean;\n\treadonly: boolean;\n\tkey: PropertyKey;\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSSignature<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSSignature::TSIndexSignature(x) => Serialize::serialize(x, serializer), + TSSignature::TSPropertySignature(x) => Serialize::serialize(x, serializer), + TSSignature::TSCallSignatureDeclaration(x) => Serialize::serialize(x, serializer), + TSSignature::TSConstructSignatureDeclaration(x) => Serialize::serialize(x, serializer), + TSSignature::TSMethodSignature(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSSignature = TSIndexSignature | TSPropertySignature | TSCallSignatureDeclaration | TSConstructSignatureDeclaration | TSMethodSignature;"; + +impl<'a> Serialize for TSIndexSignature<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSIndexSignature")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("parameters", &self.parameters)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("readonly", &self.readonly)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSIndexSignature = ({\n\ttype: 'TSIndexSignature';\n\tparameters: Array;\n\ttypeAnnotation: TSTypeAnnotation;\n\treadonly: boolean;\n}) & Span;"; + +impl<'a> Serialize for TSCallSignatureDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSCallSignatureDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("thisParam", &self.this_param)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSCallSignatureDeclaration = ({\n\ttype: 'TSCallSignatureDeclaration';\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tthisParam: (TSThisParameter) | null;\n\tparams: FormalParameters;\n\treturnType: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl Serialize for TSMethodSignatureKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + TSMethodSignatureKind::Method => { + serializer.serialize_unit_variant("TSMethodSignatureKind", 0u32, "method") + } + TSMethodSignatureKind::Get => { + serializer.serialize_unit_variant("TSMethodSignatureKind", 1u32, "get") + } + TSMethodSignatureKind::Set => { + serializer.serialize_unit_variant("TSMethodSignatureKind", 2u32, "set") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSMethodSignatureKind = 'method' | 'get' | 'set';"; + +impl<'a> Serialize for TSMethodSignature<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSMethodSignature")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("key", &self.key)?; + map.serialize_entry("computed", &self.computed)?; + map.serialize_entry("optional", &self.optional)?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("thisParam", &self.this_param)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSMethodSignature = ({\n\ttype: 'TSMethodSignature';\n\tkey: PropertyKey;\n\tcomputed: boolean;\n\toptional: boolean;\n\tkind: TSMethodSignatureKind;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tthisParam: (TSThisParameter) | null;\n\tparams: FormalParameters;\n\treturnType: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSConstructSignatureDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSConstructSignatureDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSConstructSignatureDeclaration = ({\n\ttype: 'TSConstructSignatureDeclaration';\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tparams: FormalParameters;\n\treturnType: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSIndexSignatureName<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Identifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSIndexSignatureName = ({\n\ttype: 'Identifier';\n\tname: string;\n\ttypeAnnotation: TSTypeAnnotation;\n}) & Span;"; + +impl<'a> Serialize for TSInterfaceHeritage<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSInterfaceHeritage")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSInterfaceHeritage = ({\n\ttype: 'TSInterfaceHeritage';\n\texpression: Expression;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSTypePredicate<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypePredicate")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("parameterName", &self.parameter_name)?; + map.serialize_entry("asserts", &self.asserts)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypePredicate = ({\n\ttype: 'TSTypePredicate';\n\tparameterName: TSTypePredicateName;\n\tasserts: boolean;\n\ttypeAnnotation: (TSTypeAnnotation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSTypePredicateName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSTypePredicateName::Identifier(x) => Serialize::serialize(x, serializer), + TSTypePredicateName::This(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSTypePredicateName = IdentifierName | TSThisType;"; + +impl<'a> Serialize for TSModuleDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSModuleDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("body", &self.body)?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("declare", &self.declare)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSModuleDeclaration = ({\n\ttype: 'TSModuleDeclaration';\n\tid: TSModuleDeclarationName;\n\tbody: (TSModuleDeclarationBody) | null;\n\tkind: TSModuleDeclarationKind;\n\tdeclare: boolean;\n}) & Span;"; + +impl Serialize for TSModuleDeclarationKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + TSModuleDeclarationKind::Global => { + serializer.serialize_unit_variant("TSModuleDeclarationKind", 0u32, "global") + } + TSModuleDeclarationKind::Module => { + serializer.serialize_unit_variant("TSModuleDeclarationKind", 1u32, "module") + } + TSModuleDeclarationKind::Namespace => { + serializer.serialize_unit_variant("TSModuleDeclarationKind", 2u32, "namespace") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSModuleDeclarationKind = 'global' | 'module' | 'namespace';"; + +impl<'a> Serialize for TSModuleDeclarationName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSModuleDeclarationName::Identifier(x) => Serialize::serialize(x, serializer), + TSModuleDeclarationName::StringLiteral(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSModuleDeclarationName = BindingIdentifier | StringLiteral;"; + +impl<'a> Serialize for TSModuleDeclarationBody<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSModuleDeclarationBody::TSModuleDeclaration(x) => Serialize::serialize(x, serializer), + TSModuleDeclarationBody::TSModuleBlock(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSModuleDeclarationBody = TSModuleDeclaration | TSModuleBlock;"; + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSModuleBlock = ({\n\ttype: 'TSModuleBlock';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for TSTypeLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeLiteral")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("members", &self.members)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeLiteral = ({\n\ttype: 'TSTypeLiteral';\n\tmembers: Array;\n}) & Span;"; + +impl<'a> Serialize for TSInferType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSInferType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeParameter", &self.type_parameter)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSInferType = ({\n\ttype: 'TSInferType';\n\ttypeParameter: TSTypeParameter;\n}) & Span;"; + +impl<'a> Serialize for TSTypeQuery<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeQuery")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("exprName", &self.expr_name)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeQuery = ({\n\ttype: 'TSTypeQuery';\n\texprName: TSTypeQueryExprName;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSTypeQueryExprName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSTypeQueryExprName::TSImportType(x) => Serialize::serialize(x, serializer), + TSTypeQueryExprName::IdentifierReference(x) => Serialize::serialize(x, serializer), + TSTypeQueryExprName::QualifiedName(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSTypeQueryExprName = TSImportType | IdentifierReference | TSQualifiedName;"; + +impl<'a> Serialize for TSImportType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSImportType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("isTypeOf", &self.is_type_of)?; + map.serialize_entry("parameter", &self.parameter)?; + map.serialize_entry("qualifier", &self.qualifier)?; + map.serialize_entry("attributes", &self.attributes)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSImportType = ({\n\ttype: 'TSImportType';\n\tisTypeOf: boolean;\n\tparameter: TSType;\n\tqualifier: (TSTypeName) | null;\n\tattributes: (TSImportAttributes) | null;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for TSImportAttributes<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSImportAttributes")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("attributesKeyword", &self.attributes_keyword)?; + map.serialize_entry("elements", &self.elements)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSImportAttributes = ({\n\ttype: 'TSImportAttributes';\n\tattributesKeyword: IdentifierName;\n\telements: Array;\n}) & Span;"; + +impl<'a> Serialize for TSImportAttribute<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSImportAttribute")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSImportAttribute = ({\n\ttype: 'TSImportAttribute';\n\tname: TSImportAttributeName;\n\tvalue: Expression;\n}) & Span;"; + +impl<'a> Serialize for TSImportAttributeName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSImportAttributeName::Identifier(x) => Serialize::serialize(x, serializer), + TSImportAttributeName::StringLiteral(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSImportAttributeName = IdentifierName | StringLiteral;"; + +impl<'a> Serialize for TSFunctionType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSFunctionType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("thisParam", &self.this_param)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSFunctionType = ({\n\ttype: 'TSFunctionType';\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tthisParam: (TSThisParameter) | null;\n\tparams: FormalParameters;\n\treturnType: TSTypeAnnotation;\n}) & Span;"; + +impl<'a> Serialize for TSConstructorType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSConstructorType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("abstract", &self.r#abstract)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.serialize_entry("params", &self.params)?; + map.serialize_entry("returnType", &self.return_type)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSConstructorType = ({\n\ttype: 'TSConstructorType';\n\tabstract: boolean;\n\ttypeParameters: (TSTypeParameterDeclaration) | null;\n\tparams: FormalParameters;\n\treturnType: TSTypeAnnotation;\n}) & Span;"; + +impl<'a> Serialize for TSMappedType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSMappedType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeParameter", &self.type_parameter)?; + map.serialize_entry("nameType", &self.name_type)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("optional", &self.optional)?; + map.serialize_entry("readonly", &self.readonly)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSMappedType = ({\n\ttype: 'TSMappedType';\n\ttypeParameter: TSTypeParameter;\n\tnameType: (TSType) | null;\n\ttypeAnnotation: (TSType) | null;\n\toptional: TSMappedTypeModifierOperator;\n\treadonly: TSMappedTypeModifierOperator;\n}) & Span;"; + +impl Serialize for TSMappedTypeModifierOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + TSMappedTypeModifierOperator::True => { + serializer.serialize_unit_variant("TSMappedTypeModifierOperator", 0u32, "true") + } + TSMappedTypeModifierOperator::Plus => { + serializer.serialize_unit_variant("TSMappedTypeModifierOperator", 1u32, "+") + } + TSMappedTypeModifierOperator::Minus => { + serializer.serialize_unit_variant("TSMappedTypeModifierOperator", 2u32, "-") + } + TSMappedTypeModifierOperator::None => { + serializer.serialize_unit_variant("TSMappedTypeModifierOperator", 3u32, "none") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type TSMappedTypeModifierOperator = 'true' | '+' | '-' | 'none';"; + +impl<'a> Serialize for TSTemplateLiteralType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTemplateLiteralType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("quasis", &self.quasis)?; + map.serialize_entry("types", &self.types)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTemplateLiteralType = ({\n\ttype: 'TSTemplateLiteralType';\n\tquasis: Array;\n\ttypes: Array;\n}) & Span;"; + +impl<'a> Serialize for TSAsExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSAsExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSAsExpression = ({\n\ttype: 'TSAsExpression';\n\texpression: Expression;\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSSatisfiesExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSSatisfiesExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSSatisfiesExpression = ({\n\ttype: 'TSSatisfiesExpression';\n\texpression: Expression;\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSTypeAssertion<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSTypeAssertion")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSTypeAssertion = ({\n\ttype: 'TSTypeAssertion';\n\texpression: Expression;\n\ttypeAnnotation: TSType;\n}) & Span;"; + +impl<'a> Serialize for TSImportEqualsDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSImportEqualsDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.serialize_entry("moduleReference", &self.module_reference)?; + map.serialize_entry("importKind", &self.import_kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSImportEqualsDeclaration = ({\n\ttype: 'TSImportEqualsDeclaration';\n\tid: BindingIdentifier;\n\tmoduleReference: TSModuleReference;\n\timportKind: ImportOrExportKind;\n}) & Span;"; + +impl<'a> Serialize for TSModuleReference<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + TSModuleReference::ExternalModuleReference(x) => Serialize::serialize(x, serializer), + TSModuleReference::IdentifierReference(x) => Serialize::serialize(x, serializer), + TSModuleReference::QualifiedName(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSModuleReference = TSExternalModuleReference | IdentifierReference | TSQualifiedName;"; + +impl<'a> Serialize for TSExternalModuleReference<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSExternalModuleReference")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSExternalModuleReference = ({\n\ttype: 'TSExternalModuleReference';\n\texpression: StringLiteral;\n}) & Span;"; + +impl<'a> Serialize for TSNonNullExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNonNullExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSNonNullExpression = ({\n\ttype: 'TSNonNullExpression';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for Decorator<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Decorator")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Decorator = ({\n\ttype: 'Decorator';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for TSExportAssignment<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSExportAssignment")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSExportAssignment = ({\n\ttype: 'TSExportAssignment';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for TSNamespaceExportDeclaration<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSNamespaceExportDeclaration")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("id", &self.id)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSNamespaceExportDeclaration = ({\n\ttype: 'TSNamespaceExportDeclaration';\n\tid: IdentifierName;\n}) & Span;"; + +impl<'a> Serialize for TSInstantiationExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "TSInstantiationExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type TSInstantiationExpression = ({\n\ttype: 'TSInstantiationExpression';\n\texpression: Expression;\n\ttypeParameters: TSTypeParameterInstantiation;\n}) & Span;"; + +impl Serialize for ImportOrExportKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + ImportOrExportKind::Value => { + serializer.serialize_unit_variant("ImportOrExportKind", 0u32, "value") + } + ImportOrExportKind::Type => { + serializer.serialize_unit_variant("ImportOrExportKind", 1u32, "type") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ImportOrExportKind = 'value' | 'type';"; + +impl<'a> Serialize for JSDocNullableType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSDocNullableType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("postfix", &self.postfix)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSDocNullableType = ({\n\ttype: 'JSDocNullableType';\n\ttypeAnnotation: TSType;\n\tpostfix: boolean;\n}) & Span;"; + +impl<'a> Serialize for JSDocNonNullableType<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSDocNonNullableType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("typeAnnotation", &self.type_annotation)?; + map.serialize_entry("postfix", &self.postfix)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSDocNonNullableType = ({\n\ttype: 'JSDocNonNullableType';\n\ttypeAnnotation: TSType;\n\tpostfix: boolean;\n}) & Span;"; + +impl Serialize for JSDocUnknownType { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSDocUnknownType")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSDocUnknownType = ({\n\ttype: 'JSDocUnknownType';\n}) & Span;"; + +impl<'a> Serialize for JSXElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("openingElement", &self.opening_element)?; + map.serialize_entry("closingElement", &self.closing_element)?; + map.serialize_entry("children", &self.children)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXElement = ({\n\ttype: 'JSXElement';\n\topeningElement: JSXOpeningElement;\n\tclosingElement: (JSXClosingElement) | null;\n\tchildren: Array;\n}) & Span;"; + +impl<'a> Serialize for JSXOpeningElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXOpeningElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("selfClosing", &self.self_closing)?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("attributes", &self.attributes)?; + map.serialize_entry("typeParameters", &self.type_parameters)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXOpeningElement = ({\n\ttype: 'JSXOpeningElement';\n\tselfClosing: boolean;\n\tname: JSXElementName;\n\tattributes: Array;\n\ttypeParameters: (TSTypeParameterInstantiation) | null;\n}) & Span;"; + +impl<'a> Serialize for JSXClosingElement<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXClosingElement")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXClosingElement = ({\n\ttype: 'JSXClosingElement';\n\tname: JSXElementName;\n}) & Span;"; + +impl<'a> Serialize for JSXFragment<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXFragment")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("openingFragment", &self.opening_fragment)?; + map.serialize_entry("closingFragment", &self.closing_fragment)?; + map.serialize_entry("children", &self.children)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXFragment = ({\n\ttype: 'JSXFragment';\n\topeningFragment: JSXOpeningFragment;\n\tclosingFragment: JSXClosingFragment;\n\tchildren: Array;\n}) & Span;"; + +impl Serialize for JSXOpeningFragment { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXOpeningFragment")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXOpeningFragment = ({\n\ttype: 'JSXOpeningFragment';\n}) & Span;"; + +impl Serialize for JSXClosingFragment { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXClosingFragment")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXClosingFragment = ({\n\ttype: 'JSXClosingFragment';\n}) & Span;"; + +impl<'a> Serialize for JSXNamespacedName<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXNamespacedName")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("namespace", &self.namespace)?; + map.serialize_entry("property", &self.property)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXNamespacedName = ({\n\ttype: 'JSXNamespacedName';\n\tnamespace: JSXIdentifier;\n\tproperty: JSXIdentifier;\n}) & Span;"; + +impl<'a> Serialize for JSXMemberExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXMemberExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("object", &self.object)?; + map.serialize_entry("property", &self.property)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXMemberExpression = ({\n\ttype: 'JSXMemberExpression';\n\tobject: JSXMemberExpressionObject;\n\tproperty: JSXIdentifier;\n}) & Span;"; + +impl<'a> Serialize for JSXExpressionContainer<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXExpressionContainer")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXExpressionContainer = ({\n\ttype: 'JSXExpressionContainer';\n\texpression: JSXExpression;\n}) & Span;"; + +impl<'a> Serialize for JSXExpression<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + JSXExpression::EmptyExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::BooleanLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::NullLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::NumericLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::BigIntLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::RegExpLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::StringLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::TemplateLiteral(x) => Serialize::serialize(x, serializer), + JSXExpression::Identifier(x) => Serialize::serialize(x, serializer), + JSXExpression::MetaProperty(x) => Serialize::serialize(x, serializer), + JSXExpression::Super(x) => Serialize::serialize(x, serializer), + JSXExpression::ArrayExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ArrowFunctionExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::AssignmentExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::AwaitExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::BinaryExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::CallExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ChainExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ClassExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ConditionalExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::FunctionExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ImportExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::LogicalExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::NewExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ObjectExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ParenthesizedExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::SequenceExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::TaggedTemplateExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ThisExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::UnaryExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::UpdateExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::YieldExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::PrivateInExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::JSXElement(x) => Serialize::serialize(x, serializer), + JSXExpression::JSXFragment(x) => Serialize::serialize(x, serializer), + JSXExpression::TSAsExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::TSSatisfiesExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::TSTypeAssertion(x) => Serialize::serialize(x, serializer), + JSXExpression::TSNonNullExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::TSInstantiationExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::ComputedMemberExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::StaticMemberExpression(x) => Serialize::serialize(x, serializer), + JSXExpression::PrivateFieldExpression(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXExpression = JSXEmptyExpression | BooleanLiteral | NullLiteral | NumericLiteral | BigIntLiteral | RegExpLiteral | StringLiteral | TemplateLiteral | IdentifierReference | MetaProperty | Super | ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AwaitExpression | BinaryExpression | CallExpression | ChainExpression | Class | ConditionalExpression | Function | ImportExpression | LogicalExpression | NewExpression | ObjectExpression | ParenthesizedExpression | SequenceExpression | TaggedTemplateExpression | ThisExpression | UnaryExpression | UpdateExpression | YieldExpression | PrivateInExpression | JSXElement | JSXFragment | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression | TSInstantiationExpression | ComputedMemberExpression | StaticMemberExpression | PrivateFieldExpression;"; + +impl Serialize for JSXEmptyExpression { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXEmptyExpression")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXEmptyExpression = ({\n\ttype: 'JSXEmptyExpression';\n}) & Span;"; + +impl<'a> Serialize for JSXAttributeItem<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + JSXAttributeItem::Attribute(x) => Serialize::serialize(x, serializer), + JSXAttributeItem::SpreadAttribute(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXAttributeItem = JSXAttribute | JSXSpreadAttribute;"; + +impl<'a> Serialize for JSXAttribute<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXAttribute")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXAttribute = ({\n\ttype: 'JSXAttribute';\n\tname: JSXAttributeName;\n\tvalue: (JSXAttributeValue) | null;\n}) & Span;"; + +impl<'a> Serialize for JSXSpreadAttribute<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXSpreadAttribute")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("argument", &self.argument)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXSpreadAttribute = ({\n\ttype: 'JSXSpreadAttribute';\n\targument: Expression;\n}) & Span;"; + +impl<'a> Serialize for JSXAttributeName<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + JSXAttributeName::Identifier(x) => Serialize::serialize(x, serializer), + JSXAttributeName::NamespacedName(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXAttributeName = JSXIdentifier | JSXNamespacedName;"; + +impl<'a> Serialize for JSXAttributeValue<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + JSXAttributeValue::StringLiteral(x) => Serialize::serialize(x, serializer), + JSXAttributeValue::ExpressionContainer(x) => Serialize::serialize(x, serializer), + JSXAttributeValue::Element(x) => Serialize::serialize(x, serializer), + JSXAttributeValue::Fragment(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXAttributeValue = StringLiteral | JSXExpressionContainer | JSXElement | JSXFragment;"; + +impl<'a> Serialize for JSXIdentifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXIdentifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXIdentifier = ({\n\ttype: 'JSXIdentifier';\n\tname: string;\n}) & Span;"; + +impl<'a> Serialize for JSXChild<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + JSXChild::Text(x) => Serialize::serialize(x, serializer), + JSXChild::Element(x) => Serialize::serialize(x, serializer), + JSXChild::Fragment(x) => Serialize::serialize(x, serializer), + JSXChild::ExpressionContainer(x) => Serialize::serialize(x, serializer), + JSXChild::Spread(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXChild = JSXText | JSXElement | JSXFragment | JSXExpressionContainer | JSXSpreadChild;"; + +impl<'a> Serialize for JSXSpreadChild<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXSpreadChild")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("expression", &self.expression)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type JSXSpreadChild = ({\n\ttype: 'JSXSpreadChild';\n\texpression: Expression;\n}) & Span;"; + +impl<'a> Serialize for JSXText<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "JSXText")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type JSXText = ({\n\ttype: 'JSXText';\n\tvalue: string;\n}) & Span;"; diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index eab91afe0b717..a5527fa3f0618 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -43,6 +43,8 @@ mod generated { pub mod derive_clone_in; pub mod derive_content_eq; pub mod derive_content_hash; + #[cfg(feature = "serialize")] + pub mod derive_estree; pub mod derive_get_span; pub mod derive_get_span_mut; pub mod visit; diff --git a/crates/oxc_ast/src/serialize.rs b/crates/oxc_ast/src/serialize.rs index 12b3b4fcfa8f3..a797dfdd2c05c 100644 --- a/crates/oxc_ast/src/serialize.rs +++ b/crates/oxc_ast/src/serialize.rs @@ -60,6 +60,9 @@ impl Serialize for Elision { serializer.serialize_none() } } +#[cfg(feature = "serialize")] +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Elision = null;"; /// Serialize `ArrayAssignmentTarget`, `ObjectAssignmentTarget`, `ObjectPattern`, `ArrayPattern` /// to be estree compatible, with `elements`/`properties` and `rest` fields combined. @@ -156,6 +159,17 @@ impl<'a> Serialize for FormalParameters<'a> { } } +#[cfg(feature = "serialize")] +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = r#" +export type FormalParameterRest = ({ + type: "RestElement", + argument: BindingPatternKind, + typeAnnotation: TSTypeAnnotation | null, + optional: boolean, +}) & Span; +"#; + #[derive(Serialize)] #[serde(tag = "type", rename = "FormalParameters")] struct SerFormalParameters<'a, 'b> { diff --git a/crates/oxc_ast_macros/CHANGELOG.md b/crates/oxc_ast_macros/CHANGELOG.md index 6f9daff9860b8..5444086749ae9 100644 --- a/crates/oxc_ast_macros/CHANGELOG.md +++ b/crates/oxc_ast_macros/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) + ## [0.30.0] - 2024-09-23 ### Refactor diff --git a/crates/oxc_ast_macros/Cargo.toml b/crates/oxc_ast_macros/Cargo.toml index 27cda301d9522..61bcf54da34c0 100644 --- a/crates/oxc_ast_macros/Cargo.toml +++ b/crates/oxc_ast_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_ast_macros" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_ast_macros/src/ast.rs b/crates/oxc_ast_macros/src/ast.rs index 083233f874390..3354fd07017ab 100644 --- a/crates/oxc_ast_macros/src/ast.rs +++ b/crates/oxc_ast_macros/src/ast.rs @@ -81,6 +81,8 @@ fn abs_trait( (quote!(::oxc_span::cmp::ContentEq), TokenStream::default()) } else if ident == "ContentHash" { (quote!(::oxc_span::hash::ContentHash), TokenStream::default()) + } else if ident == "ESTree" { + (quote!(::oxc_estree::ESTree), TokenStream::default()) } else { invalid_derive(ident) } diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index f657bff3281d2..4e6d6a21fddfd 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -81,7 +81,7 @@ pub fn ast(_args: TokenStream, input: TokenStream) -> TokenStream { /// The only purpose is to allow the occurrence of helper attributes used with the `tasks/ast_tools`. /// /// Read [`macro@ast`] for further details. -#[proc_macro_derive(Ast, attributes(scope, visit, span, generate_derive, clone_in, serde, tsify))] +#[proc_macro_derive(Ast, attributes(scope, visit, span, generate_derive, clone_in, estree, tsify))] pub fn ast_derive(_input: TokenStream) -> TokenStream { TokenStream::new() } diff --git a/crates/oxc_cfg/Cargo.toml b/crates/oxc_cfg/Cargo.toml index e4c072975bd9a..11b4511e8ffcb 100644 --- a/crates/oxc_cfg/Cargo.toml +++ b/crates/oxc_cfg/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_cfg" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_codegen/CHANGELOG.md b/crates/oxc_codegen/CHANGELOG.md index 217d4f57d7e28..17cb990bb6159 100644 --- a/crates/oxc_codegen/CHANGELOG.md +++ b/crates/oxc_codegen/CHANGELOG.md @@ -4,6 +4,65 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- c0e9d7e codegen: [**BREAKING**] `Codegen::into_source_text` consume `Codegen` (#6539) (overlookmotel) + +- 782f0a7 codegen: [**BREAKING**] Rename `print_char` method to `print_ascii_byte` (#6512) (overlookmotel) + +- 91c87dd codegen: [**BREAKING**] Remove `Codegen::enableSourceMap` API (#6452) (Boshen) + +- 7645e5c codegen: [**BREAKING**] Remove CommentOptions API (#6451) (Boshen) + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +### Features + +- e5ed6a5 codegen: Print negative numbers (#6624) (Boshen) + +### Bug Fixes + +- ba385fc codegen: Panic occurred when printing the comment of the right parenthesis (#6593) (Dunqing) +- 02bfbfe codegen: Preserve parenthesis for `ChainExpression` (#6430) (Dunqing) +- 2ade16e codegen: Invalid codegen when `in` inside bin expr in or loop (#6431) (camc314) +- 6896efc codegen: Fix `in` in sequence expr in for loops (#6428) (camc314) + +### Performance + +- 77f3a1a codegen: Check last char with byte methods (#6509) (overlookmotel) +- 18b68ff codegen: Optimize `CodeBuffer::print_ascii_byte` (#6516) (overlookmotel) + +### Documentation + +- 7e909a7 codegen: Fix example for `CodeBuffer::print_ascii_bytes` (#6535) (overlookmotel) +- 235d357 codegen: Improve doc comments for `CodeBuffer` (#6511) (overlookmotel) +- c8fa2eb codegen: Correct and reformat doc comments for `CodeBuffer` (#6504) (overlookmotel) +- 40d1ee4 codegen: Fix and reformat `CodeBuffer` examples (#6499) (overlookmotel) + +### Refactor + +- 51fc63d codegen: Rename `CodeBuffer::print_bytes_unchecked` method (#6517) (overlookmotel) +- 05a2ebd codegen: Reorder dependencies in `Cargo.toml` (#6514) (overlookmotel) +- e7f3e28 codegen: Rename var in `CodeBuffer` (#6510) (overlookmotel) +- 1bbd383 codegen: Rename `CodeBuffer::print_ascii_bytes` method (#6507) (overlookmotel) +- cd9fe9e codegen: Rename vars in `CodeBuffer` methods (#6506) (overlookmotel) +- fc536a5 codegen: Inline `CodeBuffer` methods (#6501) (overlookmotel) +- 7420620 codegen: Add `CodeBuffer::as_bytes` method (#6498) (overlookmotel) +- 8ae174b codegen: Rename `CodeBuffer::print_byte_unchecked` method (#6496) (overlookmotel) +- 5843e01 codegen: Shorten `CodeBuffer::take_source_text` (#6495) (overlookmotel) +- 951def6 codegen: Clarify safety comments in `CodeBuffer` (#6494) (overlookmotel) +- 84a51ee codegen: Rename vars in `CodeBuffer` (#6493) (overlookmotel) +- 05bd616 codegen: Add line break (#6492) (overlookmotel) +- 204bf55 codegen: Add `CodeBuffer` to fix soundness hole (#6148) (DonIsaac) +- 702b574 codegen: Only print necessary parentheses in TSAsExpression (#6429) (Dunqing) +- f4cdc56 minifier: Use constant folding unary expression from `oxc_ecmascript` (#6647) (Boshen) +- 1a90ec4 rust: Backport v1.82.0 changes to main branch first (#6690) (Boshen) + +### Testing + +- e7c89a5 codegen: Uncomment passed tests that are related to trailing comments (#6589) (Dunqing) +- d816b0b codegen: Add test for `CodeBuffer::print_byte_unchecked` (#6497) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 020bb80 codegen: [**BREAKING**] Change to `CodegenReturn::code` and `CodegenReturn::map` (#6310) (Boshen) diff --git a/crates/oxc_codegen/Cargo.toml b/crates/oxc_codegen/Cargo.toml index 1ba96c14f8414..86677f280036e 100644 --- a/crates/oxc_codegen/Cargo.toml +++ b/crates/oxc_codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_codegen" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 560f94466b9aa..80b78171ccfb4 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -846,46 +846,43 @@ impl<'a> Gen for ExportNamedDeclaration<'a> { if self.export_kind.is_type() { p.print_str("type "); } - match &self.declaration { - Some(decl) => { - match decl { - Declaration::VariableDeclaration(decl) => decl.print(p, ctx), - Declaration::FunctionDeclaration(decl) => decl.print(p, ctx), - Declaration::ClassDeclaration(decl) => decl.print(p, ctx), - Declaration::TSModuleDeclaration(decl) => decl.print(p, ctx), - Declaration::TSTypeAliasDeclaration(decl) => decl.print(p, ctx), - Declaration::TSInterfaceDeclaration(decl) => decl.print(p, ctx), - Declaration::TSEnumDeclaration(decl) => decl.print(p, ctx), - Declaration::TSImportEqualsDeclaration(decl) => decl.print(p, ctx), - } - if matches!( - decl, - Declaration::VariableDeclaration(_) - | Declaration::TSTypeAliasDeclaration(_) - | Declaration::TSImportEqualsDeclaration(_) - ) { - p.print_semicolon_after_statement(); - } else { - p.print_soft_newline(); - p.needs_semicolon = false; - } - } - None => { - p.print_ascii_byte(b'{'); - if !self.specifiers.is_empty() { - p.print_soft_space(); - p.print_list(&self.specifiers, ctx); - p.print_soft_space(); - } - p.print_ascii_byte(b'}'); - if let Some(source) = &self.source { - p.print_soft_space(); - p.print_str("from"); - p.print_soft_space(); - source.print(p, ctx); - } + if let Some(decl) = &self.declaration { + match decl { + Declaration::VariableDeclaration(decl) => decl.print(p, ctx), + Declaration::FunctionDeclaration(decl) => decl.print(p, ctx), + Declaration::ClassDeclaration(decl) => decl.print(p, ctx), + Declaration::TSModuleDeclaration(decl) => decl.print(p, ctx), + Declaration::TSTypeAliasDeclaration(decl) => decl.print(p, ctx), + Declaration::TSInterfaceDeclaration(decl) => decl.print(p, ctx), + Declaration::TSEnumDeclaration(decl) => decl.print(p, ctx), + Declaration::TSImportEqualsDeclaration(decl) => decl.print(p, ctx), + } + if matches!( + decl, + Declaration::VariableDeclaration(_) + | Declaration::TSTypeAliasDeclaration(_) + | Declaration::TSImportEqualsDeclaration(_) + ) { p.print_semicolon_after_statement(); + } else { + p.print_soft_newline(); + p.needs_semicolon = false; + } + } else { + p.print_ascii_byte(b'{'); + if !self.specifiers.is_empty() { + p.print_soft_space(); + p.print_list(&self.specifiers, ctx); + p.print_soft_space(); } + p.print_ascii_byte(b'}'); + if let Some(source) = &self.source { + p.print_soft_space(); + p.print_str("from"); + p.print_soft_space(); + source.print(p, ctx); + } + p.print_semicolon_after_statement(); } } } diff --git a/crates/oxc_data_structures/CHANGELOG.md b/crates/oxc_data_structures/CHANGELOG.md index 0ceb2dd4bb11f..0ae9527395d30 100644 --- a/crates/oxc_data_structures/CHANGELOG.md +++ b/crates/oxc_data_structures/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Bug Fixes + +- 7cc05f1 data_structures: Fix compilation failure on older Rust versions (#6526) (overlookmotel) + +### Documentation + +- de22b81 data-structures: Enable lint warnings on missing docs, and add missing doc comments (#6612) (DonIsaac) + ## [0.31.0] - 2024-10-08 ### Features diff --git a/crates/oxc_data_structures/Cargo.toml b/crates/oxc_data_structures/Cargo.toml index 9f387c7889bce..cc08c30aa2c17 100644 --- a/crates/oxc_data_structures/Cargo.toml +++ b/crates/oxc_data_structures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_data_structures" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_diagnostics/Cargo.toml b/crates/oxc_diagnostics/Cargo.toml index f5bf592cad930..eca9df371aca9 100644 --- a/crates/oxc_diagnostics/Cargo.toml +++ b/crates/oxc_diagnostics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_diagnostics" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_ecmascript/CHANGELOG.md b/crates/oxc_ecmascript/CHANGELOG.md index 9cbef2906d6da..6fcf1b7272ccd 100644 --- a/crates/oxc_ecmascript/CHANGELOG.md +++ b/crates/oxc_ecmascript/CHANGELOG.md @@ -4,6 +4,28 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- 15c04e5 ecmascript: Add feature flag for constant evaluation (Boshen) +- d11770d ecmascript: Add `StringToNumber` (#6576) (Boshen) +- e561880 ecmascript: Add constant_evaluation and side_effects code (#6550) (Boshen) +- 3556062 ecmascript: Add `ConstantEvaluation` (#6549) (Boshen) +- 39c2e66 ecmascript: Add `ToBigInt` and `StringToBigInt` (#6508) (Boshen) +- 6f22538 ecmascript: Add `ToBoolean`, `ToNumber`, `ToString` (#6502) (Boshen) +- 071e564 minifier: Finish implementing folding object expressions (#6586) (camc314) +- 096e590 minifier: Implement folding `charAt` string fns (#6436) (camc314) + +### Refactor + +- aa6ba24 ecmascript: Improve string to number conversion (#6577) (magic-akari) +- 6d041fb ecmascript: Remove `NumberValue` (#6519) (Boshen) +- 856cab5 ecmascript: Move ToInt32 from `oxc_syntax` to `oxc_ecmascript` (#6471) (Boshen) +- 1ba2a24 ecmascript: Remove `HasProto` which is not part of the spec (#6470) (Boshen) +- f4cdc56 minifier: Use constant folding unary expression from `oxc_ecmascript` (#6647) (Boshen) +- bbca743 minifier: Move string methods to `oxc_ecmascript` (#6472) (Boshen) + ## [0.31.0] - 2024-10-08 ### Features diff --git a/crates/oxc_ecmascript/Cargo.toml b/crates/oxc_ecmascript/Cargo.toml index 124e4672b9c49..b6f6382d98adb 100644 --- a/crates/oxc_ecmascript/Cargo.toml +++ b/crates/oxc_ecmascript/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_ecmascript" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_estree/CHANGELOG.md b/crates/oxc_estree/CHANGELOG.md new file mode 100644 index 0000000000000..b039cb23de975 --- /dev/null +++ b/crates/oxc_estree/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this package will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. + +## [0.32.0] - 2024-10-19 + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) + diff --git a/crates/oxc_estree/Cargo.toml b/crates/oxc_estree/Cargo.toml new file mode 100644 index 0000000000000..550e1fe25b002 --- /dev/null +++ b/crates/oxc_estree/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "oxc_estree" +version = "0.32.0" +authors.workspace = true +categories.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +publish = true +repository.workspace = true +rust-version.workspace = true +description.workspace = true + +[dependencies] + +[lints] +workspace = true diff --git a/crates/oxc_estree/src/lib.rs b/crates/oxc_estree/src/lib.rs new file mode 100644 index 0000000000000..9841846ee7278 --- /dev/null +++ b/crates/oxc_estree/src/lib.rs @@ -0,0 +1,3 @@ +/// Empty trait that will be used later for custom serialization and TypeScript +/// generation for AST nodes. +pub trait ESTree {} diff --git a/crates/oxc_index/Cargo.toml b/crates/oxc_index/Cargo.toml index 3556f0cd46981..96991d86b2929 100644 --- a/crates/oxc_index/Cargo.toml +++ b/crates/oxc_index/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_index" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_isolated_declarations/CHANGELOG.md b/crates/oxc_isolated_declarations/CHANGELOG.md index f9d05d4070677..b39fc01a7ff5a 100644 --- a/crates/oxc_isolated_declarations/CHANGELOG.md +++ b/crates/oxc_isolated_declarations/CHANGELOG.md @@ -4,6 +4,28 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 7645e5c codegen: [**BREAKING**] Remove CommentOptions API (#6451) (Boshen) + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +- 2808973 ast: [**BREAKING**] Add `Program::comments` (#6445) (Boshen) + +### Features + +- 15dfc1d isolated-declarations: Impl `Default` for options (#6372) (DonIsaac) + +### Bug Fixes + +- 2673397 isolated_declarations: Fix potential memory leak (#6622) (overlookmotel) + +### Refactor + +- 073b02a ast: Type params field before params in TS function declaration types (#6391) (overlookmotel) +- 856cab5 ecmascript: Move ToInt32 from `oxc_syntax` to `oxc_ecmascript` (#6471) (Boshen) +- a504f96 isolated-declarations: Mark return struct as non exhaustive (#6374) (DonIsaac) + ## [0.31.0] - 2024-10-08 - 020bb80 codegen: [**BREAKING**] Change to `CodegenReturn::code` and `CodegenReturn::map` (#6310) (Boshen) diff --git a/crates/oxc_isolated_declarations/Cargo.toml b/crates/oxc_isolated_declarations/Cargo.toml index 481b30485bd5e..4ebf89c20d145 100644 --- a/crates/oxc_isolated_declarations/Cargo.toml +++ b/crates/oxc_isolated_declarations/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_isolated_declarations" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_linter/CHANGELOG.md b/crates/oxc_linter/CHANGELOG.md index 677bd365739be..d60aeba9e96be 100644 --- a/crates/oxc_linter/CHANGELOG.md +++ b/crates/oxc_linter/CHANGELOG.md @@ -4,6 +4,91 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.10.0] - 2024-10-18 + +- 782f0a7 codegen: [**BREAKING**] Rename `print_char` method to `print_ascii_byte` (#6512) (overlookmotel) + +- 7645e5c codegen: [**BREAKING**] Remove CommentOptions API (#6451) (Boshen) + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +- 80266d8 linter: [**BREAKING**] Support plugins in oxlint config files (#6088) (DonIsaac) + +### Features + +- 6f22538 ecmascript: Add `ToBoolean`, `ToNumber`, `ToString` (#6502) (Boshen) +- 1e7fab3 linter: Implement `no-callback-in-promise` (#6157) (dalaoshu) +- c56343d linter: Promote `no_unsafe_optional_chaining` to correctness (#6491) (Boshen) +- 454874a linter: Implement `react/iframe-missing-sandbox` (#6383) (Radu Baston) +- c8174e2 linter: Add suggestions for `no-plusplus` (#6376) (camchenry) +- 6e3224d linter: Configure by category in config files (#6120) (DonIsaac) +- c5e66e1 linter/no-unused-vars: Report own type references within class, interface, and type alias declarations (#6557) (DonIsaac) +- 8c78f97 linter/node: Implement no-new-require (#6165) (Jelle van der Waa) + +### Bug Fixes + +- e340424 linter: Support import type with namespaced import in `import/no-duplicates` (#6650) (Dmitry Zakharov) +- a668397 linter: Panic in `no-else-return` (#6648) (dalaoshu) +- 41dc8e3 linter: Stack overflow in `oxc/no-async-endpoint-handlers` (#6614) (DonIsaac) +- d07a9b0 linter: Panic in `no-zero-fractions` (#6607) (dalaoshu) +- d6a0d2e linter: Fix file name checking behavior of `unicorn/filename-case` (#6463) (camchenry) +- 0784e74 linter: Error fixer of `switch-case-braces` (#6474) (dalaoshu) +- e811812 linter: Error diagnostic message based on parameter length of valid-expect (#6455) (dalaoshu) +- f71c91e linter: Move `eslint/sort-keys` to `style` category (#6377) (DonIsaac) +- 2b86de9 linter/no-control-regex: False negative for flags in template literals (#6531) (DonIsaac) +- 685a590 linter/no-control-regex: Better diagnostic messages (#6530) (DonIsaac) +- 6d5a9f2 linter/no-control-regex: Allow capture group references (#6529) (DonIsaac) +- ba53bc9 linter/no-unused-vars: False positives in TS type assertions (#6397) (DonIsaac) +- d3e59c6 linter/no-unused-vars: False positive in some default export cases (#6395) (DonIsaac) +- e08f956 linter/no-unused-vars: False positive for functions and classes in arrays (#6394) (DonIsaac) +- b9d7c5f no-unused-vars: Consider functions within conditional expressions usable (#6553) (Brian Donovan) + +### Performance + +- 0cbd4d0 linter: Avoid megamorphism in `RuleFixer` methods (#6606) (DonIsaac) +- 725f9f6 linter: Get fewer parent nodes in `unicorn/prefer-dom-node-text-content` (#6467) (camchenry) +- c00f669 linter: Use NonZeroUsize for pending module cache entries (#6439) (DonIsaac) +- a1a2721 linter: Replace `ToString::to_string` with `CompactStr` in remaining rules (#6407) (camchenry) +- c5c69d6 linter: Use `CompactStr` in `valid-title` (#6406) (camchenry) +- d66e826 linter: Use `CompactStr` in `prefer-lowercase-title` (#6405) (camchenry) +- 889400c linter: Use `CompactStr` for `get_node_name` in Jest rules (#6403) (camchenry) +- 9906849 linter: Use `CompactStr` in `no-large-snapshots` (#6402) (camchenry) +- c382ec4 linter: Use `CompactStr` in `no-hooks` (#6401) (camchenry) +- 24a5d9b linter: Use `CompactStr` in `expect-expect` (#6400) (camchenry) +- 71dbdad linter: Use `CompactStr` in `no-console` (#6399) (camchenry) +- f5f00a1 linter: Use `CompactStr` in `no-bitwise` (#6398) (camchenry) +- 62afaa9 linter/jsx-no-comment-textnodes: Remove regex for checking comment patterns (#6534) (camchenry) +- b3d0cce linter/no-unescaped-entities: Add fast path to check if char should be replaced (#6594) (camchenry) +- ee73f56 linter/no-unused-vars: Do not construct `Regex` for default ignore pattern (#6590) (camchenry) +- 77ddab8 linter/numeric-separators-style: Replace regex with number parser (#6546) (camchenry) +- 8f47cd0 linter/react: Remove regex patterns in `no-unknown-property` (#6536) (camchenry) + +### Documentation + +- 557f941 linter: Add docs to no-unused-vars and Tester (#6558) (DonIsaac) + +### Refactor + +- ecce5c5 linter: Improve recursive argument handling and diagnostics creation (#6513) (no-yan) +- f960e9e linter: Add suggested file names for `unicorn/filename-case` (#6465) (camchenry) +- 7240ee2 linter: Make advertised fix kinds consistent (#6461) (Alexander S.) +- b48c368 linter: `no_global_assign` rule: reduce name lookups (#6460) (overlookmotel) +- 2566ce7 linter: Remove OxlintOptions (#6098) (DonIsaac) +- 002078a linter: Make Runtime's members private (#6440) (DonIsaac) +- 6a0a533 linter: Move module cache logic out of Runtime (#6438) (DonIsaac) +- c18c6e9 linter: Split service code into separate modules (#6437) (DonIsaac) +- 5ea9ef7 linter: Improve labels and help message for `eslint/no-useless-constructor` (#6389) (DonIsaac) +- 2c32dac linter/no-control-regex: Remove duplicate code (#6527) (DonIsaac) +- 435a89c oxc: Remove useless `allocator.alloc(program)` calls (#6571) (Boshen) +- f70e93b oxc: Ban index methods on std::str::Chars (#6075) (dalaoshu) + +### Testing + +- a6cae98 linter: Make sure all auto-fixing rules have fixer test (#6378) (DonIsaac) +- 06b09b2 linter/no-unused-vars: Enable now-passing tests (#6556) (DonIsaac) +- badd11c linter/no-unused-vars: Ignored catch parameters (#6555) (DonIsaac) +- 84aa2a2 linter/no-useless-constructor: Add cases for initializers in subclass constructors (#6390) (DonIsaac) + ## [0.9.10] - 2024-10-07 - 5a73a66 regular_expression: [**BREAKING**] Simplify public APIs (#6262) (leaysgur) diff --git a/crates/oxc_linter/Cargo.toml b/crates/oxc_linter/Cargo.toml index 5303d2cd715ba..b2e74c9321dae 100644 --- a/crates/oxc_linter/Cargo.toml +++ b/crates/oxc_linter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_linter" -version = "0.9.10" +version = "0.10.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_linter/src/disable_directives.rs b/crates/oxc_linter/src/disable_directives.rs index 812229f1919b6..3f8ffe115b2f6 100644 --- a/crates/oxc_linter/src/disable_directives.rs +++ b/crates/oxc_linter/src/disable_directives.rs @@ -134,10 +134,10 @@ impl<'a> DisableDirectivesBuilder<'a> { // `eslint-disable-line` else if let Some(text) = text.strip_prefix("-line") { // Get the span between the preceding newline to this comment - let start = source_text[..=comment.span.start as usize] + let start = source_text[..comment.span.start as usize] .lines() .next_back() - .map_or(0, |line| comment.span.start - (line.len() as u32 - 1)); + .map_or(0, |line| comment.span.start - line.len() as u32); let stop = comment.span.start; // `eslint-disable-line` @@ -430,7 +430,8 @@ fn test() { format!(" /* {prefix}-disable , ,no-debugger, , */ debugger; - ") + "), + format!("debugger;//…{prefix}-disable-line") ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/eslint/no_cond_assign.rs b/crates/oxc_linter/src/rules/eslint/no_cond_assign.rs index 25ea98eaa0610..122d6914a8773 100644 --- a/crates/oxc_linter/src/rules/eslint/no_cond_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_cond_assign.rs @@ -78,21 +78,46 @@ impl Rule for NoCondAssign { self.check_expression(ctx, expr.test.get_inner_expression()); } AstKind::AssignmentExpression(expr) if self.config == NoCondAssignConfig::Always => { - for node_id in ctx.nodes().ancestors(node.id()).skip(1) { - match ctx.nodes().kind(node_id) { - AstKind::IfStatement(_) - | AstKind::WhileStatement(_) - | AstKind::DoWhileStatement(_) - | AstKind::ForStatement(_) - | AstKind::ConditionalExpression(_) => { - Self::emit_diagnostic(ctx, expr); + let mut spans = vec![]; + for ancestor in ctx.nodes().iter_parents(node.id()).skip(1) { + match ancestor.kind() { + AstKind::IfStatement(if_stmt) => { + spans.push(if_stmt.test.span()); + } + AstKind::WhileStatement(while_stmt) => { + spans.push(while_stmt.test.span()); + } + AstKind::DoWhileStatement(do_while_stmt) => { + spans.push(do_while_stmt.test.span()); + } + AstKind::ForStatement(for_stmt) => { + if let Some(test) = &for_stmt.test { + spans.push(test.span()); + } + if let Some(update) = &for_stmt.update { + spans.push(update.span()); + } + if let Some(update) = &for_stmt.update { + spans.push(update.span()); + } + } + AstKind::ConditionalExpression(cond_expr) => { + spans.push(cond_expr.span()); } AstKind::Function(_) | AstKind::ArrowFunctionExpression(_) | AstKind::Program(_) - | AstKind::BlockStatement(_) => break, + | AstKind::BlockStatement(_) => { + break; + } _ => {} - } + }; + } + + // Only report the diagnostic if the assignment is in a span where it should not be. + // For example, report `if (a = b) { ...}`, not `if (...) { a = b }` + if spans.iter().any(|span| span.contains_inclusive(node.span())) { + Self::emit_diagnostic(ctx, expr); } } _ => {} @@ -177,6 +202,29 @@ fn test() { ("for (;;) { (obj.key=false) }", Some(serde_json::json!(["always"]))), ("while (obj.key) { (obj.key=false) }", Some(serde_json::json!(["always"]))), ("do { (obj.key=false) } while (obj.key)", Some(serde_json::json!(["always"]))), + // https://github.com/oxc-project/oxc/issues/6656 + ( + " + if (['a', 'b', 'c', 'd'].includes(value)) newValue = value; + else newValue = 'default'; + ", + Some(serde_json::json!(["always"])), + ), + ( + " + while(true) newValue = value; + ", + Some(serde_json::json!(["always"])), + ), + ( + " + for(;;) newValue = value; + ", + Some(serde_json::json!(["always"])), + ), + ("for (; (typeof l === 'undefined' ? (l = 0) : l); i++) { }", None), + ("for (x = 0;x<10;x++) { x = 0 }", None), + ("for (x = 0;x<10;(x = x + 1)) { x = 0 }", None), ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_labels.rs b/crates/oxc_linter/src/rules/eslint/no_unused_labels.rs index 63c953a479e5a..140d7fa04ca7e 100644 --- a/crates/oxc_linter/src/rules/eslint/no_unused_labels.rs +++ b/crates/oxc_linter/src/rules/eslint/no_unused_labels.rs @@ -39,9 +39,6 @@ declare_oxc_lint!( impl Rule for NoUnusedLabels { fn run_once(&self, ctx: &LintContext) { - if ctx.file_path().extension().is_some_and(|ext| ext == "svelte") { - return; - } for id in ctx.semantic().unused_labels() { let node = ctx.semantic().nodes().get_node(*id); let AstKind::LabeledStatement(stmt) = node.kind() else { @@ -53,6 +50,10 @@ impl Rule for NoUnusedLabels { ); } } + + fn should_run(&self, ctx: &crate::context::ContextHost) -> bool { + ctx.file_path().extension().is_some_and(|ext| ext != "svelte") + } } #[test] diff --git a/crates/oxc_linter/src/rules/jest/no_untyped_mock_factory.rs b/crates/oxc_linter/src/rules/jest/no_untyped_mock_factory.rs index 0d1b5be2bd669..50b414ecb54c7 100644 --- a/crates/oxc_linter/src/rules/jest/no_untyped_mock_factory.rs +++ b/crates/oxc_linter/src/rules/jest/no_untyped_mock_factory.rs @@ -93,14 +93,14 @@ declare_oxc_lint!( impl Rule for NoUntypedMockFactory { fn run_once(&self, ctx: &LintContext<'_>) { - if !ctx.source_type().is_typescript() { - return; - } - for possible_jest_node in &collect_possible_jest_call_node(ctx) { Self::run(possible_jest_node, ctx); } } + + fn should_run(&self, ctx: &crate::context::ContextHost) -> bool { + ctx.source_type().is_typescript() + } } impl NoUntypedMockFactory { diff --git a/crates/oxc_linter/src/rules/typescript/no_namespace.rs b/crates/oxc_linter/src/rules/typescript/no_namespace.rs index 3935d3839df2d..74e4c86357d3c 100644 --- a/crates/oxc_linter/src/rules/typescript/no_namespace.rs +++ b/crates/oxc_linter/src/rules/typescript/no_namespace.rs @@ -83,10 +83,6 @@ impl Rule for NoNamespace { return; } - if self.allow_definition_files && ctx.source_type().is_typescript_definition() { - return; - } - let declaration_code = declaration.span.source_text(ctx.source_text()); let span = match declaration.kind { @@ -104,6 +100,9 @@ impl Rule for NoNamespace { } fn should_run(&self, ctx: &ContextHost) -> bool { + if self.allow_definition_files && ctx.source_type().is_typescript_definition() { + return false; + } ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/snapshots/no_cond_assign.snap b/crates/oxc_linter/src/snapshots/no_cond_assign.snap index f4454baf92c39..dbabaaea944e4 100644 --- a/crates/oxc_linter/src/snapshots/no_cond_assign.snap +++ b/crates/oxc_linter/src/snapshots/no_cond_assign.snap @@ -64,13 +64,6 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Consider wrapping the assignment in additional parentheses - ⚠ eslint(no-cond-assign): Expected a conditional expression and instead saw an assignment - ╭─[no_cond_assign.tsx:1:39] - 1 │ for (; (typeof l === 'undefined' ? (l = 0) : l); i++) { } - · ─ - ╰──── - help: Consider wrapping the assignment in additional parentheses - ⚠ eslint(no-cond-assign): Expected a conditional expression and instead saw an assignment ╭─[no_cond_assign.tsx:1:7] 1 │ if (x = 0) { } diff --git a/crates/oxc_mangler/Cargo.toml b/crates/oxc_mangler/Cargo.toml index 26d0e07f5f28c..2c49740a484a1 100644 --- a/crates/oxc_mangler/Cargo.toml +++ b/crates/oxc_mangler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_mangler" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_minifier/CHANGELOG.md b/crates/oxc_minifier/CHANGELOG.md index 15343318a5196..7965c8a468385 100644 --- a/crates/oxc_minifier/CHANGELOG.md +++ b/crates/oxc_minifier/CHANGELOG.md @@ -4,6 +4,58 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- e5ed6a5 codegen: Print negative numbers (#6624) (Boshen) +- 15c04e5 ecmascript: Add feature flag for constant evaluation (Boshen) +- e561880 ecmascript: Add constant_evaluation and side_effects code (#6550) (Boshen) +- 3556062 ecmascript: Add `ConstantEvaluation` (#6549) (Boshen) +- 39c2e66 ecmascript: Add `ToBigInt` and `StringToBigInt` (#6508) (Boshen) +- 6f22538 ecmascript: Add `ToBoolean`, `ToNumber`, `ToString` (#6502) (Boshen) +- 071e564 minifier: Finish implementing folding object expressions (#6586) (camc314) +- 590925a minifier: Finish implementing folding array expressions (#6575) (camc314) +- ef237cf minifier: Complete implementation of statement fusion (#6566) (camc314) +- 97c8a36 minifier: Implement `collapse-variable-declarations` (#6464) (dalaoshu) +- 096e590 minifier: Implement folding `charAt` string fns (#6436) (camc314) +- e5a6f5d minifier: Implement converting template literals to strings (#6486) (camc314) +- 14d0590 minifier: Implement folding of simple function calls (`Boolean`) (#6484) (camc314) +- 7fbc7b6 minifier: Implement folding of simple function calls (`String`) (#6483) (camc314) +- a4f57a4 minifier: Implement folding `indexOf` and `lastIndexOf` string fns (#6435) (camc314) +- 3677ef8 minifier: Dce ExpressionStatements with no side effect (#6457) (7086cmd) +- 06ea121 minifier: Fold for statement (#6450) (7086cmd) +- a9544ae minifier: Partially implement minification for some known string methods (#6424) (camc314) +- 9dc4ee9 minifier: Implement block stmt support for `StatementFusion` (#6422) (camc314) +- ebbf77d minifier: Implement calculations for NumberValue (#6419) (7086cmd) +- 97ac179 minifier: Arithmetic operations for infinity. (#6332) (7086cmd) +- 13b0b0b minifier: Fold literal object constructors on window (#6379) (dalaoshu) + +### Bug Fixes + +- 389d261 minifier: `~~` operator should only work on numbers (#6598) (Boshen) +- 16bea12 minifier: Use `to_js_string()` instead of `fs64::to_string` (#6597) (Boshen) +- a71e8a0 minifier: Preserve init variable declarations when removing `for` statements during DCE (#6551) (magic-akari) + +### Refactor + +- 6d041fb ecmascript: Remove `NumberValue` (#6519) (Boshen) +- 856cab5 ecmascript: Move ToInt32 from `oxc_syntax` to `oxc_ecmascript` (#6471) (Boshen) +- f4cdc56 minifier: Use constant folding unary expression from `oxc_ecmascript` (#6647) (Boshen) +- 67ad08a minifier: Unify `ValueType` (#6545) (Boshen) +- bbca743 minifier: Move string methods to `oxc_ecmascript` (#6472) (Boshen) +- 702c049 minifier: Move compress block to dce (#6468) (7086cmd) +- 46a38c6 minifier: Remove allow `clippy::unused_self` (#6441) (Boshen) +- 994b60b minifier: Use builtin get_number_value. (#6335) (7086cmd) +- 435a89c oxc: Remove useless `allocator.alloc(program)` calls (#6571) (Boshen) +- 1a90ec4 rust: Backport v1.82.0 changes to main branch first (#6690) (Boshen) + +### Testing + +- c5deb32 minifier: Port the rest of tests (#6420) (7086cmd) +- e59da61 minifier: Add all test cases for `collapse_variable_declarations` (#6421) (dalaoshu) +- 73d6a4a minifier: Port all replace_known_methods tests. (#6418) (7086cmd) + ## [0.31.0] - 2024-10-08 - 020bb80 codegen: [**BREAKING**] Change to `CodegenReturn::code` and `CodegenReturn::map` (#6310) (Boshen) diff --git a/crates/oxc_minifier/Cargo.toml b/crates/oxc_minifier/Cargo.toml index 06168b3d0358c..a944e6f3f0c6f 100644 --- a/crates/oxc_minifier/Cargo.toml +++ b/crates/oxc_minifier/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_minifier" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs index 7afac0db09558..0466d4f9ed593 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs @@ -300,7 +300,7 @@ impl<'a, 'b> PeepholeFoldConstants { | (ValueType::Boolean, ValueType::Boolean) => { let left_number = ctx.get_number_value(left)?; let right_number = ctx.get_number_value(right)?; - let Ok(value) = TryInto::::try_into(left_number + right_number) else { return None }; + let value = left_number + right_number; // Float if value has a fractional part, otherwise Decimal let number_base = if is_exact_int64(value) { NumberBase::Decimal } else { NumberBase::Float }; // todo: add raw &str diff --git a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs index 27024d841d026..30c5a6665876a 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs @@ -38,6 +38,7 @@ impl<'a> Traverse<'a> for PeepholeRemoveDeadCode { Statement::ExpressionStatement(expr_stmt) => { Self::try_fold_expression_stmt(expr_stmt, ctx) } + Statement::LabeledStatement(labeled) => Self::try_fold_labeled(labeled, ctx), _ => None, } { *stmt = new_stmt; @@ -235,6 +236,30 @@ impl<'a, 'b> PeepholeRemoveDeadCode { } } + /// Remove meaningless labeled statements. + /// + /// ```js + /// a: break a; + /// ``` + fn try_fold_labeled( + labeled: &mut LabeledStatement<'a>, + ctx: Ctx<'a, 'b>, + ) -> Option> { + let id = labeled.label.name.as_str(); + // Check the first statement in the block, or just the `break [id] ` statement. + // Check if we need to remove the whole block. + match &mut labeled.body { + Statement::BreakStatement(break_stmt) + if break_stmt.label.as_ref().is_some_and(|l| l.name.as_str() == id) => {} + Statement::BlockStatement(block) if block.body.first().is_some_and(|first| matches!(first, Statement::BreakStatement(break_stmt) if break_stmt.label.as_ref().is_some_and(|l| l.name.as_str() == id))) => {} + _ => return None, + } + let mut var = KeepVar::new(ctx.ast); + var.visit_statement(&labeled.body); + let var_decl = var.get_variable_declaration_statement(); + var_decl.unwrap_or(ctx.ast.statement_empty(SPAN)).into() + } + fn try_fold_expression_stmt( stmt: &mut ExpressionStatement<'a>, ctx: Ctx<'a, 'b>, @@ -322,12 +347,12 @@ impl<'a, 'b> PeepholeRemoveDeadCode { ); } - return Some(ctx.ast.statement_expression( + Some(ctx.ast.statement_expression( array_expr.span, ctx.ast.expression_from_sequence( ctx.ast.sequence_expression(array_expr.span, transformed_elements), ), - )); + )) } // `{a: 1, b: 2, c: foo()}` -> `foo()` @@ -413,12 +438,12 @@ impl<'a, 'b> PeepholeRemoveDeadCode { ); } - return Some(ctx.ast.statement_expression( + Some(ctx.ast.statement_expression( object_expr.span, ctx.ast.expression_from_sequence( ctx.ast.sequence_expression(object_expr.span, filtered_properties), ), - )); + )) } /// Try folding conditional expression (?:) if the condition results of the condition is known. @@ -497,7 +522,6 @@ mod test { } #[test] - #[ignore] fn test_remove_no_op_labelled_statement() { fold("a: break a;", ""); fold("a: { break a; }", ""); diff --git a/crates/oxc_module_lexer/Cargo.toml b/crates/oxc_module_lexer/Cargo.toml index 672286d3a14bd..69ea1b686046c 100644 --- a/crates/oxc_module_lexer/Cargo.toml +++ b/crates/oxc_module_lexer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_module_lexer" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_parser/CHANGELOG.md b/crates/oxc_parser/CHANGELOG.md index f48832b6bb3f2..850fad9691339 100644 --- a/crates/oxc_parser/CHANGELOG.md +++ b/crates/oxc_parser/CHANGELOG.md @@ -4,6 +4,31 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +- 2808973 ast: [**BREAKING**] Add `Program::comments` (#6445) (Boshen) + +### Features + +- 58467a5 parser: Better handling of invalid modifiers (#6482) (DonIsaac) +- 8ea6b72 parser: Better errors for reserved words used as identifier names (#6478) (DonIsaac) + +### Bug Fixes + +- 721cf0f parser: Should be treated comments where after `(` as leading comments of next token (#6588) (Dunqing) +- b1bf12c parser: Do not parse `as` and `satisfies` expression in javascript (#6442) (Boshen) + +### Performance + +- 4d8bc8c parser: Precompute `is_typescript` (#6443) (Boshen) + +### Refactor + +- 073b02a ast: Type params field before params in TS function declaration types (#6391) (overlookmotel) +- c45723b parser: Fix typo in var name (#6500) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 01b878e parser: [**BREAKING**] Use `BindingIdentifier` for `namespace` declaration names (#6003) (DonIsaac) diff --git a/crates/oxc_parser/Cargo.toml b/crates/oxc_parser/Cargo.toml index 003e3b5c6c804..b6b26f326b273 100644 --- a/crates/oxc_parser/Cargo.toml +++ b/crates/oxc_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_parser" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_prettier/src/lib.rs b/crates/oxc_prettier/src/lib.rs index 74d093c221c2e..af18238df132a 100644 --- a/crates/oxc_prettier/src/lib.rs +++ b/crates/oxc_prettier/src/lib.rs @@ -130,7 +130,7 @@ impl<'a> Prettier<'a> { } pub fn semi(&self) -> Option> { - self.options.semi.then(|| Doc::Str(";")) + self.options.semi.then_some(Doc::Str(";")) } pub fn should_print_es5_comma(&self) -> bool { diff --git a/crates/oxc_regular_expression/CHANGELOG.md b/crates/oxc_regular_expression/CHANGELOG.md index 2bd9898a4fe5d..a0cf56366ea9f 100644 --- a/crates/oxc_regular_expression/CHANGELOG.md +++ b/crates/oxc_regular_expression/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) +- b5b0af9 regular_expression: Support RegExp Modifiers (#6410) (leaysgur) + +### Bug Fixes + +- 9f9057b regular_expression: Fixed control Y regular expression (#6524) (Tapan Prakash) +- c822b48 regular_expression: Fix CharacterClass negative codegen (#6415) (leaysgur) +- 384d5be regular_expression: Flatten Spans on regex AST nodes (#6396) (ottomated) + +### Performance + +- 7c20056 regex: Reduce string allocations in `Display` impls (#6528) (DonIsaac) + +### Styling + +- fb916b2 regular_expression: Re-order dependencies in `Cargo.toml` (#6672) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 5a73a66 regular_expression: [**BREAKING**] Simplify public APIs (#6262) (leaysgur) diff --git a/crates/oxc_regular_expression/Cargo.toml b/crates/oxc_regular_expression/Cargo.toml index 1917f3c2d7b16..efccb05be41b7 100644 --- a/crates/oxc_regular_expression/Cargo.toml +++ b/crates/oxc_regular_expression/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_regular_expression" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true @@ -23,19 +23,16 @@ doctest = false oxc_allocator = { workspace = true } oxc_ast_macros = { workspace = true } oxc_diagnostics = { workspace = true } +oxc_estree = { workspace = true } oxc_span = { workspace = true } phf = { workspace = true, features = ["macros"] } rustc-hash = { workspace = true } -serde = { workspace = true, features = ["derive"], optional = true } unicode-id-start = { workspace = true } -tsify = { workspace = true, optional = true } +serde = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } [features] default = [] -serialize = ["dep:serde", "dep:tsify", "dep:wasm-bindgen", "oxc_allocator/serialize", "oxc_span/serialize"] - -[package.metadata.cargo-shear] -ignored = ["wasm-bindgen"] # wasm-bindgen used by tsify +serialize = ["dep:serde", "dep:wasm-bindgen", "oxc_allocator/serialize", "oxc_span/serialize"] diff --git a/crates/oxc_regular_expression/src/ast.rs b/crates/oxc_regular_expression/src/ast.rs index b31961d714eff..96bba7434769f 100644 --- a/crates/oxc_regular_expression/src/ast.rs +++ b/crates/oxc_regular_expression/src/ast.rs @@ -1,21 +1,14 @@ -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, Span}; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; /// The root of the `PatternParser` result. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Pattern<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Disjunction<'a>, } @@ -23,10 +16,9 @@ pub struct Pattern<'a> { /// Pile of [`Alternative`]s separated by `|`. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Disjunction<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, Alternative<'a>>, } @@ -34,10 +26,9 @@ pub struct Disjunction<'a> { /// Single unit of `|` separated alternatives. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Alternative<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub body: Vec<'a, Term<'a>>, } @@ -45,8 +36,8 @@ pub struct Alternative<'a> { /// Single unit of [`Alternative`], containing various kinds. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum Term<'a> { // Assertion, QuantifiableAssertion BoundaryAssertion(Box<'a, BoundaryAssertion>) = 0, @@ -89,8 +80,7 @@ impl<'a> GetSpan for Term<'a> { /// e.g. `^`, `$`, `\b`, `\B` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct BoundaryAssertion { pub span: Span, pub kind: BoundaryAssertionKind, @@ -98,8 +88,8 @@ pub struct BoundaryAssertion { #[ast] #[derive(Debug, Clone, PartialEq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum BoundaryAssertionKind { Start = 0, End = 1, @@ -111,10 +101,9 @@ pub enum BoundaryAssertionKind { /// e.g. `(?=...)`, `(?!...)`, `(?<=...)`, `(? { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: LookAroundAssertionKind, pub body: Disjunction<'a>, @@ -122,8 +111,8 @@ pub struct LookAroundAssertion<'a> { #[ast] #[derive(Debug, Clone, PartialEq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum LookAroundAssertionKind { Lookahead = 0, NegativeLookahead = 1, @@ -135,10 +124,9 @@ pub enum LookAroundAssertionKind { /// e.g. `a*`, `b+`, `c?`, `d{3}`, `e{4,}`, `f{5,6}` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Quantifier<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub min: u64, /// `None` means no upper bound. @@ -150,11 +138,10 @@ pub struct Quantifier<'a> { /// Single character. #[ast] #[derive(Debug, Clone, Copy)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Character { /// This will be invalid position when `UnicodeMode` is disabled and `value` is a surrogate pair. - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: CharacterKind, /// Unicode code point or UTF-16 code unit. @@ -163,8 +150,8 @@ pub struct Character { #[ast] #[derive(Debug, Clone, Copy, PartialEq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum CharacterKind { ControlLetter = 0, HexadecimalEscape = 1, @@ -183,18 +170,17 @@ pub enum CharacterKind { /// e.g. `\d`, `\D`, `\s`, `\S`, `\w`, `\W` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct CharacterClassEscape { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub kind: CharacterClassEscapeKind, } #[ast] #[derive(Debug, Clone, Copy, PartialEq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum CharacterClassEscapeKind { D = 0, NegativeD = 1, @@ -208,10 +194,9 @@ pub enum CharacterClassEscapeKind { /// e.g. `\p{ASCII}`, `\P{ASCII}`, `\p{sc=Hiragana}`, `\P{sc=Hiragana}` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct UnicodePropertyEscape<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub negative: bool, /// `true` if `UnicodeSetsMode` and `name` matches unicode property of strings. @@ -223,10 +208,9 @@ pub struct UnicodePropertyEscape<'a> { /// The `.`. #[ast] #[derive(Debug, Clone, Copy)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Dot { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, } @@ -234,10 +218,9 @@ pub struct Dot { /// e.g. `[a-z]`, `[^A-Z]`, `[abc]`, `[a&&b&&c]`, `[[a-z]--x--y]` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct CharacterClass<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub negative: bool, /// `true` if: @@ -250,8 +233,8 @@ pub struct CharacterClass<'a> { #[ast] #[derive(Debug, PartialEq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum CharacterClassContentsKind { Union = 0, /// `UnicodeSetsMode` only. @@ -262,8 +245,8 @@ pub enum CharacterClassContentsKind { #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(untagged)] pub enum CharacterClassContents<'a> { CharacterClassRange(Box<'a, CharacterClassRange>) = 0, CharacterClassEscape(Box<'a, CharacterClassEscape>) = 1, @@ -293,10 +276,9 @@ impl<'a> GetSpan for CharacterClassContents<'a> { /// e.g. `a-z`, `A-Z`, `0-9` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct CharacterClassRange { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub min: Character, pub max: Character, @@ -305,10 +287,9 @@ pub struct CharacterClassRange { /// `|` separated string of characters wrapped by `\q{}`. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct ClassStringDisjunction<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// `true` if body is empty or contains [`ClassString`] which `strings` is `true`. pub strings: bool, @@ -318,10 +299,9 @@ pub struct ClassStringDisjunction<'a> { /// Single unit of [`ClassStringDisjunction`]. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct ClassString<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// `true` if body is empty or contain 2 more characters. pub strings: bool, @@ -332,10 +312,9 @@ pub struct ClassString<'a> { /// e.g. `(...)`, `(?...)` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct CapturingGroup<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, /// Group name to be referenced by [`NamedReference`]. pub name: Option>, @@ -346,10 +325,9 @@ pub struct CapturingGroup<'a> { /// e.g. `(?:...)` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct IgnoreGroup<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub modifiers: Option, pub body: Disjunction<'a>, @@ -359,10 +337,9 @@ pub struct IgnoreGroup<'a> { /// e.g. `i` in `(?i:...)`, `-s` in `(?-s:...)` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Modifiers { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub enabling: Option, pub disabling: Option, @@ -371,8 +348,7 @@ pub struct Modifiers { /// Each part of modifier in [`Modifiers`]. #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct Modifier { pub ignore_case: bool, pub multiline: bool, @@ -383,10 +359,9 @@ pub struct Modifier { /// e.g. `\1`, `\2`, `\3` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct IndexedReference { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub index: u32, } @@ -395,10 +370,9 @@ pub struct IndexedReference { /// e.g. `\k` #[ast] #[derive(Debug)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] pub struct NamedReference<'a> { - #[serde(flatten)] + #[estree(flatten)] pub span: Span, pub name: Atom<'a>, } diff --git a/crates/oxc_regular_expression/src/generated/derive_estree.rs b/crates/oxc_regular_expression/src/generated/derive_estree.rs new file mode 100644 index 0000000000000..3e744dc59b825 --- /dev/null +++ b/crates/oxc_regular_expression/src/generated/derive_estree.rs @@ -0,0 +1,468 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/estree.rs` + +#![allow(unused_imports, unused_mut, clippy::match_same_arms)] + +use serde::{ser::SerializeMap, Serialize, Serializer}; + +#[allow(clippy::wildcard_imports)] +use crate::ast::*; + +impl<'a> Serialize for Pattern<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Pattern")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Pattern = ({\n\ttype: 'Pattern';\n\tbody: Disjunction;\n}) & Span;"; + +impl<'a> Serialize for Disjunction<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Disjunction")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Disjunction = ({\n\ttype: 'Disjunction';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for Alternative<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Alternative")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Alternative = ({\n\ttype: 'Alternative';\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for Term<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + Term::BoundaryAssertion(x) => Serialize::serialize(x, serializer), + Term::LookAroundAssertion(x) => Serialize::serialize(x, serializer), + Term::Quantifier(x) => Serialize::serialize(x, serializer), + Term::Character(x) => Serialize::serialize(x, serializer), + Term::Dot(x) => Serialize::serialize(x, serializer), + Term::CharacterClassEscape(x) => Serialize::serialize(x, serializer), + Term::UnicodePropertyEscape(x) => Serialize::serialize(x, serializer), + Term::CharacterClass(x) => Serialize::serialize(x, serializer), + Term::CapturingGroup(x) => Serialize::serialize(x, serializer), + Term::IgnoreGroup(x) => Serialize::serialize(x, serializer), + Term::IndexedReference(x) => Serialize::serialize(x, serializer), + Term::NamedReference(x) => Serialize::serialize(x, serializer), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Term = BoundaryAssertion | LookAroundAssertion | Quantifier | Character | Dot | CharacterClassEscape | UnicodePropertyEscape | CharacterClass | CapturingGroup | IgnoreGroup | IndexedReference | NamedReference;"; + +impl Serialize for BoundaryAssertion { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "BoundaryAssertion")?; + map.serialize_entry("span", &self.span)?; + map.serialize_entry("kind", &self.kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BoundaryAssertion = ({\n\ttype: 'BoundaryAssertion';\n\tspan: Span;\n\tkind: BoundaryAssertionKind;\n});"; + +impl Serialize for BoundaryAssertionKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + BoundaryAssertionKind::Start => { + serializer.serialize_unit_variant("BoundaryAssertionKind", 0u32, "start") + } + BoundaryAssertionKind::End => { + serializer.serialize_unit_variant("BoundaryAssertionKind", 1u32, "end") + } + BoundaryAssertionKind::Boundary => { + serializer.serialize_unit_variant("BoundaryAssertionKind", 2u32, "boundary") + } + BoundaryAssertionKind::NegativeBoundary => { + serializer.serialize_unit_variant("BoundaryAssertionKind", 3u32, "negativeBoundary") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type BoundaryAssertionKind = 'start' | 'end' | 'boundary' | 'negativeBoundary';"; + +impl<'a> Serialize for LookAroundAssertion<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "LookAroundAssertion")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LookAroundAssertion = ({\n\ttype: 'LookAroundAssertion';\n\tkind: LookAroundAssertionKind;\n\tbody: Disjunction;\n}) & Span;"; + +impl Serialize for LookAroundAssertionKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + LookAroundAssertionKind::Lookahead => { + serializer.serialize_unit_variant("LookAroundAssertionKind", 0u32, "lookahead") + } + LookAroundAssertionKind::NegativeLookahead => serializer.serialize_unit_variant( + "LookAroundAssertionKind", + 1u32, + "negativeLookahead", + ), + LookAroundAssertionKind::Lookbehind => { + serializer.serialize_unit_variant("LookAroundAssertionKind", 2u32, "lookbehind") + } + LookAroundAssertionKind::NegativeLookbehind => serializer.serialize_unit_variant( + "LookAroundAssertionKind", + 3u32, + "negativeLookbehind", + ), + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LookAroundAssertionKind = 'lookahead' | 'negativeLookahead' | 'lookbehind' | 'negativeLookbehind';"; + +impl<'a> Serialize for Quantifier<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Quantifier")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("min", &self.min)?; + map.serialize_entry("max", &self.max)?; + map.serialize_entry("greedy", &self.greedy)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Quantifier = ({\n\ttype: 'Quantifier';\n\tmin: number;\n\tmax: (number) | null;\n\tgreedy: boolean;\n\tbody: Term;\n}) & Span;"; + +impl Serialize for Character { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Character")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Character = ({\n\ttype: 'Character';\n\tkind: CharacterKind;\n\tvalue: number;\n}) & Span;"; + +impl Serialize for CharacterKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + CharacterKind::ControlLetter => { + serializer.serialize_unit_variant("CharacterKind", 0u32, "controlLetter") + } + CharacterKind::HexadecimalEscape => { + serializer.serialize_unit_variant("CharacterKind", 1u32, "hexadecimalEscape") + } + CharacterKind::Identifier => { + serializer.serialize_unit_variant("CharacterKind", 2u32, "identifier") + } + CharacterKind::Null => serializer.serialize_unit_variant("CharacterKind", 3u32, "null"), + CharacterKind::Octal1 => { + serializer.serialize_unit_variant("CharacterKind", 4u32, "octal1") + } + CharacterKind::Octal2 => { + serializer.serialize_unit_variant("CharacterKind", 5u32, "octal2") + } + CharacterKind::Octal3 => { + serializer.serialize_unit_variant("CharacterKind", 6u32, "octal3") + } + CharacterKind::SingleEscape => { + serializer.serialize_unit_variant("CharacterKind", 7u32, "singleEscape") + } + CharacterKind::Symbol => { + serializer.serialize_unit_variant("CharacterKind", 8u32, "symbol") + } + CharacterKind::UnicodeEscape => { + serializer.serialize_unit_variant("CharacterKind", 9u32, "unicodeEscape") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterKind = 'controlLetter' | 'hexadecimalEscape' | 'identifier' | 'null' | 'octal1' | 'octal2' | 'octal3' | 'singleEscape' | 'symbol' | 'unicodeEscape';"; + +impl Serialize for CharacterClassEscape { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CharacterClassEscape")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("kind", &self.kind)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterClassEscape = ({\n\ttype: 'CharacterClassEscape';\n\tkind: CharacterClassEscapeKind;\n}) & Span;"; + +impl Serialize for CharacterClassEscapeKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + CharacterClassEscapeKind::D => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 0u32, "d") + } + CharacterClassEscapeKind::NegativeD => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 1u32, "negativeD") + } + CharacterClassEscapeKind::S => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 2u32, "s") + } + CharacterClassEscapeKind::NegativeS => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 3u32, "negativeS") + } + CharacterClassEscapeKind::W => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 4u32, "w") + } + CharacterClassEscapeKind::NegativeW => { + serializer.serialize_unit_variant("CharacterClassEscapeKind", 5u32, "negativeW") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterClassEscapeKind = 'd' | 'negativeD' | 's' | 'negativeS' | 'w' | 'negativeW';"; + +impl<'a> Serialize for UnicodePropertyEscape<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "UnicodePropertyEscape")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("negative", &self.negative)?; + map.serialize_entry("strings", &self.strings)?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("value", &self.value)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type UnicodePropertyEscape = ({\n\ttype: 'UnicodePropertyEscape';\n\tnegative: boolean;\n\tstrings: boolean;\n\tname: string;\n\tvalue: (string) | null;\n}) & Span;"; + +impl Serialize for Dot { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Dot")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Dot = ({\n\ttype: 'Dot';\n}) & Span;"; + +impl<'a> Serialize for CharacterClass<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CharacterClass")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("negative", &self.negative)?; + map.serialize_entry("strings", &self.strings)?; + map.serialize_entry("kind", &self.kind)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterClass = ({\n\ttype: 'CharacterClass';\n\tnegative: boolean;\n\tstrings: boolean;\n\tkind: CharacterClassContentsKind;\n\tbody: Array;\n}) & Span;"; + +impl Serialize for CharacterClassContentsKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + CharacterClassContentsKind::Union => { + serializer.serialize_unit_variant("CharacterClassContentsKind", 0u32, "union") + } + CharacterClassContentsKind::Intersection => serializer.serialize_unit_variant( + "CharacterClassContentsKind", + 1u32, + "intersection", + ), + CharacterClassContentsKind::Subtraction => { + serializer.serialize_unit_variant("CharacterClassContentsKind", 2u32, "subtraction") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type CharacterClassContentsKind = 'union' | 'intersection' | 'subtraction';"; + +impl<'a> Serialize for CharacterClassContents<'a> { + fn serialize(&self, serializer: S) -> Result { + match self { + CharacterClassContents::CharacterClassRange(x) => Serialize::serialize(x, serializer), + CharacterClassContents::CharacterClassEscape(x) => Serialize::serialize(x, serializer), + CharacterClassContents::UnicodePropertyEscape(x) => Serialize::serialize(x, serializer), + CharacterClassContents::Character(x) => Serialize::serialize(x, serializer), + CharacterClassContents::NestedCharacterClass(x) => Serialize::serialize(x, serializer), + CharacterClassContents::ClassStringDisjunction(x) => { + Serialize::serialize(x, serializer) + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterClassContents = CharacterClassRange | CharacterClassEscape | UnicodePropertyEscape | Character | CharacterClass | ClassStringDisjunction;"; + +impl Serialize for CharacterClassRange { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CharacterClassRange")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("min", &self.min)?; + map.serialize_entry("max", &self.max)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CharacterClassRange = ({\n\ttype: 'CharacterClassRange';\n\tmin: Character;\n\tmax: Character;\n}) & Span;"; + +impl<'a> Serialize for ClassStringDisjunction<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ClassStringDisjunction")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("strings", &self.strings)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ClassStringDisjunction = ({\n\ttype: 'ClassStringDisjunction';\n\tstrings: boolean;\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for ClassString<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "ClassString")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("strings", &self.strings)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type ClassString = ({\n\ttype: 'ClassString';\n\tstrings: boolean;\n\tbody: Array;\n}) & Span;"; + +impl<'a> Serialize for CapturingGroup<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "CapturingGroup")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type CapturingGroup = ({\n\ttype: 'CapturingGroup';\n\tname: (string) | null;\n\tbody: Disjunction;\n}) & Span;"; + +impl<'a> Serialize for IgnoreGroup<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "IgnoreGroup")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("modifiers", &self.modifiers)?; + map.serialize_entry("body", &self.body)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type IgnoreGroup = ({\n\ttype: 'IgnoreGroup';\n\tmodifiers: (Modifiers) | null;\n\tbody: Disjunction;\n}) & Span;"; + +impl Serialize for Modifiers { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Modifiers")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("enabling", &self.enabling)?; + map.serialize_entry("disabling", &self.disabling)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Modifiers = ({\n\ttype: 'Modifiers';\n\tenabling: (Modifier) | null;\n\tdisabling: (Modifier) | null;\n}) & Span;"; + +impl Serialize for Modifier { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "Modifier")?; + map.serialize_entry("ignoreCase", &self.ignore_case)?; + map.serialize_entry("multiline", &self.multiline)?; + map.serialize_entry("sticky", &self.sticky)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type Modifier = ({\n\ttype: 'Modifier';\n\tignoreCase: boolean;\n\tmultiline: boolean;\n\tsticky: boolean;\n});"; + +impl Serialize for IndexedReference { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "IndexedReference")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("index", &self.index)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type IndexedReference = ({\n\ttype: 'IndexedReference';\n\tindex: number;\n}) & Span;"; + +impl<'a> Serialize for NamedReference<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("type", "NamedReference")?; + self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?; + map.serialize_entry("name", &self.name)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type NamedReference = ({\n\ttype: 'NamedReference';\n\tname: string;\n}) & Span;"; diff --git a/crates/oxc_regular_expression/src/lib.rs b/crates/oxc_regular_expression/src/lib.rs index c7c42f290537c..5b22c6408168a 100644 --- a/crates/oxc_regular_expression/src/lib.rs +++ b/crates/oxc_regular_expression/src/lib.rs @@ -10,6 +10,8 @@ mod generated { mod derive_clone_in; mod derive_content_eq; mod derive_content_hash; + #[cfg(feature = "serialize")] + mod derive_estree; } pub mod ast; diff --git a/crates/oxc_semantic/CHANGELOG.md b/crates/oxc_semantic/CHANGELOG.md index 7b1080650debc..1fd9fe8d2f65c 100644 --- a/crates/oxc_semantic/CHANGELOG.md +++ b/crates/oxc_semantic/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +- 2808973 ast: [**BREAKING**] Add `Program::comments` (#6445) (Boshen) + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) + +### Bug Fixes + +- 834ee2a semantic: `TSConditionalType` scope enter/exit locations (#6351) (DonIsaac) + +### Refactor + +- 073b02a ast: Type params field before params in TS function declaration types (#6391) (overlookmotel) +- 435a89c oxc: Remove useless `allocator.alloc(program)` calls (#6571) (Boshen) + ## [0.31.0] - 2024-10-08 - 01b878e parser: [**BREAKING**] Use `BindingIdentifier` for `namespace` declaration names (#6003) (DonIsaac) diff --git a/crates/oxc_semantic/Cargo.toml b/crates/oxc_semantic/Cargo.toml index 4aab9f302e71e..ad69263a85a13 100644 --- a/crates/oxc_semantic/Cargo.toml +++ b/crates/oxc_semantic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_semantic" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_semantic/src/symbol.rs b/crates/oxc_semantic/src/symbol.rs index 111f03340649e..b58ea210f26d6 100644 --- a/crates/oxc_semantic/src/symbol.rs +++ b/crates/oxc_semantic/src/symbol.rs @@ -22,6 +22,7 @@ use crate::{ #[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] const TS_APPEND_CONTENT: &'static str = r#" export type IndexVec = Array; +export type CompactStr = string; "#; /// Symbol Table diff --git a/crates/oxc_sourcemap/Cargo.toml b/crates/oxc_sourcemap/Cargo.toml index b9d45ec11660c..6f738f1c01055 100644 --- a/crates/oxc_sourcemap/Cargo.toml +++ b/crates/oxc_sourcemap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_sourcemap" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_span/CHANGELOG.md b/crates/oxc_span/CHANGELOG.md index 003fb78f3d7fa..a2e17e71462cf 100644 --- a/crates/oxc_span/CHANGELOG.md +++ b/crates/oxc_span/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) + +### Documentation + +- de22b81 data-structures: Enable lint warnings on missing docs, and add missing doc comments (#6612) (DonIsaac) +- 9e9fa9e span: Enable lint warnings on missing docs (#6617) (overlookmotel) +- 6a194f9 span: Document validity of `ModuleKind::Unambiguous` (#6423) (Boshen) + +### Refactor + +- 3faee66 span: Remove unused `ContentHash::content_hash_slice` (#6609) (DonIsaac) + ## [0.30.4] - 2024-09-28 ### Bug Fixes diff --git a/crates/oxc_span/Cargo.toml b/crates/oxc_span/Cargo.toml index 1936bb2536d73..019e7f45c8ddb 100644 --- a/crates/oxc_span/Cargo.toml +++ b/crates/oxc_span/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_span" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true @@ -22,16 +22,16 @@ doctest = false [dependencies] oxc_allocator = { workspace = true } oxc_ast_macros = { workspace = true } +oxc_estree = { workspace = true } compact_str = { workspace = true } miette = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } -tsify = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } [features] default = [] -serialize = ["compact_str/serde", "dep:serde", "dep:tsify", "dep:wasm-bindgen"] +serialize = ["compact_str/serde", "dep:serde", "dep:wasm-bindgen"] schemars = ["dep:schemars"] diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index 7e21a6edbfb91..0b181b6fdab8c 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -10,12 +10,6 @@ use serde::Serialize; use crate::{cmp::ContentEq, hash::ContentHash, CompactStr}; -#[cfg(feature = "serialize")] -#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] -const TS_APPEND_CONTENT: &'static str = r#" -export type Atom = string; -"#; - /// An inlinable string for oxc_allocator. /// /// Use [CompactStr] with [Atom::to_compact_str] or [Atom::into_compact_str] for diff --git a/crates/oxc_span/src/compact_str.rs b/crates/oxc_span/src/compact_str.rs index 3cd38cffecbf2..1378d62e69cf2 100644 --- a/crates/oxc_span/src/compact_str.rs +++ b/crates/oxc_span/src/compact_str.rs @@ -10,12 +10,6 @@ use serde::{Serialize, Serializer}; use crate::Span; -#[cfg(feature = "serialize")] -#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] -const TS_APPEND_CONTENT: &'static str = r#" -export type CompactStr = string; -"#; - /// Maximum length for inline string, which can be created with [`CompactStr::new_const`]. pub const MAX_INLINE_LEN: usize = 16; diff --git a/crates/oxc_span/src/generated/derive_estree.rs b/crates/oxc_span/src/generated/derive_estree.rs new file mode 100644 index 0000000000000..0350cbbfcdbf7 --- /dev/null +++ b/crates/oxc_span/src/generated/derive_estree.rs @@ -0,0 +1,90 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/estree.rs` + +#![allow(unused_imports, unused_mut, clippy::match_same_arms)] + +use serde::{ser::SerializeMap, Serialize, Serializer}; + +#[allow(clippy::wildcard_imports)] +use crate::source_type::*; + +#[allow(clippy::wildcard_imports)] +use crate::span::types::*; + +impl Serialize for Span { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("start", &self.start)?; + map.serialize_entry("end", &self.end)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Span = ({\n\tstart: number;\n\tend: number;\n});"; + +impl Serialize for SourceType { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("language", &self.language)?; + map.serialize_entry("moduleKind", &self.module_kind)?; + map.serialize_entry("variant", &self.variant)?; + map.end() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type SourceType = ({\n\tlanguage: Language;\n\tmoduleKind: ModuleKind;\n\tvariant: LanguageVariant;\n});"; + +impl Serialize for Language { + fn serialize(&self, serializer: S) -> Result { + match *self { + Language::JavaScript => { + serializer.serialize_unit_variant("Language", 0u32, "javascript") + } + Language::TypeScript => { + serializer.serialize_unit_variant("Language", 1u32, "typescript") + } + Language::TypeScriptDefinition => { + serializer.serialize_unit_variant("Language", 2u32, "typescriptDefinition") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type Language = 'javascript' | 'typescript' | 'typescriptDefinition';"; + +impl Serialize for ModuleKind { + fn serialize(&self, serializer: S) -> Result { + match *self { + ModuleKind::Script => serializer.serialize_unit_variant("ModuleKind", 0u32, "script"), + ModuleKind::Module => serializer.serialize_unit_variant("ModuleKind", 1u32, "module"), + ModuleKind::Unambiguous => { + serializer.serialize_unit_variant("ModuleKind", 2u32, "unambiguous") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type ModuleKind = 'script' | 'module' | 'unambiguous';"; + +impl Serialize for LanguageVariant { + fn serialize(&self, serializer: S) -> Result { + match *self { + LanguageVariant::Standard => { + serializer.serialize_unit_variant("LanguageVariant", 0u32, "standard") + } + LanguageVariant::Jsx => { + serializer.serialize_unit_variant("LanguageVariant", 1u32, "jsx") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LanguageVariant = 'standard' | 'jsx';"; diff --git a/crates/oxc_span/src/lib.rs b/crates/oxc_span/src/lib.rs index 1bed34cd32d62..2ad1c4dddd941 100644 --- a/crates/oxc_span/src/lib.rs +++ b/crates/oxc_span/src/lib.rs @@ -21,6 +21,11 @@ pub use crate::{ span::{GetSpan, GetSpanMut, Span, SPAN}, }; +mod generated { + #[cfg(feature = "serialize")] + pub mod derive_estree; +} + #[doc(hidden)] pub mod __internal { // Used by `format_compact_str!` macro defined in `compact_str.rs` diff --git a/crates/oxc_span/src/source_type/mod.rs b/crates/oxc_span/src/source_type/mod.rs index f8fe5bca56732..76049d02f70b2 100644 --- a/crates/oxc_span/src/source_type/mod.rs +++ b/crates/oxc_span/src/source_type/mod.rs @@ -1,14 +1,10 @@ -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - mod error; use std::{hash::Hash, path::Path}; use oxc_allocator::{Allocator, CloneIn}; use oxc_ast_macros::ast; -#[cfg(feature = "serialize")] -use {serde::Serialize, tsify::Tsify}; +use oxc_estree::ESTree; use crate::{cmp::ContentEq, hash::ContentHash}; pub use error::UnknownExtension; @@ -16,8 +12,8 @@ pub use error::UnknownExtension; /// Source Type for JavaScript vs TypeScript / Script vs Module / JSX #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(ESTree)] +#[estree(no_type)] pub struct SourceType { /// JavaScript or TypeScript, default JavaScript pub(super) language: Language, @@ -32,23 +28,24 @@ pub struct SourceType { /// JavaScript or TypeScript #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "lowercase")] +#[generate_derive(ESTree)] pub enum Language { /// Indicates a JavaScript or JSX file + #[estree(rename = "javascript")] JavaScript = 0, /// Indicates a TypeScript file + #[estree(rename = "typescript")] TypeScript = 1, /// Indicates a TypeScript definition file (`*.d.ts`) - #[serde(rename = "typescriptDefinition")] + #[estree(rename = "typescriptDefinition")] TypeScriptDefinition = 2, } /// Script or Module #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(ESTree)] +#[estree(rename_all = "camelCase")] pub enum ModuleKind { /// Regular JS script or CommonJS file Script = 0, @@ -68,8 +65,8 @@ pub enum ModuleKind { /// JSX for JavaScript and TypeScript #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[serde(rename_all = "camelCase")] +#[generate_derive(ESTree)] +#[estree(rename_all = "camelCase")] pub enum LanguageVariant { /// Standard JavaScript or TypeScript without any language extensions. Stage /// 3 proposals do not count as language extensions. diff --git a/crates/oxc_span/src/span/mod.rs b/crates/oxc_span/src/span/mod.rs index ab6e4ea432d89..8fb94109cd6e2 100644 --- a/crates/oxc_span/src/span/mod.rs +++ b/crates/oxc_span/src/span/mod.rs @@ -2,7 +2,7 @@ use std::ops::{Index, IndexMut, Range}; use miette::{LabeledSpan, SourceOffset, SourceSpan}; -mod types; +pub mod types; use oxc_allocator::{Allocator, CloneIn}; pub use types::Span; diff --git a/crates/oxc_span/src/span/types.rs b/crates/oxc_span/src/span/types.rs index cc57edf6dfb95..9ab08bfde8118 100644 --- a/crates/oxc_span/src/span/types.rs +++ b/crates/oxc_span/src/span/types.rs @@ -1,9 +1,5 @@ -// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` -#![allow(non_snake_case)] - use oxc_ast_macros::ast; -#[cfg(feature = "serialize")] -use ::{serde::Serialize, tsify::Tsify}; +use oxc_estree::ESTree; /// Newtype for working with text ranges /// @@ -17,8 +13,9 @@ use ::{serde::Serialize, tsify::Tsify}; /// same content), use [`ContentHash`](crate::hash::ContentHash) instead. #[ast] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(ESTree)] #[non_exhaustive] // Disallow struct expression constructor `Span {}` +#[estree(no_type)] pub struct Span { /// The zero-based start offset of the span pub start: u32, diff --git a/crates/oxc_syntax/CHANGELOG.md b/crates/oxc_syntax/CHANGELOG.md index 63002f14dfc4d..359f5aa479be1 100644 --- a/crates/oxc_syntax/CHANGELOG.md +++ b/crates/oxc_syntax/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +### Features + +- e310e52 parser: Generate `Serialize` impls in ast_tools (#6404) (ottomated) + +### Bug Fixes + +- 2ce3e5f identifier: Add `ZWSP` to `is_irregular_whitespace` (#6662) (Boshen) +- 1d3d256 transformer: Correctly trim JSX (#6639) (magic-akari) + +### Documentation + +- 335b7f2 syntax: Enable lint warnings on missing docs, and add a lot of documentation (#6611) (DonIsaac) + +### Refactor + +- 856cab5 ecmascript: Move ToInt32 from `oxc_syntax` to `oxc_ecmascript` (#6471) (Boshen) + ## [0.31.0] - 2024-10-08 ### Refactor diff --git a/crates/oxc_syntax/Cargo.toml b/crates/oxc_syntax/Cargo.toml index 03901101e7caa..6af4340111e17 100644 --- a/crates/oxc_syntax/Cargo.toml +++ b/crates/oxc_syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_syntax" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true @@ -22,6 +22,7 @@ doctest = false [dependencies] oxc_allocator = { workspace = true } oxc_ast_macros = { workspace = true } +oxc_estree = { workspace = true } oxc_index = { workspace = true } oxc_span = { workspace = true } @@ -35,13 +36,12 @@ unicode-id-start = { workspace = true } ryu-js = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } -tsify = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } [features] default = [] to_js_string = ["dep:ryu-js"] -serialize = ["bitflags/serde", "dep:serde", "dep:tsify", "dep:wasm-bindgen", "oxc_index/serialize"] +serialize = ["bitflags/serde", "dep:serde", "dep:wasm-bindgen", "oxc_index/serialize"] [package.metadata.cargo-shear] # We use `oxc_ast_macros::CloneIn` which expands to use `oxc_allocator`. diff --git a/crates/oxc_syntax/src/generated/derive_estree.rs b/crates/oxc_syntax/src/generated/derive_estree.rs new file mode 100644 index 0000000000000..f7c5997d4ecd5 --- /dev/null +++ b/crates/oxc_syntax/src/generated/derive_estree.rs @@ -0,0 +1,204 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/estree.rs` + +#![allow(unused_imports, unused_mut, clippy::match_same_arms)] + +use serde::{ser::SerializeMap, Serialize, Serializer}; + +#[allow(clippy::wildcard_imports)] +use crate::operator::*; + +impl Serialize for AssignmentOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + AssignmentOperator::Assign => { + serializer.serialize_unit_variant("AssignmentOperator", 0u32, "=") + } + AssignmentOperator::Addition => { + serializer.serialize_unit_variant("AssignmentOperator", 1u32, "+=") + } + AssignmentOperator::Subtraction => { + serializer.serialize_unit_variant("AssignmentOperator", 2u32, "-=") + } + AssignmentOperator::Multiplication => { + serializer.serialize_unit_variant("AssignmentOperator", 3u32, "*=") + } + AssignmentOperator::Division => { + serializer.serialize_unit_variant("AssignmentOperator", 4u32, "/=") + } + AssignmentOperator::Remainder => { + serializer.serialize_unit_variant("AssignmentOperator", 5u32, "%=") + } + AssignmentOperator::ShiftLeft => { + serializer.serialize_unit_variant("AssignmentOperator", 6u32, "<<=") + } + AssignmentOperator::ShiftRight => { + serializer.serialize_unit_variant("AssignmentOperator", 7u32, ">>=") + } + AssignmentOperator::ShiftRightZeroFill => { + serializer.serialize_unit_variant("AssignmentOperator", 8u32, ">>>=") + } + AssignmentOperator::BitwiseOR => { + serializer.serialize_unit_variant("AssignmentOperator", 9u32, "|=") + } + AssignmentOperator::BitwiseXOR => { + serializer.serialize_unit_variant("AssignmentOperator", 10u32, "^=") + } + AssignmentOperator::BitwiseAnd => { + serializer.serialize_unit_variant("AssignmentOperator", 11u32, "&=") + } + AssignmentOperator::LogicalAnd => { + serializer.serialize_unit_variant("AssignmentOperator", 12u32, "&&=") + } + AssignmentOperator::LogicalOr => { + serializer.serialize_unit_variant("AssignmentOperator", 13u32, "||=") + } + AssignmentOperator::LogicalNullish => { + serializer.serialize_unit_variant("AssignmentOperator", 14u32, "??=") + } + AssignmentOperator::Exponential => { + serializer.serialize_unit_variant("AssignmentOperator", 15u32, "**=") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&=' | '&&=' | '||=' | '??=' | '**=';"; + +impl Serialize for BinaryOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + BinaryOperator::Equality => { + serializer.serialize_unit_variant("BinaryOperator", 0u32, "==") + } + BinaryOperator::Inequality => { + serializer.serialize_unit_variant("BinaryOperator", 1u32, "!=") + } + BinaryOperator::StrictEquality => { + serializer.serialize_unit_variant("BinaryOperator", 2u32, "===") + } + BinaryOperator::StrictInequality => { + serializer.serialize_unit_variant("BinaryOperator", 3u32, "!==") + } + BinaryOperator::LessThan => { + serializer.serialize_unit_variant("BinaryOperator", 4u32, "<") + } + BinaryOperator::LessEqualThan => { + serializer.serialize_unit_variant("BinaryOperator", 5u32, "<=") + } + BinaryOperator::GreaterThan => { + serializer.serialize_unit_variant("BinaryOperator", 6u32, ">") + } + BinaryOperator::GreaterEqualThan => { + serializer.serialize_unit_variant("BinaryOperator", 7u32, ">=") + } + BinaryOperator::ShiftLeft => { + serializer.serialize_unit_variant("BinaryOperator", 8u32, "<<") + } + BinaryOperator::ShiftRight => { + serializer.serialize_unit_variant("BinaryOperator", 9u32, ">>") + } + BinaryOperator::ShiftRightZeroFill => { + serializer.serialize_unit_variant("BinaryOperator", 10u32, ">>>") + } + BinaryOperator::Addition => { + serializer.serialize_unit_variant("BinaryOperator", 11u32, "+") + } + BinaryOperator::Subtraction => { + serializer.serialize_unit_variant("BinaryOperator", 12u32, "-") + } + BinaryOperator::Multiplication => { + serializer.serialize_unit_variant("BinaryOperator", 13u32, "*") + } + BinaryOperator::Division => { + serializer.serialize_unit_variant("BinaryOperator", 14u32, "/") + } + BinaryOperator::Remainder => { + serializer.serialize_unit_variant("BinaryOperator", 15u32, "%") + } + BinaryOperator::BitwiseOR => { + serializer.serialize_unit_variant("BinaryOperator", 16u32, "|") + } + BinaryOperator::BitwiseXOR => { + serializer.serialize_unit_variant("BinaryOperator", 17u32, "^") + } + BinaryOperator::BitwiseAnd => { + serializer.serialize_unit_variant("BinaryOperator", 18u32, "&") + } + BinaryOperator::In => serializer.serialize_unit_variant("BinaryOperator", 19u32, "in"), + BinaryOperator::Instanceof => { + serializer.serialize_unit_variant("BinaryOperator", 20u32, "instanceof") + } + BinaryOperator::Exponential => { + serializer.serialize_unit_variant("BinaryOperator", 21u32, "**") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type BinaryOperator = '==' | '!=' | '===' | '!==' | '<' | '<=' | '>' | '>=' | '<<' | '>>' | '>>>' | '+' | '-' | '*' | '/' | '%' | '|' | '^' | '&' | 'in' | 'instanceof' | '**';"; + +impl Serialize for LogicalOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + LogicalOperator::Or => serializer.serialize_unit_variant("LogicalOperator", 0u32, "||"), + LogicalOperator::And => { + serializer.serialize_unit_variant("LogicalOperator", 1u32, "&&") + } + LogicalOperator::Coalesce => { + serializer.serialize_unit_variant("LogicalOperator", 2u32, "??") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type LogicalOperator = '||' | '&&' | '??';"; + +impl Serialize for UnaryOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + UnaryOperator::UnaryNegation => { + serializer.serialize_unit_variant("UnaryOperator", 0u32, "-") + } + UnaryOperator::UnaryPlus => { + serializer.serialize_unit_variant("UnaryOperator", 1u32, "+") + } + UnaryOperator::LogicalNot => { + serializer.serialize_unit_variant("UnaryOperator", 2u32, "!") + } + UnaryOperator::BitwiseNot => { + serializer.serialize_unit_variant("UnaryOperator", 3u32, "~") + } + UnaryOperator::Typeof => { + serializer.serialize_unit_variant("UnaryOperator", 4u32, "typeof") + } + UnaryOperator::Void => serializer.serialize_unit_variant("UnaryOperator", 5u32, "void"), + UnaryOperator::Delete => { + serializer.serialize_unit_variant("UnaryOperator", 6u32, "delete") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = + "export type UnaryOperator = '-' | '+' | '!' | '~' | 'typeof' | 'void' | 'delete';"; + +impl Serialize for UpdateOperator { + fn serialize(&self, serializer: S) -> Result { + match *self { + UpdateOperator::Increment => { + serializer.serialize_unit_variant("UpdateOperator", 0u32, "++") + } + UpdateOperator::Decrement => { + serializer.serialize_unit_variant("UpdateOperator", 1u32, "--") + } + } + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] +const TS_APPEND_CONTENT: &'static str = "export type UpdateOperator = '++' | '--';"; diff --git a/crates/oxc_syntax/src/identifier.rs b/crates/oxc_syntax/src/identifier.rs index 6ede6c3048788..938a0d44656e2 100644 --- a/crates/oxc_syntax/src/identifier.rs +++ b/crates/oxc_syntax/src/identifier.rs @@ -52,21 +52,20 @@ const MMSP: char = '\u{205f}'; const IDEOGRAPHIC_SPACE: char = '\u{3000}'; +// https://eslint.org/docs/latest/rules/no-irregular-whitespace#rule-details +#[rustfmt::skip] pub fn is_irregular_whitespace(c: char) -> bool { - matches!( - c, - VT | FF | NBSP | ZWNBSP | NEL | OGHAM_SPACE_MARK | EN_QUAD - ..ZWSP | NNBSP | MMSP | IDEOGRAPHIC_SPACE + matches!(c, + VT | FF | NBSP | ZWNBSP | NEL | OGHAM_SPACE_MARK + | EN_QUAD..=ZWSP | NNBSP | MMSP | IDEOGRAPHIC_SPACE ) } // https://github.com/microsoft/TypeScript/blob/b8e4ed8aeb0b228f544c5736908c31f136a9f7e3/src/compiler/scanner.ts#L556 -// TODO: Unclear why we match `ZWSP` here, and not in `is_irregular_whitespace`. -// https://github.com/oxc-project/oxc/pull/6639 pub fn is_white_space_single_line(c: char) -> bool { // Note: nextLine is in the Zs space, and should be considered to be a whitespace. // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript. - matches!(c, SP | TAB | ZWSP) || is_irregular_whitespace(c) + matches!(c, SP | TAB) || is_irregular_whitespace(c) } // 11.3 Line Terminators diff --git a/crates/oxc_syntax/src/lib.rs b/crates/oxc_syntax/src/lib.rs index 8e5388f5190f3..b1efc6889c05b 100644 --- a/crates/oxc_syntax/src/lib.rs +++ b/crates/oxc_syntax/src/lib.rs @@ -17,4 +17,6 @@ mod generated { mod derive_clone_in; mod derive_content_eq; mod derive_content_hash; + #[cfg(feature = "serialize")] + mod derive_estree; } diff --git a/crates/oxc_syntax/src/operator.rs b/crates/oxc_syntax/src/operator.rs index c52d75a929446..7a47493eadbdc 100644 --- a/crates/oxc_syntax/src/operator.rs +++ b/crates/oxc_syntax/src/operator.rs @@ -6,9 +6,8 @@ use oxc_allocator::CloneIn; use oxc_ast_macros::ast; +use oxc_estree::ESTree; use oxc_span::{cmp::ContentEq, hash::ContentHash}; -#[cfg(feature = "serialize")] -use {serde::Serialize, tsify::Tsify}; use crate::precedence::{GetPrecedence, Precedence}; @@ -18,56 +17,56 @@ use crate::precedence::{GetPrecedence, Precedence}; /// - [13.15 Assignment Operators](https://tc39.es/ecma262/#sec-assignment-operators) #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum AssignmentOperator { /// `=` - #[serde(rename = "=")] + #[estree(rename = "=")] Assign = 0, /// `+=` - #[serde(rename = "+=")] + #[estree(rename = "+=")] Addition = 1, /// `-=` - #[serde(rename = "-=")] + #[estree(rename = "-=")] Subtraction = 2, /// `*=` - #[serde(rename = "*=")] + #[estree(rename = "*=")] Multiplication = 3, /// `/=` - #[serde(rename = "/=")] + #[estree(rename = "/=")] Division = 4, /// `%=` - #[serde(rename = "%=")] + #[estree(rename = "%=")] Remainder = 5, /// `<<=` - #[serde(rename = "<<=")] + #[estree(rename = "<<=")] ShiftLeft = 6, /// `>>=` - #[serde(rename = ">>=")] + #[estree(rename = ">>=")] ShiftRight = 7, /// `>>>=` - #[serde(rename = ">>>=")] + #[estree(rename = ">>>=")] ShiftRightZeroFill = 8, /// `|=` - #[serde(rename = "|=")] + #[estree(rename = "|=")] BitwiseOR = 9, /// `^=` - #[serde(rename = "^=")] + #[estree(rename = "^=")] BitwiseXOR = 10, /// `&=` - #[serde(rename = "&=")] + #[estree(rename = "&=")] BitwiseAnd = 11, /// `&&=` - #[serde(rename = "&&=")] + #[estree(rename = "&&=")] LogicalAnd = 12, /// `||=` - #[serde(rename = "||=")] + #[estree(rename = "||=")] LogicalOr = 13, /// `??=` - #[serde(rename = "??=")] + #[estree(rename = "??=")] LogicalNullish = 14, /// `**=` - #[serde(rename = "**=")] + #[estree(rename = "**=")] Exponential = 15, } @@ -125,74 +124,74 @@ impl AssignmentOperator { /// - [12.10 Binary Logical Operators](https://tc39.es/ecma262/#sec-binary-logical-operators) #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum BinaryOperator { /// `==` - #[serde(rename = "==")] + #[estree(rename = "==")] Equality = 0, /// `!=` - #[serde(rename = "!=")] + #[estree(rename = "!=")] Inequality = 1, /// `===` - #[serde(rename = "===")] + #[estree(rename = "===")] StrictEquality = 2, /// `!==` - #[serde(rename = "!==")] + #[estree(rename = "!==")] StrictInequality = 3, /// `<` - #[serde(rename = "<")] + #[estree(rename = "<")] LessThan = 4, /// `<=` - #[serde(rename = "<=")] + #[estree(rename = "<=")] LessEqualThan = 5, /// `>` - #[serde(rename = ">")] + #[estree(rename = ">")] GreaterThan = 6, /// `>=` - #[serde(rename = ">=")] + #[estree(rename = ">=")] GreaterEqualThan = 7, /// `<<` - #[serde(rename = "<<")] + #[estree(rename = "<<")] ShiftLeft = 8, /// `>>` - #[serde(rename = ">>")] + #[estree(rename = ">>")] ShiftRight = 9, /// `>>>` - #[serde(rename = ">>>")] + #[estree(rename = ">>>")] ShiftRightZeroFill = 10, /// `+` - #[serde(rename = "+")] + #[estree(rename = "+")] Addition = 11, /// `-` - #[serde(rename = "-")] + #[estree(rename = "-")] Subtraction = 12, /// `*` - #[serde(rename = "*")] + #[estree(rename = "*")] Multiplication = 13, /// `/` - #[serde(rename = "/")] + #[estree(rename = "/")] Division = 14, /// `%` - #[serde(rename = "%")] + #[estree(rename = "%")] Remainder = 15, /// `|` - #[serde(rename = "|")] + #[estree(rename = "|")] BitwiseOR = 16, /// `^` - #[serde(rename = "^")] + #[estree(rename = "^")] BitwiseXOR = 17, /// `&` - #[serde(rename = "&")] + #[estree(rename = "&")] BitwiseAnd = 18, /// `in` - #[serde(rename = "in")] + #[estree(rename = "in")] In = 19, /// `instanceof` - #[serde(rename = "instanceof")] + #[estree(rename = "instanceof")] Instanceof = 20, /// `**` - #[serde(rename = "**")] + #[estree(rename = "**")] Exponential = 21, } @@ -356,17 +355,17 @@ impl GetPrecedence for BinaryOperator { /// Logical binary operators #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum LogicalOperator { /// `||` - #[serde(rename = "||")] + #[estree(rename = "||")] Or = 0, /// `&&` - #[serde(rename = "&&")] + #[estree(rename = "&&")] And = 1, /// `??` - #[serde(rename = "??")] + #[estree(rename = "??")] Coalesce = 2, } @@ -410,29 +409,29 @@ impl GetPrecedence for LogicalOperator { /// - [12.5 Unary Operators](https://tc39.es/ecma262/#sec-unary-operators) #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum UnaryOperator { /// `-` - #[serde(rename = "-")] + #[estree(rename = "-")] UnaryNegation = 0, /// `+` - #[serde(rename = "+")] + #[estree(rename = "+")] UnaryPlus = 1, /// `!` - #[serde(rename = "!")] + #[estree(rename = "!")] LogicalNot = 2, /// `~` - #[serde(rename = "~")] + #[estree(rename = "~")] BitwiseNot = 3, /// `typeof` - #[serde(rename = "typeof")] + #[estree(rename = "typeof")] Typeof = 4, /// `void` - #[serde(rename = "void")] + #[estree(rename = "void")] Void = 5, /// `delete` - #[serde(rename = "delete")] + #[estree(rename = "delete")] Delete = 6, } @@ -481,14 +480,14 @@ impl UnaryOperator { /// Unary update operators. #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq, ContentHash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[generate_derive(CloneIn, ContentEq, ContentHash, ESTree)] +#[estree(rename_all = "camelCase")] pub enum UpdateOperator { /// `++` - #[serde(rename = "++")] + #[estree(rename = "++")] Increment = 0, /// `--` - #[serde(rename = "--")] + #[estree(rename = "--")] Decrement = 1, } diff --git a/crates/oxc_transformer/CHANGELOG.md b/crates/oxc_transformer/CHANGELOG.md index b685e6a047165..ce09955230828 100644 --- a/crates/oxc_transformer/CHANGELOG.md +++ b/crates/oxc_transformer/CHANGELOG.md @@ -4,6 +4,62 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +### Features + +- a01a5df transformer: Pass TransformerCtx to async-to-generator plugin (#6633) (Dunqing) +- a9260cf transformer: `async-to-generator` plugin. (#5590) (Ethan Goh) +- 8fe1b0a transformer: Support helper loader (#6162) (Dunqing) +- ab51c2a transformer: Support `DefaultImport` in `ModuleImports` (#6434) (Dunqing) +- a3dea9c transformer/async-to-generator: Handle arrow-function correctly (#6640) (Dunqing) +- 41c8675 transformer/object-rest-spread: Using helper loader (#6449) (Dunqing) + +### Bug Fixes + +- 1d3d256 transformer: Correctly trim JSX (#6639) (magic-akari) +- c6f2b5f transformer: `HelperLoader` common transform: do not assume `babelHelpers` is global (#6569) (overlookmotel) +- 85d93ed transformer: Arrow function transform: correctly resolve `this` in class accessor properties (#6386) (overlookmotel) + +### Performance + +- f70a413 transformer: Object spread transform: do not lookup `Object` binding if not needed (#6570) (overlookmotel) + +### Documentation + +- f3451d7 transformer/async-to-generator: Remove empty lines from doc comment (#6642) (overlookmotel) +- 448388a transformer/module_imports: Update outdated comments (#6574) (Dunqing) + +### Refactor + +- 856cab5 ecmascript: Move ToInt32 from `oxc_syntax` to `oxc_ecmascript` (#6471) (Boshen) +- 1ba2a24 ecmascript: Remove `HasProto` which is not part of the spec (#6470) (Boshen) +- 435a89c oxc: Remove useless `allocator.alloc(program)` calls (#6571) (Boshen) +- 9281234 transformer: Shorten imports (#6643) (overlookmotel) +- 3af0840 transformer: `HelperLoader`: add import immediately (#6601) (overlookmotel) +- f81aa7f transformer: `HelperLoader` common transform: comments (#6599) (overlookmotel) +- 679cc68 transformer: `HelperLoader` common transform: construct string directly in arena (#6596) (overlookmotel) +- c346ebb transformer: `HelperLoader` common transform: `Helper` enum (#6595) (overlookmotel) +- 7a028b3 transformer: Remove unnecessary `#![warn]` attr (#6585) (overlookmotel) +- 8c6afe0 transformer: Reorder imports (#6582) (overlookmotel) +- 779ff46 transformer: `HelperLoader` common transform: `Helper` struct (#6568) (overlookmotel) +- bc24a24 transformer: `HelperLoader` common transform: use hashmap `Entry` API (#6567) (overlookmotel) +- 9f02fc7 transformer: `HelperLoader` common transform: re-order fields (#6565) (overlookmotel) +- 50ecade transformer: `HelperLoader` common transform: remove `Rc`s (#6564) (overlookmotel) +- 1c1e9fc transformer: `HelperLoader` common transform: reorder methods (#6563) (overlookmotel) +- c9054c8 transformer: Rename `ImportKind` to `Import` (#6561) (overlookmotel) +- 9542c4e transformer: Add more specific methods to `ModuleImportsStore` (#6560) (overlookmotel) +- 7e57a1d transformer: `ImportKind` use `BoundIdentifier` (#6559) (overlookmotel) +- 602df9d transformer: Re-order fields of `Common` and `TransformCtx` (#6562) (overlookmotel) +- 390abca transformer/async-to-generator: Use `helper_call_expr` (#6634) (Dunqing) +- 2ff917f transformer/async-to-generator: Move internal methods below entry points (#6632) (Dunqing) + +### Styling + +- 9d43a11 transformer: Re-order dependencies (#6659) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 01b878e parser: [**BREAKING**] Use `BindingIdentifier` for `namespace` declaration names (#6003) (DonIsaac) diff --git a/crates/oxc_transformer/Cargo.toml b/crates/oxc_transformer/Cargo.toml index 168c5b2942d56..492b79a92c613 100644 --- a/crates/oxc_transformer/Cargo.toml +++ b/crates/oxc_transformer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_transformer" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/crates/oxc_traverse/CHANGELOG.md b/crates/oxc_traverse/CHANGELOG.md index e390bf25966be..9d53f39a54b3a 100644 --- a/crates/oxc_traverse/CHANGELOG.md +++ b/crates/oxc_traverse/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 2808973 ast: [**BREAKING**] Add `Program::comments` (#6445) (Boshen) + +### Features + +- d9718ad ast_tools: Support `#[scope(exit_before)]` (#6350) (DonIsaac) + +### Bug Fixes + +- 834ee2a semantic: `TSConditionalType` scope enter/exit locations (#6351) (DonIsaac) + +### Performance + +- ac77c87 traverse: Optimize `TraverseScoping::generate_uid_name` (#6663) (overlookmotel) + +### Refactor + +- 073b02a ast: Type params field before params in TS function declaration types (#6391) (overlookmotel) + ## [0.31.0] - 2024-10-08 - 01b878e parser: [**BREAKING**] Use `BindingIdentifier` for `namespace` declaration names (#6003) (DonIsaac) diff --git a/crates/oxc_traverse/Cargo.toml b/crates/oxc_traverse/Cargo.toml index 095cbab89d993..8858bede45212 100644 --- a/crates/oxc_traverse/Cargo.toml +++ b/crates/oxc_traverse/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_traverse" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/editors/vscode/CHANGELOG.md b/editors/vscode/CHANGELOG.md index 3e8607801daab..ea52d8ff6aa50 100644 --- a/editors/vscode/CHANGELOG.md +++ b/editors/vscode/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.10.0] - 2024-10-18 + +- 7f6b219 editor/vscode: [**BREAKING**] Unify configuration logic (#6630) (DonIsaac) + +### Features + + +### Bug Fixes + +- cf92730 editor: Use human-readable output channel names (#6629) (DonIsaac) +- d9159a2 editor: Misaligned command prefixes (#6628) (DonIsaac) +- b9c94bb editors/vscode: Temporarily solve oxc_language_server issue on windows (#6384) (dalaoshu) + ## [0.9.10] - 2024-10-07 ### Features diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 9119ad4720f95..076697981e2cc 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -3,7 +3,7 @@ "description": "oxc vscode extension", "packageManager": "pnpm@9.12.1", "license": "MIT", - "version": "0.9.10", + "version": "0.10.0", "icon": "icon.png", "publisher": "oxc", "displayName": "Oxc", diff --git a/napi/transform/CHANGELOG.md b/napi/transform/CHANGELOG.md index 111a092b37f65..25fd40270a834 100644 --- a/napi/transform/CHANGELOG.md +++ b/napi/transform/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.32.0] - 2024-10-19 + +- 91c87dd codegen: [**BREAKING**] Remove `Codegen::enableSourceMap` API (#6452) (Boshen) + +- 7645e5c codegen: [**BREAKING**] Remove CommentOptions API (#6451) (Boshen) + +- 5200960 oxc: [**BREAKING**] Remove passing `Trivias` around (#6446) (Boshen) + +### Refactor + + ## [0.31.0] - 2024-10-08 - 020bb80 codegen: [**BREAKING**] Change to `CodegenReturn::code` and `CodegenReturn::map` (#6310) (Boshen) diff --git a/napi/transform/Cargo.toml b/napi/transform/Cargo.toml index 7e87598cba26c..d38746238ac38 100644 --- a/napi/transform/Cargo.toml +++ b/napi/transform/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxc_transform_napi" -version = "0.31.0" +version = "0.32.0" authors.workspace = true categories.workspace = true edition.workspace = true diff --git a/npm/oxc-parser/package.json b/npm/oxc-parser/package.json index 5ed04889a79e9..257842ee55929 100644 --- a/npm/oxc-parser/package.json +++ b/npm/oxc-parser/package.json @@ -1,6 +1,6 @@ { "name": "oxc-parser", - "version": "0.31.0", + "version": "0.32.0", "description": "Oxc Parser Node API", "keywords": [ "Parser" diff --git a/npm/oxc-transform/package.json b/npm/oxc-transform/package.json index 1cde24f6d844f..f1e7dee3a2ad1 100644 --- a/npm/oxc-transform/package.json +++ b/npm/oxc-transform/package.json @@ -1,6 +1,6 @@ { "name": "oxc-transform", - "version": "0.31.0", + "version": "0.32.0", "description": "Oxc transform Node API", "keywords": [ "transform" diff --git a/npm/oxlint/CHANGELOG.md b/npm/oxlint/CHANGELOG.md index 44ab161f6269f..168405250adee 100644 --- a/npm/oxlint/CHANGELOG.md +++ b/npm/oxlint/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) until v1.0.0. +## [0.10.0] - 2024-10-18 + +### Features + +- 6e3224d linter: Configure by category in config files (#6120) (DonIsaac) + ## [0.9.9] - 2024-09-27 ### Bug Fixes diff --git a/npm/oxlint/package.json b/npm/oxlint/package.json index f06c7b12409cc..990bcb450526a 100644 --- a/npm/oxlint/package.json +++ b/npm/oxlint/package.json @@ -1,6 +1,6 @@ { "name": "oxlint", - "version": "0.9.10", + "version": "0.10.0", "description": "Linter for the JavaScript Oxidation Compiler", "keywords": [], "author": "Boshen and oxc contributors", diff --git a/tasks/ast_tools/src/derives/estree.rs b/tasks/ast_tools/src/derives/estree.rs new file mode 100644 index 0000000000000..82457ffa83e6c --- /dev/null +++ b/tasks/ast_tools/src/derives/estree.rs @@ -0,0 +1,229 @@ +use convert_case::{Case, Casing}; +use itertools::Itertools; +use proc_macro2::TokenStream; +use quote::quote; + +use super::{define_derive, Derive, DeriveOutput}; +use crate::{ + codegen::LateCtx, + markers::ESTreeStructAttribute, + schema::{ + serialize::{enum_variant_name, get_type_tag}, + EnumDef, GetGenerics, GetIdent, StructDef, TypeDef, TypeName, + }, +}; + +define_derive! { + pub struct DeriveESTree; +} + +impl Derive for DeriveESTree { + fn trait_name() -> &'static str { + "ESTree" + } + + fn derive(&mut self, def: &TypeDef, _: &LateCtx) -> TokenStream { + let ts_type_def = match def { + TypeDef::Enum(def) => typescript_enum(def), + TypeDef::Struct(def) => typescript_struct(def), + }; + let ts_type_def = quote! { + #[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] + const TS_APPEND_CONTENT: &'static str = #ts_type_def; + }; + if let TypeDef::Struct(def) = def { + if def + .markers + .estree + .as_ref() + .is_some_and(|e| e == &ESTreeStructAttribute::CustomSerialize) + { + return ts_type_def; + } + } + + let body = match def { + TypeDef::Enum(def) => serialize_enum(def), + TypeDef::Struct(def) => serialize_struct(def), + }; + let ident = def.ident(); + + let lifetime = if def.has_lifetime() { quote!(<'a>) } else { TokenStream::new() }; + quote! { + impl #lifetime Serialize for #ident #lifetime { + fn serialize(&self, serializer: S) -> Result { + #body + } + } + + ///@@line_break + #ts_type_def + } + } + + fn prelude() -> TokenStream { + quote! { + #![allow(unused_imports, unused_mut, clippy::match_same_arms)] + + ///@@line_break + use serde::{Serialize, Serializer, ser::SerializeMap}; + } + } +} + +fn serialize_struct(def: &StructDef) -> TokenStream { + let ident = def.ident(); + // If type_tag is Some, we serialize it manually. If None, either one of + // the fields is named r#type, or the struct does not need a "type" field. + let type_tag = get_type_tag(def); + + let mut fields = vec![]; + if let Some(ty) = &type_tag { + fields.push(quote! { map.serialize_entry("type", #ty)?; }); + } + for field in &def.fields { + if field.markers.derive_attributes.estree.skip { + continue; + } + let name = match &field.markers.derive_attributes.estree.rename { + Some(rename) => rename.to_string(), + None => field.name.clone().unwrap().to_case(Case::Camel), + }; + assert!( + !(name == "type" && type_tag.is_some()), + "Unexpected r#type field when #[estree(type = ...)] is specified (on {ident})" + ); + + let ident = field.ident().unwrap(); + if field.markers.derive_attributes.estree.flatten { + fields.push(quote! { + self.#ident.serialize( + serde::__private::ser::FlatMapSerializer(&mut map) + )?; + }); + } else { + fields.push(quote! { + map.serialize_entry(#name, &self.#ident)?; + }); + } + } + + quote! { + let mut map = serializer.serialize_map(None)?; + #(#fields)* + map.end() + } +} + +// 3 different kinds of AST enums: +// 1. Transparent enums, which would be #[serde(untagged)]. These take their +// type tag from their children. Each of the variants is its own struct. +// 2. Type enums, which are not camelCased. These are for example the +// r#type field of a Function, and are used instead of the struct name +// as the type field on the JSON. +// 3. All other enums, which are camelCased. +fn serialize_enum(def: &EnumDef) -> TokenStream { + let ident = def.ident(); + if def.markers.estree.untagged { + let match_branches = def.all_variants().map(|var| { + let var_ident = var.ident(); + assert!(var.fields.len() == 1, "Each variant of an untagged enum must have exactly one inner field (on {ident}::{var_ident})"); + quote! { + #ident::#var_ident(x) => { + Serialize::serialize(x, serializer) + } + } + }); + quote! { + match self { + #(#match_branches),* + } + } + } else { + let match_branches = def.all_variants().map(|var| { + let var_ident = var.ident(); + let enum_name = ident.to_string(); + let discriminant = u32::from(var.discriminant); + let serialized_to = enum_variant_name(var, def); + assert!( + var.fields.is_empty(), + "Tagged enums must not have inner fields (on {ident}::{var_ident})" + ); + quote! { + #ident::#var_ident => { + serializer.serialize_unit_variant(#enum_name, #discriminant, #serialized_to) + } + } + }); + quote! { + match *self { + #(#match_branches),* + } + } + } +} + +// Untagged enums: "type Expression = BooleanLiteral | NullLiteral" +// Tagged enums: "type PropertyKind = 'init' | 'get' | 'set'" +fn typescript_enum(def: &EnumDef) -> String { + let union = if def.markers.estree.untagged { + def.all_variants().map(|var| type_to_string(var.fields[0].typ.name())).join(" | ") + } else { + def.all_variants().map(|var| format!("'{}'", enum_variant_name(var, def))).join(" | ") + }; + let ident = def.ident(); + format!("export type {ident} = {union};") +} + +fn typescript_struct(def: &StructDef) -> String { + let ident = def.ident(); + let mut fields = String::new(); + let mut extends = vec![]; + + if let Some(type_tag) = get_type_tag(def) { + fields.push_str(&format!("\n\ttype: '{type_tag}';")); + } + + for field in &def.fields { + if field.markers.derive_attributes.estree.skip { + continue; + } + let ty = match &field.markers.derive_attributes.tsify_type { + Some(ty) => ty.clone(), + None => type_to_string(field.typ.name()), + }; + + if field.markers.derive_attributes.estree.flatten { + extends.push(ty); + continue; + } + + let name = match &field.markers.derive_attributes.estree.rename { + Some(rename) => rename.to_string(), + None => field.name.clone().unwrap().to_case(Case::Camel), + }; + + fields.push_str(&format!("\n\t{name}: {ty};")); + } + let extends = + if extends.is_empty() { String::new() } else { format!(" & {}", extends.join(" & ")) }; + format!("export type {ident} = ({{{fields}\n}}){extends};") +} + +fn type_to_string(ty: &TypeName) -> String { + match ty { + TypeName::Ident(ident) => match ident.as_str() { + "f64" | "f32" | "usize" | "u64" | "u32" | "u16" | "u8" | "i64" | "i32" | "i16" + | "i8" => "number", + "bool" => "boolean", + "str" | "String" | "Atom" | "CompactStr" => "string", + ty => ty, + } + .to_string(), + TypeName::Vec(type_name) => format!("Array<{}>", type_to_string(type_name)), + TypeName::Box(type_name) | TypeName::Ref(type_name) | TypeName::Complex(type_name) => { + type_to_string(type_name) + } + TypeName::Opt(type_name) => format!("({}) | null", type_to_string(type_name)), + } +} diff --git a/tasks/ast_tools/src/derives/mod.rs b/tasks/ast_tools/src/derives/mod.rs index f6617b34cc399..d1c917d46c7a3 100644 --- a/tasks/ast_tools/src/derives/mod.rs +++ b/tasks/ast_tools/src/derives/mod.rs @@ -7,11 +7,13 @@ use crate::{codegen::LateCtx, schema::TypeDef}; mod clone_in; mod content_eq; mod content_hash; +mod estree; mod get_span; pub use clone_in::DeriveCloneIn; pub use content_eq::DeriveContentEq; pub use content_hash::DeriveContentHash; +pub use estree::DeriveESTree; pub use get_span::{DeriveGetSpan, DeriveGetSpanMut}; pub trait Derive { @@ -40,10 +42,10 @@ macro_rules! define_derive { let prelude = Self::prelude(); // from `x::y::z` to `crate::y::z::*` - let use_modules = module_paths.into_iter().map(|it|{ + let use_modules = module_paths.into_iter().map(|it| { let local_path = ["crate"] .into_iter() - .chain(it.split("::").skip(1)) + .chain(it.strip_suffix("::mod").unwrap_or(it).split("::").skip(1)) .chain(["*"]) .join("::"); let use_module: syn::ItemUse = @@ -106,10 +108,17 @@ macro_rules! define_derive { .fold(Vec::new(), |mut acc, (path, (modules, streams))| { let mut modules = Vec::from_iter(modules); modules.sort(); + + let file_name = Self::trait_name().to_case(Case::Snake); + let file_name = match file_name.as_str() { + "es_tree" => "estree", + f => f, + }; + acc.push(( $crate::output( format!("crates/{}", path.split("::").next().unwrap()).as_str(), - format!("derive_{}.rs", Self::trait_name().to_case(Case::Snake)).as_str() + format!("derive_{}.rs", file_name).as_str() ), Self::template( modules, diff --git a/tasks/ast_tools/src/main.rs b/tasks/ast_tools/src/main.rs index dc9e3595dfef2..c500924f418c4 100644 --- a/tasks/ast_tools/src/main.rs +++ b/tasks/ast_tools/src/main.rs @@ -17,7 +17,10 @@ mod rust_ast; mod schema; mod util; -use derives::{DeriveCloneIn, DeriveContentEq, DeriveContentHash, DeriveGetSpan, DeriveGetSpanMut}; +use derives::{ + DeriveCloneIn, DeriveContentEq, DeriveContentHash, DeriveESTree, DeriveGetSpan, + DeriveGetSpanMut, +}; use fmt::cargo_fmt; use generators::{ AssertLayouts, AstBuilderGenerator, AstKindGenerator, Generator, GeneratorOutput, @@ -75,6 +78,7 @@ fn main() -> std::result::Result<(), Box> { .derive(DeriveGetSpanMut) .derive(DeriveContentEq) .derive(DeriveContentHash) + .derive(DeriveESTree) .generate(AssertLayouts) .generate(AstKindGenerator) .generate(AstBuilderGenerator) diff --git a/tasks/ast_tools/src/markers.rs b/tasks/ast_tools/src/markers.rs index 7d634c8bd8a00..9b3996383fcf9 100644 --- a/tasks/ast_tools/src/markers.rs +++ b/tasks/ast_tools/src/markers.rs @@ -7,7 +7,7 @@ use syn::{ parse2, punctuated::Punctuated, spanned::Spanned, - token, Attribute, Expr, Ident, Meta, MetaNameValue, Token, + token, Attribute, Expr, Ident, LitStr, Meta, MetaNameValue, Token, }; use crate::util::NormalizeError; @@ -74,6 +74,8 @@ pub struct ScopeMarkers { #[derive(Debug, Default, Serialize)] pub struct DeriveAttributes { pub clone_in: CloneInAttribute, + pub estree: ESTreeFieldAttribute, + pub tsify_type: Option, } /// A enum representing the value passed in `#[clone_in(...)]` derive helper attribute. @@ -94,6 +96,137 @@ impl From<&Ident> for CloneInAttribute { } } +/// An enum representing the `#[estree(...)]` attributes that we implement for structs. +#[derive(Debug, Serialize, PartialEq, Eq)] +pub enum ESTreeStructAttribute { + CustomSerialize, + NoType, + Type(String), +} + +impl Parse for ESTreeStructAttribute { + fn parse(input: ParseStream) -> Result { + let is_type = input.peek(Token![type]); + if is_type { + input.parse::()?; + input.parse::()?; + Ok(Self::Type(input.parse::()?.value())) + } else { + let ident = input.call(Ident::parse_any).unwrap().to_string(); + match ident.as_str() { + "no_type" => Ok(Self::NoType), + "custom_serialize" => Ok(Self::CustomSerialize), + _ => panic!("Unsupported #[estree(...)] argument: {ident}"), + } + } + } +} + +/// A struct representing the `#[estree(...)]` attributes that we implement for enums. +#[derive(Debug, Serialize, Default)] +pub struct ESTreeEnumAttribute { + pub rename_all: Option, + pub untagged: bool, +} + +impl Parse for ESTreeEnumAttribute { + fn parse(input: ParseStream) -> Result { + let mut rename_all = None; + let mut untagged = false; + + loop { + let ident = input.call(Ident::parse_any).unwrap().to_string(); + match ident.as_str() { + "rename_all" => { + input.parse::()?; + assert!( + rename_all.replace(input.parse::()?.value()).is_none(), + "Duplicate estree(rename_all)" + ); + } + "untagged" => { + if untagged { + panic!("Duplicate estree(untagged)"); + } else { + untagged = true; + } + } + arg => panic!("Unsupported #[estree(...)] argument: {arg}"), + } + let comma = input.peek(Token![,]); + if comma { + input.parse::().unwrap(); + } else { + break; + } + } + Ok(Self { rename_all, untagged }) + } +} + +/// A struct representing the `#[estree(...)]` attributes that we implement for fields. +#[derive(Debug, Serialize, Default)] +pub struct ESTreeFieldAttribute { + pub flatten: bool, + pub skip: bool, + pub rename: Option, +} + +impl Parse for ESTreeFieldAttribute { + fn parse(input: ParseStream) -> Result { + let mut flatten = false; + let mut skip = false; + let mut rename = None; + + loop { + let ident = input.call(Ident::parse_any).unwrap().to_string(); + match ident.as_str() { + "rename" => { + input.parse::()?; + assert!( + rename.replace(input.parse::()?.value()).is_none(), + "Duplicate estree(rename)" + ); + } + "flatten" => { + if flatten { + panic!("Duplicate estree(flatten)"); + } else { + flatten = true; + } + } + "skip" => { + if skip { + panic!("Duplicate estree(skip)"); + } else { + skip = true; + } + } + arg => panic!("Unsupported #[estree(...)] argument: {arg}"), + } + let comma = input.peek(Token![,]); + if comma { + input.parse::().unwrap(); + } else { + break; + } + } + Ok(Self { flatten, skip, rename }) + } +} + +/// A struct representing the `#[tsify(type = "...")]` attribute. +pub struct TsifyAttribute(String); + +impl Parse for TsifyAttribute { + fn parse(input: ParseStream) -> Result { + input.parse::()?; + input.parse::()?; + let type_ = input.parse::()?; + Ok(Self(type_.value())) + } +} + /// A struct representing the `#[scope(...)]` attribute. #[derive(Debug, Default)] pub struct ScopeAttribute { @@ -228,13 +361,44 @@ where Ok(None) } } + fn try_parse_estree(attr: &Attribute) -> crate::Result> { + if attr.path().is_ident("estree") { + let arg = attr.parse_args_with(ESTreeFieldAttribute::parse).normalize()?; + Ok(Some(arg)) + } else { + Ok(None) + } + } + fn try_parse_tsify_type(attr: &Attribute) -> crate::Result> { + if attr.path().is_ident("tsify") { + let arg = attr.parse_args_with(TsifyAttribute::parse).normalize()?; + Ok(Some(arg.0)) + } else { + Ok(None) + } + } let mut clone_in = None; + let mut estree = None; + let mut tsify_type = None; for attr in attrs { if let Some(attr) = try_parse_clone_in(attr)? { assert!(clone_in.replace(attr).is_none(), "Duplicate `#[clone_in(...)]` attribute."); } + if let Some(attr) = try_parse_estree(attr)? { + assert!(estree.replace(attr).is_none(), "Duplicate `#[estree(...)]` attribute."); + } + if let Some(attr) = try_parse_tsify_type(attr)? { + assert!( + tsify_type.replace(attr).is_none(), + "Duplicate `#[tsify(type = \"...\")]` attribute." + ); + } } - Ok(DeriveAttributes { clone_in: clone_in.unwrap_or_default() }) + Ok(DeriveAttributes { + clone_in: clone_in.unwrap_or_default(), + estree: estree.unwrap_or_default(), + tsify_type, + }) } pub fn get_scope_attribute<'a, I>(attrs: I) -> Option> @@ -254,3 +418,15 @@ where result.normalize() }) } + +pub fn get_estree_attribute<'a, T, I>(attrs: I) -> Option> +where + I: IntoIterator, + T: Parse, +{ + let attr = attrs.into_iter().find(|it| it.path().is_ident("estree")); + attr.map(|attr| { + debug_assert!(attr.path().is_ident("estree")); + attr.parse_args_with(T::parse).normalize() + }) +} diff --git a/tasks/ast_tools/src/passes/linker.rs b/tasks/ast_tools/src/passes/linker.rs index cac898840f842..2a2d97b964f63 100644 --- a/tasks/ast_tools/src/passes/linker.rs +++ b/tasks/ast_tools/src/passes/linker.rs @@ -49,8 +49,8 @@ impl Pass for Linker { .meta .inherits .drain(..) - .map(|it| match it { - Inherit::Unlinked(ref sup) => { + .map(|it| match &it { + Inherit::Unlinked(sup) => { let linkee = ctx .find(&Cow::Owned(sup.to_string())) .normalize_with(format!("Unknown type {sup:?}"))?; diff --git a/tasks/ast_tools/src/schema/defs.rs b/tasks/ast_tools/src/schema/defs.rs index 4625599165477..488c8789f1d28 100644 --- a/tasks/ast_tools/src/schema/defs.rs +++ b/tasks/ast_tools/src/schema/defs.rs @@ -2,7 +2,10 @@ use serde::Serialize; use super::{with_either, TypeName}; use crate::{ - markers::{DeriveAttributes, ScopeAttribute, ScopeMarkers, VisitMarkers}, + markers::{ + DeriveAttributes, ESTreeEnumAttribute, ESTreeStructAttribute, ScopeAttribute, ScopeMarkers, + VisitMarkers, + }, util::{ToIdent, TypeAnalysis, TypeWrapper}, TypeId, }; @@ -60,7 +63,7 @@ pub struct StructDef { #[serde(skip)] pub generated_derives: Vec, #[serde(skip)] - pub markers: OuterMarkers, + pub markers: StructOuterMarkers, #[serde(skip)] pub module_path: String, } @@ -84,6 +87,8 @@ pub struct EnumDef { pub generated_derives: Vec, #[serde(skip)] pub module_path: String, + #[serde(skip)] + pub markers: EnumOuterMarkers, } impl EnumDef { @@ -226,8 +231,14 @@ impl TypeRef { } #[derive(Debug)] -pub struct OuterMarkers { +pub struct StructOuterMarkers { pub scope: Option, + pub estree: Option, +} + +#[derive(Debug)] +pub struct EnumOuterMarkers { + pub estree: ESTreeEnumAttribute, } #[derive(Debug, Serialize)] diff --git a/tasks/ast_tools/src/schema/mod.rs b/tasks/ast_tools/src/schema/mod.rs index 67e005326f318..fc7df13766558 100644 --- a/tasks/ast_tools/src/schema/mod.rs +++ b/tasks/ast_tools/src/schema/mod.rs @@ -5,7 +5,10 @@ use serde::Serialize; use crate::{ codegen, layout::KnownLayout, - markers::{get_derive_attributes, get_scope_attribute, get_scope_markers, get_visit_markers}, + markers::{ + get_derive_attributes, get_estree_attribute, get_scope_attribute, get_scope_markers, + get_visit_markers, + }, rust_ast as rust, util::{unexpanded_macro_err, TypeExt}, Result, TypeId, @@ -14,6 +17,7 @@ use crate::{ mod defs; mod get_generics; mod get_ident; +pub mod serialize; mod to_type; pub use defs::*; pub use get_generics::GetGenerics; @@ -103,8 +107,15 @@ impl<'a> IntoIterator for &'a Schema { } } -fn parse_outer_markers(attrs: &Vec) -> Result { - Ok(OuterMarkers { scope: get_scope_attribute(attrs).transpose()? }) +fn parse_struct_outer_markers(attrs: &Vec) -> Result { + Ok(StructOuterMarkers { + scope: get_scope_attribute(attrs).transpose()?, + estree: get_estree_attribute(attrs).transpose()?, + }) +} + +fn parse_enum_outer_markers(attrs: &Vec) -> Result { + Ok(EnumOuterMarkers { estree: get_estree_attribute(attrs).transpose()?.unwrap_or_default() }) } fn parse_inner_markers(attrs: &Vec) -> Result { @@ -167,6 +178,7 @@ fn lower_ast_enum(it @ rust::Enum { item, meta }: &rust::Enum, ctx: &codegen::Ea align_32, offsets_32, + markers: parse_enum_outer_markers(&item.attrs).unwrap(), generated_derives: parse_generate_derive(&item.attrs), module_path: meta.module_path.clone(), @@ -201,7 +213,7 @@ fn lower_ast_struct( align_32, offsets_32, - markers: parse_outer_markers(&item.attrs).unwrap(), + markers: parse_struct_outer_markers(&item.attrs).unwrap(), generated_derives: parse_generate_derive(&item.attrs), module_path: meta.module_path.clone(), diff --git a/tasks/ast_tools/src/schema/serialize.rs b/tasks/ast_tools/src/schema/serialize.rs new file mode 100644 index 0000000000000..623402fdf04c8 --- /dev/null +++ b/tasks/ast_tools/src/schema/serialize.rs @@ -0,0 +1,32 @@ +use super::{EnumDef, StructDef, VariantDef}; +use crate::{markers::ESTreeStructAttribute, schema::GetIdent}; +use convert_case::{Case, Casing}; + +pub fn enum_variant_name(var: &VariantDef, enm: &EnumDef) -> String { + match var.markers.derive_attributes.estree.rename.as_ref() { + Some(rename) => rename.to_string(), + None => match enm.markers.estree.rename_all.as_deref() { + Some("camelCase") => var.ident().to_string().to_case(Case::Camel), + Some(case) => { + panic!("Unsupported rename_all: {case} (on {})", enm.ident()) + } + None => var.ident().to_string(), + }, + } +} + +pub fn get_type_tag(def: &StructDef) -> Option { + match &def.markers.estree { + Some(ESTreeStructAttribute::NoType) => None, + Some(ESTreeStructAttribute::Type(type_name)) => Some(type_name.clone()), + Some(ESTreeStructAttribute::CustomSerialize) | None => { + let has_type_field = + def.fields.iter().any(|f| matches!(f.name.as_deref(), Some("type"))); + if has_type_field { + None + } else { + Some(def.ident().to_string()) + } + } + } +} diff --git a/wasm/parser/package.json b/wasm/parser/package.json index 55b641e7696f7..30c9397a0a52a 100644 --- a/wasm/parser/package.json +++ b/wasm/parser/package.json @@ -1,6 +1,6 @@ { "name": "@oxc-parser/wasm", - "version": "0.31.0", + "version": "0.32.0", "description": "Wasm target for the oxc parser.", "packageManager": "pnpm@9.12.1", "keywords": [ From 9f3dfd01cecfbf3c785d52ae2795361f31862dcf Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sun, 20 Oct 2024 00:15:18 +0000 Subject: [PATCH 10/25] [autofix.ci] apply automated fixes --- crates/oxc_allocator/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index 2e11d20d3cf02..8cefe15fa9d16 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -25,9 +25,9 @@ bump-scope = { workspace = true } serde = { workspace = true, optional = true } [dev-dependencies] +bump-scope = { workspace = true, features = ["serde"] } serde = { workspace = true } serde_json = { workspace = true } -bump-scope = { workspace = true, features = ["serde"] } [features] serialize = ["dep:serde", "bump-scope/serde"] From f76c21e146c46cf6b12bd8b49853ed3c09fe1e14 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:54:19 +0200 Subject: [PATCH 11/25] feat(allocator): `IntoIter` newtype, `pub mod vec`, more docs --- crates/oxc_allocator/src/lib.rs | 2 +- crates/oxc_allocator/src/vec.rs | 96 ++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 2b51e660251f3..c686d3f63b52d 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -53,7 +53,7 @@ mod boxed; mod clone_in; mod convert; mod string; -mod vec; +pub mod vec; pub use boxed::{Address, Box}; pub use clone_in::CloneIn; diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 8ed6cc9ff7aeb..0691ac911c467 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -649,6 +649,19 @@ impl_slice_eq1! { ['t] Cow<'_, [T]>, Vec<'t, U> where T: Clone } impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, [U; N] } impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, &[U; N] } +/// A draining iterator for `Vec`. +/// +/// This `struct` is created by [`Vec::drain`]. +/// See its documentation for more. +/// +/// # Example +/// +/// ``` +/// # use oxc_allocator::{ Allocator, Vec }; +/// # let allocator = Allocator::default(); +/// let mut v = Vec::from_iter_in([0, 1, 2], &allocator); +/// let iter: oxc_allocator::vec::Drain<'_, _> = v.drain(..); +/// ``` pub struct Drain<'a, T>(bump_scope::owned_slice::Drain<'a, T>); impl Iterator for Drain<'_, T> { @@ -676,6 +689,20 @@ impl ExactSizeIterator for Drain<'_, T> {} impl FusedIterator for Drain<'_, T> {} +/// A splicing iterator for `Vec`. +/// +/// This struct is created by [`Vec::splice()`]. +/// See its documentation for more. +/// +/// # Example +/// +/// ``` +/// # use oxc_allocator::{ Allocator, Vec }; +/// # let allocator = Allocator::default(); +/// let mut v = Vec::from_iter_in([0, 1, 2], &allocator); +/// let new = [7, 8]; +/// let iter: oxc_allocator::vec::Splice<'_, _> = v.splice(1.., new); +/// ``` pub struct Splice<'a, I: Iterator>(bump_scope::bump_vec::Splice<'a, I, Global>); impl Iterator for Splice<'_, I> { @@ -710,8 +737,73 @@ impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { } } +/// An iterator that moves out of a vector. +/// +/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec) +/// (provided by the [`IntoIterator`] trait). +/// +/// # Example +/// +/// ``` +/// # use oxc_allocator::{ Allocator, Vec }; +/// let v = Vec::from_iter_in([0, 1, 2], &allocator); +/// let iter: std::vec::IntoIter<_> = v.into_iter(); +/// ``` +pub struct IntoIter<'alloc, T>(bump_scope::bump_vec::IntoIter<'alloc, 'alloc, T>); + +impl IntoIter<'_, T> { + /// Returns the remaining items of this iterator as a slice. + #[must_use] + #[inline(always)] + pub fn as_slice(&self) -> &[T] { + self.0.as_slice() + } + + /// Returns the remaining items of this iterator as a mutable slice. + #[must_use] + #[inline(always)] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.0.as_mut_slice() + } +} + +impl Iterator for IntoIter<'_, T> { + type Item = T; + + #[inline(always)] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline(always)] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline(always)] + fn count(self) -> usize { + self.0.count() + } +} + +impl DoubleEndedIterator for IntoIter<'_, T> { + #[inline(always)] + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + +impl ExactSizeIterator for IntoIter<'_, T> { + #[inline(always)] + fn len(&self) -> usize { + self.0.len() + } +} + +impl FusedIterator for IntoIter<'_, T> {} + impl<'alloc, T> IntoIterator for Vec<'alloc, T> { - type IntoIter = as IntoIterator>::IntoIter; + type IntoIter = IntoIter<'alloc, T>; type Item = T; #[inline(always)] @@ -719,7 +811,7 @@ impl<'alloc, T> IntoIterator for Vec<'alloc, T> { let inner = ManuallyDrop::into_inner(self.0); // TODO: `allocator_api2::vec::Vec::IntoIter` is `Drop`. // Wrap it in `ManuallyDrop` to prevent that. - inner.into_iter() + IntoIter(inner.into_iter()) } } From f8208dc3f6b140a8f2709bbc3ff76c33c4838a74 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 02:34:08 +0200 Subject: [PATCH 12/25] feat(allocator): add vec methods, fix clippy and docs --- crates/oxc_allocator/src/vec.rs | 111 ++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 0691ac911c467..319d3773caf6e 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -1,3 +1,7 @@ +// We're wrapping an existing implementation. Having those wrapper functions +// must incur no overhead, so we declare them `#[inline(always)]`. +#![allow(clippy::inline_always)] + //! Arena Vec. //! //! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) @@ -154,7 +158,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// Appends an element to the back of a collection. #[inline(always)] pub fn push(&mut self, value: T) { - self.0.push(value) + self.0.push(value); } /// Removes the last element from a vector and returns it, or [`None`] if it @@ -181,7 +185,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline(always)] pub fn insert(&mut self, index: usize, element: T) { - self.0.insert(index, element) + self.0.insert(index, element); } /// Removes and returns the element at position `index` within the vector, @@ -209,6 +213,34 @@ impl<'alloc, T> Vec<'alloc, T> { self.0.remove(index) } + /// Removes an element from the vector and returns it. + /// + /// The removed element is replaced by the last element of the vector. + /// + /// This does not preserve ordering, but is *O*(1). + /// If you need to preserve the element order, use [`remove`] instead. + /// + /// # Panics + /// Panics if `index` is out of bounds. + /// + /// [`remove`]: Self::remove + /// # Examples + /// ``` + /// # use oxc_allocator::{ Allocator, Vec }; + /// # let allocator = Allocator::default(); + /// let mut v = Vec::from_iter_in(["foo", "bar", "baz", "qux"], &allocator); + /// + /// assert_eq!(v.swap_remove(1), "bar"); + /// assert_eq!(v, ["foo", "qux", "baz"]); + /// + /// assert_eq!(v.swap_remove(0), "foo"); + /// assert_eq!(v, ["baz", "qux"]); + /// ``` + #[inline(always)] + pub fn swap_remove(&mut self, index: usize) -> T { + self.0.swap_remove(index) + } + /// Shortens the vector, keeping the first `len` elements and dropping /// the rest. /// @@ -258,8 +290,8 @@ impl<'alloc, T> Vec<'alloc, T> { /// assert_eq!(vec, []); /// ``` /// - /// [`clear`]: BumpVec::clear - /// [`drain`]: BumpVec::drain + /// [`clear`]: Self::clear + /// [`drain`]: Self::drain #[inline(always)] pub fn truncate(&mut self, len: usize) { self.0.truncate(len); @@ -334,6 +366,8 @@ impl<'alloc, T> Vec<'alloc, T> { pub fn append(&mut self, other: &mut Self) { self.reserve(other.len()); + // SAFETY: + // We have allocated enough space for the additional elements from `other`. unsafe { other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr().add(self.len()), other.len()); @@ -365,6 +399,8 @@ impl<'alloc, T> Vec<'alloc, T> { pub fn prepend(&mut self, other: &mut Self) { self.reserve(other.len()); + // SAFETY: + // We have allocated enough space for the additional elements from `other`. unsafe { // copy existing content forward to make space self.as_mut_ptr().copy_to(self.as_mut_ptr().add(other.len()), self.len()); @@ -489,7 +525,7 @@ impl<'alloc, T> Vec<'alloc, T> { where F: FnMut(&T) -> bool, { - self.retain_mut(|elem| f(elem)) + self.retain_mut(|elem| f(elem)); } /// Retains only the elements specified by the predicate, passing a mutable reference to it. @@ -519,7 +555,7 @@ impl<'alloc, T> Vec<'alloc, T> { where F: FnMut(&mut T) -> bool, { - self.0.retain(f) + self.0.retain(f); } /// Reserves capacity for at least `additional` more elements to be inserted @@ -588,15 +624,63 @@ impl<'alloc, T> Vec<'alloc, T> { /// - `new_len` must be less than or equal to the [`capacity`]. /// - The elements at `old_len..new_len` must be initialized. /// - /// [`resize`]: BumpVec::resize - /// [`truncate`]: BumpVec::truncate - /// [`extend`]: BumpVec::extend - /// [`clear`]: BumpVec::clear - /// [`capacity`]: BumpVec::capacity + /// [`resize`]: Self::resize + /// [`truncate`]: Self::truncate + /// [`extend`]: Self::extend + /// [`clear`]: Self::clear + /// [`capacity`]: Self::capacity #[inline(always)] pub unsafe fn set_len(&mut self, new_len: usize) { self.0.set_len(new_len); } + + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with the result of + /// calling the closure `f`. The return values from `f` will end up + /// in the `Vec` in the order they have been generated. + /// + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method uses a closure to create new values on every push. If + /// you'd rather [`Clone`] a given value, use [`Vec::resize`]. If you + /// want to use the [`Default`] trait to generate values, you can + /// pass [`Default::default`] as the second argument. + #[inline(always)] + pub fn resize_with(&mut self, new_len: usize, f: F) + where + F: FnMut() -> T, + { + self.0.resize_with(new_len, f); + } +} + +impl Vec<'_, T> +where + T: Clone, +{ + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with `value`. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method requires `T` to implement [`Clone`], + /// in order to be able to clone the passed value. + /// If you need more flexibility (or want to rely on [`Default`] instead of + /// [`Clone`]), use [`resize_with`]. + /// If you only need to resize to a smaller size, use [`truncate`]. + /// + /// [`resize_with`]: Self::resize_with + /// [`truncate`]: Self::truncate + #[inline(always)] + pub fn resize(&mut self, new_len: usize, value: T) + where + T: Clone, + { + self.0.resize(new_len, value); + } } impl<'alloc, T: Debug> Debug for Vec<'alloc, T> { @@ -625,6 +709,7 @@ where macro_rules! impl_slice_eq1 { ([$($($vars:tt)+)?] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => { + #[allow(clippy::partialeq_ne_impl)] impl<$($($vars)+,)? T, U> PartialEq<$rhs> for $lhs where T: PartialEq, @@ -739,7 +824,7 @@ impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { /// An iterator that moves out of a vector. /// -/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec) +/// This `struct` is created by the `into_iter` method on [`Vec`] /// (provided by the [`IntoIterator`] trait). /// /// # Example @@ -852,7 +937,7 @@ impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { impl Extend for Vec<'_, T> { #[inline(always)] fn extend>(&mut self, iter: I) { - self.0.extend(iter) + self.0.extend(iter); } } From c069844ca53319ce04379d699bc4d6d97c0429aa Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 02:34:37 +0200 Subject: [PATCH 13/25] fix(allocator): implement serialize without derive for string --- crates/oxc_allocator/src/string.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index 81196eca32671..cc04d630f1b3f 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -2,8 +2,10 @@ use bump_scope::BumpString as StringImpl; use crate::Allocator; +#[cfg(any(feature = "serialize", test))] +use serde::{Serialize, Serializer}; + /// A bump-allocated string. -#[cfg_attr(any(feature = "serialize", test), derive(serde::Serialize))] pub struct String<'a>(StringImpl<'a, 'a>); impl<'a> String<'a> { @@ -50,3 +52,14 @@ impl<'a> String<'a> { self.0.as_str() } } + +#[cfg(any(feature = "serialize", test))] +impl<'alloc> Serialize for String<'alloc> { + #[inline(always)] + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + self.0.serialize(s) + } +} From 1f5e4f8c561ec32849cf2b3e5f1cf76f5c869d25 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 02:54:34 +0200 Subject: [PATCH 14/25] fix(allocator): stacked borrow violation due to missing `as(_mut)_ptr` method for `Vec` --- crates/oxc_allocator/src/vec.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 319d3773caf6e..fd3f45f9d938a 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -155,6 +155,22 @@ impl<'alloc, T> Vec<'alloc, T> { self.0.as_mut_slice() } + /// Returns a raw pointer to the slice, or a dangling raw pointer + /// valid for zero sized reads. + #[must_use] + #[inline(always)] + pub fn as_ptr(&self) -> *const T { + self.0.as_ptr() + } + + /// Returns an unsafe mutable pointer to slice, or a dangling + /// raw pointer valid for zero sized reads. + #[must_use] + #[inline(always)] + pub fn as_mut_ptr(&mut self) -> *mut T { + self.0.as_mut_ptr() + } + /// Appends an element to the back of a collection. #[inline(always)] pub fn push(&mut self, value: T) { From 91262a76ee04ff7c91031fd8ffd1ea18b47a9a77 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 04:00:45 +0200 Subject: [PATCH 15/25] fix: method rename due to merge --- crates/oxc_transformer/src/es2022/class_static_block.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_transformer/src/es2022/class_static_block.rs b/crates/oxc_transformer/src/es2022/class_static_block.rs index 8f637a61f71df..372254f6ecd44 100644 --- a/crates/oxc_transformer/src/es2022/class_static_block.rs +++ b/crates/oxc_transformer/src/es2022/class_static_block.rs @@ -298,7 +298,7 @@ impl<'a> Keys<'a> { let mut key = AString::with_capacity_in(num_str.len() + 1, ctx.ast.allocator); key.push('_'); key.push_str(num_str); - let key = Atom::from(key.into_bump_str()); + let key = Atom::from(key.into_str()); self.numbered.push(&key.as_str()[1..]); From 546a7cdbcf314af0c64220f13fbbe927759e5886 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 06:32:35 +0200 Subject: [PATCH 16/25] refactor(allocator): `bump-scope` generic arguments as constants --- crates/oxc_allocator/src/lib.rs | 21 ++++++++++++++------- crates/oxc_allocator/src/string.rs | 6 ++---- crates/oxc_allocator/src/vec.rs | 4 +--- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index fbf090d9777f5..d6c0b9efdcefe 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -44,7 +44,7 @@ use std::{ ops::{Deref, DerefMut}, }; -use bump_scope::Bump; +use allocator_api2::alloc::Global; /// A bump-allocated string. type BumpScope<'a> = bump_scope::BumpScope<'a>; @@ -63,6 +63,13 @@ pub use convert::{FromIn, IntoIn}; pub use string::String; pub use vec::Vec; +const BUMP_UPWARDS: bool = true; +const MINIMUM_ALIGNMENT: usize = 1; + +type BumpImpl = bump_scope::Bump; +type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +type StringImpl<'a> = bump_scope::BumpString<'a, 'a, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; + /// A bump-allocated memory arena based on [bump-scope]. /// /// ## No `Drop`s @@ -72,7 +79,7 @@ pub use vec::Vec; /// easy to leak memory or other resources. #[derive(Default)] pub struct Allocator { - bump: Bump, + bump: BumpImpl, } impl<'a> From<&'a Allocator> for &'a BumpScope<'a> { @@ -81,14 +88,14 @@ impl<'a> From<&'a Allocator> for &'a BumpScope<'a> { } } -impl From for Allocator { - fn from(bump: Bump) -> Self { +impl From for Allocator { + fn from(bump: BumpImpl) -> Self { Self { bump } } } impl Deref for Allocator { - type Target = Bump; + type Target = BumpImpl; fn deref(&self) -> &Self::Target { &self.bump @@ -105,13 +112,13 @@ impl DerefMut for Allocator { mod test { use std::ops::Deref; - use bump_scope::Bump; + use super::BumpImpl; use crate::Allocator; #[test] fn test_api() { - let bump = Bump::new(); + let bump = BumpImpl::new(); let allocator: Allocator = bump.into(); #[allow(clippy::explicit_deref_methods)] { diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index cc04d630f1b3f..867ae92075195 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -1,12 +1,10 @@ -use bump_scope::BumpString as StringImpl; - -use crate::Allocator; +use crate::{Allocator, StringImpl}; #[cfg(any(feature = "serialize", test))] use serde::{Serialize, Serializer}; /// A bump-allocated string. -pub struct String<'a>(StringImpl<'a, 'a>); +pub struct String<'a>(StringImpl<'a>); impl<'a> String<'a> { /// Constructs a new empty `String`. diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index fd3f45f9d938a..44404a604f5aa 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -23,9 +23,7 @@ use allocator_api2::alloc::Global; #[cfg(any(feature = "serialize", test))] use serde::{ser::SerializeSeq, Serialize, Serializer}; -use crate::{Allocator, Box}; - -type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T>; +use crate::{Allocator, Box, VecImpl}; /// A `Vec` without [`Drop`], which stores its data in the arena allocator. /// From b942f710eb6b9226519210148e526b5cac294f00 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 06:47:32 +0200 Subject: [PATCH 17/25] feat(allocator): removed `Deref` and `From` implementations --- crates/oxc_allocator/src/boxed.rs | 4 +- crates/oxc_allocator/src/clone_in.rs | 2 +- crates/oxc_allocator/src/lib.rs | 55 +++---------------- crates/oxc_allocator/src/string.rs | 8 +-- crates/oxc_allocator/src/vec.rs | 6 +- crates/oxc_span/src/atom.rs | 2 +- .../src/plugins/replace_global_defines.rs | 2 +- 7 files changed, 19 insertions(+), 60 deletions(-) diff --git a/crates/oxc_allocator/src/boxed.rs b/crates/oxc_allocator/src/boxed.rs index 05fd95bc77f9c..0d3b492de027f 100644 --- a/crates/oxc_allocator/src/boxed.rs +++ b/crates/oxc_allocator/src/boxed.rs @@ -68,7 +68,7 @@ impl<'alloc, T> Box<'alloc, T> { /// let in_arena: Box = Box::new_in(5, &arena); /// ``` pub fn new_in(value: T, allocator: &Allocator) -> Self { - Self(allocator.alloc(value).into_raw(), PhantomData) + Self(allocator.bump.alloc(value).into_raw(), PhantomData) } /// Create a fake [`Box`] with a dangling pointer. @@ -176,7 +176,7 @@ mod test { let allocator = Allocator::default(); let mut b = Box::new_in("x", &allocator); let b = &mut *b; - *b = allocator.alloc("v").into_ref(); + *b = allocator.bump.alloc("v").into_ref(); assert_eq!(*b, "v"); } diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index 711cbc6901498..4814030008f3b 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -75,7 +75,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for &'old_alloc str { type Cloned = &'new_alloc str; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { - allocator.alloc_str(self).into_ref() + allocator.alloc_str(self) } } diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index d6c0b9efdcefe..53be998b9fb4d 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -39,16 +39,8 @@ //! assert!(parsed.errors.is_empty()); //! ``` #![warn(missing_docs)] -use std::{ - convert::From, - ops::{Deref, DerefMut}, -}; - use allocator_api2::alloc::Global; -/// A bump-allocated string. -type BumpScope<'a> = bump_scope::BumpScope<'a>; - mod address; mod boxed; mod clone_in; @@ -82,47 +74,14 @@ pub struct Allocator { bump: BumpImpl, } -impl<'a> From<&'a Allocator> for &'a BumpScope<'a> { - fn from(value: &'a Allocator) -> Self { - value.bump.as_scope() - } -} - -impl From for Allocator { - fn from(bump: BumpImpl) -> Self { - Self { bump } - } -} - -impl Deref for Allocator { - type Target = BumpImpl; - - fn deref(&self) -> &Self::Target { - &self.bump - } -} - -impl DerefMut for Allocator { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.bump +impl Allocator { + /// Allocate a string slice. + pub fn alloc_str(&self, s: &str) -> &mut str { + self.bump.alloc_str(s).into_mut() } -} - -#[cfg(test)] -mod test { - use std::ops::Deref; - - use super::BumpImpl; - - use crate::Allocator; - #[test] - fn test_api() { - let bump = BumpImpl::new(); - let allocator: Allocator = bump.into(); - #[allow(clippy::explicit_deref_methods)] - { - _ = allocator.deref(); - } + /// Deallocates every chunk but the newest, which is also the biggest. + pub fn reset(&mut self) { + self.bump.reset(); } } diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index 867ae92075195..2281578dec286 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -10,19 +10,19 @@ impl<'a> String<'a> { /// Constructs a new empty `String`. #[inline] pub fn new_in(allocator: &'a Allocator) -> Self { - Self(StringImpl::new_in(allocator)) + Self(StringImpl::new_in(&allocator.bump)) } /// Constructs a `String` from a `&str`. #[inline] pub fn from_str_in(string: &str, allocator: &'a Allocator) -> Self { - Self(StringImpl::from_str_in(string, allocator)) + Self(StringImpl::from_str_in(string, &allocator.bump)) } /// Constructs a new empty `String` with the specified capacity. #[inline] pub fn with_capacity_in(capacity: usize, allocator: &'a Allocator) -> Self { - Self(StringImpl::with_capacity_in(capacity, allocator)) + Self(StringImpl::with_capacity_in(capacity, &allocator.bump)) } /// Converts a `String` into a `&str`. @@ -53,7 +53,7 @@ impl<'a> String<'a> { #[cfg(any(feature = "serialize", test))] impl<'alloc> Serialize for String<'alloc> { - #[inline(always)] + #[inline] fn serialize(&self, s: S) -> Result where S: Serializer, diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 44404a604f5aa..8853fa2df499d 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -54,7 +54,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline(always)] pub fn new_in(allocator: &'alloc Allocator) -> Self { - Self(ManuallyDrop::new(VecImpl::new_in(allocator))) + Self(ManuallyDrop::new(VecImpl::new_in(&allocator.bump))) } /// Constructs a new, empty `Vec` with at least the specified capacity @@ -106,7 +106,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` #[inline(always)] pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self { - Self(ManuallyDrop::new(VecImpl::with_capacity_in(capacity, allocator))) + Self(ManuallyDrop::new(VecImpl::with_capacity_in(capacity, &allocator.bump))) } /// Create a new [`Vec`] whose elements are taken from an iterator and @@ -115,7 +115,7 @@ impl<'alloc, T> Vec<'alloc, T> { /// This is behaviorally identical to [`FromIterator::from_iter`]. #[inline(always)] pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { - Self(ManuallyDrop::new(VecImpl::from_iter_in(iter, allocator))) + Self(ManuallyDrop::new(VecImpl::from_iter_in(iter, &allocator.bump))) } /// Returns the total number of elements the vector can hold without diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index 0b181b6fdab8c..179aa1971ba1f 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -73,7 +73,7 @@ impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> { impl<'alloc> FromIn<'alloc, &str> for Atom<'alloc> { fn from_in(s: &str, allocator: &'alloc Allocator) -> Self { - Self::from(&*oxc_allocator::String::from_str_in(s, allocator).into_str()) + Self::from(oxc_allocator::String::from_str_in(s, allocator).into_str()) } } diff --git a/crates/oxc_transformer/src/plugins/replace_global_defines.rs b/crates/oxc_transformer/src/plugins/replace_global_defines.rs index 1ce131a51ab6e..74c28656bd08d 100644 --- a/crates/oxc_transformer/src/plugins/replace_global_defines.rs +++ b/crates/oxc_transformer/src/plugins/replace_global_defines.rs @@ -229,7 +229,7 @@ impl<'a> ReplaceGlobalDefines<'a> { // Construct a new expression because we don't have ast clone right now. fn parse_value(&self, source_text: &str) -> Expression<'a> { // Allocate the string lazily because replacement happens rarely. - let source_text = self.allocator.alloc_str(source_text).into_ref(); + let source_text = self.allocator.alloc_str(source_text); // Unwrapping here, it should already be checked by [ReplaceGlobalDefinesConfig::new]. Parser::new(self.allocator, source_text, SourceType::default()).parse_expression().unwrap() } From 5e96313d555c2448c66e6abd2a57cb6424f8c0b4 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 07:00:10 +0200 Subject: [PATCH 18/25] feat(allocator): use generic parameter for other `*Impl` types --- crates/oxc_allocator/src/lib.rs | 2 -- crates/oxc_allocator/src/string.rs | 5 ++++- crates/oxc_allocator/src/vec.rs | 12 +++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 53be998b9fb4d..a1e019fc4b422 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -59,8 +59,6 @@ const BUMP_UPWARDS: bool = true; const MINIMUM_ALIGNMENT: usize = 1; type BumpImpl = bump_scope::Bump; -type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; -type StringImpl<'a> = bump_scope::BumpString<'a, 'a, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; /// A bump-allocated memory arena based on [bump-scope]. /// diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index 2281578dec286..c72570a49754d 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -1,8 +1,11 @@ -use crate::{Allocator, StringImpl}; +use crate::{Allocator, BUMP_UPWARDS, MINIMUM_ALIGNMENT}; +use allocator_api2::alloc::Global; #[cfg(any(feature = "serialize", test))] use serde::{Serialize, Serializer}; +type StringImpl<'a> = bump_scope::BumpString<'a, 'a, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; + /// A bump-allocated string. pub struct String<'a>(StringImpl<'a>); diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 8853fa2df499d..13f2005bfdd19 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -23,7 +23,13 @@ use allocator_api2::alloc::Global; #[cfg(any(feature = "serialize", test))] use serde::{ser::SerializeSeq, Serialize, Serializer}; -use crate::{Allocator, Box, VecImpl}; +use crate::{Allocator, Box, BUMP_UPWARDS, MINIMUM_ALIGNMENT}; + +type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +type SpliceImpl<'a, I> = + bump_scope::bump_vec::Splice<'a, I, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +type IntoIterImpl<'a, T> = + bump_scope::bump_vec::IntoIter<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; /// A `Vec` without [`Drop`], which stores its data in the arena allocator. /// @@ -802,7 +808,7 @@ impl FusedIterator for Drain<'_, T> {} /// let new = [7, 8]; /// let iter: oxc_allocator::vec::Splice<'_, _> = v.splice(1.., new); /// ``` -pub struct Splice<'a, I: Iterator>(bump_scope::bump_vec::Splice<'a, I, Global>); +pub struct Splice<'a, I: Iterator>(SpliceImpl<'a, I>); impl Iterator for Splice<'_, I> { type Item = I::Item; @@ -848,7 +854,7 @@ impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { /// let v = Vec::from_iter_in([0, 1, 2], &allocator); /// let iter: std::vec::IntoIter<_> = v.into_iter(); /// ``` -pub struct IntoIter<'alloc, T>(bump_scope::bump_vec::IntoIter<'alloc, 'alloc, T>); +pub struct IntoIter<'alloc, T>(IntoIterImpl<'alloc, T>); impl IntoIter<'_, T> { /// Returns the remaining items of this iterator as a slice. From 2e3d33bdd3ecc44333ece406dbf228c49ffe1775 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 07:02:39 +0200 Subject: [PATCH 19/25] feat(allocator): `inline(always)` what wasn't already --- crates/oxc_allocator/src/lib.rs | 8 +++++++- crates/oxc_allocator/src/string.rs | 16 ++++++++-------- crates/oxc_allocator/src/vec.rs | 4 ---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index a1e019fc4b422..5a758ff2e7342 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -39,6 +39,10 @@ //! assert!(parsed.errors.is_empty()); //! ``` #![warn(missing_docs)] +// We're wrapping an existing implementation. Having those wrapper functions +// must incur no overhead, so we declare them `#[inline(always)]`. +#![allow(clippy::inline_always)] + use allocator_api2::alloc::Global; mod address; @@ -55,7 +59,7 @@ pub use convert::{FromIn, IntoIn}; pub use string::String; pub use vec::Vec; -const BUMP_UPWARDS: bool = true; +const BUMP_UPWARDS: bool = false; const MINIMUM_ALIGNMENT: usize = 1; type BumpImpl = bump_scope::Bump; @@ -74,11 +78,13 @@ pub struct Allocator { impl Allocator { /// Allocate a string slice. + #[inline(always)] pub fn alloc_str(&self, s: &str) -> &mut str { self.bump.alloc_str(s).into_mut() } /// Deallocates every chunk but the newest, which is also the biggest. + #[inline(always)] pub fn reset(&mut self) { self.bump.reset(); } diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index c72570a49754d..92f4e3e06c0cf 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -11,44 +11,44 @@ pub struct String<'a>(StringImpl<'a>); impl<'a> String<'a> { /// Constructs a new empty `String`. - #[inline] + #[inline(always)] pub fn new_in(allocator: &'a Allocator) -> Self { Self(StringImpl::new_in(&allocator.bump)) } /// Constructs a `String` from a `&str`. - #[inline] + #[inline(always)] pub fn from_str_in(string: &str, allocator: &'a Allocator) -> Self { Self(StringImpl::from_str_in(string, &allocator.bump)) } /// Constructs a new empty `String` with the specified capacity. - #[inline] + #[inline(always)] pub fn with_capacity_in(capacity: usize, allocator: &'a Allocator) -> Self { Self(StringImpl::with_capacity_in(capacity, &allocator.bump)) } /// Converts a `String` into a `&str`. - #[inline] + #[inline(always)] pub fn into_str(self) -> &'a str { // First converts it to a `FixedBumpString` to suppress it trying to shrink its allocation. self.0.into_fixed_string().into_str() } /// Appends a given string slice to the end of this string. - #[inline] + #[inline(always)] pub fn push_str(&mut self, string: &str) { self.0.push_str(string); } /// Appends a given `char` to the end of this string. - #[inline] + #[inline(always)] pub fn push(&mut self, c: char) { self.0.push(c); } /// Extracts a string slice containing the entire `String`. - #[inline] + #[inline(always)] pub fn as_str(&self) -> &str { self.0.as_str() } @@ -56,7 +56,7 @@ impl<'a> String<'a> { #[cfg(any(feature = "serialize", test))] impl<'alloc> Serialize for String<'alloc> { - #[inline] + #[inline(always)] fn serialize(&self, s: S) -> Result where S: Serializer, diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 13f2005bfdd19..0b2baf2ff9ff1 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -1,7 +1,3 @@ -// We're wrapping an existing implementation. Having those wrapper functions -// must incur no overhead, so we declare them `#[inline(always)]`. -#![allow(clippy::inline_always)] - //! Arena Vec. //! //! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) From 0d40d3cb3326f78713a41211a9c982b8d604dc78 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:13:00 +0200 Subject: [PATCH 20/25] refactor(allocator): `DrainImpl` alias --- crates/oxc_allocator/src/vec.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 0b2baf2ff9ff1..1059ba00a250c 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -22,6 +22,7 @@ use serde::{ser::SerializeSeq, Serialize, Serializer}; use crate::{Allocator, Box, BUMP_UPWARDS, MINIMUM_ALIGNMENT}; type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +type DrainImpl<'a, T> = bump_scope::owned_slice::Drain<'a, T>; type SpliceImpl<'a, I> = bump_scope::bump_vec::Splice<'a, I, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; type IntoIterImpl<'a, T> = @@ -763,7 +764,7 @@ impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, &[U; N] } /// let mut v = Vec::from_iter_in([0, 1, 2], &allocator); /// let iter: oxc_allocator::vec::Drain<'_, _> = v.drain(..); /// ``` -pub struct Drain<'a, T>(bump_scope::owned_slice::Drain<'a, T>); +pub struct Drain<'a, T>(DrainImpl<'a, T>); impl Iterator for Drain<'_, T> { type Item = T; From 5fd3622e4dc6770ef11602889c7d06451218213e Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:17:43 +0200 Subject: [PATCH 21/25] feat(allocator): rename `into_str` back to `into_bump_str` to keep diff with main smaller --- crates/oxc_allocator/src/convert.rs | 2 +- crates/oxc_allocator/src/string.rs | 2 +- crates/oxc_ast/src/ast_builder_impl.rs | 4 ++-- crates/oxc_parser/src/lexer/identifier.rs | 2 +- crates/oxc_parser/src/lexer/string.rs | 2 +- crates/oxc_parser/src/lexer/template.rs | 2 +- crates/oxc_prettier/src/doc.rs | 2 +- crates/oxc_prettier/src/format/string.rs | 2 +- crates/oxc_span/src/atom.rs | 2 +- crates/oxc_transformer/src/common/helper_loader.rs | 2 +- crates/oxc_transformer/src/es2022/class_static_block.rs | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/oxc_allocator/src/convert.rs b/crates/oxc_allocator/src/convert.rs index 05f3c30223a54..2f9122b817a0e 100644 --- a/crates/oxc_allocator/src/convert.rs +++ b/crates/oxc_allocator/src/convert.rs @@ -49,7 +49,7 @@ impl<'a> FromIn<'a, String> for crate::String<'a> { impl<'a> FromIn<'a, String> for &'a str { #[inline(always)] fn from_in(value: String, allocator: &'a Allocator) -> Self { - crate::String::from_str_in(value.as_str(), allocator).into_str() + crate::String::from_str_in(value.as_str(), allocator).into_bump_str() } } diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index 92f4e3e06c0cf..a7b1699dad35d 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -30,7 +30,7 @@ impl<'a> String<'a> { /// Converts a `String` into a `&str`. #[inline(always)] - pub fn into_str(self) -> &'a str { + pub fn into_bump_str(self) -> &'a str { // First converts it to a `FixedBumpString` to suppress it trying to shrink its allocation. self.0.into_fixed_string().into_str() } diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index d1801e9ddc162..47d98436579ce 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -72,13 +72,13 @@ impl<'a> AstBuilder<'a> { /// in the heap. #[inline] pub fn str(self, value: &str) -> &'a str { - String::from_str_in(value, self.allocator).into_str() + String::from_str_in(value, self.allocator).into_bump_str() } /// Allocate an [`Atom`] from a string slice. #[inline] pub fn atom(self, value: &str) -> Atom<'a> { - Atom::from(String::from_str_in(value, self.allocator).into_str()) + Atom::from(String::from_str_in(value, self.allocator).into_bump_str()) } /// # SAFETY diff --git a/crates/oxc_parser/src/lexer/identifier.rs b/crates/oxc_parser/src/lexer/identifier.rs index 0f25883af9c90..961af1da57170 100644 --- a/crates/oxc_parser/src/lexer/identifier.rs +++ b/crates/oxc_parser/src/lexer/identifier.rs @@ -199,7 +199,7 @@ impl<'a> Lexer<'a> { } // Convert `str` to arena slice and save to `escaped_strings` - let id = str.into_str(); + let id = str.into_bump_str(); self.save_string(true, id); id } diff --git a/crates/oxc_parser/src/lexer/string.rs b/crates/oxc_parser/src/lexer/string.rs index e12d579236058..73c9635c83040 100644 --- a/crates/oxc_parser/src/lexer/string.rs +++ b/crates/oxc_parser/src/lexer/string.rs @@ -146,7 +146,7 @@ macro_rules! handle_string_literal_escape { } // Convert `str` to arena slice and save to `escaped_strings` - $lexer.save_string(true, str.into_str()); + $lexer.save_string(true, str.into_bump_str()); Kind::Str }}; diff --git a/crates/oxc_parser/src/lexer/template.rs b/crates/oxc_parser/src/lexer/template.rs index 9ff416104121f..ea672dfa5bb27 100644 --- a/crates/oxc_parser/src/lexer/template.rs +++ b/crates/oxc_parser/src/lexer/template.rs @@ -300,7 +300,7 @@ impl<'a> Lexer<'a> { }, }; - self.save_template_string(is_valid_escape_sequence, str.into_str()); + self.save_template_string(is_valid_escape_sequence, str.into_bump_str()); ret } diff --git a/crates/oxc_prettier/src/doc.rs b/crates/oxc_prettier/src/doc.rs index c753a19dec367..417d7a3e78fc9 100644 --- a/crates/oxc_prettier/src/doc.rs +++ b/crates/oxc_prettier/src/doc.rs @@ -188,7 +188,7 @@ pub trait DocBuilder<'a> { #[inline] fn str(&self, s: &str) -> Doc<'a> { - Doc::Str(String::from_str_in(s, self.allocator()).into_str()) + Doc::Str(String::from_str_in(s, self.allocator()).into_bump_str()) } #[inline] diff --git a/crates/oxc_prettier/src/format/string.rs b/crates/oxc_prettier/src/format/string.rs index f24070d6c9a6a..56f8f92b17419 100644 --- a/crates/oxc_prettier/src/format/string.rs +++ b/crates/oxc_prettier/src/format/string.rs @@ -61,5 +61,5 @@ pub(super) fn print_string<'a>( prefer_single_quote: bool, ) -> &'a str { let enclosing_quote = get_preferred_quote(raw_text, prefer_single_quote); - make_string(p, raw_text, enclosing_quote).into_str() + make_string(p, raw_text, enclosing_quote).into_bump_str() } diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index 179aa1971ba1f..9a424d49af4b0 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -73,7 +73,7 @@ impl<'alloc> FromIn<'alloc, &Atom<'alloc>> for Atom<'alloc> { impl<'alloc> FromIn<'alloc, &str> for Atom<'alloc> { fn from_in(s: &str, allocator: &'alloc Allocator) -> Self { - Self::from(oxc_allocator::String::from_str_in(s, allocator).into_str()) + Self::from(oxc_allocator::String::from_str_in(s, allocator).into_bump_str()) } } diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index f495e64b72f7d..7169223514624 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -251,7 +251,7 @@ impl<'a> HelperLoaderStore<'a> { source.push_str(&self.module_name); source.push_str("/helpers/"); source.push_str(helper_name); - let source = Atom::from(source.into_str()); + let source = Atom::from(source.into_bump_str()); let binding = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import); diff --git a/crates/oxc_transformer/src/es2022/class_static_block.rs b/crates/oxc_transformer/src/es2022/class_static_block.rs index 372254f6ecd44..8f637a61f71df 100644 --- a/crates/oxc_transformer/src/es2022/class_static_block.rs +++ b/crates/oxc_transformer/src/es2022/class_static_block.rs @@ -298,7 +298,7 @@ impl<'a> Keys<'a> { let mut key = AString::with_capacity_in(num_str.len() + 1, ctx.ast.allocator); key.push('_'); key.push_str(num_str); - let key = Atom::from(key.into_str()); + let key = Atom::from(key.into_bump_str()); self.numbered.push(&key.as_str()[1..]); From 864c53f1e42bb4068e83f4b9c77cd794c635419d Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Fri, 25 Oct 2024 05:19:53 +0200 Subject: [PATCH 22/25] feat(allocator): switch back to bumping upwards --- crates/oxc_allocator/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 5a758ff2e7342..44007edea09a9 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -59,7 +59,7 @@ pub use convert::{FromIn, IntoIn}; pub use string::String; pub use vec::Vec; -const BUMP_UPWARDS: bool = false; +const BUMP_UPWARDS: bool = true; const MINIMUM_ALIGNMENT: usize = 1; type BumpImpl = bump_scope::Bump; From badb66ca6fd3f63686b413e349e6ca10a1480e10 Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 26 Oct 2024 05:46:04 +0200 Subject: [PATCH 23/25] fix: UB when splicing by updating `bump-scope` to `0.10.6` --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 841a631c6f4f3..472c70dcbe106 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "bump-scope" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2611a1654ad8eaf7a7ec539964b3fd39e746c2a60a0fc558ec238689a04dcd0" +checksum = "2b9ad7c0b139a8d8d73a36be7596c592e98dbbd11dec24050e7483621451ad76" dependencies = [ "allocator-api2", "serde", diff --git a/Cargo.toml b/Cargo.toml index b5e2965ec546f..c9eea2e5a22ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,7 +128,7 @@ base64 = "0.22.1" base64-simd = "0.8" bitflags = "2.6.0" bpaf = "0.9.15" -bump-scope = "0.10.5" +bump-scope = "0.10.6" cfg-if = "1.0.0" compact_str = "0.8.0" console = "0.15.8" From fe9db0f038f2c9e3b1ecaa91a6298bddaf4a239c Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 26 Oct 2024 05:56:04 +0200 Subject: [PATCH 24/25] feat(allocator): added `from_iter_exact_in` and use it for `CloneIn for Vec` --- crates/oxc_allocator/src/clone_in.rs | 2 +- crates/oxc_allocator/src/vec.rs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index 4814030008f3b..63b6487ff0981 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -59,7 +59,7 @@ where type Cloned = Vec<'new_alloc, C>; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { - Vec::from_iter_in(self.iter().map(|it| it.clone_in(allocator)), allocator) + Vec::from_iter_exact_in(self.iter().map(|it| it.clone_in(allocator)), allocator) } } diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 1059ba00a250c..bf0b2a2979f65 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -117,10 +117,26 @@ impl<'alloc, T> Vec<'alloc, T> { /// /// This is behaviorally identical to [`FromIterator::from_iter`]. #[inline(always)] - pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { + pub fn from_iter_in(iter: I, allocator: &'alloc Allocator) -> Self + where + I: IntoIterator, + { Self(ManuallyDrop::new(VecImpl::from_iter_in(iter, &allocator.bump))) } + /// Create a new [`Vec`] whose elements are taken from an exact iterator and + /// allocated in the given `allocator`. + /// + /// This is behaviorally identical to [`FromIterator::from_iter`]. + #[inline(always)] + pub fn from_iter_exact_in(iter: I, allocator: &'alloc Allocator) -> Self + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + Self(ManuallyDrop::new(VecImpl::from_iter_exact_in(iter, &allocator.bump))) + } + /// Returns the total number of elements the vector can hold without /// reallocating. /// From f7e47f423852a43dd6de6e8a16bfc7cbe49e1e6f Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:49:02 +0200 Subject: [PATCH 25/25] refactor!(allocator): implement `Vec` using `allocator_api2::vec::Vec`, implement `String` as a wrapper around `Vec`, bump downwards --- Cargo.lock | 1 - crates/oxc_allocator/Cargo.toml | 3 +- crates/oxc_allocator/src/boxed.rs | 4 +- crates/oxc_allocator/src/clone_in.rs | 4 +- crates/oxc_allocator/src/lib.rs | 72 ++- crates/oxc_allocator/src/string.rs | 154 ++++- crates/oxc_allocator/src/vec.rs | 921 ++------------------------- 7 files changed, 232 insertions(+), 927 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 472c70dcbe106..fa60f9393ffe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,7 +185,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b9ad7c0b139a8d8d73a36be7596c592e98dbbd11dec24050e7483621451ad76" dependencies = [ "allocator-api2", - "serde", "sptr", ] diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index bd5e94dc9c828..102ef860e8bf9 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -25,9 +25,8 @@ bump-scope = { workspace = true } serde = { workspace = true, optional = true } [dev-dependencies] -bump-scope = { workspace = true, features = ["serde"] } serde = { workspace = true } serde_json = { workspace = true } [features] -serialize = ["dep:serde", "bump-scope/serde"] +serialize = ["dep:serde"] diff --git a/crates/oxc_allocator/src/boxed.rs b/crates/oxc_allocator/src/boxed.rs index 0d3b492de027f..979204b6444e7 100644 --- a/crates/oxc_allocator/src/boxed.rs +++ b/crates/oxc_allocator/src/boxed.rs @@ -68,7 +68,7 @@ impl<'alloc, T> Box<'alloc, T> { /// let in_arena: Box = Box::new_in(5, &arena); /// ``` pub fn new_in(value: T, allocator: &Allocator) -> Self { - Self(allocator.bump.alloc(value).into_raw(), PhantomData) + Self(allocator.alloc(value).into_raw(), PhantomData) } /// Create a fake [`Box`] with a dangling pointer. @@ -176,7 +176,7 @@ mod test { let allocator = Allocator::default(); let mut b = Box::new_in("x", &allocator); let b = &mut *b; - *b = allocator.bump.alloc("v").into_ref(); + *b = allocator.bump.alloc("v").into_mut(); assert_eq!(*b, "v"); } diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index 63b6487ff0981..3610bd7a1edc2 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -7,7 +7,7 @@ use crate::{Allocator, Box, Vec}; /// As a convention `Cloned` associated type should always be the same as `Self`, /// It'd only differ in the lifetime, Here's an example: /// -/// ```ignore +/// ``` /// impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Struct<'old_alloc> { /// type Cloned = Struct<'new_alloc>; /// fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { @@ -59,7 +59,7 @@ where type Cloned = Vec<'new_alloc, C>; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { - Vec::from_iter_exact_in(self.iter().map(|it| it.clone_in(allocator)), allocator) + Vec::from_iter_in(self.iter().map(|it| it.clone_in(allocator)), allocator) } } diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 44007edea09a9..1b8c5e1226a83 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -31,40 +31,40 @@ //! Consumers of the [`oxc` umbrella crate](https://crates.io/crates/oxc) pass //! [`Allocator`] references to other tools. //! -//! ```ignore +//! ``` //! use oxc::{allocator::Allocator, parser::Parser, span::SourceType}; //! -//! let allocator = Allocator::default(); +//! let allocator = Allocator::default() //! let parsed = Parser::new(&allocator, "let x = 1;", SourceType::default()); //! assert!(parsed.errors.is_empty()); //! ``` #![warn(missing_docs)] -// We're wrapping an existing implementation. Having those wrapper functions -// must incur no overhead, so we declare them `#[inline(always)]`. -#![allow(clippy::inline_always)] - -use allocator_api2::alloc::Global; +use std::{ + convert::From, + ops::{Deref, DerefMut}, +}; mod address; mod boxed; mod clone_in; mod convert; mod string; -pub mod vec; +mod vec; pub use address::{Address, GetAddress}; +use allocator_api2::alloc::Global; pub use boxed::Box; pub use clone_in::CloneIn; pub use convert::{FromIn, IntoIn}; pub use string::String; pub use vec::Vec; -const BUMP_UPWARDS: bool = true; +const BUMP_UPWARDS: bool = false; const MINIMUM_ALIGNMENT: usize = 1; -type BumpImpl = bump_scope::Bump; +type Bump = bump_scope::Bump; -/// A bump-allocated memory arena based on [bump-scope]. +/// A bump-allocated memory arena based on [bumpalo]. /// /// ## No `Drop`s /// @@ -73,19 +73,51 @@ type BumpImpl = bump_scope::Bump; /// easy to leak memory or other resources. #[derive(Default)] pub struct Allocator { - bump: BumpImpl, + bump: Bump, } impl Allocator { - /// Allocate a string slice. - #[inline(always)] - pub fn alloc_str(&self, s: &str) -> &mut str { - self.bump.alloc_str(s).into_mut() + /// Allocate a `str`. + pub fn alloc_str(&self, src: &str) -> &mut str { + self.bump.alloc_str(src).into_mut() } +} + +impl From for Allocator { + fn from(bump: Bump) -> Self { + Self { bump } + } +} + +impl Deref for Allocator { + type Target = Bump; + + fn deref(&self) -> &Self::Target { + &self.bump + } +} + +impl DerefMut for Allocator { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bump + } +} + +#[cfg(test)] +mod test { + use std::ops::Deref; + + use bump_scope::Bump; + + use crate::Allocator; - /// Deallocates every chunk but the newest, which is also the biggest. - #[inline(always)] - pub fn reset(&mut self) { - self.bump.reset(); + #[test] + fn test_api() { + let bump = Bump::new(); + let allocator: Allocator = bump.into(); + #[allow(clippy::explicit_deref_methods)] + { + _ = allocator.deref(); + } } } diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index a7b1699dad35d..0835df103ca35 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -1,66 +1,156 @@ -use crate::{Allocator, BUMP_UPWARDS, MINIMUM_ALIGNMENT}; +use std::{ + mem, + ops::{Deref, DerefMut}, + ptr, str, +}; -use allocator_api2::alloc::Global; -#[cfg(any(feature = "serialize", test))] -use serde::{Serialize, Serializer}; - -type StringImpl<'a> = bump_scope::BumpString<'a, 'a, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +use crate::{Allocator, Vec}; /// A bump-allocated string. -pub struct String<'a>(StringImpl<'a>); +pub struct String<'a> { + vec: Vec<'a, u8>, +} impl<'a> String<'a> { /// Constructs a new empty `String`. - #[inline(always)] + #[inline] pub fn new_in(allocator: &'a Allocator) -> Self { - Self(StringImpl::new_in(&allocator.bump)) + Self { vec: Vec::new_in(allocator) } } /// Constructs a `String` from a `&str`. - #[inline(always)] - pub fn from_str_in(string: &str, allocator: &'a Allocator) -> Self { - Self(StringImpl::from_str_in(string, &allocator.bump)) + #[inline] + pub fn from_str_in(s: &str, allocator: &'a Allocator) -> Self { + // code taken from `bumpalo::collections::String::from_str_in` + let len = s.len(); + let mut t = String::with_capacity_in(len, allocator); + // SAFETY: + // * `src` is valid for reads of `s.len()` bytes by virtue of being an allocated `&str`. + // * `dst` is valid for writes of `s.len()` bytes as `String::with_capacity_in(s.len(), bump)` + // above guarantees that. + // * Alignment is not relevant as `u8` has no alignment requirements. + // * Source and destination ranges cannot overlap as we just reserved the destination + // range from the bump. + unsafe { ptr::copy_nonoverlapping(s.as_ptr(), t.vec.as_mut_ptr(), len) }; + // SAFETY: We reserved sufficent capacity for the string above. + // The elements at `0..len` were initialized by `copy_nonoverlapping` above. + unsafe { t.vec.set_len(len) }; + t } /// Constructs a new empty `String` with the specified capacity. - #[inline(always)] + #[inline] pub fn with_capacity_in(capacity: usize, allocator: &'a Allocator) -> Self { - Self(StringImpl::with_capacity_in(capacity, &allocator.bump)) + Self { vec: Vec::with_capacity_in(capacity, allocator) } } /// Converts a `String` into a `&str`. - #[inline(always)] + #[inline] pub fn into_bump_str(self) -> &'a str { - // First converts it to a `FixedBumpString` to suppress it trying to shrink its allocation. - self.0.into_fixed_string().into_str() + #![allow( + clippy::undocumented_unsafe_blocks, + clippy::missing_transmute_annotations, + clippy::forget_non_drop + )] + // code taken from `bumpalo::collections::String::into_bump_str` + let s = unsafe { + let s = self.as_str(); + mem::transmute(s) + }; + mem::forget(self); + s } /// Appends a given string slice to the end of this string. - #[inline(always)] + #[inline] pub fn push_str(&mut self, string: &str) { - self.0.push_str(string); + self.vec.extend_from_slice_copy(string.as_bytes()); } /// Appends a given `char` to the end of this string. - #[inline(always)] - pub fn push(&mut self, c: char) { - self.0.push(c); + #[inline] + pub fn push(&mut self, ch: char) { + match ch.len_utf8() { + 1 => self.vec.push(ch as u8), + _ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()), + } } /// Extracts a string slice containing the entire `String`. - #[inline(always)] + #[inline] pub fn as_str(&self) -> &str { - self.0.as_str() + self } } -#[cfg(any(feature = "serialize", test))] -impl<'alloc> Serialize for String<'alloc> { - #[inline(always)] - fn serialize(&self, s: S) -> Result - where - S: Serializer, - { - self.0.serialize(s) +impl Deref for String<'_> { + type Target = str; + + #[inline] + fn deref(&self) -> &Self::Target { + #[allow(clippy::undocumented_unsafe_blocks)] + unsafe { + str::from_utf8_unchecked(&self.vec) + } + } +} + +impl DerefMut for String<'_> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + #[allow(clippy::undocumented_unsafe_blocks)] + unsafe { + str::from_utf8_unchecked_mut(&mut self.vec) + } + } +} + +// code taken from `bumpalo::collections::Vec` +impl<'alloc> Vec<'alloc, u8> { + /// Copies all elements in the slice `other` and appends them to the `Vec`. + /// + /// Note that this function is same as [`extend_from_slice`] except that it is optimized for + /// slices of types that implement the `Copy` trait. If and when Rust gets specialization + /// this function will likely be deprecated (but still available). + pub fn extend_from_slice_copy(&mut self, other: &[u8]) { + // Reserve space in the Vec for the values to be added + self.reserve(other.len()); + + // Copy values into the space that was just reserved + // SAFETY: + // * `self` has enough capacity to store `other.len()` more items as `self.reserve(other.len())` + // above guarantees that. + // * Source and destination data ranges cannot overlap as we just reserved the destination + // range from the bump. + unsafe { + self.extend_from_slice_copy_unchecked(other); + } + } + + /// Helper method to copy all of the items in `other` and append them to the end of `self`. + /// + /// SAFETY: + /// * The caller is responsible for: + /// * calling [`reserve`](Self::reserve) beforehand to guarantee that there is enough + /// capacity to store `other.len()` more items. + /// * guaranteeing that `self` and `other` do not overlap. + unsafe fn extend_from_slice_copy_unchecked(&mut self, other: &[u8]) { + let old_len = self.len(); + debug_assert!(old_len + other.len() <= self.capacity()); + + // SAFETY: + // * `src` is valid for reads of `other.len()` values by virtue of being a `&[T]`. + // * `dst` is valid for writes of `other.len()` bytes because the caller of this + // method is required to `reserve` capacity to store at least `other.len()` items + // beforehand. + // * Because `src` is a `&[T]` and dst is a `&[T]` within the `Vec`, + // `copy_nonoverlapping`'s alignment requirements are met. + // * Caller is required to guarantee that the source and destination ranges cannot overlap + unsafe { + let src = other.as_ptr(); + let dst = self.as_mut_ptr().add(old_len); + ptr::copy_nonoverlapping(src, dst, other.len()); + self.set_len(old_len + other.len()); + } } } diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index bf0b2a2979f65..7d4cb76b81ac8 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -2,31 +2,20 @@ //! //! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) -use core::fmt; use std::{ self, - borrow::Cow, - fmt::Debug, + fmt::{self, Debug}, hash::{Hash, Hasher}, - iter::FusedIterator, mem::ManuallyDrop, - ops::{self, Index, RangeBounds}, - slice::SliceIndex, + ops, + ptr::NonNull, }; -use allocator_api2::alloc::Global; - +use allocator_api2::vec; #[cfg(any(feature = "serialize", test))] use serde::{ser::SerializeSeq, Serialize, Serializer}; -use crate::{Allocator, Box, BUMP_UPWARDS, MINIMUM_ALIGNMENT}; - -type VecImpl<'a, T> = bump_scope::BumpVec<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; -type DrainImpl<'a, T> = bump_scope::owned_slice::Drain<'a, T>; -type SpliceImpl<'a, I> = - bump_scope::bump_vec::Splice<'a, I, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; -type IntoIterImpl<'a, T> = - bump_scope::bump_vec::IntoIter<'a, 'a, T, Global, MINIMUM_ALIGNMENT, BUMP_UPWARDS>; +use crate::{Allocator, Box, Bump}; /// A `Vec` without [`Drop`], which stores its data in the arena allocator. /// @@ -38,7 +27,8 @@ type IntoIterImpl<'a, T> = /// /// Note: This is not a soundness issue, as Rust does not support relying on `drop` /// being called to guarantee soundness. -pub struct Vec<'alloc, T>(ManuallyDrop>); +#[derive(PartialEq, Eq)] +pub struct Vec<'alloc, T>(pub(crate) ManuallyDrop>); impl<'alloc, T> Vec<'alloc, T> { /// Constructs a new, empty `Vec`. @@ -55,9 +45,9 @@ impl<'alloc, T> Vec<'alloc, T> { /// let mut vec: Vec = Vec::new_in(&arena); /// assert!(vec.is_empty()); /// ``` - #[inline(always)] + #[inline] pub fn new_in(allocator: &'alloc Allocator) -> Self { - Self(ManuallyDrop::new(VecImpl::new_in(&allocator.bump))) + Self(ManuallyDrop::new(vec::Vec::new_in(allocator))) } /// Constructs a new, empty `Vec` with at least the specified capacity @@ -107,242 +97,23 @@ impl<'alloc, T> Vec<'alloc, T> { /// let vec_units = Vec::<()>::with_capacity_in(10, &arena); /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` - #[inline(always)] + #[inline] pub fn with_capacity_in(capacity: usize, allocator: &'alloc Allocator) -> Self { - Self(ManuallyDrop::new(VecImpl::with_capacity_in(capacity, &allocator.bump))) + Self(ManuallyDrop::new(vec::Vec::with_capacity_in(capacity, allocator))) } /// Create a new [`Vec`] whose elements are taken from an iterator and /// allocated in the given `allocator`. /// - /// This is behaviorally identical to [`FromIterator::from_iter`]. - #[inline(always)] - pub fn from_iter_in(iter: I, allocator: &'alloc Allocator) -> Self - where - I: IntoIterator, - { - Self(ManuallyDrop::new(VecImpl::from_iter_in(iter, &allocator.bump))) - } - - /// Create a new [`Vec`] whose elements are taken from an exact iterator and - /// allocated in the given `allocator`. - /// - /// This is behaviorally identical to [`FromIterator::from_iter`]. - #[inline(always)] - pub fn from_iter_exact_in(iter: I, allocator: &'alloc Allocator) -> Self - where - I: IntoIterator, - I::IntoIter: ExactSizeIterator, - { - Self(ManuallyDrop::new(VecImpl::from_iter_exact_in(iter, &allocator.bump))) - } - - /// Returns the total number of elements the vector can hold without - /// reallocating. - /// - /// # Examples - /// - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let vec = Vec::::with_capacity_in(2048, &allocator); - /// assert!(vec.capacity() >= 2048); - /// ``` - #[must_use] - #[inline(always)] - pub fn capacity(&self) -> usize { - self.0.capacity() - } - - /// Extracts a slice containing the entire vector. - /// - /// Equivalent to `&s[..]`. - #[must_use] - #[inline(always)] - pub fn as_slice(&self) -> &[T] { - self.0.as_slice() - } - - /// Extracts a mutable slice containing the entire vector. - /// - /// Equivalent to `&mut s[..]`. - #[must_use] - #[inline(always)] - pub fn as_mut_slice(&mut self) -> &mut [T] { - self.0.as_mut_slice() - } - - /// Returns a raw pointer to the slice, or a dangling raw pointer - /// valid for zero sized reads. - #[must_use] - #[inline(always)] - pub fn as_ptr(&self) -> *const T { - self.0.as_ptr() - } - - /// Returns an unsafe mutable pointer to slice, or a dangling - /// raw pointer valid for zero sized reads. - #[must_use] - #[inline(always)] - pub fn as_mut_ptr(&mut self) -> *mut T { - self.0.as_mut_ptr() - } - - /// Appends an element to the back of a collection. - #[inline(always)] - pub fn push(&mut self, value: T) { - self.0.push(value); - } - - /// Removes the last element from a vector and returns it, or [`None`] if it - /// is empty. - #[inline(always)] - pub fn pop(&mut self) -> Option { - self.0.pop() - } - - /// Inserts an element at position `index` within the vector, shifting all elements after it to the right. - /// - /// # Panics - /// Panics if `index > len`. - /// - /// # Examples - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); - /// vec.insert(1, 4); - /// assert_eq!(vec, [1, 4, 2, 3]); - /// vec.insert(4, 5); - /// assert_eq!(vec, [1, 4, 2, 3, 5]); - /// ``` - #[inline(always)] - pub fn insert(&mut self, index: usize, element: T) { - self.0.insert(index, element); - } - - /// Removes and returns the element at position `index` within the vector, - /// shifting all elements after it to the left. - /// - /// Note: Because this shifts over the remaining elements, it has a - /// worst-case performance of *O*(*n*). If you don't need the order of elements - /// to be preserved, use [`swap_remove`] instead. - /// - /// # Panics - /// Panics if `index` is out of bounds. - /// - /// [`swap_remove`]: Self::swap_remove - /// - /// # Examples - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - /// assert_eq!(v.remove(1), 2); - /// assert_eq!(v, [1, 3]); - /// ``` - #[track_caller] - pub fn remove(&mut self, index: usize) -> T { - self.0.remove(index) - } - - /// Removes an element from the vector and returns it. - /// - /// The removed element is replaced by the last element of the vector. - /// - /// This does not preserve ordering, but is *O*(1). - /// If you need to preserve the element order, use [`remove`] instead. - /// - /// # Panics - /// Panics if `index` is out of bounds. - /// - /// [`remove`]: Self::remove - /// # Examples - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let mut v = Vec::from_iter_in(["foo", "bar", "baz", "qux"], &allocator); - /// - /// assert_eq!(v.swap_remove(1), "bar"); - /// assert_eq!(v, ["foo", "qux", "baz"]); - /// - /// assert_eq!(v.swap_remove(0), "foo"); - /// assert_eq!(v, ["baz", "qux"]); - /// ``` - #[inline(always)] - pub fn swap_remove(&mut self, index: usize) -> T { - self.0.swap_remove(index) - } - - /// Shortens the vector, keeping the first `len` elements and dropping - /// the rest. - /// - /// If `len` is greater than the vector's current length, this has no - /// effect. - /// - /// The [`drain`] method can emulate `truncate`, but causes the excess - /// elements to be returned instead of dropped. - /// - /// Note that this method has no effect on the allocated capacity - /// of the vector. - /// - /// # Examples - /// - /// Truncating a five element vector to two elements: - /// - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// # - /// let mut vec = Vec::from_iter_in([1, 2, 3, 4, 5], &allocator); - /// vec.truncate(2); - /// assert_eq!(vec, [1, 2]); - /// ``` - /// - /// No truncation occurs when `len` is greater than the vector's current - /// length: - /// - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// # - /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); - /// vec.truncate(8); - /// assert_eq!(vec, [1, 2, 3]); - /// ``` - /// - /// Truncating when `len == 0` is equivalent to calling the [`clear`] - /// method. - /// - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// # - /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); - /// vec.truncate(0); - /// assert_eq!(vec, []); - /// ``` - /// - /// [`clear`]: Self::clear - /// [`drain`]: Self::drain - #[inline(always)] - pub fn truncate(&mut self, len: usize) { - self.0.truncate(len); - } - - /// Clears the vector, removing all values. - /// - /// # Examples - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3, 4, 5], &allocator); - /// vec.clear(); - /// assert!(vec.is_empty()); - /// ``` - #[inline(always)] - pub fn clear(&mut self) { - self.0.clear(); + /// This is behaviorially identical to [`FromIterator::from_iter`]. + #[inline] + pub fn from_iter_in>(iter: I, allocator: &'alloc Allocator) -> Self { + let iter = iter.into_iter(); + let hint = iter.size_hint(); + let capacity = hint.1.unwrap_or(hint.0); + let mut vec = ManuallyDrop::new(vec::Vec::with_capacity_in(capacity, &**allocator)); + vec.extend(iter); + Self(vec) } /// Converts the vector into [`Box<[T]>`][owned slice]. @@ -365,11 +136,12 @@ impl<'alloc, T> Vec<'alloc, T> { /// ``` /// /// [owned slice]: Box - #[inline(always)] pub fn into_boxed_slice(self) -> Box<'alloc, [T]> { - // By first calling `into_fixed_vec` we don't shrink the allocation. - let ptr = ManuallyDrop::into_inner(self.0).into_fixed_vec().into_boxed_slice().into_raw(); + let inner = ManuallyDrop::into_inner(self.0); + let slice = inner.leak(); + let ptr = NonNull::from(slice); // SAFETY: `ptr` points to a valid slice `[T]`. + // `allocator_api2::vec::Vec::leak` consumes the inner `Vec` without dropping it. // Lifetime of returned `Box<'alloc, [T]>` is same as lifetime of consumed `Vec<'alloc, T>`, // so data in the `Box` must be valid for its lifetime. // `Vec` uniquely owned the data, and we have consumed the `Vec`, so the new `Box` has @@ -377,559 +149,31 @@ impl<'alloc, T> Vec<'alloc, T> { // `ptr` was created from a `&mut [T]`. unsafe { Box::from_non_null(ptr) } } - - /// Moves all the elements of `other` into `self`, leaving `other` empty. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` bytes. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); - /// let mut vec2 = Vec::from_iter_in([4, 5, 6], &allocator); - /// vec.append(&mut vec2); - /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); - /// assert_eq!(vec2, []); - /// ``` - #[inline(always)] - pub fn append(&mut self, other: &mut Self) { - self.reserve(other.len()); - - // SAFETY: - // We have allocated enough space for the additional elements from `other`. - unsafe { - other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr().add(self.len()), other.len()); - - let self_len = self.len(); - self.set_len(self_len + other.len()); - - other.set_len(0); - } - } - - /// Moves all the elements of `other` into `self`, leaving `other` empty. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` bytes. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3], &allocator); - /// let mut vec2 = Vec::from_iter_in([4, 5, 6], &allocator); - /// vec.prepend(&mut vec2); - /// assert_eq!(vec, [4, 5, 6, 1, 2, 3]); - /// assert_eq!(vec2, []); - /// ``` - #[inline(always)] - pub fn prepend(&mut self, other: &mut Self) { - self.reserve(other.len()); - - // SAFETY: - // We have allocated enough space for the additional elements from `other`. - unsafe { - // copy existing content forward to make space - self.as_mut_ptr().copy_to(self.as_mut_ptr().add(other.len()), self.len()); - - // copy other - other.as_ptr().copy_to_nonoverlapping(self.as_mut_ptr(), other.len()); - - let self_len = self.len(); - self.set_len(self_len + other.len()); - - other.set_len(0); - } - } - - /// Removes the specified range from the vector in bulk, returning all - /// removed elements as an iterator. If the iterator is dropped before - /// being fully consumed, it drops the remaining removed elements. - /// - /// The returned iterator keeps a mutable borrow on the vector to optimize - /// its implementation. - /// - /// # Panics - /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. - /// - /// # Leaking - /// - /// If the returned iterator goes out of scope without being dropped (due to - /// [`mem::forget`](core::mem::forget), for example), the vector may have lost and leaked - /// elements arbitrarily, including elements outside the range. - /// - /// # Examples - /// - /// ``` - /// # use oxc_allocator::{ Allocator, Vec }; - /// # let allocator = Allocator::default(); - /// let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - /// let u = Vec::from_iter_in(v.drain(1..), &allocator); - /// assert_eq!(v, [1]); - /// assert_eq!(u, [2, 3]); - /// - /// // A full range clears the vector, like `clear()` does - /// v.drain(..); - /// assert_eq!(v, []); - /// ``` - pub fn drain(&mut self, range: R) -> Drain<'_, T> - where - R: RangeBounds, - { - Drain(self.0.drain(range)) - } - - /// Creates a splicing iterator that replaces the specified range in the vector - /// with the given `replace_with` iterator and yields the removed items. - /// `replace_with` does not need to be the same length as `range`. - /// - /// `range` is removed even if the iterator is not consumed until the end. - /// - /// It is unspecified how many elements are removed from the vector - /// if the `Splice` value is leaked. - /// - /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped. - /// - /// This is optimal if: - /// - /// * The tail (elements in the vector after `range`) is empty, - /// * or `replace_with` yields fewer or equal elements than `range`’s length - /// * or the lower bound of its `size_hint()` is exact. - /// - /// Otherwise, a temporary vector is allocated and the tail is moved twice. - /// - /// # Panics - /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator: Allocator = Allocator::default(); - /// let mut v = Vec::from_iter_in([1, 2, 3, 4], &allocator); - /// let new = [7, 8, 9]; - /// let u = Vec::from_iter_in(v.splice(1..3, new), &allocator); - /// assert_eq!(v, &[1, 7, 8, 9, 4]); - /// assert_eq!(u, &[2, 3]); - /// ``` - #[inline(always)] - pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> - where - R: RangeBounds, - I: IntoIterator, - { - Splice(self.0.splice(range, replace_with)) - } - - /// Retains only the elements specified by the predicate, passing a mutable reference to it. - /// - /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. - /// This method operates in place, visiting each element exactly once in the - /// original order, and preserves the order of the retained elements. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &allocator); - /// - /// vec.retain_mut(|x| if *x <= 3 { - /// *x += 1; - /// true - /// } else { - /// false - /// }); - /// - /// assert_eq!(vec, [2, 3, 4]); - /// ``` - #[inline(always)] - pub fn retain(&mut self, mut f: F) - where - F: FnMut(&T) -> bool, - { - self.retain_mut(|elem| f(elem)); - } - - /// Retains only the elements specified by the predicate, passing a mutable reference to it. - /// - /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. - /// This method operates in place, visiting each element exactly once in the - /// original order, and preserves the order of the retained elements. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1, 2, 3, 4], &allocator); - /// - /// vec.retain_mut(|x| if *x <= 3 { - /// *x += 1; - /// true - /// } else { - /// false - /// }); - /// - /// assert_eq!(vec, [2, 3, 4]); - /// ``` - #[inline(always)] - pub fn retain_mut(&mut self, f: F) - where - F: FnMut(&mut T) -> bool, - { - self.0.retain(f); - } - - /// Reserves capacity for at least `additional` more elements to be inserted - /// in the given `Vec`. The collection may reserve more space to - /// speculatively avoid frequent reallocations. After calling `reserve`, - /// capacity will be greater than or equal to `self.len() + additional`. - /// Does nothing if capacity is already sufficient. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` bytes. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1], &allocator); - /// vec.reserve(10); - /// assert!(vec.capacity() >= 11); - /// ``` - #[inline(always)] - pub fn reserve(&mut self, additional: usize) { - self.0.reserve(additional); - } - - /// Reserves the minimum capacity for at least `additional` more elements to - /// be inserted in the given `Vec`. Unlike [`reserve`], this will not - /// deliberately over-allocate to speculatively avoid frequent allocations. - /// After calling `reserve_exact`, capacity will be greater than or equal to - /// `self.len() + additional`. Does nothing if the capacity is already - /// sufficient. - /// - /// Note that the allocator may give the collection more space than it - /// requests. Therefore, capacity can not be relied upon to be precisely - /// minimal. Prefer [`reserve`] if future insertions are expected. - /// - /// [`reserve`]: Vec::reserve - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` bytes. - /// - /// # Examples - /// - /// ``` - /// use oxc_allocator::{ Allocator, Vec }; - /// let allocator = Allocator::default(); - /// let mut vec = Vec::from_iter_in([1], &allocator); - /// vec.reserve_exact(10); - /// assert!(vec.capacity() >= 11); - /// ``` - #[inline(always)] - pub fn reserve_exact(&mut self, additional: usize) { - self.0.reserve_exact(additional); - } - - /// Forces the length of the vector to `new_len`. - /// - /// This is a low-level operation that maintains none of the normal - /// invariants of the type. Normally changing the length of a vector - /// is done using one of the safe operations instead, such as - /// [`resize`], [`truncate`], [`extend`], or [`clear`]. - /// - /// # Safety - /// - `new_len` must be less than or equal to the [`capacity`]. - /// - The elements at `old_len..new_len` must be initialized. - /// - /// [`resize`]: Self::resize - /// [`truncate`]: Self::truncate - /// [`extend`]: Self::extend - /// [`clear`]: Self::clear - /// [`capacity`]: Self::capacity - #[inline(always)] - pub unsafe fn set_len(&mut self, new_len: usize) { - self.0.set_len(new_len); - } - - /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. - /// - /// If `new_len` is greater than `len`, the `Vec` is extended by the - /// difference, with each additional slot filled with the result of - /// calling the closure `f`. The return values from `f` will end up - /// in the `Vec` in the order they have been generated. - /// - /// If `new_len` is less than `len`, the `Vec` is simply truncated. - /// - /// This method uses a closure to create new values on every push. If - /// you'd rather [`Clone`] a given value, use [`Vec::resize`]. If you - /// want to use the [`Default`] trait to generate values, you can - /// pass [`Default::default`] as the second argument. - #[inline(always)] - pub fn resize_with(&mut self, new_len: usize, f: F) - where - F: FnMut() -> T, - { - self.0.resize_with(new_len, f); - } -} - -impl Vec<'_, T> -where - T: Clone, -{ - /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. - /// - /// If `new_len` is greater than `len`, the `Vec` is extended by the - /// difference, with each additional slot filled with `value`. - /// If `new_len` is less than `len`, the `Vec` is simply truncated. - /// - /// This method requires `T` to implement [`Clone`], - /// in order to be able to clone the passed value. - /// If you need more flexibility (or want to rely on [`Default`] instead of - /// [`Clone`]), use [`resize_with`]. - /// If you only need to resize to a smaller size, use [`truncate`]. - /// - /// [`resize_with`]: Self::resize_with - /// [`truncate`]: Self::truncate - #[inline(always)] - pub fn resize(&mut self, new_len: usize, value: T) - where - T: Clone, - { - self.0.resize(new_len, value); - } -} - -impl<'alloc, T: Debug> Debug for Vec<'alloc, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let inner = &*self.0; - f.debug_tuple("Vec").field(inner).finish() - } -} - -#[cfg(any(feature = "serialize", test))] -impl<'alloc, T> Serialize for Vec<'alloc, T> -where - T: Serialize, -{ - fn serialize(&self, s: S) -> Result - where - S: Serializer, - { - let mut seq = s.serialize_seq(Some(self.0.len()))?; - for e in self.0.iter() { - seq.serialize_element(e)?; - } - seq.end() - } -} - -macro_rules! impl_slice_eq1 { - ([$($($vars:tt)+)?] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => { - #[allow(clippy::partialeq_ne_impl)] - impl<$($($vars)+,)? T, U> PartialEq<$rhs> for $lhs - where - T: PartialEq, - $($ty: $bound)? - { - #[inline] - fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } - #[inline] - fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] } - } - } -} - -impl_slice_eq1! { ['t, 'u] Vec<'t, T>, Vec<'u, U> } -impl_slice_eq1! { ['t] Vec<'t, T>, &[U] } -impl_slice_eq1! { [] Vec<'_, T>, &mut [U] } -impl_slice_eq1! { [] &[T], Vec<'_, U> } -impl_slice_eq1! { [] &mut [T], Vec<'_, U> } -impl_slice_eq1! { [] Vec<'_, T>, [U] } -impl_slice_eq1! { [] [T], Vec<'_, U> } -impl_slice_eq1! { ['t] Cow<'_, [T]>, Vec<'t, U> where T: Clone } -impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, [U; N] } -impl_slice_eq1! { ['t, const N: usize] Vec<'t, T>, &[U; N] } - -/// A draining iterator for `Vec`. -/// -/// This `struct` is created by [`Vec::drain`]. -/// See its documentation for more. -/// -/// # Example -/// -/// ``` -/// # use oxc_allocator::{ Allocator, Vec }; -/// # let allocator = Allocator::default(); -/// let mut v = Vec::from_iter_in([0, 1, 2], &allocator); -/// let iter: oxc_allocator::vec::Drain<'_, _> = v.drain(..); -/// ``` -pub struct Drain<'a, T>(DrainImpl<'a, T>); - -impl Iterator for Drain<'_, T> { - type Item = T; - - #[inline] - fn next(&mut self) -> Option { - self.0.next() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -impl DoubleEndedIterator for Drain<'_, T> { - #[inline] - fn next_back(&mut self) -> Option { - self.0.next_back() - } } -impl ExactSizeIterator for Drain<'_, T> {} - -impl FusedIterator for Drain<'_, T> {} - -/// A splicing iterator for `Vec`. -/// -/// This struct is created by [`Vec::splice()`]. -/// See its documentation for more. -/// -/// # Example -/// -/// ``` -/// # use oxc_allocator::{ Allocator, Vec }; -/// # let allocator = Allocator::default(); -/// let mut v = Vec::from_iter_in([0, 1, 2], &allocator); -/// let new = [7, 8]; -/// let iter: oxc_allocator::vec::Splice<'_, _> = v.splice(1.., new); -/// ``` -pub struct Splice<'a, I: Iterator>(SpliceImpl<'a, I>); - -impl Iterator for Splice<'_, I> { - type Item = I::Item; - - #[inline(always)] - fn next(&mut self) -> Option { - self.0.next() - } - - #[inline(always)] - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -impl<'alloc, T> Eq for Vec<'alloc, T> where T: Eq {} - impl<'alloc, T> ops::Deref for Vec<'alloc, T> { - type Target = [T]; + type Target = vec::Vec; - #[inline(always)] fn deref(&self) -> &Self::Target { &self.0 } } impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut [T] { + fn deref_mut(&mut self) -> &mut vec::Vec { &mut self.0 } } -/// An iterator that moves out of a vector. -/// -/// This `struct` is created by the `into_iter` method on [`Vec`] -/// (provided by the [`IntoIterator`] trait). -/// -/// # Example -/// -/// ``` -/// # use oxc_allocator::{ Allocator, Vec }; -/// let v = Vec::from_iter_in([0, 1, 2], &allocator); -/// let iter: std::vec::IntoIter<_> = v.into_iter(); -/// ``` -pub struct IntoIter<'alloc, T>(IntoIterImpl<'alloc, T>); - -impl IntoIter<'_, T> { - /// Returns the remaining items of this iterator as a slice. - #[must_use] - #[inline(always)] - pub fn as_slice(&self) -> &[T] { - self.0.as_slice() - } - - /// Returns the remaining items of this iterator as a mutable slice. - #[must_use] - #[inline(always)] - pub fn as_mut_slice(&mut self) -> &mut [T] { - self.0.as_mut_slice() - } -} - -impl Iterator for IntoIter<'_, T> { - type Item = T; - - #[inline(always)] - fn next(&mut self) -> Option { - self.0.next() - } - - #[inline(always)] - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - - #[inline(always)] - fn count(self) -> usize { - self.0.count() - } -} - -impl DoubleEndedIterator for IntoIter<'_, T> { - #[inline(always)] - fn next_back(&mut self) -> Option { - self.0.next_back() - } -} - -impl ExactSizeIterator for IntoIter<'_, T> { - #[inline(always)] - fn len(&self) -> usize { - self.0.len() - } -} - -impl FusedIterator for IntoIter<'_, T> {} - impl<'alloc, T> IntoIterator for Vec<'alloc, T> { - type IntoIter = IntoIter<'alloc, T>; + type IntoIter = as IntoIterator>::IntoIter; type Item = T; - #[inline(always)] fn into_iter(self) -> Self::IntoIter { let inner = ManuallyDrop::into_inner(self.0); // TODO: `allocator_api2::vec::Vec::IntoIter` is `Drop`. // Wrap it in `ManuallyDrop` to prevent that. - IntoIter(inner.into_iter()) + inner.into_iter() } } @@ -937,18 +181,16 @@ impl<'alloc, T> IntoIterator for &'alloc Vec<'alloc, T> { type IntoIter = std::slice::Iter<'alloc, T>; type Item = &'alloc T; - #[inline(always)] fn into_iter(self) -> Self::IntoIter { self.0.iter() } } -impl> Index for Vec<'_, T> { - type Output = I::Output; +impl<'alloc, T> ops::Index for Vec<'alloc, T> { + type Output = T; - #[inline] - fn index(&self, index: I) -> &Self::Output { - Index::index(&**self, index) + fn index(&self, index: usize) -> &Self::Output { + self.0.index(index) } } @@ -959,6 +201,23 @@ impl> Index for Vec<'_, T> { // } // } +#[cfg(any(feature = "serialize", test))] +impl<'alloc, T> Serialize for Vec<'alloc, T> +where + T: Serialize, +{ + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let mut seq = s.serialize_seq(Some(self.0.len()))?; + for e in self.0.iter() { + seq.serialize_element(e)?; + } + seq.end() + } +} + impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { fn hash(&self, state: &mut H) { for e in self.0.iter() { @@ -967,10 +226,10 @@ impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { } } -impl Extend for Vec<'_, T> { - #[inline(always)] - fn extend>(&mut self, iter: I) { - self.0.extend(iter); +impl<'alloc, T: Debug> Debug for Vec<'alloc, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let inner = &*self.0; + f.debug_tuple("Vec").field(inner).finish() } } @@ -1025,78 +284,4 @@ mod test { // Check length of slice is equal to what `v.len()` was, not `v.capacity()` assert_eq!(b.len(), 3); } - - #[test] - fn append() { - let allocator = Allocator::default(); - - { - let mut v = Vec::new_in(&allocator); - let mut other = Vec::::new_in(&allocator); - v.append(&mut other); - assert!(v.is_empty()); - assert!(other.is_empty()); - } - - { - let mut v = Vec::new_in(&allocator); - let mut other = Vec::from_iter_in([1, 2, 3], &allocator); - v.append(&mut other); - assert_eq!(v.as_slice(), &[1, 2, 3]); - assert!(other.is_empty()); - } - - { - let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - let mut other = Vec::new_in(&allocator); - v.append(&mut other); - assert_eq!(v.as_slice(), &[1, 2, 3]); - assert!(other.is_empty()); - } - - { - let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - let mut other = Vec::from_iter_in([4, 5, 6], &allocator); - v.append(&mut other); - assert_eq!(v.as_slice(), &[1, 2, 3, 4, 5, 6]); - assert!(other.is_empty()); - } - } - - #[test] - fn prepend() { - let allocator = Allocator::default(); - - { - let mut v = Vec::new_in(&allocator); - let mut other = Vec::::new_in(&allocator); - v.prepend(&mut other); - assert!(v.is_empty()); - assert!(other.is_empty()); - } - - { - let mut v = Vec::new_in(&allocator); - let mut other = Vec::from_iter_in([1, 2, 3], &allocator); - v.prepend(&mut other); - assert_eq!(v.as_slice(), &[1, 2, 3]); - assert!(other.is_empty()); - } - - { - let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - let mut other = Vec::new_in(&allocator); - v.prepend(&mut other); - assert_eq!(v.as_slice(), &[1, 2, 3]); - assert!(other.is_empty()); - } - - { - let mut v = Vec::from_iter_in([1, 2, 3], &allocator); - let mut other = Vec::from_iter_in([4, 5, 6], &allocator); - v.prepend(&mut other); - assert_eq!(v.as_slice(), &[4, 5, 6, 1, 2, 3]); - assert!(other.is_empty()); - } - } }