diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index 0a3339409441a..d9f748833293d 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -59,6 +59,22 @@ pub struct NumericLiteral<'a> { pub base: NumberBase, } +/// String literal +/// +/// +#[ast(visit)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] +#[estree(type = "Literal", via = crate::serialize::ESTreeLiteral)] +pub struct StringLiteral<'a> { + /// Node location in source code + pub span: Span, + /// The value of the string + pub value: Atom<'a>, + /// The string as it appears in source code, including quotes + pub raw: &'a str, +} + /// BigInt literal #[ast(visit)] #[derive(Debug, Clone)] @@ -128,19 +144,6 @@ pub enum RegExpPattern<'a> { Pattern(Box<'a, Pattern<'a>>) = 2, } -/// String literal -/// -/// -#[ast(visit)] -#[derive(Debug, Clone)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash, ESTree)] -pub struct StringLiteral<'a> { - /// Node location in source code - pub span: Span, - /// The string as it appears in source code - pub value: Atom<'a>, -} - bitflags! { /// Regular expression flags. /// diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index 46528ae7f6158..eb4a8a664d190 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -25,6 +25,12 @@ const _: () = { assert!(offset_of!(NumericLiteral, raw) == 16usize); assert!(offset_of!(NumericLiteral, base) == 32usize); + assert!(size_of::() == 40usize); + assert!(align_of::() == 8usize); + assert!(offset_of!(StringLiteral, span) == 0usize); + assert!(offset_of!(StringLiteral, value) == 8usize); + assert!(offset_of!(StringLiteral, raw) == 24usize); + assert!(size_of::() == 32usize); assert!(align_of::() == 8usize); assert!(offset_of!(BigIntLiteral, span) == 0usize); @@ -45,11 +51,6 @@ const _: () = { assert!(size_of::() == 24usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 24usize); - assert!(align_of::() == 8usize); - assert!(offset_of!(StringLiteral, span) == 0usize); - assert!(offset_of!(StringLiteral, value) == 8usize); - assert!(size_of::() == 160usize); assert!(align_of::() == 8usize); assert!(offset_of!(Program, span) == 0usize); @@ -335,11 +336,11 @@ const _: () = { assert!(size_of::() == 16usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 48usize); + assert!(size_of::() == 64usize); assert!(align_of::() == 8usize); assert!(offset_of!(Directive, span) == 0usize); assert!(offset_of!(Directive, expression) == 8usize); - assert!(offset_of!(Directive, directive) == 32usize); + assert!(offset_of!(Directive, directive) == 48usize); assert!(size_of::() == 24usize); assert!(align_of::() == 8usize); @@ -703,23 +704,23 @@ const _: () = { assert!(offset_of!(ImportExpression, source) == 8usize); assert!(offset_of!(ImportExpression, arguments) == 24usize); - assert!(size_of::() == 80usize); + assert!(size_of::() == 96usize); assert!(align_of::() == 8usize); assert!(offset_of!(ImportDeclaration, span) == 0usize); assert!(offset_of!(ImportDeclaration, specifiers) == 8usize); assert!(offset_of!(ImportDeclaration, source) == 40usize); - assert!(offset_of!(ImportDeclaration, with_clause) == 64usize); - assert!(offset_of!(ImportDeclaration, import_kind) == 72usize); + assert!(offset_of!(ImportDeclaration, with_clause) == 80usize); + assert!(offset_of!(ImportDeclaration, import_kind) == 88usize); assert!(size_of::() == 16usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 88usize); + assert!(size_of::() == 96usize); assert!(align_of::() == 8usize); assert!(offset_of!(ImportSpecifier, span) == 0usize); assert!(offset_of!(ImportSpecifier, imported) == 8usize); - assert!(offset_of!(ImportSpecifier, local) == 48usize); - assert!(offset_of!(ImportSpecifier, import_kind) == 80usize); + assert!(offset_of!(ImportSpecifier, local) == 56usize); + assert!(offset_of!(ImportSpecifier, import_kind) == 88usize); assert!(size_of::() == 40usize); assert!(align_of::() == 8usize); @@ -737,49 +738,49 @@ const _: () = { assert!(offset_of!(WithClause, attributes_keyword) == 8usize); assert!(offset_of!(WithClause, with_entries) == 32usize); - assert!(size_of::() == 64usize); + assert!(size_of::() == 96usize); assert!(align_of::() == 8usize); assert!(offset_of!(ImportAttribute, span) == 0usize); assert!(offset_of!(ImportAttribute, key) == 8usize); - assert!(offset_of!(ImportAttribute, value) == 40usize); + assert!(offset_of!(ImportAttribute, value) == 56usize); - assert!(size_of::() == 32usize); + assert!(size_of::() == 48usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 96usize); + assert!(size_of::() == 112usize); assert!(align_of::() == 8usize); assert!(offset_of!(ExportNamedDeclaration, span) == 0usize); assert!(offset_of!(ExportNamedDeclaration, declaration) == 8usize); assert!(offset_of!(ExportNamedDeclaration, specifiers) == 24usize); assert!(offset_of!(ExportNamedDeclaration, source) == 56usize); - assert!(offset_of!(ExportNamedDeclaration, export_kind) == 80usize); - assert!(offset_of!(ExportNamedDeclaration, with_clause) == 88usize); + assert!(offset_of!(ExportNamedDeclaration, export_kind) == 96usize); + assert!(offset_of!(ExportNamedDeclaration, with_clause) == 104usize); - assert!(size_of::() == 64usize); + assert!(size_of::() == 72usize); assert!(align_of::() == 8usize); assert!(offset_of!(ExportDefaultDeclaration, span) == 0usize); assert!(offset_of!(ExportDefaultDeclaration, declaration) == 8usize); assert!(offset_of!(ExportDefaultDeclaration, exported) == 24usize); - assert!(size_of::() == 88usize); + assert!(size_of::() == 112usize); assert!(align_of::() == 8usize); assert!(offset_of!(ExportAllDeclaration, span) == 0usize); assert!(offset_of!(ExportAllDeclaration, exported) == 8usize); - assert!(offset_of!(ExportAllDeclaration, source) == 48usize); - assert!(offset_of!(ExportAllDeclaration, with_clause) == 72usize); - assert!(offset_of!(ExportAllDeclaration, export_kind) == 80usize); + assert!(offset_of!(ExportAllDeclaration, source) == 56usize); + assert!(offset_of!(ExportAllDeclaration, with_clause) == 96usize); + assert!(offset_of!(ExportAllDeclaration, export_kind) == 104usize); - assert!(size_of::() == 96usize); + assert!(size_of::() == 112usize); assert!(align_of::() == 8usize); assert!(offset_of!(ExportSpecifier, span) == 0usize); assert!(offset_of!(ExportSpecifier, local) == 8usize); - assert!(offset_of!(ExportSpecifier, exported) == 48usize); - assert!(offset_of!(ExportSpecifier, export_kind) == 88usize); + assert!(offset_of!(ExportSpecifier, exported) == 56usize); + assert!(offset_of!(ExportSpecifier, export_kind) == 104usize); assert!(size_of::() == 16usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 40usize); + assert!(size_of::() == 48usize); assert!(align_of::() == 8usize); assert!(size_of::() == 24usize); @@ -1089,19 +1090,19 @@ const _: () = { assert!(size_of::() == 16usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 72usize); + assert!(size_of::() == 80usize); assert!(align_of::() == 8usize); assert!(offset_of!(TSModuleDeclaration, span) == 0usize); assert!(offset_of!(TSModuleDeclaration, id) == 8usize); - assert!(offset_of!(TSModuleDeclaration, body) == 48usize); - assert!(offset_of!(TSModuleDeclaration, kind) == 64usize); - assert!(offset_of!(TSModuleDeclaration, declare) == 65usize); - assert!(offset_of!(TSModuleDeclaration, scope_id) == 68usize); + assert!(offset_of!(TSModuleDeclaration, body) == 56usize); + assert!(offset_of!(TSModuleDeclaration, kind) == 72usize); + assert!(offset_of!(TSModuleDeclaration, declare) == 73usize); + assert!(offset_of!(TSModuleDeclaration, scope_id) == 76usize); assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); - assert!(size_of::() == 40usize); + assert!(size_of::() == 48usize); assert!(align_of::() == 8usize); assert!(size_of::() == 16usize); @@ -1147,13 +1148,13 @@ const _: () = { assert!(offset_of!(TSImportAttributes, attributes_keyword) == 8usize); assert!(offset_of!(TSImportAttributes, elements) == 32usize); - assert!(size_of::() == 56usize); + assert!(size_of::() == 72usize); assert!(align_of::() == 8usize); assert!(offset_of!(TSImportAttribute, span) == 0usize); assert!(offset_of!(TSImportAttribute, name) == 8usize); - assert!(offset_of!(TSImportAttribute, value) == 40usize); + assert!(offset_of!(TSImportAttribute, value) == 56usize); - assert!(size_of::() == 32usize); + assert!(size_of::() == 48usize); assert!(align_of::() == 8usize); assert!(size_of::() == 40usize); @@ -1219,7 +1220,7 @@ const _: () = { assert!(size_of::() == 16usize); assert!(align_of::() == 8usize); - assert!(size_of::() == 32usize); + assert!(size_of::() == 48usize); assert!(align_of::() == 8usize); assert!(offset_of!(TSExternalModuleReference, span) == 0usize); assert!(offset_of!(TSExternalModuleReference, expression) == 8usize); @@ -1582,6 +1583,12 @@ const _: () = { assert!(offset_of!(NumericLiteral, raw) == 16usize); assert!(offset_of!(NumericLiteral, base) == 24usize); + assert!(size_of::() == 24usize); + assert!(align_of::() == 4usize); + assert!(offset_of!(StringLiteral, span) == 0usize); + assert!(offset_of!(StringLiteral, value) == 8usize); + assert!(offset_of!(StringLiteral, raw) == 16usize); + assert!(size_of::() == 20usize); assert!(align_of::() == 4usize); assert!(offset_of!(BigIntLiteral, span) == 0usize); @@ -1602,11 +1609,6 @@ const _: () = { assert!(size_of::() == 12usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 16usize); - assert!(align_of::() == 4usize); - assert!(offset_of!(StringLiteral, span) == 0usize); - assert!(offset_of!(StringLiteral, value) == 8usize); - assert!(size_of::() == 88usize); assert!(align_of::() == 4usize); assert!(offset_of!(Program, span) == 0usize); @@ -1892,11 +1894,11 @@ const _: () = { assert!(size_of::() == 8usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 32usize); + assert!(size_of::() == 40usize); assert!(align_of::() == 4usize); assert!(offset_of!(Directive, span) == 0usize); assert!(offset_of!(Directive, expression) == 8usize); - assert!(offset_of!(Directive, directive) == 24usize); + assert!(offset_of!(Directive, directive) == 32usize); assert!(size_of::() == 16usize); assert!(align_of::() == 4usize); @@ -2260,23 +2262,23 @@ const _: () = { assert!(offset_of!(ImportExpression, source) == 8usize); assert!(offset_of!(ImportExpression, arguments) == 16usize); - assert!(size_of::() == 48usize); + assert!(size_of::() == 56usize); assert!(align_of::() == 4usize); assert!(offset_of!(ImportDeclaration, span) == 0usize); assert!(offset_of!(ImportDeclaration, specifiers) == 8usize); assert!(offset_of!(ImportDeclaration, source) == 24usize); - assert!(offset_of!(ImportDeclaration, with_clause) == 40usize); - assert!(offset_of!(ImportDeclaration, import_kind) == 44usize); + assert!(offset_of!(ImportDeclaration, with_clause) == 48usize); + assert!(offset_of!(ImportDeclaration, import_kind) == 52usize); assert!(size_of::() == 8usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 56usize); + assert!(size_of::() == 60usize); assert!(align_of::() == 4usize); assert!(offset_of!(ImportSpecifier, span) == 0usize); assert!(offset_of!(ImportSpecifier, imported) == 8usize); - assert!(offset_of!(ImportSpecifier, local) == 32usize); - assert!(offset_of!(ImportSpecifier, import_kind) == 52usize); + assert!(offset_of!(ImportSpecifier, local) == 36usize); + assert!(offset_of!(ImportSpecifier, import_kind) == 56usize); assert!(size_of::() == 28usize); assert!(align_of::() == 4usize); @@ -2294,49 +2296,49 @@ const _: () = { assert!(offset_of!(WithClause, attributes_keyword) == 8usize); assert!(offset_of!(WithClause, with_entries) == 24usize); - assert!(size_of::() == 44usize); + assert!(size_of::() == 60usize); assert!(align_of::() == 4usize); assert!(offset_of!(ImportAttribute, span) == 0usize); assert!(offset_of!(ImportAttribute, key) == 8usize); - assert!(offset_of!(ImportAttribute, value) == 28usize); + assert!(offset_of!(ImportAttribute, value) == 36usize); - assert!(size_of::() == 20usize); + assert!(size_of::() == 28usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 56usize); + assert!(size_of::() == 64usize); assert!(align_of::() == 4usize); assert!(offset_of!(ExportNamedDeclaration, span) == 0usize); assert!(offset_of!(ExportNamedDeclaration, declaration) == 8usize); assert!(offset_of!(ExportNamedDeclaration, specifiers) == 16usize); assert!(offset_of!(ExportNamedDeclaration, source) == 32usize); - assert!(offset_of!(ExportNamedDeclaration, export_kind) == 48usize); - assert!(offset_of!(ExportNamedDeclaration, with_clause) == 52usize); + assert!(offset_of!(ExportNamedDeclaration, export_kind) == 56usize); + assert!(offset_of!(ExportNamedDeclaration, with_clause) == 60usize); - assert!(size_of::() == 40usize); + assert!(size_of::() == 44usize); assert!(align_of::() == 4usize); assert!(offset_of!(ExportDefaultDeclaration, span) == 0usize); assert!(offset_of!(ExportDefaultDeclaration, declaration) == 8usize); assert!(offset_of!(ExportDefaultDeclaration, exported) == 16usize); - assert!(size_of::() == 56usize); + assert!(size_of::() == 68usize); assert!(align_of::() == 4usize); assert!(offset_of!(ExportAllDeclaration, span) == 0usize); assert!(offset_of!(ExportAllDeclaration, exported) == 8usize); - assert!(offset_of!(ExportAllDeclaration, source) == 32usize); - assert!(offset_of!(ExportAllDeclaration, with_clause) == 48usize); - assert!(offset_of!(ExportAllDeclaration, export_kind) == 52usize); + assert!(offset_of!(ExportAllDeclaration, source) == 36usize); + assert!(offset_of!(ExportAllDeclaration, with_clause) == 60usize); + assert!(offset_of!(ExportAllDeclaration, export_kind) == 64usize); - assert!(size_of::() == 60usize); + assert!(size_of::() == 68usize); assert!(align_of::() == 4usize); assert!(offset_of!(ExportSpecifier, span) == 0usize); assert!(offset_of!(ExportSpecifier, local) == 8usize); - assert!(offset_of!(ExportSpecifier, exported) == 32usize); - assert!(offset_of!(ExportSpecifier, export_kind) == 56usize); + assert!(offset_of!(ExportSpecifier, exported) == 36usize); + assert!(offset_of!(ExportSpecifier, export_kind) == 64usize); assert!(size_of::() == 8usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 24usize); + assert!(size_of::() == 28usize); assert!(align_of::() == 4usize); assert!(size_of::() == 20usize); @@ -2646,19 +2648,19 @@ const _: () = { assert!(size_of::() == 12usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 48usize); + assert!(size_of::() == 52usize); assert!(align_of::() == 4usize); assert!(offset_of!(TSModuleDeclaration, span) == 0usize); assert!(offset_of!(TSModuleDeclaration, id) == 8usize); - assert!(offset_of!(TSModuleDeclaration, body) == 32usize); - assert!(offset_of!(TSModuleDeclaration, kind) == 40usize); - assert!(offset_of!(TSModuleDeclaration, declare) == 41usize); - assert!(offset_of!(TSModuleDeclaration, scope_id) == 44usize); + assert!(offset_of!(TSModuleDeclaration, body) == 36usize); + assert!(offset_of!(TSModuleDeclaration, kind) == 44usize); + assert!(offset_of!(TSModuleDeclaration, declare) == 45usize); + assert!(offset_of!(TSModuleDeclaration, scope_id) == 48usize); assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); - assert!(size_of::() == 24usize); + assert!(size_of::() == 28usize); assert!(align_of::() == 4usize); assert!(size_of::() == 8usize); @@ -2704,13 +2706,13 @@ const _: () = { assert!(offset_of!(TSImportAttributes, attributes_keyword) == 8usize); assert!(offset_of!(TSImportAttributes, elements) == 24usize); - assert!(size_of::() == 36usize); + assert!(size_of::() == 44usize); assert!(align_of::() == 4usize); assert!(offset_of!(TSImportAttribute, span) == 0usize); assert!(offset_of!(TSImportAttribute, name) == 8usize); - assert!(offset_of!(TSImportAttribute, value) == 28usize); + assert!(offset_of!(TSImportAttribute, value) == 36usize); - assert!(size_of::() == 20usize); + assert!(size_of::() == 28usize); assert!(align_of::() == 4usize); assert!(size_of::() == 24usize); @@ -2776,7 +2778,7 @@ const _: () = { assert!(size_of::() == 8usize); assert!(align_of::() == 4usize); - assert!(size_of::() == 24usize); + assert!(size_of::() == 32usize); assert!(align_of::() == 4usize); assert!(offset_of!(TSExternalModuleReference, span) == 0usize); assert!(offset_of!(TSExternalModuleReference, expression) == 8usize); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 773ea68e86221..7c67ba8f532fa 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -116,6 +116,49 @@ impl<'a> AstBuilder<'a> { Box::new_in(self.numeric_literal(span, value, raw, base), self.allocator) } + /// Build a [`StringLiteral`]. + /// + /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_string_literal`] instead. + /// + /// ## Parameters + /// - span: Node location in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes + #[inline] + pub fn string_literal(self, span: Span, value: A, raw: S) -> StringLiteral<'a> + where + A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, + { + StringLiteral { + span, + value: value.into_in(self.allocator), + raw: raw.into_in(self.allocator), + } + } + + /// Build a [`StringLiteral`], and store it in the memory arena. + /// + /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::string_literal`] instead. + /// + /// ## Parameters + /// - span: Node location in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes + #[inline] + pub fn alloc_string_literal( + self, + span: Span, + value: A, + raw: S, + ) -> Box<'a, StringLiteral<'a>> + where + A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, + { + Box::new_in(self.string_literal(span, value, raw), self.allocator) + } + /// Build a [`BigIntLiteral`]. /// /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_big_int_literal`] instead. @@ -190,36 +233,6 @@ impl<'a> AstBuilder<'a> { Box::new_in(self.reg_exp_literal(span, regex, raw), self.allocator) } - /// Build a [`StringLiteral`]. - /// - /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_string_literal`] instead. - /// - /// ## Parameters - /// - span: Node location in source code - /// - value: The string as it appears in source code - #[inline] - pub fn string_literal(self, span: Span, value: A) -> StringLiteral<'a> - where - A: IntoIn<'a, Atom<'a>>, - { - StringLiteral { span, value: value.into_in(self.allocator) } - } - - /// Build a [`StringLiteral`], and store it in the memory arena. - /// - /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::string_literal`] instead. - /// - /// ## Parameters - /// - span: Node location in source code - /// - value: The string as it appears in source code - #[inline] - pub fn alloc_string_literal(self, span: Span, value: A) -> Box<'a, StringLiteral<'a>> - where - A: IntoIn<'a, Atom<'a>>, - { - Box::new_in(self.string_literal(span, value), self.allocator) - } - /// Build a [`Program`]. /// /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_program`] instead. @@ -467,13 +480,15 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn expression_string_literal(self, span: Span, value: A) -> Expression<'a> + pub fn expression_string_literal(self, span: Span, value: A, raw: S) -> Expression<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - Expression::StringLiteral(self.alloc(self.string_literal(span, value))) + Expression::StringLiteral(self.alloc(self.string_literal(span, value, raw))) } /// Build an [`Expression::TemplateLiteral`] @@ -7173,17 +7188,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn import_attribute_key_string_literal( + pub fn import_attribute_key_string_literal( self, span: Span, value: A, + raw: S, ) -> ImportAttributeKey<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - ImportAttributeKey::StringLiteral(self.string_literal(span, value)) + ImportAttributeKey::StringLiteral(self.string_literal(span, value, raw)) } /// Build an [`ExportNamedDeclaration`]. @@ -7560,13 +7578,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn module_export_name_string_literal(self, span: Span, value: A) -> ModuleExportName<'a> + pub fn module_export_name_string_literal( + self, + span: Span, + value: A, + raw: S, + ) -> ModuleExportName<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - ModuleExportName::StringLiteral(self.string_literal(span, value)) + ModuleExportName::StringLiteral(self.string_literal(span, value, raw)) } /// Build a [`TSThisParameter`]. @@ -7774,13 +7799,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn ts_enum_member_name_string_literal(self, span: Span, value: A) -> TSEnumMemberName<'a> + pub fn ts_enum_member_name_string_literal( + self, + span: Span, + value: A, + raw: S, + ) -> TSEnumMemberName<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - TSEnumMemberName::StaticStringLiteral(self.alloc(self.string_literal(span, value))) + TSEnumMemberName::StaticStringLiteral(self.alloc(self.string_literal(span, value, raw))) } /// Build a [`TSEnumMemberName::StaticTemplateLiteral`] @@ -7984,13 +8016,15 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn ts_literal_string_literal(self, span: Span, value: A) -> TSLiteral<'a> + pub fn ts_literal_string_literal(self, span: Span, value: A, raw: S) -> TSLiteral<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - TSLiteral::StringLiteral(self.alloc(self.string_literal(span, value))) + TSLiteral::StringLiteral(self.alloc(self.string_literal(span, value, raw))) } /// Build a [`TSLiteral::TemplateLiteral`] @@ -11034,17 +11068,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn ts_module_declaration_name_string_literal( + pub fn ts_module_declaration_name_string_literal( self, span: Span, value: A, + raw: S, ) -> TSModuleDeclarationName<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - TSModuleDeclarationName::StringLiteral(self.string_literal(span, value)) + TSModuleDeclarationName::StringLiteral(self.string_literal(span, value, raw)) } /// Build a [`TSModuleDeclarationBody::TSModuleDeclaration`] @@ -11432,17 +11469,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn ts_import_attribute_name_string_literal( + pub fn ts_import_attribute_name_string_literal( self, span: Span, value: A, + raw: S, ) -> TSImportAttributeName<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - TSImportAttributeName::StringLiteral(self.string_literal(span, value)) + TSImportAttributeName::StringLiteral(self.string_literal(span, value, raw)) } /// Build a [`TSFunctionType`]. @@ -12826,17 +12866,20 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: Node location in source code - /// - value: The string as it appears in source code + /// - value: The value of the string + /// - raw: The string as it appears in source code, including quotes #[inline] - pub fn jsx_attribute_value_string_literal( + pub fn jsx_attribute_value_string_literal( self, span: Span, value: A, + raw: S, ) -> JSXAttributeValue<'a> where A: IntoIn<'a, Atom<'a>>, + S: IntoIn<'a, &'a str>, { - JSXAttributeValue::StringLiteral(self.alloc(self.string_literal(span, value))) + JSXAttributeValue::StringLiteral(self.alloc(self.string_literal(span, value, raw))) } /// Build a [`JSXAttributeValue::ExpressionContainer`] diff --git a/crates/oxc_ast/src/generated/ast_kind.rs b/crates/oxc_ast/src/generated/ast_kind.rs index 5942241a45c15..2e100ed38d0d6 100644 --- a/crates/oxc_ast/src/generated/ast_kind.rs +++ b/crates/oxc_ast/src/generated/ast_kind.rs @@ -13,9 +13,9 @@ pub enum AstType { BooleanLiteral, NullLiteral, NumericLiteral, + StringLiteral, BigIntLiteral, RegExpLiteral, - StringLiteral, Program, IdentifierName, IdentifierReference, @@ -183,9 +183,9 @@ pub enum AstKind<'a> { BooleanLiteral(&'a BooleanLiteral), NullLiteral(&'a NullLiteral), NumericLiteral(&'a NumericLiteral<'a>), + StringLiteral(&'a StringLiteral<'a>), BigIntLiteral(&'a BigIntLiteral<'a>), RegExpLiteral(&'a RegExpLiteral<'a>), - StringLiteral(&'a StringLiteral<'a>), Program(&'a Program<'a>), IdentifierName(&'a IdentifierName<'a>), IdentifierReference(&'a IdentifierReference<'a>), @@ -354,9 +354,9 @@ impl<'a> GetSpan for AstKind<'a> { Self::BooleanLiteral(it) => it.span(), Self::NullLiteral(it) => it.span(), Self::NumericLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), Self::BigIntLiteral(it) => it.span(), Self::RegExpLiteral(it) => it.span(), - Self::StringLiteral(it) => it.span(), Self::Program(it) => it.span(), Self::IdentifierName(it) => it.span(), Self::IdentifierReference(it) => it.span(), @@ -549,8 +549,8 @@ impl<'a> AstKind<'a> { } #[inline] - pub fn as_big_int_literal(&self) -> Option<&'a BigIntLiteral<'a>> { - if let Self::BigIntLiteral(v) = self { + pub fn as_string_literal(&self) -> Option<&'a StringLiteral<'a>> { + if let Self::StringLiteral(v) = self { Some(*v) } else { None @@ -558,8 +558,8 @@ impl<'a> AstKind<'a> { } #[inline] - pub fn as_reg_exp_literal(&self) -> Option<&'a RegExpLiteral<'a>> { - if let Self::RegExpLiteral(v) = self { + pub fn as_big_int_literal(&self) -> Option<&'a BigIntLiteral<'a>> { + if let Self::BigIntLiteral(v) = self { Some(*v) } else { None @@ -567,8 +567,8 @@ impl<'a> AstKind<'a> { } #[inline] - pub fn as_string_literal(&self) -> Option<&'a StringLiteral<'a>> { - if let Self::StringLiteral(v) = self { + pub fn as_reg_exp_literal(&self) -> Option<&'a RegExpLiteral<'a>> { + if let Self::RegExpLiteral(v) = self { Some(*v) } else { None diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs index 91082daf172d6..2d04316cb3ea9 100644 --- a/crates/oxc_ast/src/generated/derive_clone_in.rs +++ b/crates/oxc_ast/src/generated/derive_clone_in.rs @@ -44,6 +44,17 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for NumericLiteral<'old_alloc> } } +impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for StringLiteral<'old_alloc> { + type Cloned = StringLiteral<'new_alloc>; + fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { + StringLiteral { + span: CloneIn::clone_in(&self.span, allocator), + value: CloneIn::clone_in(&self.value, allocator), + raw: CloneIn::clone_in(&self.raw, allocator), + } + } +} + impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for BigIntLiteral<'old_alloc> { type Cloned = BigIntLiteral<'new_alloc>; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { @@ -87,16 +98,6 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for RegExpPattern<'old_alloc> { } } -impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for StringLiteral<'old_alloc> { - type Cloned = StringLiteral<'new_alloc>; - fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { - StringLiteral { - span: CloneIn::clone_in(&self.span, allocator), - value: CloneIn::clone_in(&self.value, allocator), - } - } -} - impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Program<'old_alloc> { type Cloned = Program<'new_alloc>; fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { diff --git a/crates/oxc_ast/src/generated/derive_content_eq.rs b/crates/oxc_ast/src/generated/derive_content_eq.rs index c05760395c05d..7d0bacf161ecb 100644 --- a/crates/oxc_ast/src/generated/derive_content_eq.rs +++ b/crates/oxc_ast/src/generated/derive_content_eq.rs @@ -35,6 +35,13 @@ impl<'a> ContentEq for NumericLiteral<'a> { } } +impl<'a> ContentEq for StringLiteral<'a> { + fn content_eq(&self, other: &Self) -> bool { + ContentEq::content_eq(&self.value, &other.value) + && ContentEq::content_eq(&self.raw, &other.raw) + } +} + impl<'a> ContentEq for BigIntLiteral<'a> { fn content_eq(&self, other: &Self) -> bool { ContentEq::content_eq(&self.raw, &other.raw) @@ -75,12 +82,6 @@ impl<'a> ContentEq for RegExpPattern<'a> { } } -impl<'a> ContentEq for StringLiteral<'a> { - fn content_eq(&self, other: &Self) -> bool { - ContentEq::content_eq(&self.value, &other.value) - } -} - impl<'a> ContentEq for Program<'a> { fn content_eq(&self, other: &Self) -> bool { ContentEq::content_eq(&self.source_type, &other.source_type) diff --git a/crates/oxc_ast/src/generated/derive_content_hash.rs b/crates/oxc_ast/src/generated/derive_content_hash.rs index 75f00965d3819..8d2160ad5655f 100644 --- a/crates/oxc_ast/src/generated/derive_content_hash.rs +++ b/crates/oxc_ast/src/generated/derive_content_hash.rs @@ -23,6 +23,13 @@ impl ContentHash for BooleanLiteral { } } +impl<'a> ContentHash for StringLiteral<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&self.value, state); + ContentHash::content_hash(&self.raw, state); + } +} + impl<'a> ContentHash for BigIntLiteral<'a> { fn content_hash(&self, state: &mut H) { ContentHash::content_hash(&self.raw, state); @@ -55,12 +62,6 @@ impl<'a> ContentHash for RegExpPattern<'a> { } } -impl<'a> ContentHash for StringLiteral<'a> { - fn content_hash(&self, state: &mut H) { - ContentHash::content_hash(&self.value, state); - } -} - impl<'a> ContentHash for Program<'a> { fn content_hash(&self, state: &mut H) { ContentHash::content_hash(&self.source_type, state); diff --git a/crates/oxc_ast/src/generated/derive_estree.rs b/crates/oxc_ast/src/generated/derive_estree.rs index 17cd751ba9438..4a5d1267dd401 100644 --- a/crates/oxc_ast/src/generated/derive_estree.rs +++ b/crates/oxc_ast/src/generated/derive_estree.rs @@ -31,6 +31,12 @@ impl<'a> Serialize for NumericLiteral<'a> { } } +impl<'a> Serialize for StringLiteral<'a> { + fn serialize(&self, serializer: S) -> Result { + crate::serialize::ESTreeLiteral::from(self).serialize(serializer) + } +} + impl<'a> Serialize for BigIntLiteral<'a> { fn serialize(&self, serializer: S) -> Result { crate::serialize::ESTreeLiteral::from(self).serialize(serializer) @@ -62,16 +68,6 @@ impl<'a> Serialize for RegExpPattern<'a> { } } -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() - } -} - impl<'a> Serialize for Program<'a> { fn serialize(&self, serializer: S) -> Result { let mut map = serializer.serialize_map(None)?; diff --git a/crates/oxc_ast/src/generated/derive_get_span.rs b/crates/oxc_ast/src/generated/derive_get_span.rs index 9f2de7d1294db..c30a48e0faa39 100644 --- a/crates/oxc_ast/src/generated/derive_get_span.rs +++ b/crates/oxc_ast/src/generated/derive_get_span.rs @@ -34,21 +34,21 @@ impl<'a> GetSpan for NumericLiteral<'a> { } } -impl<'a> GetSpan for BigIntLiteral<'a> { +impl<'a> GetSpan for StringLiteral<'a> { #[inline] fn span(&self) -> Span { self.span } } -impl<'a> GetSpan for RegExpLiteral<'a> { +impl<'a> GetSpan for BigIntLiteral<'a> { #[inline] fn span(&self) -> Span { self.span } } -impl<'a> GetSpan for StringLiteral<'a> { +impl<'a> GetSpan for RegExpLiteral<'a> { #[inline] fn span(&self) -> Span { self.span diff --git a/crates/oxc_ast/src/generated/derive_get_span_mut.rs b/crates/oxc_ast/src/generated/derive_get_span_mut.rs index 38b0041f11ede..95fe7a3baf101 100644 --- a/crates/oxc_ast/src/generated/derive_get_span_mut.rs +++ b/crates/oxc_ast/src/generated/derive_get_span_mut.rs @@ -34,21 +34,21 @@ impl<'a> GetSpanMut for NumericLiteral<'a> { } } -impl<'a> GetSpanMut for BigIntLiteral<'a> { +impl<'a> GetSpanMut for StringLiteral<'a> { #[inline] fn span_mut(&mut self) -> &mut Span { &mut self.span } } -impl<'a> GetSpanMut for RegExpLiteral<'a> { +impl<'a> GetSpanMut for BigIntLiteral<'a> { #[inline] fn span_mut(&mut self) -> &mut Span { &mut self.span } } -impl<'a> GetSpanMut for StringLiteral<'a> { +impl<'a> GetSpanMut for RegExpLiteral<'a> { #[inline] fn span_mut(&mut self) -> &mut Span { &mut self.span diff --git a/crates/oxc_ast/src/serialize.rs b/crates/oxc_ast/src/serialize.rs index 66cab18770721..05624205d4853 100644 --- a/crates/oxc_ast/src/serialize.rs +++ b/crates/oxc_ast/src/serialize.rs @@ -53,6 +53,12 @@ impl<'a> From<&'a NumericLiteral<'a>> for ESTreeLiteral<'a, f64> { } } +impl<'a> From<&'a StringLiteral<'a>> for ESTreeLiteral<'a, &'a str> { + fn from(value: &'a StringLiteral) -> Self { + Self { span: value.span, value: &value.value, raw: value.raw, bigint: None, regex: None } + } +} + impl<'a> From<&'a BigIntLiteral<'a>> for ESTreeLiteral<'a, ()> { fn from(value: &'a BigIntLiteral) -> Self { let src = &value.raw.strip_suffix('n').unwrap().cow_replace('_', ""); diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 4664cf10acd1a..fb031eae259c6 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -396,9 +396,10 @@ impl<'a> ParserImpl<'a> { return Err(self.unexpected()); } let value = self.cur_string(); + let raw = self.cur_src(); let span = self.start_span(); self.bump_any(); - Ok(self.ast.string_literal(self.end_span(span), value)) + Ok(self.ast.string_literal(self.end_span(span), value, raw)) } /// Section [Array Expression](https://tc39.es/ecma262/#prod-ArrayLiteral) diff --git a/crates/oxc_traverse/src/generated/traverse.rs b/crates/oxc_traverse/src/generated/traverse.rs index 6ab2a0d844a9d..fe19d7f0b5543 100644 --- a/crates/oxc_traverse/src/generated/traverse.rs +++ b/crates/oxc_traverse/src/generated/traverse.rs @@ -1494,6 +1494,11 @@ pub trait Traverse<'a> { #[inline] fn exit_numeric_literal(&mut self, node: &mut NumericLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} + #[inline] + fn enter_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} + #[inline] + fn exit_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} + #[inline] fn enter_big_int_literal(&mut self, node: &mut BigIntLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} #[inline] @@ -1504,11 +1509,6 @@ pub trait Traverse<'a> { #[inline] fn exit_reg_exp_literal(&mut self, node: &mut RegExpLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} - #[inline] - fn enter_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} - #[inline] - fn exit_string_literal(&mut self, node: &mut StringLiteral<'a>, ctx: &mut TraverseCtx<'a>) {} - #[inline] fn enter_ts_this_parameter( &mut self, diff --git a/crates/oxc_traverse/src/generated/walk.rs b/crates/oxc_traverse/src/generated/walk.rs index 0e849819c0c6c..52f9dcf3861e9 100644 --- a/crates/oxc_traverse/src/generated/walk.rs +++ b/crates/oxc_traverse/src/generated/walk.rs @@ -3612,6 +3612,15 @@ pub(crate) unsafe fn walk_numeric_literal<'a, Tr: Traverse<'a>>( traverser.exit_numeric_literal(&mut *node, ctx); } +pub(crate) unsafe fn walk_string_literal<'a, Tr: Traverse<'a>>( + traverser: &mut Tr, + node: *mut StringLiteral<'a>, + ctx: &mut TraverseCtx<'a>, +) { + traverser.enter_string_literal(&mut *node, ctx); + traverser.exit_string_literal(&mut *node, ctx); +} + pub(crate) unsafe fn walk_big_int_literal<'a, Tr: Traverse<'a>>( traverser: &mut Tr, node: *mut BigIntLiteral<'a>, @@ -3630,15 +3639,6 @@ pub(crate) unsafe fn walk_reg_exp_literal<'a, Tr: Traverse<'a>>( traverser.exit_reg_exp_literal(&mut *node, ctx); } -pub(crate) unsafe fn walk_string_literal<'a, Tr: Traverse<'a>>( - traverser: &mut Tr, - node: *mut StringLiteral<'a>, - ctx: &mut TraverseCtx<'a>, -) { - traverser.enter_string_literal(&mut *node, ctx); - traverser.exit_string_literal(&mut *node, ctx); -} - pub(crate) unsafe fn walk_ts_this_parameter<'a, Tr: Traverse<'a>>( traverser: &mut Tr, node: *mut TSThisParameter<'a>, diff --git a/npm/oxc-types/types.d.ts b/npm/oxc-types/types.d.ts index 1caa9915c5077..1df3d68de461f 100644 --- a/npm/oxc-types/types.d.ts +++ b/npm/oxc-types/types.d.ts @@ -19,6 +19,12 @@ export interface NumericLiteral extends Span { raw: string; } +export interface StringLiteral extends Span { + type: 'Literal'; + value: string; + raw: string; +} + export interface BigIntLiteral extends Span { type: 'Literal'; raw: string; @@ -40,11 +46,6 @@ export interface RegExp { export type RegExpPattern = string | string | Pattern; -export interface StringLiteral extends Span { - type: 'StringLiteral'; - value: string; -} - export interface Program extends Span { type: 'Program'; sourceType: SourceType;