From 1d12388df4f7622b3b583b97d19b7ef8c5187a9e Mon Sep 17 00:00:00 2001 From: rzvxa Date: Tue, 27 Aug 2024 13:03:52 +0330 Subject: [PATCH] feat(ast, parser): add optional `oxc_regular_expression` types to the parser and AST. --- .github/.generated_ast_watch_list.yml | 2 + Cargo.lock | 5 + crates/oxc_ast/Cargo.toml | 10 +- crates/oxc_ast/src/ast/literal.rs | 7 +- crates/oxc_ast/src/ast_impl/literal.rs | 3 +- .../oxc_ast/src/generated/assert_layouts.rs | 315 +++++++++++++++- crates/oxc_parser/src/js/expression.rs | 2 +- .../oxc_prettier/src/format/call_arguments.rs | 2 +- crates/oxc_regular_expression/Cargo.toml | 15 + crates/oxc_regular_expression/src/ast.rs | 253 +++++++++---- .../src/generated/derive_clone_in.rs | 338 ++++++++++++++++++ crates/oxc_regular_expression/src/lib.rs | 4 + .../src/generators/assert_layouts.rs | 4 + tasks/ast_tools/src/main.rs | 1 + 14 files changed, 868 insertions(+), 93 deletions(-) create mode 100644 crates/oxc_regular_expression/src/generated/derive_clone_in.rs diff --git a/.github/.generated_ast_watch_list.yml b/.github/.generated_ast_watch_list.yml index df3fdfb8383edc..b31c1ee6ead2ed 100644 --- a/.github/.generated_ast_watch_list.yml +++ b/.github/.generated_ast_watch_list.yml @@ -10,12 +10,14 @@ src: - 'crates/oxc_syntax/src/operator.rs' - 'crates/oxc_span/src/span/types.rs' - 'crates/oxc_span/src/source_type/types.rs' + - 'crates/oxc_regular_expression/src/ast.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' - 'crates/oxc_ast/src/generated/visit.rs' - 'crates/oxc_ast/src/generated/visit_mut.rs' - 'crates/oxc_ast/src/generated/derive_clone_in.rs' + - 'crates/oxc_regular_expression/src/generated/derive_clone_in.rs' - 'crates/oxc_syntax/src/generated/derive_clone_in.rs' - 'crates/oxc_ast/src/generated/derive_get_span.rs' - 'crates/oxc_ast/src/generated/derive_get_span_mut.rs' diff --git a/Cargo.lock b/Cargo.lock index a292f0aafce396..fcb3bed213d663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1444,6 +1444,7 @@ dependencies = [ "num-bigint", "oxc_allocator", "oxc_ast_macros", + "oxc_regular_expression", "oxc_span", "oxc_syntax", "serde", @@ -1799,11 +1800,15 @@ name = "oxc_regular_expression" version = "0.25.0" dependencies = [ "oxc_allocator", + "oxc_ast_macros", "oxc_diagnostics", "oxc_span", "phf 0.11.2", "rustc-hash", + "serde", + "tsify", "unicode-id-start", + "wasm-bindgen", ] [[package]] diff --git a/crates/oxc_ast/Cargo.toml b/crates/oxc_ast/Cargo.toml index e492f1e7cc3e52..5a3f58f6c7910c 100644 --- a/crates/oxc_ast/Cargo.toml +++ b/crates/oxc_ast/Cargo.toml @@ -19,10 +19,11 @@ workspace = true doctest = false [dependencies] -oxc_allocator = { workspace = true } -oxc_ast_macros = { workspace = true } -oxc_span = { workspace = true } -oxc_syntax = { workspace = true } +oxc_allocator = { workspace = true } +oxc_ast_macros = { workspace = true } +oxc_span = { workspace = true } +oxc_syntax = { workspace = true } +oxc_regular_expression = { workspace = true } bitflags = { workspace = true } num-bigint = { workspace = true } @@ -44,4 +45,5 @@ serialize = [ "oxc_span/serialize", "oxc_syntax/serialize", "oxc_syntax/to_js_string", + "oxc_regular_expression/serialize" ] diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index 333f2111af118b..f7eb29ea089f3b 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -12,6 +12,7 @@ use std::hash::Hash; use bitflags::bitflags; use oxc_allocator::CloneIn; use oxc_ast_macros::ast; +use oxc_regular_expression::ast::Pattern; use oxc_span::{Atom, GetSpan, GetSpanMut, Span}; use oxc_syntax::number::{BigintBase, NumberBase}; #[cfg(feature = "serialize")] @@ -86,7 +87,7 @@ pub struct BigIntLiteral<'a> { /// /// #[ast(visit)] -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Hash)] #[generate_derive(CloneIn, GetSpan, GetSpanMut)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] @@ -103,12 +104,12 @@ pub struct RegExpLiteral<'a> { /// /// #[ast] -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Hash)] #[generate_derive(CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct RegExp<'a> { /// The regex pattern between the slashes - pub pattern: Atom<'a>, + pub pattern: Pattern<'a>, /// Regex flags after the closing slash pub flags: RegExpFlags, } diff --git a/crates/oxc_ast/src/ast_impl/literal.rs b/crates/oxc_ast/src/ast_impl/literal.rs index c95788307b4c86..37f2efe6a68e72 100644 --- a/crates/oxc_ast/src/ast_impl/literal.rs +++ b/crates/oxc_ast/src/ast_impl/literal.rs @@ -115,7 +115,8 @@ impl<'a> fmt::Display for BigIntLiteral<'a> { impl<'a> fmt::Display for RegExp<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "/{}/{}", self.pattern, self.flags) + // TODO: fix me + write!(f, "/{}/{}", "TODO", self.flags) } } diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index e3453b27ed6931..1c34c93ca6eac2 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -6,6 +6,9 @@ use std::mem::{align_of, offset_of, size_of}; #[allow(clippy::wildcard_imports)] use crate::ast::*; +#[allow(clippy::wildcard_imports)] +use oxc_regular_expression::ast::*; + #[cfg(target_pointer_width = "64")] const _: () = { assert!(size_of::() == 12usize); @@ -30,16 +33,16 @@ const _: () = { assert!(offset_of!(BigIntLiteral, raw) == 8usize); assert!(offset_of!(BigIntLiteral, base) == 24usize); - assert!(size_of::() == 32usize); + assert!(size_of::() == 64usize); assert!(align_of::() == 8usize); assert!(offset_of!(RegExpLiteral, span) == 0usize); assert!(offset_of!(RegExpLiteral, value) == 8usize); assert!(offset_of!(RegExpLiteral, regex) == 8usize); - assert!(size_of::() == 24usize); + assert!(size_of::() == 56usize); assert!(align_of::() == 8usize); assert!(offset_of!(RegExp, pattern) == 0usize); - assert!(offset_of!(RegExp, flags) == 16usize); + assert!(offset_of!(RegExp, flags) == 48usize); assert!(size_of::() == 0usize); assert!(align_of::() == 1usize); @@ -1405,6 +1408,156 @@ const _: () = { assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); + + assert!(size_of::() == 72usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(RegularExpression, span) == 0usize); + assert!(offset_of!(RegularExpression, pattern) == 8usize); + assert!(offset_of!(RegularExpression, flags) == 56usize); + + assert!(size_of::() == 16usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Flags, span) == 0usize); + assert!(offset_of!(Flags, global) == 8usize); + assert!(offset_of!(Flags, ignore_case) == 9usize); + assert!(offset_of!(Flags, multiline) == 10usize); + assert!(offset_of!(Flags, unicode) == 11usize); + assert!(offset_of!(Flags, sticky) == 12usize); + assert!(offset_of!(Flags, dot_all) == 13usize); + assert!(offset_of!(Flags, has_indices) == 14usize); + assert!(offset_of!(Flags, unicode_sets) == 15usize); + + assert!(size_of::() == 48usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(Pattern, span) == 0usize); + assert!(offset_of!(Pattern, body) == 8usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(Disjunction, span) == 0usize); + assert!(offset_of!(Disjunction, body) == 8usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(Alternative, span) == 0usize); + assert!(offset_of!(Alternative, body) == 8usize); + + assert!(size_of::() == 24usize); + assert!(align_of::() == 8usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(BoundaryAssertion, span) == 0usize); + assert!(offset_of!(BoundaryAssertion, kind) == 8usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 56usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(LookAroundAssertion, span) == 0usize); + assert!(offset_of!(LookAroundAssertion, kind) == 8usize); + assert!(offset_of!(LookAroundAssertion, body) == 16usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 64usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(Quantifier, span) == 0usize); + assert!(offset_of!(Quantifier, min) == 8usize); + assert!(offset_of!(Quantifier, max) == 16usize); + assert!(offset_of!(Quantifier, greedy) == 32usize); + assert!(offset_of!(Quantifier, body) == 40usize); + + assert!(size_of::() == 16usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Character, span) == 0usize); + assert!(offset_of!(Character, kind) == 8usize); + assert!(offset_of!(Character, value) == 12usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CharacterClassEscape, span) == 0usize); + assert!(offset_of!(CharacterClassEscape, kind) == 8usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 48usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(UnicodePropertyEscape, span) == 0usize); + assert!(offset_of!(UnicodePropertyEscape, negative) == 8usize); + assert!(offset_of!(UnicodePropertyEscape, strings) == 9usize); + assert!(offset_of!(UnicodePropertyEscape, name) == 16usize); + assert!(offset_of!(UnicodePropertyEscape, value) == 32usize); + + assert!(size_of::() == 8usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Dot, span) == 0usize); + + assert!(size_of::() == 48usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(CharacterClass, span) == 0usize); + assert!(offset_of!(CharacterClass, negative) == 8usize); + assert!(offset_of!(CharacterClass, kind) == 9usize); + assert!(offset_of!(CharacterClass, body) == 16usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 24usize); + assert!(align_of::() == 8usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CharacterClassRange, span) == 0usize); + assert!(offset_of!(CharacterClassRange, min) == 8usize); + assert!(offset_of!(CharacterClassRange, max) == 24usize); + + assert!(size_of::() == 48usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(ClassStringDisjunction, span) == 0usize); + assert!(offset_of!(ClassStringDisjunction, strings) == 8usize); + assert!(offset_of!(ClassStringDisjunction, body) == 16usize); + + assert!(size_of::() == 48usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(ClassString, span) == 0usize); + assert!(offset_of!(ClassString, strings) == 8usize); + assert!(offset_of!(ClassString, body) == 16usize); + + assert!(size_of::() == 64usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(CapturingGroup, span) == 0usize); + assert!(offset_of!(CapturingGroup, name) == 8usize); + assert!(offset_of!(CapturingGroup, body) == 24usize); + + assert!(size_of::() == 56usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(IgnoreGroup, span) == 0usize); + assert!(offset_of!(IgnoreGroup, enabling_modifiers) == 8usize); + assert!(offset_of!(IgnoreGroup, disabling_modifiers) == 11usize); + assert!(offset_of!(IgnoreGroup, body) == 16usize); + + assert!(size_of::() == 3usize); + assert!(align_of::() == 1usize); + assert!(offset_of!(ModifierFlags, ignore_case) == 0usize); + assert!(offset_of!(ModifierFlags, sticky) == 1usize); + assert!(offset_of!(ModifierFlags, multiline) == 2usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(IndexedReference, span) == 0usize); + assert!(offset_of!(IndexedReference, index) == 8usize); + + assert!(size_of::() == 24usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(NamedReference, span) == 0usize); + assert!(offset_of!(NamedReference, name) == 8usize); }; #[cfg(target_pointer_width = "32")] @@ -1431,16 +1584,16 @@ const _: () = { assert!(offset_of!(BigIntLiteral, raw) == 8usize); assert!(offset_of!(BigIntLiteral, base) == 16usize); - assert!(size_of::() == 20usize); + assert!(size_of::() == 44usize); assert!(align_of::() == 4usize); assert!(offset_of!(RegExpLiteral, span) == 0usize); assert!(offset_of!(RegExpLiteral, value) == 8usize); assert!(offset_of!(RegExpLiteral, regex) == 8usize); - assert!(size_of::() == 12usize); + assert!(size_of::() == 36usize); assert!(align_of::() == 4usize); assert!(offset_of!(RegExp, pattern) == 0usize); - assert!(offset_of!(RegExp, flags) == 8usize); + assert!(offset_of!(RegExp, flags) == 32usize); assert!(size_of::() == 0usize); assert!(align_of::() == 1usize); @@ -2806,6 +2959,156 @@ const _: () = { assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); + + assert!(size_of::() == 56usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(RegularExpression, span) == 0usize); + assert!(offset_of!(RegularExpression, pattern) == 8usize); + assert!(offset_of!(RegularExpression, flags) == 40usize); + + assert!(size_of::() == 16usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Flags, span) == 0usize); + assert!(offset_of!(Flags, global) == 8usize); + assert!(offset_of!(Flags, ignore_case) == 9usize); + assert!(offset_of!(Flags, multiline) == 10usize); + assert!(offset_of!(Flags, unicode) == 11usize); + assert!(offset_of!(Flags, sticky) == 12usize); + assert!(offset_of!(Flags, dot_all) == 13usize); + assert!(offset_of!(Flags, has_indices) == 14usize); + assert!(offset_of!(Flags, unicode_sets) == 15usize); + + assert!(size_of::() == 32usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Pattern, span) == 0usize); + assert!(offset_of!(Pattern, body) == 8usize); + + assert!(size_of::() == 24usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Disjunction, span) == 0usize); + assert!(offset_of!(Disjunction, body) == 8usize); + + assert!(size_of::() == 24usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Alternative, span) == 0usize); + assert!(offset_of!(Alternative, body) == 8usize); + + assert!(size_of::() == 20usize); + assert!(align_of::() == 4usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(BoundaryAssertion, span) == 0usize); + assert!(offset_of!(BoundaryAssertion, kind) == 8usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 36usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(LookAroundAssertion, span) == 0usize); + assert!(offset_of!(LookAroundAssertion, kind) == 8usize); + assert!(offset_of!(LookAroundAssertion, body) == 12usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 56usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(Quantifier, span) == 0usize); + assert!(offset_of!(Quantifier, min) == 8usize); + assert!(offset_of!(Quantifier, max) == 16usize); + assert!(offset_of!(Quantifier, greedy) == 32usize); + assert!(offset_of!(Quantifier, body) == 36usize); + + assert!(size_of::() == 16usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Character, span) == 0usize); + assert!(offset_of!(Character, kind) == 8usize); + assert!(offset_of!(Character, value) == 12usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CharacterClassEscape, span) == 0usize); + assert!(offset_of!(CharacterClassEscape, kind) == 8usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 28usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(UnicodePropertyEscape, span) == 0usize); + assert!(offset_of!(UnicodePropertyEscape, negative) == 8usize); + assert!(offset_of!(UnicodePropertyEscape, strings) == 9usize); + assert!(offset_of!(UnicodePropertyEscape, name) == 12usize); + assert!(offset_of!(UnicodePropertyEscape, value) == 20usize); + + assert!(size_of::() == 8usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(Dot, span) == 0usize); + + assert!(size_of::() == 28usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CharacterClass, span) == 0usize); + assert!(offset_of!(CharacterClass, negative) == 8usize); + assert!(offset_of!(CharacterClass, kind) == 9usize); + assert!(offset_of!(CharacterClass, body) == 12usize); + + assert!(size_of::() == 1usize); + assert!(align_of::() == 1usize); + + assert!(size_of::() == 20usize); + assert!(align_of::() == 4usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CharacterClassRange, span) == 0usize); + assert!(offset_of!(CharacterClassRange, min) == 8usize); + assert!(offset_of!(CharacterClassRange, max) == 24usize); + + assert!(size_of::() == 28usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(ClassStringDisjunction, span) == 0usize); + assert!(offset_of!(ClassStringDisjunction, strings) == 8usize); + assert!(offset_of!(ClassStringDisjunction, body) == 12usize); + + assert!(size_of::() == 28usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(ClassString, span) == 0usize); + assert!(offset_of!(ClassString, strings) == 8usize); + assert!(offset_of!(ClassString, body) == 12usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(CapturingGroup, span) == 0usize); + assert!(offset_of!(CapturingGroup, name) == 8usize); + assert!(offset_of!(CapturingGroup, body) == 16usize); + + assert!(size_of::() == 40usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(IgnoreGroup, span) == 0usize); + assert!(offset_of!(IgnoreGroup, enabling_modifiers) == 8usize); + assert!(offset_of!(IgnoreGroup, disabling_modifiers) == 11usize); + assert!(offset_of!(IgnoreGroup, body) == 16usize); + + assert!(size_of::() == 3usize); + assert!(align_of::() == 1usize); + assert!(offset_of!(ModifierFlags, ignore_case) == 0usize); + assert!(offset_of!(ModifierFlags, sticky) == 1usize); + assert!(offset_of!(ModifierFlags, multiline) == 2usize); + + assert!(size_of::() == 12usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(IndexedReference, span) == 0usize); + assert!(offset_of!(IndexedReference, index) == 8usize); + + assert!(size_of::() == 16usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(NamedReference, span) == 0usize); + assert!(offset_of!(NamedReference, name) == 8usize); }; #[cfg(not(any(target_pointer_width = "64", target_pointer_width = "32")))] diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 86c806c267d90a..5c916e28f9e573 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -344,7 +344,7 @@ impl<'a> ParserImpl<'a> { let pattern = &self.source_text[pattern_start as usize..pattern_end as usize]; self.bump_any(); - let _pattern = self + let pattern = self .options .parse_regular_expression .then(|| self.parse_regex_pattern(pattern_start, pattern, flags)); diff --git a/crates/oxc_prettier/src/format/call_arguments.rs b/crates/oxc_prettier/src/format/call_arguments.rs index fcc278320fa0ee..c68d6e867d7f45 100644 --- a/crates/oxc_prettier/src/format/call_arguments.rs +++ b/crates/oxc_prettier/src/format/call_arguments.rs @@ -238,7 +238,7 @@ fn is_hopefully_short_call_argument(mut node: &Expression) -> bool { fn is_simple_call_argument(node: &Expression, depth: usize) -> bool { if let Expression::RegExpLiteral(literal) = node { - return literal.regex.pattern.len() <= 5; + return literal.regex.pattern.body.span.len() <= 5; } if node.is_literal() || is_string_word_type(node) { diff --git a/crates/oxc_regular_expression/Cargo.toml b/crates/oxc_regular_expression/Cargo.toml index 3451429b2ef223..18730528a5de3a 100644 --- a/crates/oxc_regular_expression/Cargo.toml +++ b/crates/oxc_regular_expression/Cargo.toml @@ -23,7 +23,22 @@ doctest = false oxc_allocator = { workspace = true } oxc_diagnostics = { workspace = true } oxc_span = { workspace = true } +oxc_ast_macros = { workspace = true } phf = { workspace = true, features = ["macros"] } rustc-hash = { workspace = true } unicode-id-start = { workspace = true } +serde = { workspace = true, features = ["derive"], optional = true } + +tsify = { 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", +] diff --git a/crates/oxc_regular_expression/src/ast.rs b/crates/oxc_regular_expression/src/ast.rs index edd8405ba3d540..d142180260df23 100644 --- a/crates/oxc_regular_expression/src/ast.rs +++ b/crates/oxc_regular_expression/src/ast.rs @@ -1,14 +1,33 @@ -use oxc_allocator::{Box, Vec}; -use oxc_span::{Atom as SpanAtom, Span}; +// NB: `#[span]`, `#[scope(...)]`,`#[visit(...)]` and `#[generate_derive(...)]` do NOT do anything to the code. +// 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. -#[derive(Debug)] +// 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_span::{Atom, Span}; + +#[cfg(feature = "serialize")] +use serde::Serialize; +#[cfg(feature = "serialize")] +use tsify::Tsify; + +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct RegularExpression<'a> { pub span: Span, pub pattern: Pattern<'a>, pub flags: Flags, } -#[derive(Debug)] +#[ast] +#[derive(Debug, Clone, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Flags { pub span: Span, pub global: bool, @@ -22,80 +41,109 @@ pub struct Flags { } /// The root of the `PatternParser` result. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Pattern<'a> { pub span: Span, pub body: Disjunction<'a>, } /// Pile of [`Alternative`]s separated by `|`. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Disjunction<'a> { pub span: Span, pub body: Vec<'a, Alternative<'a>>, } /// Single unit of `|` separated alternatives. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Alternative<'a> { pub span: Span, pub body: Vec<'a, Term<'a>>, } /// Single unit of [`Alternative`], containing various kinds. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum Term<'a> { // Assertion, QuantifiableAssertion - BoundaryAssertion(BoundaryAssertion), - LookAroundAssertion(Box<'a, LookAroundAssertion<'a>>), + BoundaryAssertion(BoundaryAssertion) = 0, + LookAroundAssertion(Box<'a, LookAroundAssertion<'a>>) = 1, // Quantifier - Quantifier(Box<'a, Quantifier<'a>>), + Quantifier(Box<'a, Quantifier<'a>>) = 2, // Atom, ExtendedAtom - Character(Character), - Dot(Dot), - CharacterClassEscape(CharacterClassEscape), - UnicodePropertyEscape(Box<'a, UnicodePropertyEscape<'a>>), - CharacterClass(Box<'a, CharacterClass<'a>>), - CapturingGroup(Box<'a, CapturingGroup<'a>>), - IgnoreGroup(Box<'a, IgnoreGroup<'a>>), - IndexedReference(IndexedReference), - NamedReference(Box<'a, NamedReference<'a>>), + Character(Character) = 3, + Dot(Dot) = 4, + CharacterClassEscape(CharacterClassEscape) = 5, + UnicodePropertyEscape(Box<'a, UnicodePropertyEscape<'a>>) = 6, + CharacterClass(Box<'a, CharacterClass<'a>>) = 7, + CapturingGroup(Box<'a, CapturingGroup<'a>>) = 8, + IgnoreGroup(Box<'a, IgnoreGroup<'a>>) = 9, + IndexedReference(IndexedReference) = 10, + NamedReference(Box<'a, NamedReference<'a>>) = 11, } /// Simple form of assertion. /// e.g. `^`, `$`, `\b`, `\B` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct BoundaryAssertion { pub span: Span, pub kind: BoundaryAssertionKind, } -#[derive(Debug)] + +#[ast] +#[derive(Debug, Clone, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum BoundaryAssertionKind { - Start, - End, - Boundary, - NegativeBoundary, + Start = 0, + End = 1, + Boundary = 2, + NegativeBoundary = 3, } /// Lookaround assertion. /// e.g. `(?=...)`, `(?!...)`, `(?<=...)`, `(? { pub span: Span, pub kind: LookAroundAssertionKind, pub body: Disjunction<'a>, } -#[derive(Debug)] + +#[ast] +#[derive(Debug, Clone, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum LookAroundAssertionKind { - Lookahead, - NegativeLookahead, - Lookbehind, - NegativeLookbehind, + Lookahead = 0, + NegativeLookahead = 1, + Lookbehind = 2, + NegativeLookbehind = 3, } /// Quantifier holding a [`Term`] and its repetition count. /// e.g. `a*`, `b+`, `c?`, `d{3}`, `e{4,}`, `f{5,6}` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Quantifier<'a> { pub span: Span, pub min: u64, @@ -106,7 +154,10 @@ pub struct Quantifier<'a> { } /// Single character. -#[derive(Debug, Copy, Clone)] +#[ast] +#[derive(Debug, Clone, Copy, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Character { /// This will be invalid position when `UnicodeMode` is disabled and `value` is a surrogate pair. pub span: Span, @@ -115,57 +166,75 @@ pub struct Character { pub value: u32, } -#[derive(Debug, Copy, Clone)] +#[ast] +#[derive(Debug, Clone, Copy, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterKind { - ControlLetter, - HexadecimalEscape, - Identifier, - Null, - Octal, - SingleEscape, - Symbol, - UnicodeEscape, + ControlLetter = 0, + HexadecimalEscape = 1, + Identifier = 2, + Null = 3, + Octal = 4, + SingleEscape = 5, + Symbol = 6, + UnicodeEscape = 7, } /// Character class. /// e.g. `\d`, `\D`, `\s`, `\S`, `\w`, `\W` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClassEscape { pub span: Span, pub kind: CharacterClassEscapeKind, } -#[derive(Debug)] +#[ast] +#[derive(Debug, Clone, Copy, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassEscapeKind { - D, - NegativeD, - S, - NegativeS, - W, - NegativeW, + D = 0, + NegativeD = 1, + S = 2, + NegativeS = 3, + W = 4, + NegativeW = 5, } /// Unicode property. /// e.g. `\p{ASCII}`, `\P{ASCII}`, `\p{sc=Hiragana}`, `\P{sc=Hiragana}` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct UnicodePropertyEscape<'a> { pub span: Span, pub negative: bool, /// `true` if `UnicodeSetsMode` and `name` matched unicode property of strings. pub strings: bool, - pub name: SpanAtom<'a>, - pub value: Option>, + pub name: Atom<'a>, + pub value: Option>, } /// The `.`. -#[derive(Debug)] +#[ast] +#[derive(Debug, Clone, Copy, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Dot { pub span: Span, } /// Character class wrapped by `[]`. /// e.g. `[a-z]`, `[^A-Z]`, `[abc]`, `[a&&b&&c]`, `[[a-z]--x--y]` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClass<'a> { pub span: Span, pub negative: bool, @@ -173,30 +242,39 @@ pub struct CharacterClass<'a> { pub body: Vec<'a, CharacterClassContents<'a>>, } -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassContentsKind { - Union, + Union = 0, /// `UnicodeSetsMode` only. - Intersection, + Intersection = 1, /// `UnicodeSetsMode` only. - Subtraction, + Subtraction = 2, } -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassContents<'a> { - CharacterClassRange(Box<'a, CharacterClassRange>), - CharacterClassEscape(CharacterClassEscape), - UnicodePropertyEscape(Box<'a, UnicodePropertyEscape<'a>>), - Character(Character), + CharacterClassRange(Box<'a, CharacterClassRange>) = 0, + CharacterClassEscape(CharacterClassEscape) = 1, + UnicodePropertyEscape(Box<'a, UnicodePropertyEscape<'a>>) = 2, + Character(Character) = 3, /// `UnicodeSetsMode` only - NestedCharacterClass(Box<'a, CharacterClass<'a>>), + NestedCharacterClass(Box<'a, CharacterClass<'a>>) = 4, /// `UnicodeSetsMode` only - ClassStringDisjunction(Box<'a, ClassStringDisjunction<'a>>), + ClassStringDisjunction(Box<'a, ClassStringDisjunction<'a>>) = 5, } /// `-` separated range of characters. /// e.g. `a-z`, `A-Z`, `0-9` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClassRange { pub span: Span, pub min: Character, @@ -204,7 +282,10 @@ pub struct CharacterClassRange { } /// `|` separated string of characters wrapped by `\q{}`. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ClassStringDisjunction<'a> { pub span: Span, /// `true` if body is empty or contain [`ClassString`] which `strings` is `true` @@ -213,7 +294,10 @@ pub struct ClassStringDisjunction<'a> { } /// Single unit of [`ClassStringDisjunction`]. -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ClassString<'a> { pub span: Span, /// `true` if body is empty or contain 2 more characters. @@ -223,16 +307,22 @@ pub struct ClassString<'a> { /// Named or unnamed capturing group. /// e.g. `(...)`, `(?...)` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CapturingGroup<'a> { pub span: Span, - pub name: Option>, + pub name: Option>, pub body: Disjunction<'a>, } /// Pseudo-group for ignoring. /// e.g. `(?:...)` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct IgnoreGroup<'a> { pub span: Span, pub enabling_modifiers: Option, @@ -240,7 +330,10 @@ pub struct IgnoreGroup<'a> { pub body: Disjunction<'a>, } -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ModifierFlags { pub ignore_case: bool, pub sticky: bool, @@ -249,7 +342,10 @@ pub struct ModifierFlags { /// Backreference by index. /// e.g. `\1`, `\2`, `\3` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct IndexedReference { pub span: Span, pub index: u32, @@ -257,8 +353,11 @@ pub struct IndexedReference { /// Backreference by name. /// e.g. `\k` -#[derive(Debug)] +#[ast] +#[derive(Debug, Hash)] +#[generate_derive(CloneIn)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct NamedReference<'a> { pub span: Span, - pub name: SpanAtom<'a>, + pub name: Atom<'a>, } diff --git a/crates/oxc_regular_expression/src/generated/derive_clone_in.rs b/crates/oxc_regular_expression/src/generated/derive_clone_in.rs new file mode 100644 index 00000000000000..674fc2c6074830 --- /dev/null +++ b/crates/oxc_regular_expression/src/generated/derive_clone_in.rs @@ -0,0 +1,338 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/clone_in.rs` + +#![allow(clippy::default_trait_access)] + +use oxc_allocator::{Allocator, CloneIn}; + +#[allow(clippy::wildcard_imports)] +use crate::ast::*; + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for RegularExpression<'old_alloc> { + type Cloned = RegularExpression<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + RegularExpression { + span: self.span.clone_in(allocator), + pattern: self.pattern.clone_in(allocator), + flags: self.flags.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for Flags { + type Cloned = Flags; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + Flags { + span: self.span.clone_in(allocator), + global: self.global.clone_in(allocator), + ignore_case: self.ignore_case.clone_in(allocator), + multiline: self.multiline.clone_in(allocator), + unicode: self.unicode.clone_in(allocator), + sticky: self.sticky.clone_in(allocator), + dot_all: self.dot_all.clone_in(allocator), + has_indices: self.has_indices.clone_in(allocator), + unicode_sets: self.unicode_sets.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Pattern<'old_alloc> { + type Cloned = Pattern<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + Pattern { span: self.span.clone_in(allocator), body: self.body.clone_in(allocator) } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Disjunction<'old_alloc> { + type Cloned = Disjunction<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + Disjunction { span: self.span.clone_in(allocator), body: self.body.clone_in(allocator) } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Alternative<'old_alloc> { + type Cloned = Alternative<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + Alternative { span: self.span.clone_in(allocator), body: self.body.clone_in(allocator) } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Term<'old_alloc> { + type Cloned = Term<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + match self { + Self::BoundaryAssertion(it) => Term::BoundaryAssertion(it.clone_in(allocator)), + Self::LookAroundAssertion(it) => Term::LookAroundAssertion(it.clone_in(allocator)), + Self::Quantifier(it) => Term::Quantifier(it.clone_in(allocator)), + Self::Character(it) => Term::Character(it.clone_in(allocator)), + Self::Dot(it) => Term::Dot(it.clone_in(allocator)), + Self::CharacterClassEscape(it) => Term::CharacterClassEscape(it.clone_in(allocator)), + Self::UnicodePropertyEscape(it) => Term::UnicodePropertyEscape(it.clone_in(allocator)), + Self::CharacterClass(it) => Term::CharacterClass(it.clone_in(allocator)), + Self::CapturingGroup(it) => Term::CapturingGroup(it.clone_in(allocator)), + Self::IgnoreGroup(it) => Term::IgnoreGroup(it.clone_in(allocator)), + Self::IndexedReference(it) => Term::IndexedReference(it.clone_in(allocator)), + Self::NamedReference(it) => Term::NamedReference(it.clone_in(allocator)), + } + } +} + +impl<'alloc> CloneIn<'alloc> for BoundaryAssertion { + type Cloned = BoundaryAssertion; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + BoundaryAssertion { + span: self.span.clone_in(allocator), + kind: self.kind.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for BoundaryAssertionKind { + type Cloned = BoundaryAssertionKind; + fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned { + match self { + Self::Start => BoundaryAssertionKind::Start, + Self::End => BoundaryAssertionKind::End, + Self::Boundary => BoundaryAssertionKind::Boundary, + Self::NegativeBoundary => BoundaryAssertionKind::NegativeBoundary, + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for LookAroundAssertion<'old_alloc> { + type Cloned = LookAroundAssertion<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + LookAroundAssertion { + span: self.span.clone_in(allocator), + kind: self.kind.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for LookAroundAssertionKind { + type Cloned = LookAroundAssertionKind; + fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned { + match self { + Self::Lookahead => LookAroundAssertionKind::Lookahead, + Self::NegativeLookahead => LookAroundAssertionKind::NegativeLookahead, + Self::Lookbehind => LookAroundAssertionKind::Lookbehind, + Self::NegativeLookbehind => LookAroundAssertionKind::NegativeLookbehind, + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Quantifier<'old_alloc> { + type Cloned = Quantifier<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + Quantifier { + span: self.span.clone_in(allocator), + min: self.min.clone_in(allocator), + max: self.max.clone_in(allocator), + greedy: self.greedy.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for Character { + type Cloned = Character; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + Character { + span: self.span.clone_in(allocator), + kind: self.kind.clone_in(allocator), + value: self.value.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for CharacterKind { + type Cloned = CharacterKind; + fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned { + match self { + Self::ControlLetter => CharacterKind::ControlLetter, + Self::HexadecimalEscape => CharacterKind::HexadecimalEscape, + Self::Identifier => CharacterKind::Identifier, + Self::Null => CharacterKind::Null, + Self::Octal => CharacterKind::Octal, + Self::SingleEscape => CharacterKind::SingleEscape, + Self::Symbol => CharacterKind::Symbol, + Self::UnicodeEscape => CharacterKind::UnicodeEscape, + } + } +} + +impl<'alloc> CloneIn<'alloc> for CharacterClassEscape { + type Cloned = CharacterClassEscape; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + CharacterClassEscape { + span: self.span.clone_in(allocator), + kind: self.kind.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for CharacterClassEscapeKind { + type Cloned = CharacterClassEscapeKind; + fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned { + match self { + Self::D => CharacterClassEscapeKind::D, + Self::NegativeD => CharacterClassEscapeKind::NegativeD, + Self::S => CharacterClassEscapeKind::S, + Self::NegativeS => CharacterClassEscapeKind::NegativeS, + Self::W => CharacterClassEscapeKind::W, + Self::NegativeW => CharacterClassEscapeKind::NegativeW, + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for UnicodePropertyEscape<'old_alloc> { + type Cloned = UnicodePropertyEscape<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + UnicodePropertyEscape { + span: self.span.clone_in(allocator), + negative: self.negative.clone_in(allocator), + strings: self.strings.clone_in(allocator), + name: self.name.clone_in(allocator), + value: self.value.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for Dot { + type Cloned = Dot; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + Dot { span: self.span.clone_in(allocator) } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for CharacterClass<'old_alloc> { + type Cloned = CharacterClass<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + CharacterClass { + span: self.span.clone_in(allocator), + negative: self.negative.clone_in(allocator), + kind: self.kind.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for CharacterClassContentsKind { + type Cloned = CharacterClassContentsKind; + fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned { + match self { + Self::Union => CharacterClassContentsKind::Union, + Self::Intersection => CharacterClassContentsKind::Intersection, + Self::Subtraction => CharacterClassContentsKind::Subtraction, + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for CharacterClassContents<'old_alloc> { + type Cloned = CharacterClassContents<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + match self { + Self::CharacterClassRange(it) => { + CharacterClassContents::CharacterClassRange(it.clone_in(allocator)) + } + Self::CharacterClassEscape(it) => { + CharacterClassContents::CharacterClassEscape(it.clone_in(allocator)) + } + Self::UnicodePropertyEscape(it) => { + CharacterClassContents::UnicodePropertyEscape(it.clone_in(allocator)) + } + Self::Character(it) => CharacterClassContents::Character(it.clone_in(allocator)), + Self::NestedCharacterClass(it) => { + CharacterClassContents::NestedCharacterClass(it.clone_in(allocator)) + } + Self::ClassStringDisjunction(it) => { + CharacterClassContents::ClassStringDisjunction(it.clone_in(allocator)) + } + } + } +} + +impl<'alloc> CloneIn<'alloc> for CharacterClassRange { + type Cloned = CharacterClassRange; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + CharacterClassRange { + span: self.span.clone_in(allocator), + min: self.min.clone_in(allocator), + max: self.max.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ClassStringDisjunction<'old_alloc> { + type Cloned = ClassStringDisjunction<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + ClassStringDisjunction { + span: self.span.clone_in(allocator), + strings: self.strings.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for ClassString<'old_alloc> { + type Cloned = ClassString<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + ClassString { + span: self.span.clone_in(allocator), + strings: self.strings.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for CapturingGroup<'old_alloc> { + type Cloned = CapturingGroup<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + CapturingGroup { + span: self.span.clone_in(allocator), + name: self.name.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for IgnoreGroup<'old_alloc> { + type Cloned = IgnoreGroup<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + IgnoreGroup { + span: self.span.clone_in(allocator), + enabling_modifiers: self.enabling_modifiers.clone_in(allocator), + disabling_modifiers: self.disabling_modifiers.clone_in(allocator), + body: self.body.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for ModifierFlags { + type Cloned = ModifierFlags; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + ModifierFlags { + ignore_case: self.ignore_case.clone_in(allocator), + sticky: self.sticky.clone_in(allocator), + multiline: self.multiline.clone_in(allocator), + } + } +} + +impl<'alloc> CloneIn<'alloc> for IndexedReference { + type Cloned = IndexedReference; + fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned { + IndexedReference { + span: self.span.clone_in(allocator), + index: self.index.clone_in(allocator), + } + } +} + +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for NamedReference<'old_alloc> { + type Cloned = NamedReference<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + NamedReference { span: self.span.clone_in(allocator), name: self.name.clone_in(allocator) } + } +} diff --git a/crates/oxc_regular_expression/src/lib.rs b/crates/oxc_regular_expression/src/lib.rs index 5b2d4758915efe..6c6befe362579d 100644 --- a/crates/oxc_regular_expression/src/lib.rs +++ b/crates/oxc_regular_expression/src/lib.rs @@ -8,6 +8,10 @@ mod literal_parser; mod options; mod span; +mod generated { + mod derive_clone_in; +} + pub use crate::body_parser::PatternParser; pub use crate::flag_parser::FlagsParser; pub use crate::literal_parser::Parser; diff --git a/tasks/ast_tools/src/generators/assert_layouts.rs b/tasks/ast_tools/src/generators/assert_layouts.rs index b30f8189506f62..f6cf2ffc01728f 100644 --- a/tasks/ast_tools/src/generators/assert_layouts.rs +++ b/tasks/ast_tools/src/generators/assert_layouts.rs @@ -40,6 +40,10 @@ impl Generator for AssertLayouts { #[allow(clippy::wildcard_imports)] use crate::ast::*; + ///@@line_break + #[allow(clippy::wildcard_imports)] + use oxc_regular_expression::ast::*; + ///@@line_break #[cfg(target_pointer_width = "64")] const _: () = { #(#assertions_64)* }; diff --git a/tasks/ast_tools/src/main.rs b/tasks/ast_tools/src/main.rs index 5f4e885e4a1131..cac3ed40c2ede4 100644 --- a/tasks/ast_tools/src/main.rs +++ b/tasks/ast_tools/src/main.rs @@ -34,6 +34,7 @@ static SOURCE_PATHS: &[&str] = &[ "crates/oxc_syntax/src/operator.rs", "crates/oxc_span/src/span/types.rs", "crates/oxc_span/src/source_type/types.rs", + "crates/oxc_regular_expression/src/ast.rs", ]; const AST_CRATE: &str = "crates/oxc_ast";