diff --git a/.github/.generated_ast_watch_list.yml b/.github/.generated_ast_watch_list.yml index 8187535cb7f88..887a9d0cf5b1a 100644 --- a/.github/.generated_ast_watch_list.yml +++ b/.github/.generated_ast_watch_list.yml @@ -24,4 +24,7 @@ src: - 'crates/oxc_ast/src/generated/derive_content_eq.rs' - 'crates/oxc_regular_expression/src/generated/derive_content_eq.rs' - 'crates/oxc_syntax/src/generated/derive_content_eq.rs' + - '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' - 'tasks/ast_codegen/src/**' diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 78ddb1eead3c4..91be58de65ef7 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -9,7 +9,7 @@ use std::cell::Cell; use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; -use oxc_span::{cmp::ContentEq, Atom, GetSpan, GetSpanMut, SourceType, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, SourceType, Span}; use oxc_syntax::{ operator::{ AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator, @@ -34,7 +34,7 @@ use tsify::Tsify; strict_if(self.source_type.is_strict() || self.directives.iter().any(Directive::is_use_strict)), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct Program<'a> { @@ -56,8 +56,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum Expression<'a> { @@ -206,8 +206,8 @@ 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, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "Identifier")] pub struct IdentifierName<'a> { @@ -223,7 +223,7 @@ 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)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "Identifier")] pub struct IdentifierReference<'a> { @@ -248,7 +248,7 @@ 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)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "Identifier")] pub struct BindingIdentifier<'a> { @@ -273,8 +273,8 @@ pub struct BindingIdentifier<'a> { /// /// See: [13.1 Identifiers](https://tc39.es/ecma262/#sec-identifiers) #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "Identifier")] pub struct LabelIdentifier<'a> { @@ -287,8 +287,8 @@ pub struct LabelIdentifier<'a> { /// /// Represents a `this` expression, which is a reference to the current object. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ThisExpression { @@ -300,8 +300,8 @@ pub struct ThisExpression { /// /// Represents an array literal, which can include elements, spread elements, or null values. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ArrayExpression<'a> { @@ -322,8 +322,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(untagged)] pub enum ArrayExpressionElement<'a> { @@ -344,8 +344,8 @@ pub enum ArrayExpressionElement<'a> { /// Array Expression Elision Element /// Serialized as `null` in JSON AST. See `serialize.rs`. #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] pub struct Elision { pub span: Span, } @@ -354,8 +354,8 @@ pub struct Elision { /// /// Represents an object literal, which can include properties, spread properties, or computed properties and trailing comma. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ObjectExpression<'a> { @@ -369,8 +369,8 @@ pub struct ObjectExpression<'a> { /// Represents a property in an object literal. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ObjectPropertyKind<'a> { @@ -384,8 +384,8 @@ pub enum ObjectPropertyKind<'a> { /// /// Represents a property in an object literal. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ObjectProperty<'a> { @@ -407,8 +407,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum PropertyKey<'a> { @@ -423,8 +423,8 @@ pub enum PropertyKey<'a> { /// Represents the kind of property in an object literal or class. #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum PropertyKind { @@ -440,8 +440,8 @@ pub enum PropertyKind { /// /// Represents a template literal, which can include quasi elements and expression elements. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TemplateLiteral<'a> { @@ -455,8 +455,8 @@ pub struct TemplateLiteral<'a> { /// /// Represents a tagged template expression, which can include a tag and a quasi. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TaggedTemplateExpression<'a> { @@ -471,8 +471,8 @@ pub struct TaggedTemplateExpression<'a> { /// /// Represents a quasi element in a template literal. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TemplateElement<'a> { @@ -484,8 +484,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, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct TemplateElementValue<'a> { /// A raw interpretation where backslashes do not have special meaning. @@ -503,8 +503,8 @@ pub struct TemplateElementValue<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum MemberExpression<'a> { @@ -531,8 +531,8 @@ pub use match_member_expression; /// /// Represents a computed member access expression, which can include an object and an expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ComputedMemberExpression<'a> { @@ -547,8 +547,8 @@ pub struct ComputedMemberExpression<'a> { /// /// Represents a static member access expression, which can include an object and a property. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct StaticMemberExpression<'a> { @@ -563,8 +563,8 @@ pub struct StaticMemberExpression<'a> { /// /// Represents a private field access expression, which can include an object and a private identifier. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct PrivateFieldExpression<'a> { @@ -592,8 +592,8 @@ pub struct PrivateFieldExpression<'a> { /// // ^^^^^^^^^^^^^^ type_parameters /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct CallExpression<'a> { @@ -618,8 +618,8 @@ pub struct CallExpression<'a> { /// // type_parameters /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct NewExpression<'a> { @@ -634,8 +634,8 @@ pub struct NewExpression<'a> { /// /// Represents a meta property. The following syntaxes are supported. `import.meta`, `new.target`. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct MetaProperty<'a> { @@ -649,8 +649,8 @@ pub struct MetaProperty<'a> { /// /// Represents a spread element, which can include an argument. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct SpreadElement<'a> { @@ -667,8 +667,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum Argument<'a> { @@ -683,8 +683,8 @@ 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, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct UpdateExpression<'a> { @@ -699,8 +699,8 @@ 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, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct UnaryExpression<'a> { @@ -714,8 +714,8 @@ pub struct UnaryExpression<'a> { /// /// Represents a binary expression, which can include a left expression, an operator, and a right expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BinaryExpression<'a> { @@ -730,8 +730,8 @@ pub struct BinaryExpression<'a> { /// /// Represents a private in expression, which can include a private identifier, an operator, and a expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct PrivateInExpression<'a> { @@ -746,8 +746,8 @@ 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, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct LogicalExpression<'a> { @@ -762,8 +762,8 @@ pub struct LogicalExpression<'a> { /// /// Represents a conditional expression, which can include a test, a consequent, and an alternate. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ConditionalExpression<'a> { @@ -778,8 +778,8 @@ pub struct ConditionalExpression<'a> { /// /// Represents an assignment expression, which can include an operator, a target, and a expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AssignmentExpression<'a> { @@ -798,8 +798,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum AssignmentTarget<'a> { @@ -817,8 +817,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum SimpleAssignmentTarget<'a> { @@ -872,8 +872,8 @@ macro_rules! match_simple_assignment_target { pub use match_simple_assignment_target; #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum AssignmentTargetPattern<'a> { @@ -894,8 +894,8 @@ pub use match_assignment_target_pattern; /// /// Represents an array assignment target, which can include elements and a rest element. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type")] pub struct ArrayAssignmentTarget<'a> { @@ -913,8 +913,8 @@ pub struct ArrayAssignmentTarget<'a> { /// /// Represents an object assignment target, which can include properties and a rest element. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type")] pub struct ObjectAssignmentTarget<'a> { @@ -930,8 +930,8 @@ pub struct ObjectAssignmentTarget<'a> { /// /// Represents a rest element in an array assignment target, which can include a target. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "RestElement")] pub struct AssignmentTargetRest<'a> { @@ -948,8 +948,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum AssignmentTargetMaybeDefault<'a> { @@ -960,8 +960,8 @@ pub enum AssignmentTargetMaybeDefault<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AssignmentTargetWithDefault<'a> { @@ -972,8 +972,8 @@ pub struct AssignmentTargetWithDefault<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum AssignmentTargetProperty<'a> { @@ -985,8 +985,8 @@ pub enum AssignmentTargetProperty<'a> { /// /// Represents an assignment target property identifier, which can include a binding and an init expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AssignmentTargetPropertyIdentifier<'a> { @@ -1000,8 +1000,8 @@ pub struct AssignmentTargetPropertyIdentifier<'a> { /// /// Represents an assignment target property property, which can include a name and a binding. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AssignmentTargetPropertyProperty<'a> { @@ -1015,8 +1015,8 @@ pub struct AssignmentTargetPropertyProperty<'a> { /// /// Represents a sequence expression, which can include expressions. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct SequenceExpression<'a> { @@ -1029,8 +1029,8 @@ pub struct SequenceExpression<'a> { /// /// Represents a super expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct Super { @@ -1042,8 +1042,8 @@ pub struct Super { /// /// Represents an await expression, which can include an argument. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AwaitExpression<'a> { @@ -1056,8 +1056,8 @@ pub struct AwaitExpression<'a> { /// /// Represents a chain expression, which can include an expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ChainExpression<'a> { @@ -1073,8 +1073,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ChainElement<'a> { @@ -1088,8 +1088,8 @@ pub enum ChainElement<'a> { /// /// Represents a parenthesized expression, which can include an expression. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ParenthesizedExpression<'a> { @@ -1106,8 +1106,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum Statement<'a> { @@ -1141,8 +1141,8 @@ pub enum Statement<'a> { /// /// Represents a directive statement, which can include a string literal. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct Directive<'a> { @@ -1158,8 +1158,8 @@ pub struct Directive<'a> { /// /// Represents a hashbang directive, which can include a value. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct Hashbang<'a> { @@ -1174,7 +1174,7 @@ pub struct Hashbang<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BlockStatement<'a> { @@ -1188,8 +1188,8 @@ pub struct BlockStatement<'a> { /// Declarations and the Variable Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum Declaration<'a> { @@ -1225,8 +1225,8 @@ pub use match_declaration; /// /// Represents a variable declaration, which can include a kind, declarations, and modifiers. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct VariableDeclaration<'a> { @@ -1238,8 +1238,8 @@ pub struct VariableDeclaration<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum VariableDeclarationKind { @@ -1252,8 +1252,8 @@ pub enum VariableDeclarationKind { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct VariableDeclarator<'a> { @@ -1268,8 +1268,8 @@ pub struct VariableDeclarator<'a> { /// Empty Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct EmptyStatement { @@ -1279,8 +1279,8 @@ pub struct EmptyStatement { /// Expression Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ExpressionStatement<'a> { @@ -1291,8 +1291,8 @@ pub struct ExpressionStatement<'a> { /// If Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct IfStatement<'a> { @@ -1305,8 +1305,8 @@ pub struct IfStatement<'a> { /// Do-While Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct DoWhileStatement<'a> { @@ -1318,8 +1318,8 @@ pub struct DoWhileStatement<'a> { /// While Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct WhileStatement<'a> { @@ -1333,7 +1333,7 @@ pub struct WhileStatement<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ForStatement<'a> { @@ -1355,8 +1355,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ForStatementInit<'a> { @@ -1370,7 +1370,7 @@ pub enum ForStatementInit<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ForInStatement<'a> { @@ -1391,8 +1391,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ForStatementLeft<'a> { @@ -1405,7 +1405,7 @@ pub enum ForStatementLeft<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ForOfStatement<'a> { @@ -1422,8 +1422,8 @@ pub struct ForOfStatement<'a> { /// Continue Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ContinueStatement<'a> { @@ -1434,8 +1434,8 @@ pub struct ContinueStatement<'a> { /// Break Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BreakStatement<'a> { @@ -1446,8 +1446,8 @@ pub struct BreakStatement<'a> { /// Return Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ReturnStatement<'a> { @@ -1458,8 +1458,8 @@ pub struct ReturnStatement<'a> { /// With Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct WithStatement<'a> { @@ -1473,7 +1473,7 @@ pub struct WithStatement<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct SwitchStatement<'a> { @@ -1488,8 +1488,8 @@ pub struct SwitchStatement<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct SwitchCase<'a> { @@ -1501,8 +1501,8 @@ pub struct SwitchCase<'a> { /// Labelled Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct LabeledStatement<'a> { @@ -1514,8 +1514,8 @@ pub struct LabeledStatement<'a> { /// Throw Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ThrowStatement<'a> { @@ -1526,8 +1526,8 @@ pub struct ThrowStatement<'a> { /// Try Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TryStatement<'a> { @@ -1542,7 +1542,7 @@ pub struct TryStatement<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::CatchClause))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct CatchClause<'a> { @@ -1556,8 +1556,8 @@ pub struct CatchClause<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct CatchParameter<'a> { @@ -1568,8 +1568,8 @@ pub struct CatchParameter<'a> { /// Debugger Statement #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct DebuggerStatement { @@ -1580,8 +1580,8 @@ pub struct DebuggerStatement { /// Destructuring Binding Patterns /// * #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct BindingPattern<'a> { @@ -1595,8 +1595,8 @@ pub struct BindingPattern<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum BindingPatternKind<'a> { @@ -1614,8 +1614,8 @@ pub enum BindingPatternKind<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct AssignmentPattern<'a> { @@ -1627,8 +1627,8 @@ pub struct AssignmentPattern<'a> { // See serializer in serialize.rs #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type")] pub struct ObjectPattern<'a> { @@ -1641,8 +1641,8 @@ pub struct ObjectPattern<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BindingProperty<'a> { @@ -1656,8 +1656,8 @@ pub struct BindingProperty<'a> { // See serializer in serialize.rs #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type")] pub struct ArrayPattern<'a> { @@ -1670,8 +1670,8 @@ pub struct ArrayPattern<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "RestElement")] pub struct BindingRestElement<'a> { @@ -1688,7 +1688,7 @@ pub struct BindingRestElement<'a> { strict_if(self.is_strict()), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct Function<'a> { @@ -1725,8 +1725,8 @@ pub struct Function<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum FunctionType { FunctionDeclaration = 0, @@ -1739,8 +1739,8 @@ pub enum FunctionType { /// // See serializer in serialize.rs #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type")] pub struct FormalParameters<'a> { @@ -1754,8 +1754,8 @@ pub struct FormalParameters<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct FormalParameter<'a> { @@ -1769,8 +1769,8 @@ pub struct FormalParameter<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum FormalParameterKind { /// @@ -1785,8 +1785,8 @@ pub enum FormalParameterKind { /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct FunctionBody<'a> { @@ -1803,7 +1803,7 @@ pub struct FunctionBody<'a> { strict_if(self.body.has_use_strict_directive()), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ArrowFunctionExpression<'a> { @@ -1824,8 +1824,8 @@ pub struct ArrowFunctionExpression<'a> { /// Generator Function Definitions #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct YieldExpression<'a> { @@ -1839,7 +1839,7 @@ pub struct YieldExpression<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::StrictMode))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct Class<'a> { @@ -1911,8 +1911,8 @@ pub struct Class<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum ClassType { /// Class declaration statement @@ -1929,8 +1929,8 @@ pub enum ClassType { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ClassBody<'a> { @@ -1958,8 +1958,8 @@ pub struct ClassBody<'a> { /// } /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ClassElement<'a> { @@ -1982,8 +1982,8 @@ pub enum ClassElement<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct MethodDefinition<'a> { @@ -2011,8 +2011,8 @@ pub struct MethodDefinition<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum MethodDefinitionType { MethodDefinition = 0, @@ -2020,8 +2020,8 @@ pub enum MethodDefinitionType { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct PropertyDefinition<'a> { @@ -2102,8 +2102,8 @@ pub struct PropertyDefinition<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum PropertyDefinitionType { PropertyDefinition = 0, @@ -2111,8 +2111,8 @@ pub enum PropertyDefinitionType { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum MethodDefinitionKind { @@ -2130,8 +2130,8 @@ 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, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct PrivateIdentifier<'a> { @@ -2156,7 +2156,7 @@ pub struct PrivateIdentifier<'a> { #[ast(visit)] #[scope(flags(ScopeFlags::ClassStaticBlock))] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct StaticBlock<'a> { @@ -2192,8 +2192,8 @@ pub struct StaticBlock<'a> { /// export as namespace d; // TSNamespaceExportDeclaration /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ModuleDeclaration<'a> { @@ -2229,8 +2229,8 @@ macro_rules! match_module_declaration { pub use match_module_declaration; #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum AccessorPropertyType { AccessorProperty = 0, @@ -2246,8 +2246,8 @@ pub enum AccessorPropertyType { /// } /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub struct AccessorProperty<'a> { @@ -2290,8 +2290,8 @@ pub struct AccessorProperty<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ImportExpression<'a> { @@ -2302,8 +2302,8 @@ pub struct ImportExpression<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ImportDeclaration<'a> { @@ -2319,8 +2319,8 @@ pub struct ImportDeclaration<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ImportDeclarationSpecifier<'a> { @@ -2336,8 +2336,8 @@ pub enum ImportDeclarationSpecifier<'a> { // import {imported} from "source" // import {imported as local} from "source" #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ImportSpecifier<'a> { @@ -2367,8 +2367,8 @@ pub struct ImportSpecifier<'a> { /// ``` /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ImportDefaultSpecifier<'a> { @@ -2385,8 +2385,8 @@ pub struct ImportDefaultSpecifier<'a> { /// import * as local from "source"; /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ImportNamespaceSpecifier<'a> { @@ -2396,8 +2396,8 @@ pub struct ImportNamespaceSpecifier<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct WithClause<'a> { @@ -2408,8 +2408,8 @@ pub struct WithClause<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ImportAttribute<'a> { @@ -2420,8 +2420,8 @@ pub struct ImportAttribute<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ImportAttributeKey<'a> { @@ -2441,8 +2441,8 @@ pub enum ImportAttributeKey<'a> { /// // export_kind source /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ExportNamedDeclaration<'a> { @@ -2467,8 +2467,8 @@ pub struct ExportNamedDeclaration<'a> { /// export default AssignmentExpression /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct ExportDefaultDeclaration<'a> { @@ -2488,8 +2488,8 @@ pub struct ExportDefaultDeclaration<'a> { /// // ^^^^^^^^^^^^^^^ source /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ExportAllDeclaration<'a> { @@ -2515,8 +2515,8 @@ pub struct ExportAllDeclaration<'a> { /// // exported ^^^ ^^^ local /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct ExportSpecifier<'a> { @@ -2534,8 +2534,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ExportDefaultDeclarationKind<'a> { @@ -2558,8 +2558,8 @@ pub enum ExportDefaultDeclarationKind<'a> { /// * es2022: /// * #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum ModuleExportName<'a> { diff --git a/crates/oxc_ast/src/ast/jsx.rs b/crates/oxc_ast/src/ast/jsx.rs index de5784e4a5331..bd28dffde6769 100644 --- a/crates/oxc_ast/src/ast/jsx.rs +++ b/crates/oxc_ast/src/ast/jsx.rs @@ -9,7 +9,7 @@ use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; -use oxc_span::{cmp::ContentEq, Atom, GetSpan, GetSpanMut, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; #[cfg(feature = "serialize")] use serde::Serialize; #[cfg(feature = "serialize")] @@ -37,8 +37,8 @@ use super::{inherit_variants, js::*, literal::*, ts::*}; /// /// See: [JSX Syntax](https://facebook.github.io/jsx/) #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSXElement<'a> { @@ -68,8 +68,8 @@ pub struct JSXElement<'a> { /// // ^ type_parameters /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSXOpeningElement<'a> { @@ -102,8 +102,8 @@ pub struct JSXOpeningElement<'a> { /// // <- no closing element /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXClosingElement<'a> { @@ -121,8 +121,8 @@ pub struct JSXClosingElement<'a> { /// /// See: [`React.Fragment`](https://react.dev/reference/react/Fragment) #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSXFragment<'a> { @@ -138,8 +138,8 @@ pub struct JSXFragment<'a> { /// JSX Opening Fragment (`<>`) #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXOpeningFragment { @@ -149,8 +149,8 @@ pub struct JSXOpeningFragment { /// JSX Closing Fragment (``) #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXClosingFragment { @@ -160,8 +160,8 @@ pub struct JSXClosingFragment { /// JSX Element Name #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXElementName<'a> { @@ -185,8 +185,8 @@ pub enum JSXElementName<'a> { /// /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXNamespacedName<'a> { @@ -214,8 +214,8 @@ pub struct JSXNamespacedName<'a> { /// [`object`]: JSXMemberExpression::object /// [`member expression`]: JSXMemberExpressionObject::MemberExpression #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXMemberExpression<'a> { @@ -228,8 +228,8 @@ pub struct JSXMemberExpression<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXMemberExpressionObject<'a> { @@ -252,8 +252,8 @@ pub enum JSXMemberExpressionObject<'a> { /// /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXExpressionContainer<'a> { @@ -271,8 +271,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXExpression<'a> { @@ -284,8 +284,8 @@ pub enum JSXExpression<'a> { /// An empty JSX expression (`{}`) #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXEmptyExpression { @@ -305,8 +305,8 @@ pub struct JSXEmptyExpression { /// // Attribute SpreadAttribute /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXAttributeItem<'a> { @@ -328,8 +328,8 @@ pub enum JSXAttributeItem<'a> { /// /// // name ^^^ ^^^^ value #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXAttribute<'a> { @@ -351,8 +351,8 @@ pub struct JSXAttribute<'a> { /// // ^^^^^^^^ argument /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXSpreadAttribute<'a> { @@ -377,8 +377,8 @@ pub struct JSXSpreadAttribute<'a> { /// // ^^^^^^^ NamespacedName /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXAttributeName<'a> { @@ -407,8 +407,8 @@ pub enum JSXAttributeName<'a> { /// // ^^^^^^^^^^^ Element /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXAttributeValue<'a> { @@ -424,8 +424,8 @@ pub enum JSXAttributeValue<'a> { /// /// [`IdentifierName`]: super::IdentifierName #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXIdentifier<'a> { @@ -441,8 +441,8 @@ pub struct JSXIdentifier<'a> { /// /// Part of a [`JSXElement`]. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum JSXChild<'a> { @@ -462,8 +462,8 @@ pub enum JSXChild<'a> { /// /// Variant of [`JSXChild`] that represents an object spread (`{...expression}`). #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXSpreadChild<'a> { @@ -484,8 +484,8 @@ pub struct JSXSpreadChild<'a> { /// "Some string" // but `"Some string"` is a StringLiteral. /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct JSXText<'a> { diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index 4f286246787b9..64038ebd0a96d 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -13,7 +13,7 @@ use bitflags::bitflags; use oxc_allocator::{Box, CloneIn}; use oxc_ast_macros::ast; use oxc_regular_expression::ast::Pattern; -use oxc_span::{cmp::ContentEq, Atom, GetSpan, GetSpanMut, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; use oxc_syntax::number::{BigintBase, NumberBase}; #[cfg(feature = "serialize")] use serde::Serialize; @@ -24,8 +24,8 @@ use tsify::Tsify; /// /// #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BooleanLiteral { @@ -69,8 +69,8 @@ pub struct NumericLiteral<'a> { /// BigInt literal #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct BigIntLiteral<'a> { @@ -87,8 +87,8 @@ pub struct BigIntLiteral<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct RegExpLiteral<'a> { @@ -104,8 +104,8 @@ pub struct RegExpLiteral<'a> { /// /// #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct RegExp<'a> { /// The regex pattern between the slashes @@ -118,8 +118,8 @@ pub struct RegExp<'a> { /// /// This pattern may or may not be parsed. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum RegExpPattern<'a> { /// Unparsed pattern, Contains a string slice of the pattern. @@ -131,8 +131,8 @@ pub enum RegExpPattern<'a> { } #[ast] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct EmptyObject; @@ -140,8 +140,8 @@ pub struct EmptyObject; /// /// #[ast(visit)] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct StringLiteral<'a> { diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 5c7a0de6e4efa..6c70e2aeed823 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -10,11 +10,11 @@ // Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]` #![allow(non_snake_case)] -use std::{cell::Cell, hash::Hash}; +use std::cell::Cell; use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; -use oxc_span::{cmp::ContentEq, Atom, GetSpan, GetSpanMut, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, GetSpan, GetSpanMut, Span}; use oxc_syntax::scope::ScopeId; #[cfg(feature = "serialize")] use serde::Serialize; @@ -34,8 +34,8 @@ export interface TSIndexSignatureName extends Span { "#; #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSThisParameter<'a> { @@ -65,7 +65,7 @@ pub struct TSThisParameter<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSEnumDeclaration<'a> { @@ -95,8 +95,8 @@ pub struct TSEnumDeclaration<'a> { /// } /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSEnumMember<'a> { @@ -113,8 +113,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSEnumMemberName<'a> { @@ -142,8 +142,8 @@ pub enum TSEnumMemberName<'a> { /// // ^^^^^^^^ ^^^^^^^^ /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeAnnotation<'a> { @@ -168,8 +168,8 @@ pub struct TSTypeAnnotation<'a> { /// // ^ /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSLiteralType<'a> { @@ -179,8 +179,8 @@ pub struct TSLiteralType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSLiteral<'a> { @@ -199,8 +199,8 @@ pub enum TSLiteral<'a> { /// This is the root-level type for TypeScript types, kind of like [`Expression`] is for /// expressions. #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSType<'a> { @@ -305,7 +305,7 @@ pub use match_ts_type; #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSConditionalType<'a> { @@ -330,8 +330,8 @@ pub struct TSConditionalType<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSUnionType<'a> { @@ -344,8 +344,8 @@ pub struct TSUnionType<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSIntersectionType<'a> { @@ -355,8 +355,8 @@ pub struct TSIntersectionType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSParenthesizedType<'a> { @@ -374,8 +374,8 @@ pub struct TSParenthesizedType<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeOperator<'a> { @@ -386,8 +386,8 @@ pub struct TSTypeOperator<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSTypeOperatorOperator { @@ -408,8 +408,8 @@ pub enum TSTypeOperatorOperator { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSArrayType<'a> { @@ -430,8 +430,8 @@ pub struct TSArrayType<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSIndexedAccessType<'a> { @@ -451,8 +451,8 @@ pub struct TSIndexedAccessType<'a> { /// /// #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTupleType<'a> { @@ -462,8 +462,8 @@ pub struct TSTupleType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSNamedTupleMember<'a> { @@ -475,8 +475,8 @@ pub struct TSNamedTupleMember<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSOptionalType<'a> { @@ -486,8 +486,8 @@ pub struct TSOptionalType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSRestType<'a> { @@ -505,8 +505,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSTupleElement<'a> { @@ -520,8 +520,8 @@ pub enum TSTupleElement<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSAnyKeyword { @@ -530,8 +530,8 @@ pub struct TSAnyKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSStringKeyword { @@ -540,8 +540,8 @@ pub struct TSStringKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSBooleanKeyword { @@ -550,8 +550,8 @@ pub struct TSBooleanKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSNumberKeyword { @@ -560,8 +560,8 @@ pub struct TSNumberKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSNeverKeyword { @@ -571,8 +571,8 @@ pub struct TSNeverKeyword { /// `type Uppercase = intrinsic;` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSIntrinsicKeyword { @@ -581,8 +581,8 @@ pub struct TSIntrinsicKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSUnknownKeyword { @@ -591,8 +591,8 @@ pub struct TSUnknownKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSNullKeyword { @@ -601,8 +601,8 @@ pub struct TSNullKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSUndefinedKeyword { @@ -611,8 +611,8 @@ pub struct TSUndefinedKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSVoidKeyword { @@ -621,8 +621,8 @@ pub struct TSVoidKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSSymbolKeyword { @@ -631,8 +631,8 @@ pub struct TSSymbolKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSThisType { @@ -641,8 +641,8 @@ pub struct TSThisType { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSObjectKeyword { @@ -651,8 +651,8 @@ pub struct TSObjectKeyword { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type")] pub struct TSBigIntKeyword { @@ -664,8 +664,8 @@ pub struct TSBigIntKeyword { /// type D = B.a; /// type E = D.c.b.a; #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeReference<'a> { @@ -679,8 +679,8 @@ pub struct TSTypeReference<'a> { /// IdentifierReference /// NamespaceName . IdentifierReference #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSTypeName<'a> { @@ -698,8 +698,8 @@ macro_rules! match_ts_type_name { pub use match_ts_type_name; #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSQualifiedName<'a> { @@ -710,8 +710,8 @@ pub struct TSQualifiedName<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeParameterInstantiation<'a> { @@ -721,8 +721,8 @@ pub struct TSTypeParameterInstantiation<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeParameter<'a> { @@ -737,8 +737,8 @@ pub struct TSTypeParameter<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeParameterDeclaration<'a> { @@ -750,7 +750,7 @@ pub struct TSTypeParameterDeclaration<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeAliasDeclaration<'a> { @@ -767,8 +767,8 @@ pub struct TSTypeAliasDeclaration<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSAccessibility { @@ -778,8 +778,8 @@ pub enum TSAccessibility { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSClassImplements<'a> { @@ -795,7 +795,7 @@ pub struct TSClassImplements<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSInterfaceDeclaration<'a> { @@ -814,8 +814,8 @@ pub struct TSInterfaceDeclaration<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSInterfaceBody<'a> { @@ -825,8 +825,8 @@ pub struct TSInterfaceBody<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSPropertySignature<'a> { @@ -840,8 +840,8 @@ pub struct TSPropertySignature<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSSignature<'a> { @@ -864,8 +864,8 @@ pub enum TSSignature<'a> { /// } /// ``` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSIndexSignature<'a> { @@ -877,8 +877,8 @@ pub struct TSIndexSignature<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSCallSignatureDeclaration<'a> { @@ -891,8 +891,8 @@ pub struct TSCallSignatureDeclaration<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSMethodSignatureKind { @@ -904,7 +904,7 @@ pub enum TSMethodSignatureKind { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSMethodSignature<'a> { @@ -926,7 +926,7 @@ pub struct TSMethodSignature<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSConstructSignatureDeclaration<'a> { @@ -941,8 +941,8 @@ pub struct TSConstructSignatureDeclaration<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[serde(tag = "type", rename = "Identifier", rename_all = "camelCase")] pub struct TSIndexSignatureName<'a> { @@ -953,8 +953,8 @@ pub struct TSIndexSignatureName<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSInterfaceHeritage<'a> { @@ -965,8 +965,8 @@ pub struct TSInterfaceHeritage<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypePredicate<'a> { @@ -978,8 +978,8 @@ pub struct TSTypePredicate<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSTypePredicateName<'a> { @@ -993,7 +993,7 @@ pub enum TSTypePredicateName<'a> { strict_if(self.body.as_ref().is_some_and(TSModuleDeclarationBody::is_strict)), )] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSModuleDeclaration<'a> { @@ -1019,8 +1019,8 @@ pub struct TSModuleDeclaration<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSModuleDeclarationKind { @@ -1036,8 +1036,8 @@ impl TSModuleDeclarationKind { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSModuleDeclarationName<'a> { @@ -1046,8 +1046,8 @@ pub enum TSModuleDeclarationName<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSModuleDeclarationBody<'a> { @@ -1057,8 +1057,8 @@ pub enum TSModuleDeclarationBody<'a> { // See serializer in serialize.rs #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSModuleBlock<'a> { @@ -1070,8 +1070,8 @@ pub struct TSModuleBlock<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeLiteral<'a> { @@ -1081,8 +1081,8 @@ pub struct TSTypeLiteral<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSInferType<'a> { @@ -1092,8 +1092,8 @@ pub struct TSInferType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeQuery<'a> { @@ -1110,8 +1110,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSTypeQueryExprName<'a> { @@ -1122,8 +1122,8 @@ pub enum TSTypeQueryExprName<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSImportType<'a> { @@ -1137,8 +1137,8 @@ pub struct TSImportType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSImportAttributes<'a> { @@ -1149,8 +1149,8 @@ pub struct TSImportAttributes<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSImportAttribute<'a> { @@ -1161,8 +1161,8 @@ pub struct TSImportAttribute<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged)] pub enum TSImportAttributeName<'a> { @@ -1171,8 +1171,8 @@ pub enum TSImportAttributeName<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSFunctionType<'a> { @@ -1185,8 +1185,8 @@ pub struct TSFunctionType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSConstructorType<'a> { @@ -1201,7 +1201,7 @@ pub struct TSConstructorType<'a> { #[ast(visit)] #[scope] #[derive(Debug)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSMappedType<'a> { @@ -1218,8 +1218,8 @@ pub struct TSMappedType<'a> { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSMappedTypeModifierOperator { @@ -1232,8 +1232,8 @@ pub enum TSMappedTypeModifierOperator { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTemplateLiteralType<'a> { @@ -1244,8 +1244,8 @@ pub struct TSTemplateLiteralType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSAsExpression<'a> { @@ -1256,8 +1256,8 @@ pub struct TSAsExpression<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSSatisfiesExpression<'a> { @@ -1268,8 +1268,8 @@ pub struct TSSatisfiesExpression<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSTypeAssertion<'a> { @@ -1280,8 +1280,8 @@ pub struct TSTypeAssertion<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSImportEqualsDeclaration<'a> { @@ -1299,8 +1299,8 @@ inherit_variants! { /// /// [`ast` module docs]: `super` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(untagged, rename_all = "camelCase")] pub enum TSModuleReference<'a> { @@ -1311,8 +1311,8 @@ pub enum TSModuleReference<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSExternalModuleReference<'a> { @@ -1322,8 +1322,8 @@ pub struct TSExternalModuleReference<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSNonNullExpression<'a> { @@ -1357,8 +1357,8 @@ pub struct TSNonNullExpression<'a> { /// [`IdentifierReference`]: crate::ast::js::IdentifierReference /// [`CallExpression`]: crate::ast::js::CallExpression #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct Decorator<'a> { @@ -1371,8 +1371,8 @@ pub struct Decorator<'a> { /// /// `export = foo` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSExportAssignment<'a> { @@ -1385,8 +1385,8 @@ pub struct TSExportAssignment<'a> { /// /// `export as namespace foo` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSNamespaceExportDeclaration<'a> { @@ -1396,8 +1396,8 @@ pub struct TSNamespaceExportDeclaration<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct TSInstantiationExpression<'a> { @@ -1409,8 +1409,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, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum ImportOrExportKind { @@ -1424,8 +1424,8 @@ pub enum ImportOrExportKind { /// `type foo = ty?` or `type foo = ?ty` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSDocNullableType<'a> { @@ -1438,8 +1438,8 @@ pub struct JSDocNullableType<'a> { /// `type foo = ty!` or `type foo = !ty` #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSDocNonNullableType<'a> { @@ -1450,8 +1450,8 @@ pub struct JSDocNonNullableType<'a> { } #[ast(visit)] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(tag = "type", rename_all = "camelCase")] pub struct JSDocUnknownType { diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index 10e064ad8f336..f9f198d35dc39 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -1,6 +1,6 @@ use crate::ast::*; -use std::{borrow::Cow, cell::Cell, fmt, hash::Hash}; +use std::{borrow::Cow, cell::Cell, fmt}; use oxc_allocator::{Box, FromIn, Vec}; use oxc_span::{Atom, GetSpan, SourceType, Span}; @@ -37,15 +37,6 @@ impl<'a> Program<'a> { } } -impl<'a> Hash for Program<'a> { - fn hash(&self, state: &mut H) { - self.source_type.hash(state); - self.directives.hash(state); - self.hashbang.hash(state); - self.body.hash(state); - } -} - impl<'a> Program<'a> { pub fn is_empty(&self) -> bool { self.body.is_empty() && self.directives.is_empty() @@ -327,12 +318,6 @@ impl<'a> fmt::Display for IdentifierName<'a> { } } -impl<'a> Hash for IdentifierReference<'a> { - fn hash(&self, state: &mut H) { - self.name.hash(state); - } -} - impl<'a> IdentifierReference<'a> { #[inline] pub fn new(span: Span, name: Atom<'a>) -> Self { @@ -360,12 +345,6 @@ impl<'a> fmt::Display for IdentifierReference<'a> { } } -impl<'a> Hash for BindingIdentifier<'a> { - fn hash(&self, state: &mut H) { - self.name.hash(state); - } -} - impl<'a> BindingIdentifier<'a> { pub fn new(span: Span, name: Atom<'a>) -> Self { Self { span, name, symbol_id: Cell::default() } @@ -769,12 +748,6 @@ impl<'a> BlockStatement<'a> { } } -impl<'a> Hash for BlockStatement<'a> { - fn hash(&self, state: &mut H) { - self.body.hash(state); - } -} - impl<'a> Declaration<'a> { pub fn is_typescript_syntax(&self) -> bool { match self { @@ -868,15 +841,6 @@ impl<'a> ForStatement<'a> { } } -impl<'a> Hash for ForStatement<'a> { - fn hash(&self, state: &mut H) { - self.init.hash(state); - self.test.hash(state); - self.update.hash(state); - self.body.hash(state); - } -} - impl<'a> ForStatementInit<'a> { /// LexicalDeclaration[In, Yield, Await] : /// LetOrConst BindingList[?In, ?Yield, ?Await] ; @@ -896,14 +860,6 @@ impl<'a> ForInStatement<'a> { } } -impl<'a> Hash for ForInStatement<'a> { - fn hash(&self, state: &mut H) { - self.left.hash(state); - self.right.hash(state); - self.body.hash(state); - } -} - impl<'a> ForOfStatement<'a> { pub fn new( span: Span, @@ -916,15 +872,6 @@ impl<'a> ForOfStatement<'a> { } } -impl<'a> Hash for ForOfStatement<'a> { - fn hash(&self, state: &mut H) { - self.r#await.hash(state); - self.left.hash(state); - self.right.hash(state); - self.body.hash(state); - } -} - impl<'a> ForStatementLeft<'a> { /// LexicalDeclaration[In, Yield, Await] : /// LetOrConst BindingList[?In, ?Yield, ?Await] ; @@ -939,13 +886,6 @@ impl<'a> SwitchStatement<'a> { } } -impl<'a> Hash for SwitchStatement<'a> { - fn hash(&self, state: &mut H) { - self.discriminant.hash(state); - self.cases.hash(state); - } -} - impl<'a> SwitchCase<'a> { pub fn is_default_case(&self) -> bool { self.test.is_none() @@ -962,13 +902,6 @@ impl<'a> CatchClause<'a> { } } -impl<'a> Hash for CatchClause<'a> { - fn hash(&self, state: &mut H) { - self.param.hash(state); - self.body.hash(state); - } -} - impl<'a> BindingPattern<'a> { pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self { Self { kind, type_annotation: None, optional: false } @@ -1111,21 +1044,6 @@ impl<'a> Function<'a> { } } -impl<'a> Hash for Function<'a> { - fn hash(&self, state: &mut H) { - self.r#type.hash(state); - self.id.hash(state); - self.generator.hash(state); - self.r#async.hash(state); - self.declare.hash(state); - self.this_param.hash(state); - self.params.hash(state); - self.body.hash(state); - self.type_parameters.hash(state); - self.return_type.hash(state); - } -} - impl<'a> FormalParameters<'a> { pub fn parameters_count(&self) -> usize { self.items.len() + self.rest.as_ref().map_or(0, |_| 1) @@ -1209,17 +1127,6 @@ impl<'a> ArrowFunctionExpression<'a> { } } -impl<'a> Hash for ArrowFunctionExpression<'a> { - fn hash(&self, state: &mut H) { - self.expression.hash(state); - self.r#async.hash(state); - self.params.hash(state); - self.body.hash(state); - self.type_parameters.hash(state); - self.return_type.hash(state); - } -} - impl<'a> Class<'a> { #[allow(clippy::too_many_arguments)] pub fn new( @@ -1278,21 +1185,6 @@ impl<'a> Class<'a> { } } -impl<'a> Hash for Class<'a> { - fn hash(&self, state: &mut H) { - self.r#type.hash(state); - self.decorators.hash(state); - self.id.hash(state); - self.super_class.hash(state); - self.body.hash(state); - self.type_parameters.hash(state); - self.super_type_parameters.hash(state); - self.implements.hash(state); - self.r#abstract.hash(state); - self.declare.hash(state); - } -} - impl<'a> ClassElement<'a> { /// Returns `true` if this is a [`ClassElement::StaticBlock`]. pub fn is_static_block(&self) -> bool { @@ -1467,12 +1359,6 @@ impl<'a> StaticBlock<'a> { } } -impl<'a> Hash for StaticBlock<'a> { - fn hash(&self, state: &mut H) { - self.body.hash(state); - } -} - impl<'a> ModuleDeclaration<'a> { pub fn is_typescript_syntax(&self) -> bool { match self { diff --git a/crates/oxc_ast/src/ast_impl/literal.rs b/crates/oxc_ast/src/ast_impl/literal.rs index 1b73e7efc2b2b..9f7bd619e6294 100644 --- a/crates/oxc_ast/src/ast_impl/literal.rs +++ b/crates/oxc_ast/src/ast_impl/literal.rs @@ -12,7 +12,7 @@ use std::{ use oxc_allocator::CloneIn; use oxc_regular_expression::ast::Pattern; -use oxc_span::{cmp::ContentEq, Atom, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, Span}; use oxc_syntax::number::NumberBase; impl BooleanLiteral { @@ -36,10 +36,10 @@ impl fmt::Display for BooleanLiteral { } } -impl Hash for NullLiteral { +impl ContentHash for NullLiteral { #[inline] - fn hash(&self, state: &mut H) { - None::.hash(state); + fn content_hash(&self, state: &mut H) { + Hash::hash(&Option::::None, state); } } @@ -89,10 +89,10 @@ impl<'a> NumericLiteral<'a> { } } -impl<'a> Hash for NumericLiteral<'a> { - fn hash(&self, state: &mut H) { - self.base.hash(state); - self.raw.hash(state); +impl<'a> ContentHash for NumericLiteral<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&self.base, state); + ContentHash::content_hash(&self.raw, state); } } @@ -177,6 +177,12 @@ impl ContentEq for RegExpFlags { } } +impl ContentHash for RegExpFlags { + fn content_hash(&self, state: &mut H) { + Hash::hash(self, state); + } +} + impl<'alloc> CloneIn<'alloc> for RegExpFlags { type Cloned = Self; fn clone_in(&self, _: &'alloc oxc_allocator::Allocator) -> Self::Cloned { diff --git a/crates/oxc_ast/src/ast_impl/ts.rs b/crates/oxc_ast/src/ast_impl/ts.rs index 03b6884097716..86afae710b411 100644 --- a/crates/oxc_ast/src/ast_impl/ts.rs +++ b/crates/oxc_ast/src/ast_impl/ts.rs @@ -3,7 +3,7 @@ //! [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/ast-spec) //! [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md) -use std::{cell::Cell, fmt, hash::Hash}; +use std::{cell::Cell, fmt}; use oxc_allocator::Vec; use oxc_span::{Atom, Span}; @@ -22,15 +22,6 @@ impl<'a> TSEnumDeclaration<'a> { } } -impl<'a> Hash for TSEnumDeclaration<'a> { - fn hash(&self, state: &mut H) { - self.id.hash(state); - self.members.hash(state); - self.r#const.hash(state); - self.declare.hash(state); - } -} - impl<'a> TSType<'a> { pub fn get_identifier_reference(&self) -> Option> { match self { @@ -168,15 +159,6 @@ impl<'a> TSModuleDeclaration<'a> { } } -impl<'a> Hash for TSModuleDeclaration<'a> { - fn hash(&self, state: &mut H) { - self.id.hash(state); - self.body.hash(state); - self.kind.hash(state); - self.declare.hash(state); - } -} - impl<'a> TSModuleDeclarationName<'a> { pub fn is_string_literal(&self) -> bool { matches!(self, Self::StringLiteral(_)) @@ -250,68 +232,3 @@ impl ImportOrExportKind { matches!(self, Self::Type) } } - -impl<'a> Hash for TSMappedType<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.type_parameter.hash(state); - self.name_type.hash(state); - self.type_annotation.hash(state); - self.optional.hash(state); - self.readonly.hash(state); - } -} - -impl<'a> Hash for TSConditionalType<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.check_type.hash(state); - self.extends_type.hash(state); - self.true_type.hash(state); - self.false_type.hash(state); - } -} - -impl<'a> Hash for TSInterfaceDeclaration<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.id.hash(state); - self.type_parameters.hash(state); - self.extends.hash(state); - self.body.hash(state); - self.declare.hash(state); - } -} - -impl<'a> Hash for TSTypeAliasDeclaration<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.id.hash(state); - self.type_parameters.hash(state); - self.type_annotation.hash(state); - self.declare.hash(state); - } -} - -impl<'a> Hash for TSMethodSignature<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.key.hash(state); - self.computed.hash(state); - self.optional.hash(state); - self.kind.hash(state); - self.this_param.hash(state); - self.params.hash(state); - self.return_type.hash(state); - self.type_parameters.hash(state); - } -} - -impl<'a> Hash for TSConstructSignatureDeclaration<'a> { - fn hash(&self, state: &mut H) { - self.span.hash(state); - self.params.hash(state); - self.return_type.hash(state); - self.type_parameters.hash(state); - } -} diff --git a/crates/oxc_ast/src/generated/derive_content_hash.rs b/crates/oxc_ast/src/generated/derive_content_hash.rs new file mode 100644 index 0000000000000..9526a339c7680 --- /dev/null +++ b/crates/oxc_ast/src/generated/derive_content_hash.rs @@ -0,0 +1,2375 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/content_hash.rs` + +#![allow(clippy::match_same_arms)] + +use std::{hash::Hasher, mem::discriminant}; + +use oxc_span::hash::ContentHash; + +#[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 ContentHash for BooleanLiteral { + fn content_hash(&self, state: &mut H) { + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for BigIntLiteral<'a> { + fn content_hash(&self, state: &mut H) { + self.raw.content_hash(state); + self.base.content_hash(state); + } +} + +impl<'a> ContentHash for RegExpLiteral<'a> { + fn content_hash(&self, state: &mut H) { + self.value.content_hash(state); + self.regex.content_hash(state); + } +} + +impl<'a> ContentHash for RegExp<'a> { + fn content_hash(&self, state: &mut H) { + self.pattern.content_hash(state); + self.flags.content_hash(state); + } +} + +impl<'a> ContentHash for RegExpPattern<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Raw(it) => it.content_hash(state), + Self::Invalid(it) => it.content_hash(state), + Self::Pattern(it) => it.content_hash(state), + } + } +} + +impl ContentHash for EmptyObject { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for StringLiteral<'a> { + fn content_hash(&self, state: &mut H) { + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for Program<'a> { + fn content_hash(&self, state: &mut H) { + self.source_type.content_hash(state); + self.hashbang.content_hash(state); + self.directives.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for Expression<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for IdentifierName<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for IdentifierReference<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for BindingIdentifier<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for LabelIdentifier<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl ContentHash for ThisExpression { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for ArrayExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.elements.content_hash(state); + } +} + +impl<'a> ContentHash for ArrayExpressionElement<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::SpreadElement(it) => it.content_hash(state), + Self::Elision(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl ContentHash for Elision { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for ObjectExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.properties.content_hash(state); + } +} + +impl<'a> ContentHash for ObjectPropertyKind<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ObjectProperty(it) => it.content_hash(state), + Self::SpreadProperty(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ObjectProperty<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.key.content_hash(state); + self.value.content_hash(state); + self.init.content_hash(state); + self.method.content_hash(state); + self.shorthand.content_hash(state); + self.computed.content_hash(state); + } +} + +impl<'a> ContentHash for PropertyKey<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::StaticIdentifier(it) => it.content_hash(state), + Self::PrivateIdentifier(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl ContentHash for PropertyKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TemplateLiteral<'a> { + fn content_hash(&self, state: &mut H) { + self.quasis.content_hash(state); + self.expressions.content_hash(state); + } +} + +impl<'a> ContentHash for TaggedTemplateExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.tag.content_hash(state); + self.quasi.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TemplateElement<'a> { + fn content_hash(&self, state: &mut H) { + self.tail.content_hash(state); + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for TemplateElementValue<'a> { + fn content_hash(&self, state: &mut H) { + self.raw.content_hash(state); + self.cooked.content_hash(state); + } +} + +impl<'a> ContentHash for MemberExpression<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ComputedMemberExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.object.content_hash(state); + self.expression.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for StaticMemberExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.object.content_hash(state); + self.property.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for PrivateFieldExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.object.content_hash(state); + self.field.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for CallExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.callee.content_hash(state); + self.type_parameters.content_hash(state); + self.arguments.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for NewExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.callee.content_hash(state); + self.arguments.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for MetaProperty<'a> { + fn content_hash(&self, state: &mut H) { + self.meta.content_hash(state); + self.property.content_hash(state); + } +} + +impl<'a> ContentHash for SpreadElement<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for Argument<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::SpreadElement(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for UpdateExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.operator.content_hash(state); + self.prefix.content_hash(state); + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for UnaryExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.operator.content_hash(state); + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for BinaryExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.operator.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for PrivateInExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.operator.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for LogicalExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.operator.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for ConditionalExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.test.content_hash(state); + self.consequent.content_hash(state); + self.alternate.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.operator.content_hash(state); + self.left.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentTarget<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::AssignmentTargetIdentifier(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + Self::ArrayAssignmentTarget(it) => it.content_hash(state), + Self::ObjectAssignmentTarget(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for SimpleAssignmentTarget<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::AssignmentTargetIdentifier(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for AssignmentTargetPattern<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ArrayAssignmentTarget(it) => it.content_hash(state), + Self::ObjectAssignmentTarget(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ArrayAssignmentTarget<'a> { + fn content_hash(&self, state: &mut H) { + self.elements.content_hash(state); + self.rest.content_hash(state); + } +} + +impl<'a> ContentHash for ObjectAssignmentTarget<'a> { + fn content_hash(&self, state: &mut H) { + self.properties.content_hash(state); + self.rest.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentTargetRest<'a> { + fn content_hash(&self, state: &mut H) { + self.target.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentTargetMaybeDefault<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::AssignmentTargetWithDefault(it) => it.content_hash(state), + Self::AssignmentTargetIdentifier(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + Self::ArrayAssignmentTarget(it) => it.content_hash(state), + Self::ObjectAssignmentTarget(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for AssignmentTargetWithDefault<'a> { + fn content_hash(&self, state: &mut H) { + self.binding.content_hash(state); + self.init.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentTargetProperty<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::AssignmentTargetPropertyIdentifier(it) => it.content_hash(state), + Self::AssignmentTargetPropertyProperty(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for AssignmentTargetPropertyIdentifier<'a> { + fn content_hash(&self, state: &mut H) { + self.binding.content_hash(state); + self.init.content_hash(state); + } +} + +impl<'a> ContentHash for AssignmentTargetPropertyProperty<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.binding.content_hash(state); + } +} + +impl<'a> ContentHash for SequenceExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expressions.content_hash(state); + } +} + +impl ContentHash for Super { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for AwaitExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for ChainExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for ChainElement<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::CallExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ParenthesizedExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for Statement<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::BlockStatement(it) => it.content_hash(state), + Self::BreakStatement(it) => it.content_hash(state), + Self::ContinueStatement(it) => it.content_hash(state), + Self::DebuggerStatement(it) => it.content_hash(state), + Self::DoWhileStatement(it) => it.content_hash(state), + Self::EmptyStatement(it) => it.content_hash(state), + Self::ExpressionStatement(it) => it.content_hash(state), + Self::ForInStatement(it) => it.content_hash(state), + Self::ForOfStatement(it) => it.content_hash(state), + Self::ForStatement(it) => it.content_hash(state), + Self::IfStatement(it) => it.content_hash(state), + Self::LabeledStatement(it) => it.content_hash(state), + Self::ReturnStatement(it) => it.content_hash(state), + Self::SwitchStatement(it) => it.content_hash(state), + Self::ThrowStatement(it) => it.content_hash(state), + Self::TryStatement(it) => it.content_hash(state), + Self::WhileStatement(it) => it.content_hash(state), + Self::WithStatement(it) => it.content_hash(state), + Self::VariableDeclaration(it) => it.content_hash(state), + Self::FunctionDeclaration(it) => it.content_hash(state), + Self::ClassDeclaration(it) => it.content_hash(state), + Self::TSTypeAliasDeclaration(it) => it.content_hash(state), + Self::TSInterfaceDeclaration(it) => it.content_hash(state), + Self::TSEnumDeclaration(it) => it.content_hash(state), + Self::TSModuleDeclaration(it) => it.content_hash(state), + Self::TSImportEqualsDeclaration(it) => it.content_hash(state), + Self::ImportDeclaration(it) => it.content_hash(state), + Self::ExportAllDeclaration(it) => it.content_hash(state), + Self::ExportDefaultDeclaration(it) => it.content_hash(state), + Self::ExportNamedDeclaration(it) => it.content_hash(state), + Self::TSExportAssignment(it) => it.content_hash(state), + Self::TSNamespaceExportDeclaration(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for Directive<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.directive.content_hash(state); + } +} + +impl<'a> ContentHash for Hashbang<'a> { + fn content_hash(&self, state: &mut H) { + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for BlockStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for Declaration<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::VariableDeclaration(it) => it.content_hash(state), + Self::FunctionDeclaration(it) => it.content_hash(state), + Self::ClassDeclaration(it) => it.content_hash(state), + Self::TSTypeAliasDeclaration(it) => it.content_hash(state), + Self::TSInterfaceDeclaration(it) => it.content_hash(state), + Self::TSEnumDeclaration(it) => it.content_hash(state), + Self::TSModuleDeclaration(it) => it.content_hash(state), + Self::TSImportEqualsDeclaration(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for VariableDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.declarations.content_hash(state); + self.declare.content_hash(state); + } +} + +impl ContentHash for VariableDeclarationKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for VariableDeclarator<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.id.content_hash(state); + self.init.content_hash(state); + self.definite.content_hash(state); + } +} + +impl ContentHash for EmptyStatement { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for ExpressionStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for IfStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.test.content_hash(state); + self.consequent.content_hash(state); + self.alternate.content_hash(state); + } +} + +impl<'a> ContentHash for DoWhileStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + self.test.content_hash(state); + } +} + +impl<'a> ContentHash for WhileStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.test.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ForStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.init.content_hash(state); + self.test.content_hash(state); + self.update.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ForStatementInit<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::VariableDeclaration(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ForInStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.right.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ForStatementLeft<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::VariableDeclaration(it) => it.content_hash(state), + Self::AssignmentTargetIdentifier(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + Self::ArrayAssignmentTarget(it) => it.content_hash(state), + Self::ObjectAssignmentTarget(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ForOfStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.r#await.content_hash(state); + self.left.content_hash(state); + self.right.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ContinueStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.label.content_hash(state); + } +} + +impl<'a> ContentHash for BreakStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.label.content_hash(state); + } +} + +impl<'a> ContentHash for ReturnStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for WithStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.object.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for SwitchStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.discriminant.content_hash(state); + self.cases.content_hash(state); + } +} + +impl<'a> ContentHash for SwitchCase<'a> { + fn content_hash(&self, state: &mut H) { + self.test.content_hash(state); + self.consequent.content_hash(state); + } +} + +impl<'a> ContentHash for LabeledStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.label.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ThrowStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for TryStatement<'a> { + fn content_hash(&self, state: &mut H) { + self.block.content_hash(state); + self.handler.content_hash(state); + self.finalizer.content_hash(state); + } +} + +impl<'a> ContentHash for CatchClause<'a> { + fn content_hash(&self, state: &mut H) { + self.param.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for CatchParameter<'a> { + fn content_hash(&self, state: &mut H) { + self.pattern.content_hash(state); + } +} + +impl ContentHash for DebuggerStatement { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for BindingPattern<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.type_annotation.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for BindingPatternKind<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::BindingIdentifier(it) => it.content_hash(state), + Self::ObjectPattern(it) => it.content_hash(state), + Self::ArrayPattern(it) => it.content_hash(state), + Self::AssignmentPattern(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for AssignmentPattern<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for ObjectPattern<'a> { + fn content_hash(&self, state: &mut H) { + self.properties.content_hash(state); + self.rest.content_hash(state); + } +} + +impl<'a> ContentHash for BindingProperty<'a> { + fn content_hash(&self, state: &mut H) { + self.key.content_hash(state); + self.value.content_hash(state); + self.shorthand.content_hash(state); + self.computed.content_hash(state); + } +} + +impl<'a> ContentHash for ArrayPattern<'a> { + fn content_hash(&self, state: &mut H) { + self.elements.content_hash(state); + self.rest.content_hash(state); + } +} + +impl<'a> ContentHash for BindingRestElement<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for Function<'a> { + fn content_hash(&self, state: &mut H) { + self.r#type.content_hash(state); + self.id.content_hash(state); + self.generator.content_hash(state); + self.r#async.content_hash(state); + self.declare.content_hash(state); + self.type_parameters.content_hash(state); + self.this_param.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.body.content_hash(state); + } +} + +impl ContentHash for FunctionType { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for FormalParameters<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.items.content_hash(state); + self.rest.content_hash(state); + } +} + +impl<'a> ContentHash for FormalParameter<'a> { + fn content_hash(&self, state: &mut H) { + self.decorators.content_hash(state); + self.pattern.content_hash(state); + self.accessibility.content_hash(state); + self.readonly.content_hash(state); + self.r#override.content_hash(state); + } +} + +impl ContentHash for FormalParameterKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for FunctionBody<'a> { + fn content_hash(&self, state: &mut H) { + self.directives.content_hash(state); + self.statements.content_hash(state); + } +} + +impl<'a> ContentHash for ArrowFunctionExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.r#async.content_hash(state); + self.type_parameters.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for YieldExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.delegate.content_hash(state); + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for Class<'a> { + fn content_hash(&self, state: &mut H) { + self.r#type.content_hash(state); + self.decorators.content_hash(state); + self.id.content_hash(state); + self.type_parameters.content_hash(state); + self.super_class.content_hash(state); + self.super_type_parameters.content_hash(state); + self.implements.content_hash(state); + self.body.content_hash(state); + self.r#abstract.content_hash(state); + self.declare.content_hash(state); + } +} + +impl ContentHash for ClassType { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for ClassBody<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ClassElement<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::StaticBlock(it) => it.content_hash(state), + Self::MethodDefinition(it) => it.content_hash(state), + Self::PropertyDefinition(it) => it.content_hash(state), + Self::AccessorProperty(it) => it.content_hash(state), + Self::TSIndexSignature(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for MethodDefinition<'a> { + fn content_hash(&self, state: &mut H) { + self.r#type.content_hash(state); + self.decorators.content_hash(state); + self.key.content_hash(state); + self.value.content_hash(state); + self.kind.content_hash(state); + self.computed.content_hash(state); + self.r#static.content_hash(state); + self.r#override.content_hash(state); + self.optional.content_hash(state); + self.accessibility.content_hash(state); + } +} + +impl ContentHash for MethodDefinitionType { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for PropertyDefinition<'a> { + fn content_hash(&self, state: &mut H) { + self.r#type.content_hash(state); + self.decorators.content_hash(state); + self.key.content_hash(state); + self.value.content_hash(state); + self.computed.content_hash(state); + self.r#static.content_hash(state); + self.declare.content_hash(state); + self.r#override.content_hash(state); + self.optional.content_hash(state); + self.definite.content_hash(state); + self.readonly.content_hash(state); + self.type_annotation.content_hash(state); + self.accessibility.content_hash(state); + } +} + +impl ContentHash for PropertyDefinitionType { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for MethodDefinitionKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for PrivateIdentifier<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for StaticBlock<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ModuleDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ImportDeclaration(it) => it.content_hash(state), + Self::ExportAllDeclaration(it) => it.content_hash(state), + Self::ExportDefaultDeclaration(it) => it.content_hash(state), + Self::ExportNamedDeclaration(it) => it.content_hash(state), + Self::TSExportAssignment(it) => it.content_hash(state), + Self::TSNamespaceExportDeclaration(it) => it.content_hash(state), + } + } +} + +impl ContentHash for AccessorPropertyType { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for AccessorProperty<'a> { + fn content_hash(&self, state: &mut H) { + self.r#type.content_hash(state); + self.decorators.content_hash(state); + self.key.content_hash(state); + self.value.content_hash(state); + self.computed.content_hash(state); + self.r#static.content_hash(state); + self.definite.content_hash(state); + self.type_annotation.content_hash(state); + self.accessibility.content_hash(state); + } +} + +impl<'a> ContentHash for ImportExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.source.content_hash(state); + self.arguments.content_hash(state); + } +} + +impl<'a> ContentHash for ImportDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.specifiers.content_hash(state); + self.source.content_hash(state); + self.with_clause.content_hash(state); + self.import_kind.content_hash(state); + } +} + +impl<'a> ContentHash for ImportDeclarationSpecifier<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ImportSpecifier(it) => it.content_hash(state), + Self::ImportDefaultSpecifier(it) => it.content_hash(state), + Self::ImportNamespaceSpecifier(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ImportSpecifier<'a> { + fn content_hash(&self, state: &mut H) { + self.imported.content_hash(state); + self.local.content_hash(state); + self.import_kind.content_hash(state); + } +} + +impl<'a> ContentHash for ImportDefaultSpecifier<'a> { + fn content_hash(&self, state: &mut H) { + self.local.content_hash(state); + } +} + +impl<'a> ContentHash for ImportNamespaceSpecifier<'a> { + fn content_hash(&self, state: &mut H) { + self.local.content_hash(state); + } +} + +impl<'a> ContentHash for WithClause<'a> { + fn content_hash(&self, state: &mut H) { + self.attributes_keyword.content_hash(state); + self.with_entries.content_hash(state); + } +} + +impl<'a> ContentHash for ImportAttribute<'a> { + fn content_hash(&self, state: &mut H) { + self.key.content_hash(state); + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for ImportAttributeKey<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ExportNamedDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.declaration.content_hash(state); + self.specifiers.content_hash(state); + self.source.content_hash(state); + self.export_kind.content_hash(state); + self.with_clause.content_hash(state); + } +} + +impl<'a> ContentHash for ExportDefaultDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.declaration.content_hash(state); + self.exported.content_hash(state); + } +} + +impl<'a> ContentHash for ExportAllDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.exported.content_hash(state); + self.source.content_hash(state); + self.with_clause.content_hash(state); + self.export_kind.content_hash(state); + } +} + +impl<'a> ContentHash for ExportSpecifier<'a> { + fn content_hash(&self, state: &mut H) { + self.local.content_hash(state); + self.exported.content_hash(state); + self.export_kind.content_hash(state); + } +} + +impl<'a> ContentHash for ExportDefaultDeclarationKind<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::FunctionDeclaration(it) => it.content_hash(state), + Self::ClassDeclaration(it) => it.content_hash(state), + Self::TSInterfaceDeclaration(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for ModuleExportName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::IdentifierName(it) => it.content_hash(state), + Self::IdentifierReference(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSThisParameter<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSEnumDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.members.content_hash(state); + self.r#const.content_hash(state); + self.declare.content_hash(state); + } +} + +impl<'a> ContentHash for TSEnumMember<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.initializer.content_hash(state); + } +} + +impl<'a> ContentHash for TSEnumMemberName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::StaticIdentifier(it) => it.content_hash(state), + Self::StaticStringLiteral(it) => it.content_hash(state), + Self::StaticTemplateLiteral(it) => it.content_hash(state), + Self::StaticNumericLiteral(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSTypeAnnotation<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSLiteralType<'a> { + fn content_hash(&self, state: &mut H) { + self.literal.content_hash(state); + } +} + +impl<'a> ContentHash for TSLiteral<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSType<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::TSAnyKeyword(it) => it.content_hash(state), + Self::TSBigIntKeyword(it) => it.content_hash(state), + Self::TSBooleanKeyword(it) => it.content_hash(state), + Self::TSIntrinsicKeyword(it) => it.content_hash(state), + Self::TSNeverKeyword(it) => it.content_hash(state), + Self::TSNullKeyword(it) => it.content_hash(state), + Self::TSNumberKeyword(it) => it.content_hash(state), + Self::TSObjectKeyword(it) => it.content_hash(state), + Self::TSStringKeyword(it) => it.content_hash(state), + Self::TSSymbolKeyword(it) => it.content_hash(state), + Self::TSUndefinedKeyword(it) => it.content_hash(state), + Self::TSUnknownKeyword(it) => it.content_hash(state), + Self::TSVoidKeyword(it) => it.content_hash(state), + Self::TSArrayType(it) => it.content_hash(state), + Self::TSConditionalType(it) => it.content_hash(state), + Self::TSConstructorType(it) => it.content_hash(state), + Self::TSFunctionType(it) => it.content_hash(state), + Self::TSImportType(it) => it.content_hash(state), + Self::TSIndexedAccessType(it) => it.content_hash(state), + Self::TSInferType(it) => it.content_hash(state), + Self::TSIntersectionType(it) => it.content_hash(state), + Self::TSLiteralType(it) => it.content_hash(state), + Self::TSMappedType(it) => it.content_hash(state), + Self::TSNamedTupleMember(it) => it.content_hash(state), + Self::TSQualifiedName(it) => it.content_hash(state), + Self::TSTemplateLiteralType(it) => it.content_hash(state), + Self::TSThisType(it) => it.content_hash(state), + Self::TSTupleType(it) => it.content_hash(state), + Self::TSTypeLiteral(it) => it.content_hash(state), + Self::TSTypeOperatorType(it) => it.content_hash(state), + Self::TSTypePredicate(it) => it.content_hash(state), + Self::TSTypeQuery(it) => it.content_hash(state), + Self::TSTypeReference(it) => it.content_hash(state), + Self::TSUnionType(it) => it.content_hash(state), + Self::TSParenthesizedType(it) => it.content_hash(state), + Self::JSDocNullableType(it) => it.content_hash(state), + Self::JSDocNonNullableType(it) => it.content_hash(state), + Self::JSDocUnknownType(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSConditionalType<'a> { + fn content_hash(&self, state: &mut H) { + self.check_type.content_hash(state); + self.extends_type.content_hash(state); + self.true_type.content_hash(state); + self.false_type.content_hash(state); + } +} + +impl<'a> ContentHash for TSUnionType<'a> { + fn content_hash(&self, state: &mut H) { + self.types.content_hash(state); + } +} + +impl<'a> ContentHash for TSIntersectionType<'a> { + fn content_hash(&self, state: &mut H) { + self.types.content_hash(state); + } +} + +impl<'a> ContentHash for TSParenthesizedType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeOperator<'a> { + fn content_hash(&self, state: &mut H) { + self.operator.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl ContentHash for TSTypeOperatorOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TSArrayType<'a> { + fn content_hash(&self, state: &mut H) { + self.element_type.content_hash(state); + } +} + +impl<'a> ContentHash for TSIndexedAccessType<'a> { + fn content_hash(&self, state: &mut H) { + self.object_type.content_hash(state); + self.index_type.content_hash(state); + } +} + +impl<'a> ContentHash for TSTupleType<'a> { + fn content_hash(&self, state: &mut H) { + self.element_types.content_hash(state); + } +} + +impl<'a> ContentHash for TSNamedTupleMember<'a> { + fn content_hash(&self, state: &mut H) { + self.element_type.content_hash(state); + self.label.content_hash(state); + self.optional.content_hash(state); + } +} + +impl<'a> ContentHash for TSOptionalType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSRestType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSTupleElement<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::TSOptionalType(it) => it.content_hash(state), + Self::TSRestType(it) => it.content_hash(state), + Self::TSAnyKeyword(it) => it.content_hash(state), + Self::TSBigIntKeyword(it) => it.content_hash(state), + Self::TSBooleanKeyword(it) => it.content_hash(state), + Self::TSIntrinsicKeyword(it) => it.content_hash(state), + Self::TSNeverKeyword(it) => it.content_hash(state), + Self::TSNullKeyword(it) => it.content_hash(state), + Self::TSNumberKeyword(it) => it.content_hash(state), + Self::TSObjectKeyword(it) => it.content_hash(state), + Self::TSStringKeyword(it) => it.content_hash(state), + Self::TSSymbolKeyword(it) => it.content_hash(state), + Self::TSUndefinedKeyword(it) => it.content_hash(state), + Self::TSUnknownKeyword(it) => it.content_hash(state), + Self::TSVoidKeyword(it) => it.content_hash(state), + Self::TSArrayType(it) => it.content_hash(state), + Self::TSConditionalType(it) => it.content_hash(state), + Self::TSConstructorType(it) => it.content_hash(state), + Self::TSFunctionType(it) => it.content_hash(state), + Self::TSImportType(it) => it.content_hash(state), + Self::TSIndexedAccessType(it) => it.content_hash(state), + Self::TSInferType(it) => it.content_hash(state), + Self::TSIntersectionType(it) => it.content_hash(state), + Self::TSLiteralType(it) => it.content_hash(state), + Self::TSMappedType(it) => it.content_hash(state), + Self::TSNamedTupleMember(it) => it.content_hash(state), + Self::TSQualifiedName(it) => it.content_hash(state), + Self::TSTemplateLiteralType(it) => it.content_hash(state), + Self::TSThisType(it) => it.content_hash(state), + Self::TSTupleType(it) => it.content_hash(state), + Self::TSTypeLiteral(it) => it.content_hash(state), + Self::TSTypeOperatorType(it) => it.content_hash(state), + Self::TSTypePredicate(it) => it.content_hash(state), + Self::TSTypeQuery(it) => it.content_hash(state), + Self::TSTypeReference(it) => it.content_hash(state), + Self::TSUnionType(it) => it.content_hash(state), + Self::TSParenthesizedType(it) => it.content_hash(state), + Self::JSDocNullableType(it) => it.content_hash(state), + Self::JSDocNonNullableType(it) => it.content_hash(state), + Self::JSDocUnknownType(it) => it.content_hash(state), + } + } +} + +impl ContentHash for TSAnyKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSStringKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSBooleanKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSNumberKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSNeverKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSIntrinsicKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSUnknownKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSNullKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSUndefinedKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSVoidKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSSymbolKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSThisType { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSObjectKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for TSBigIntKeyword { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for TSTypeReference<'a> { + fn content_hash(&self, state: &mut H) { + self.type_name.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::IdentifierReference(it) => it.content_hash(state), + Self::QualifiedName(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSQualifiedName<'a> { + fn content_hash(&self, state: &mut H) { + self.left.content_hash(state); + self.right.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeParameterInstantiation<'a> { + fn content_hash(&self, state: &mut H) { + self.params.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeParameter<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.constraint.content_hash(state); + self.default.content_hash(state); + self.r#in.content_hash(state); + self.out.content_hash(state); + self.r#const.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeParameterDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.params.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeAliasDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.type_parameters.content_hash(state); + self.type_annotation.content_hash(state); + self.declare.content_hash(state); + } +} + +impl ContentHash for TSAccessibility { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TSClassImplements<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSInterfaceDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.extends.content_hash(state); + self.type_parameters.content_hash(state); + self.body.content_hash(state); + self.declare.content_hash(state); + } +} + +impl<'a> ContentHash for TSInterfaceBody<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for TSPropertySignature<'a> { + fn content_hash(&self, state: &mut H) { + self.computed.content_hash(state); + self.optional.content_hash(state); + self.readonly.content_hash(state); + self.key.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSSignature<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::TSIndexSignature(it) => it.content_hash(state), + Self::TSPropertySignature(it) => it.content_hash(state), + Self::TSCallSignatureDeclaration(it) => it.content_hash(state), + Self::TSConstructSignatureDeclaration(it) => it.content_hash(state), + Self::TSMethodSignature(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSIndexSignature<'a> { + fn content_hash(&self, state: &mut H) { + self.parameters.content_hash(state); + self.type_annotation.content_hash(state); + self.readonly.content_hash(state); + } +} + +impl<'a> ContentHash for TSCallSignatureDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.this_param.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl ContentHash for TSMethodSignatureKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TSMethodSignature<'a> { + fn content_hash(&self, state: &mut H) { + self.key.content_hash(state); + self.computed.content_hash(state); + self.optional.content_hash(state); + self.kind.content_hash(state); + self.this_param.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSConstructSignatureDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.params.content_hash(state); + self.return_type.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSIndexSignatureName<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSInterfaceHeritage<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypePredicate<'a> { + fn content_hash(&self, state: &mut H) { + self.parameter_name.content_hash(state); + self.asserts.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypePredicateName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::This(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSModuleDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.body.content_hash(state); + self.kind.content_hash(state); + self.declare.content_hash(state); + } +} + +impl ContentHash for TSModuleDeclarationKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TSModuleDeclarationName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSModuleDeclarationBody<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::TSModuleDeclaration(it) => it.content_hash(state), + Self::TSModuleBlock(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSModuleBlock<'a> { + fn content_hash(&self, state: &mut H) { + self.directives.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeLiteral<'a> { + fn content_hash(&self, state: &mut H) { + self.members.content_hash(state); + } +} + +impl<'a> ContentHash for TSInferType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_parameter.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeQuery<'a> { + fn content_hash(&self, state: &mut H) { + self.expr_name.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeQueryExprName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::TSImportType(it) => it.content_hash(state), + Self::IdentifierReference(it) => it.content_hash(state), + Self::QualifiedName(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSImportType<'a> { + fn content_hash(&self, state: &mut H) { + self.is_type_of.content_hash(state); + self.parameter.content_hash(state); + self.qualifier.content_hash(state); + self.attributes.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSImportAttributes<'a> { + fn content_hash(&self, state: &mut H) { + self.attributes_keyword.content_hash(state); + self.elements.content_hash(state); + } +} + +impl<'a> ContentHash for TSImportAttribute<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for TSImportAttributeName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSFunctionType<'a> { + fn content_hash(&self, state: &mut H) { + self.this_param.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSConstructorType<'a> { + fn content_hash(&self, state: &mut H) { + self.r#abstract.content_hash(state); + self.params.content_hash(state); + self.return_type.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for TSMappedType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_parameter.content_hash(state); + self.name_type.content_hash(state); + self.type_annotation.content_hash(state); + self.optional.content_hash(state); + self.readonly.content_hash(state); + } +} + +impl ContentHash for TSMappedTypeModifierOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for TSTemplateLiteralType<'a> { + fn content_hash(&self, state: &mut H) { + self.quasis.content_hash(state); + self.types.content_hash(state); + } +} + +impl<'a> ContentHash for TSAsExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSSatisfiesExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSTypeAssertion<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_annotation.content_hash(state); + } +} + +impl<'a> ContentHash for TSImportEqualsDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + self.module_reference.content_hash(state); + self.import_kind.content_hash(state); + } +} + +impl<'a> ContentHash for TSModuleReference<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::ExternalModuleReference(it) => it.content_hash(state), + Self::IdentifierReference(it) => it.content_hash(state), + Self::QualifiedName(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for TSExternalModuleReference<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for TSNonNullExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for Decorator<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for TSExportAssignment<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for TSNamespaceExportDeclaration<'a> { + fn content_hash(&self, state: &mut H) { + self.id.content_hash(state); + } +} + +impl<'a> ContentHash for TSInstantiationExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl ContentHash for ImportOrExportKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for JSDocNullableType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + self.postfix.content_hash(state); + } +} + +impl<'a> ContentHash for JSDocNonNullableType<'a> { + fn content_hash(&self, state: &mut H) { + self.type_annotation.content_hash(state); + self.postfix.content_hash(state); + } +} + +impl ContentHash for JSDocUnknownType { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for JSXElement<'a> { + fn content_hash(&self, state: &mut H) { + self.opening_element.content_hash(state); + self.closing_element.content_hash(state); + self.children.content_hash(state); + } +} + +impl<'a> ContentHash for JSXOpeningElement<'a> { + fn content_hash(&self, state: &mut H) { + self.self_closing.content_hash(state); + self.name.content_hash(state); + self.attributes.content_hash(state); + self.type_parameters.content_hash(state); + } +} + +impl<'a> ContentHash for JSXClosingElement<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for JSXFragment<'a> { + fn content_hash(&self, state: &mut H) { + self.opening_fragment.content_hash(state); + self.closing_fragment.content_hash(state); + self.children.content_hash(state); + } +} + +impl ContentHash for JSXOpeningFragment { + fn content_hash(&self, _: &mut H) {} +} + +impl ContentHash for JSXClosingFragment { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for JSXElementName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::IdentifierReference(it) => it.content_hash(state), + Self::NamespacedName(it) => it.content_hash(state), + Self::MemberExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXNamespacedName<'a> { + fn content_hash(&self, state: &mut H) { + self.namespace.content_hash(state); + self.property.content_hash(state); + } +} + +impl<'a> ContentHash for JSXMemberExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.object.content_hash(state); + self.property.content_hash(state); + } +} + +impl<'a> ContentHash for JSXMemberExpressionObject<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::IdentifierReference(it) => it.content_hash(state), + Self::MemberExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXExpressionContainer<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for JSXExpression<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::EmptyExpression(it) => it.content_hash(state), + Self::BooleanLiteral(it) => it.content_hash(state), + Self::NullLiteral(it) => it.content_hash(state), + Self::NumericLiteral(it) => it.content_hash(state), + Self::BigIntLiteral(it) => it.content_hash(state), + Self::RegExpLiteral(it) => it.content_hash(state), + Self::StringLiteral(it) => it.content_hash(state), + Self::TemplateLiteral(it) => it.content_hash(state), + Self::Identifier(it) => it.content_hash(state), + Self::MetaProperty(it) => it.content_hash(state), + Self::Super(it) => it.content_hash(state), + Self::ArrayExpression(it) => it.content_hash(state), + Self::ArrowFunctionExpression(it) => it.content_hash(state), + Self::AssignmentExpression(it) => it.content_hash(state), + Self::AwaitExpression(it) => it.content_hash(state), + Self::BinaryExpression(it) => it.content_hash(state), + Self::CallExpression(it) => it.content_hash(state), + Self::ChainExpression(it) => it.content_hash(state), + Self::ClassExpression(it) => it.content_hash(state), + Self::ConditionalExpression(it) => it.content_hash(state), + Self::FunctionExpression(it) => it.content_hash(state), + Self::ImportExpression(it) => it.content_hash(state), + Self::LogicalExpression(it) => it.content_hash(state), + Self::NewExpression(it) => it.content_hash(state), + Self::ObjectExpression(it) => it.content_hash(state), + Self::ParenthesizedExpression(it) => it.content_hash(state), + Self::SequenceExpression(it) => it.content_hash(state), + Self::TaggedTemplateExpression(it) => it.content_hash(state), + Self::ThisExpression(it) => it.content_hash(state), + Self::UnaryExpression(it) => it.content_hash(state), + Self::UpdateExpression(it) => it.content_hash(state), + Self::YieldExpression(it) => it.content_hash(state), + Self::PrivateInExpression(it) => it.content_hash(state), + Self::JSXElement(it) => it.content_hash(state), + Self::JSXFragment(it) => it.content_hash(state), + Self::TSAsExpression(it) => it.content_hash(state), + Self::TSSatisfiesExpression(it) => it.content_hash(state), + Self::TSTypeAssertion(it) => it.content_hash(state), + Self::TSNonNullExpression(it) => it.content_hash(state), + Self::TSInstantiationExpression(it) => it.content_hash(state), + Self::ComputedMemberExpression(it) => it.content_hash(state), + Self::StaticMemberExpression(it) => it.content_hash(state), + Self::PrivateFieldExpression(it) => it.content_hash(state), + } + } +} + +impl ContentHash for JSXEmptyExpression { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for JSXAttributeItem<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Attribute(it) => it.content_hash(state), + Self::SpreadAttribute(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXAttribute<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.value.content_hash(state); + } +} + +impl<'a> ContentHash for JSXSpreadAttribute<'a> { + fn content_hash(&self, state: &mut H) { + self.argument.content_hash(state); + } +} + +impl<'a> ContentHash for JSXAttributeName<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Identifier(it) => it.content_hash(state), + Self::NamespacedName(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXAttributeValue<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::StringLiteral(it) => it.content_hash(state), + Self::ExpressionContainer(it) => it.content_hash(state), + Self::Element(it) => it.content_hash(state), + Self::Fragment(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXIdentifier<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} + +impl<'a> ContentHash for JSXChild<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::Text(it) => it.content_hash(state), + Self::Element(it) => it.content_hash(state), + Self::Fragment(it) => it.content_hash(state), + Self::ExpressionContainer(it) => it.content_hash(state), + Self::Spread(it) => it.content_hash(state), + } + } +} + +impl<'a> ContentHash for JSXSpreadChild<'a> { + fn content_hash(&self, state: &mut H) { + self.expression.content_hash(state); + } +} + +impl<'a> ContentHash for JSXText<'a> { + fn content_hash(&self, state: &mut H) { + self.value.content_hash(state); + } +} diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index dd0b35474813e..e8cc9c1bd4e14 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -43,6 +43,7 @@ mod generated { pub mod ast_kind; pub mod derive_clone_in; pub mod derive_content_eq; + pub mod derive_content_hash; pub mod derive_get_span; pub mod derive_get_span_mut; pub mod visit; diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index b9141c6af8a17..c4ecedf948617 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -42,6 +42,15 @@ fn assert_generated_derives(attrs: &[syn::Attribute]) -> TokenStream2 { fn abs_trait( ident: &syn::Ident, ) -> (/* absolute type path */ TokenStream2, /* possible generics */ TokenStream2) { + #[cold] + fn invalid_derive(ident: &syn::Ident) -> ! { + panic!( + "Invalid derive trait(generate_derive): {ident}.\n\ + Help: If you are trying to implement a new `generate_derive` trait, \ + Make sure to add it to the list below." + ) + } + if ident == "CloneIn" { (quote!(::oxc_allocator::CloneIn), quote!(<'static>)) } else if ident == "GetSpan" { @@ -50,9 +59,10 @@ fn assert_generated_derives(attrs: &[syn::Attribute]) -> TokenStream2 { (quote!(::oxc_span::GetSpanMut), TokenStream2::default()) } else if ident == "ContentEq" { (quote!(::oxc_span::cmp::ContentEq), quote!(<()>)) + } else if ident == "ContentHash" { + (quote!(::oxc_span::hash::ContentHash), TokenStream2::default()) } else { - panic!("Invalid derive trait(generate_derive): {ident}.\ - Help: If you are trying to implement a new `generate_derive` trait, Make sure to add it to the list above."); + invalid_derive(ident) } } diff --git a/crates/oxc_linter/src/ast_util.rs b/crates/oxc_linter/src/ast_util.rs index 1e8395de77599..a501edc92862a 100644 --- a/crates/oxc_linter/src/ast_util.rs +++ b/crates/oxc_linter/src/ast_util.rs @@ -1,15 +1,15 @@ -use std::hash::{Hash, Hasher}; +use core::hash::Hasher; use oxc_ast::ast::BindingIdentifier; use oxc_ast::AstKind; use oxc_semantic::{AstNode, AstNodeId, SymbolId}; -use oxc_span::{GetSpan, Span}; +use oxc_span::{hash::ContentHash, GetSpan, Span}; use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator}; use rustc_hash::FxHasher; -pub fn calculate_hash(t: &T) -> u64 { +pub fn calculate_hash(t: &T) -> u64 { let mut hasher = FxHasher::default(); - t.hash(&mut hasher); + t.content_hash(&mut hasher); hasher.finish() } #[allow(clippy::wildcard_imports)] diff --git a/crates/oxc_regular_expression/src/ast.rs b/crates/oxc_regular_expression/src/ast.rs index c743618f94c8a..e398a4349d0e2 100644 --- a/crates/oxc_regular_expression/src/ast.rs +++ b/crates/oxc_regular_expression/src/ast.rs @@ -7,7 +7,7 @@ use oxc_allocator::{Box, CloneIn, Vec}; use oxc_ast_macros::ast; -use oxc_span::{cmp::ContentEq, Atom, Span}; +use oxc_span::{cmp::ContentEq, hash::ContentHash, Atom, Span}; #[cfg(feature = "serialize")] use serde::Serialize; @@ -15,8 +15,8 @@ use serde::Serialize; use tsify::Tsify; #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct RegularExpression<'a> { pub span: Span, @@ -25,8 +25,8 @@ pub struct RegularExpression<'a> { } #[ast] -#[derive(Debug, Clone, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Flags { pub span: Span, @@ -42,8 +42,8 @@ pub struct Flags { /// The root of the `PatternParser` result. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Pattern<'a> { pub span: Span, @@ -52,8 +52,8 @@ pub struct Pattern<'a> { /// Pile of [`Alternative`]s separated by `|`. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Disjunction<'a> { pub span: Span, @@ -62,8 +62,8 @@ pub struct Disjunction<'a> { /// Single unit of `|` separated alternatives. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Alternative<'a> { pub span: Span, @@ -72,8 +72,8 @@ pub struct Alternative<'a> { /// Single unit of [`Alternative`], containing various kinds. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum Term<'a> { // Assertion, QuantifiableAssertion @@ -96,8 +96,8 @@ pub enum Term<'a> { /// Simple form of assertion. /// e.g. `^`, `$`, `\b`, `\B` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct BoundaryAssertion { pub span: Span, @@ -105,8 +105,8 @@ pub struct BoundaryAssertion { } #[ast] -#[derive(Debug, Clone, Hash, PartialEq)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, PartialEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum BoundaryAssertionKind { Start = 0, @@ -118,8 +118,8 @@ pub enum BoundaryAssertionKind { /// Lookaround assertion. /// e.g. `(?=...)`, `(?!...)`, `(?<=...)`, `(? { pub span: Span, @@ -128,8 +128,8 @@ pub struct LookAroundAssertion<'a> { } #[ast] -#[derive(Debug, Clone, Hash, PartialEq)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, PartialEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum LookAroundAssertionKind { Lookahead = 0, @@ -141,8 +141,8 @@ pub enum LookAroundAssertionKind { /// Quantifier holding a [`Term`] and its repetition count. /// e.g. `a*`, `b+`, `c?`, `d{3}`, `e{4,}`, `f{5,6}` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Quantifier<'a> { pub span: Span, @@ -155,8 +155,8 @@ pub struct Quantifier<'a> { /// Single character. #[ast] -#[derive(Debug, Clone, Copy, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[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. @@ -167,8 +167,8 @@ pub struct Character { } #[ast] -#[derive(Debug, Clone, Copy, Hash, PartialEq)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterKind { ControlLetter = 0, @@ -184,8 +184,8 @@ pub enum CharacterKind { /// Character class. /// e.g. `\d`, `\D`, `\s`, `\S`, `\w`, `\W` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClassEscape { pub span: Span, @@ -193,8 +193,8 @@ pub struct CharacterClassEscape { } #[ast] -#[derive(Debug, Clone, Copy, Hash, PartialEq)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassEscapeKind { D = 0, @@ -208,8 +208,8 @@ pub enum CharacterClassEscapeKind { /// Unicode property. /// e.g. `\p{ASCII}`, `\P{ASCII}`, `\p{sc=Hiragana}`, `\P{sc=Hiragana}` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct UnicodePropertyEscape<'a> { pub span: Span, @@ -222,8 +222,8 @@ pub struct UnicodePropertyEscape<'a> { /// The `.`. #[ast] -#[derive(Debug, Clone, Copy, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct Dot { pub span: Span, @@ -232,8 +232,8 @@ pub struct Dot { /// Character class wrapped by `[]`. /// e.g. `[a-z]`, `[^A-Z]`, `[abc]`, `[a&&b&&c]`, `[[a-z]--x--y]` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClass<'a> { pub span: Span, @@ -243,8 +243,8 @@ pub struct CharacterClass<'a> { } #[ast] -#[derive(Debug, Hash, PartialEq)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, PartialEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassContentsKind { Union = 0, @@ -255,8 +255,8 @@ pub enum CharacterClassContentsKind { } #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum CharacterClassContents<'a> { CharacterClassRange(Box<'a, CharacterClassRange>) = 0, @@ -272,8 +272,8 @@ pub enum CharacterClassContents<'a> { /// `-` separated range of characters. /// e.g. `a-z`, `A-Z`, `0-9` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CharacterClassRange { pub span: Span, @@ -283,8 +283,8 @@ pub struct CharacterClassRange { /// `|` separated string of characters wrapped by `\q{}`. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ClassStringDisjunction<'a> { pub span: Span, @@ -295,8 +295,8 @@ pub struct ClassStringDisjunction<'a> { /// Single unit of [`ClassStringDisjunction`]. #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ClassString<'a> { pub span: Span, @@ -308,8 +308,8 @@ pub struct ClassString<'a> { /// Named or unnamed capturing group. /// e.g. `(...)`, `(?...)` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct CapturingGroup<'a> { pub span: Span, @@ -320,8 +320,8 @@ pub struct CapturingGroup<'a> { /// Pseudo-group for ignoring. /// e.g. `(?:...)` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct IgnoreGroup<'a> { pub span: Span, @@ -331,8 +331,8 @@ pub struct IgnoreGroup<'a> { } #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct ModifierFlags { pub ignore_case: bool, @@ -343,8 +343,8 @@ pub struct ModifierFlags { /// Backreference by index. /// e.g. `\1`, `\2`, `\3` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct IndexedReference { pub span: Span, @@ -354,8 +354,8 @@ pub struct IndexedReference { /// Backreference by name. /// e.g. `\k` #[ast] -#[derive(Debug, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct NamedReference<'a> { pub span: Span, diff --git a/crates/oxc_regular_expression/src/generated/derive_content_hash.rs b/crates/oxc_regular_expression/src/generated/derive_content_hash.rs new file mode 100644 index 0000000000000..9fb4a3e586016 --- /dev/null +++ b/crates/oxc_regular_expression/src/generated/derive_content_hash.rs @@ -0,0 +1,225 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/content_hash.rs` + +#![allow(clippy::match_same_arms)] + +use std::{hash::Hasher, mem::discriminant}; + +use oxc_span::hash::ContentHash; + +#[allow(clippy::wildcard_imports)] +use crate::ast::*; + +impl<'a> ContentHash for RegularExpression<'a> { + fn content_hash(&self, state: &mut H) { + self.pattern.content_hash(state); + self.flags.content_hash(state); + } +} + +impl ContentHash for Flags { + fn content_hash(&self, state: &mut H) { + self.global.content_hash(state); + self.ignore_case.content_hash(state); + self.multiline.content_hash(state); + self.unicode.content_hash(state); + self.sticky.content_hash(state); + self.dot_all.content_hash(state); + self.has_indices.content_hash(state); + self.unicode_sets.content_hash(state); + } +} + +impl<'a> ContentHash for Pattern<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for Disjunction<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for Alternative<'a> { + fn content_hash(&self, state: &mut H) { + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for Term<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::BoundaryAssertion(it) => it.content_hash(state), + Self::LookAroundAssertion(it) => it.content_hash(state), + Self::Quantifier(it) => it.content_hash(state), + Self::Character(it) => it.content_hash(state), + Self::Dot(it) => it.content_hash(state), + Self::CharacterClassEscape(it) => it.content_hash(state), + Self::UnicodePropertyEscape(it) => it.content_hash(state), + Self::CharacterClass(it) => it.content_hash(state), + Self::CapturingGroup(it) => it.content_hash(state), + Self::IgnoreGroup(it) => it.content_hash(state), + Self::IndexedReference(it) => it.content_hash(state), + Self::NamedReference(it) => it.content_hash(state), + } + } +} + +impl ContentHash for BoundaryAssertion { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + } +} + +impl ContentHash for BoundaryAssertionKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for LookAroundAssertion<'a> { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.body.content_hash(state); + } +} + +impl ContentHash for LookAroundAssertionKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for Quantifier<'a> { + fn content_hash(&self, state: &mut H) { + self.min.content_hash(state); + self.max.content_hash(state); + self.greedy.content_hash(state); + self.body.content_hash(state); + } +} + +impl ContentHash for Character { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + self.value.content_hash(state); + } +} + +impl ContentHash for CharacterKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for CharacterClassEscape { + fn content_hash(&self, state: &mut H) { + self.kind.content_hash(state); + } +} + +impl ContentHash for CharacterClassEscapeKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for UnicodePropertyEscape<'a> { + fn content_hash(&self, state: &mut H) { + self.negative.content_hash(state); + self.strings.content_hash(state); + self.name.content_hash(state); + self.value.content_hash(state); + } +} + +impl ContentHash for Dot { + fn content_hash(&self, _: &mut H) {} +} + +impl<'a> ContentHash for CharacterClass<'a> { + fn content_hash(&self, state: &mut H) { + self.negative.content_hash(state); + self.kind.content_hash(state); + self.body.content_hash(state); + } +} + +impl ContentHash for CharacterClassContentsKind { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl<'a> ContentHash for CharacterClassContents<'a> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + match self { + Self::CharacterClassRange(it) => it.content_hash(state), + Self::CharacterClassEscape(it) => it.content_hash(state), + Self::UnicodePropertyEscape(it) => it.content_hash(state), + Self::Character(it) => it.content_hash(state), + Self::NestedCharacterClass(it) => it.content_hash(state), + Self::ClassStringDisjunction(it) => it.content_hash(state), + } + } +} + +impl ContentHash for CharacterClassRange { + fn content_hash(&self, state: &mut H) { + self.min.content_hash(state); + self.max.content_hash(state); + } +} + +impl<'a> ContentHash for ClassStringDisjunction<'a> { + fn content_hash(&self, state: &mut H) { + self.strings.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for ClassString<'a> { + fn content_hash(&self, state: &mut H) { + self.strings.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for CapturingGroup<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + self.body.content_hash(state); + } +} + +impl<'a> ContentHash for IgnoreGroup<'a> { + fn content_hash(&self, state: &mut H) { + self.enabling_modifiers.content_hash(state); + self.disabling_modifiers.content_hash(state); + self.body.content_hash(state); + } +} + +impl ContentHash for ModifierFlags { + fn content_hash(&self, state: &mut H) { + self.ignore_case.content_hash(state); + self.sticky.content_hash(state); + self.multiline.content_hash(state); + } +} + +impl ContentHash for IndexedReference { + fn content_hash(&self, state: &mut H) { + self.index.content_hash(state); + } +} + +impl<'a> ContentHash for NamedReference<'a> { + fn content_hash(&self, state: &mut H) { + self.name.content_hash(state); + } +} diff --git a/crates/oxc_regular_expression/src/lib.rs b/crates/oxc_regular_expression/src/lib.rs index 84b0256fec279..d3720a7096727 100644 --- a/crates/oxc_regular_expression/src/lib.rs +++ b/crates/oxc_regular_expression/src/lib.rs @@ -12,6 +12,7 @@ mod surrogate_pair; mod generated { mod derive_clone_in; mod derive_content_eq; + mod derive_content_hash; } pub use crate::body_parser::PatternParser; diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index 2d059a0e7a4f7..03152bed92fdb 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -8,7 +8,7 @@ use compact_str::CompactString; #[cfg(feature = "serialize")] use serde::{Serialize, Serializer}; -use crate::{cmp::ContentEq, Span}; +use crate::{cmp::ContentEq, hash::ContentHash, Span}; use oxc_allocator::{Allocator, CloneIn, FromIn}; #[cfg(feature = "serialize")] @@ -204,6 +204,12 @@ impl<'a> ContentEq<&Atom<'a>> for Cow<'_, str> { } } +impl<'a> ContentHash for Atom<'a> { + fn content_hash(&self, state: &mut H) { + hash::Hash::hash(self, state); + } +} + impl<'a> hash::Hash for Atom<'a> { fn hash(&self, hasher: &mut H) { self.as_str().hash(hasher); diff --git a/crates/oxc_span/src/hash.rs b/crates/oxc_span/src/hash.rs new file mode 100644 index 0000000000000..eee15b72d9556 --- /dev/null +++ b/crates/oxc_span/src/hash.rs @@ -0,0 +1,74 @@ +use core::hash::Hasher; +use std::{ + hash::Hash, + mem::{discriminant, Discriminant}, +}; + +/// This trait works similarly to [std::hash::Hash] but it gives the liberty of hashing +/// the object's content loosely. This would mean the implementor can skip some parts of +/// the content while calculating the hash. +/// +/// As an example, In AST types we ignore fields such as [crate::Span]. +pub trait ContentHash { + fn content_hash(&self, state: &mut H); + + /// The default implementation is usually sufficient. + fn content_hash_slice(data: &[Self], state: &mut H) + where + Self: Sized, + { + for piece in data { + piece.content_hash(state); + } + } +} + +/// Short-Circuting implementation for [Discriminant] since it is used to hash enums. +impl ContentHash for Discriminant { + fn content_hash(&self, state: &mut H) { + Hash::hash(self, state); + } +} + +impl ContentHash for Option { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + if let Some(it) = self { + ContentHash::content_hash(it, state); + } + } +} + +impl<'a, T: ContentHash> ContentHash for oxc_allocator::Box<'a, T> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(self.as_ref(), state); + } +} + +impl<'a, T: ContentHash> ContentHash for oxc_allocator::Vec<'a, T> { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash_slice(self.as_slice(), state); + } +} + +mod auto_impl_content_hash { + use super::ContentHash; + macro_rules! impl_content_hash { + ($($t:ty)*) => { + $( + impl ContentHash for $t { + fn content_hash(&self, state: &mut H) { + std::hash::Hash::hash(self, state); + } + } + )* + }; + } + + impl_content_hash! { + char &str + bool isize usize + u8 u16 u32 u64 u128 + i8 i16 i32 i64 i128 + } +} diff --git a/crates/oxc_span/src/lib.rs b/crates/oxc_span/src/lib.rs index e73cce1fc2f07..8c1babb1780c8 100644 --- a/crates/oxc_span/src/lib.rs +++ b/crates/oxc_span/src/lib.rs @@ -7,6 +7,7 @@ mod source_type; mod span; pub mod cmp; +pub mod hash; pub use crate::{ atom::{Atom, CompactStr, MAX_INLINE_LEN as ATOM_MAX_INLINE_LEN}, diff --git a/crates/oxc_span/src/source_type/mod.rs b/crates/oxc_span/src/source_type/mod.rs index 92b65a574cc58..372d2093a6c77 100644 --- a/crates/oxc_span/src/source_type/mod.rs +++ b/crates/oxc_span/src/source_type/mod.rs @@ -3,10 +3,10 @@ mod types; pub use error::UnknownExtension; use oxc_allocator::{Allocator, CloneIn}; -use std::path::Path; +use std::{hash::Hash, path::Path}; pub use types::*; -use crate::cmp::ContentEq; +use crate::{cmp::ContentEq, hash::ContentHash}; impl Default for SourceType { #[inline] @@ -30,6 +30,13 @@ impl ContentEq for SourceType { } } +impl ContentHash for SourceType { + #[inline] + fn content_hash(&self, state: &mut H) { + self.hash(state); + } +} + /// Valid file extensions pub const VALID_EXTENSIONS: [&str; 8] = ["js", "mjs", "cjs", "jsx", "ts", "mts", "cts", "tsx"]; diff --git a/crates/oxc_span/src/span/mod.rs b/crates/oxc_span/src/span/mod.rs index 669d9d187a9eb..1f332e914f117 100644 --- a/crates/oxc_span/src/span/mod.rs +++ b/crates/oxc_span/src/span/mod.rs @@ -1,7 +1,4 @@ -use std::{ - hash::{Hash, Hasher}, - ops::{Index, IndexMut, Range}, -}; +use std::ops::{Index, IndexMut, Range}; use miette::{LabeledSpan, SourceOffset, SourceSpan}; @@ -353,12 +350,6 @@ impl From> for Span { } } -impl Hash for Span { - fn hash(&self, _state: &mut H) { - // hash to nothing so all ast spans can be comparable with hash - } -} - impl From for SourceSpan { fn from(val: Span) -> Self { Self::new(SourceOffset::from(val.start as usize), val.size() as usize) @@ -413,7 +404,7 @@ mod test { let mut first = DefaultHasher::new(); let mut second = DefaultHasher::new(); Span::new(0, 5).hash(&mut first); - Span::new(10, 20).hash(&mut second); + Span::new(0, 5).hash(&mut second); assert_eq!(first.finish(), second.finish()); } #[test] diff --git a/crates/oxc_span/src/span/types.rs b/crates/oxc_span/src/span/types.rs index f23f29bd668c4..ede19af712088 100644 --- a/crates/oxc_span/src/span/types.rs +++ b/crates/oxc_span/src/span/types.rs @@ -29,7 +29,7 @@ use oxc_ast_macros::ast; /// assert_eq!(first.finish(), second.finish()); /// ``` #[ast] -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[non_exhaustive] // Disallow struct expression constructor `Span {}` pub struct Span { diff --git a/crates/oxc_syntax/src/generated/derive_content_hash.rs b/crates/oxc_syntax/src/generated/derive_content_hash.rs new file mode 100644 index 0000000000000..9fa9350d36388 --- /dev/null +++ b/crates/oxc_syntax/src/generated/derive_content_hash.rs @@ -0,0 +1,56 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/derives/content_hash.rs` + +#![allow(clippy::match_same_arms)] + +use std::{hash::Hasher, mem::discriminant}; + +use oxc_span::hash::ContentHash; + +#[allow(clippy::wildcard_imports)] +use crate::number::*; + +#[allow(clippy::wildcard_imports)] +use crate::operator::*; + +impl ContentHash for NumberBase { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for BigintBase { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for AssignmentOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for BinaryOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for LogicalOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for UnaryOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} + +impl ContentHash for UpdateOperator { + fn content_hash(&self, state: &mut H) { + ContentHash::content_hash(&discriminant(self), state); + } +} diff --git a/crates/oxc_syntax/src/lib.rs b/crates/oxc_syntax/src/lib.rs index 2dc84ba3f0045..c64073bbb4208 100644 --- a/crates/oxc_syntax/src/lib.rs +++ b/crates/oxc_syntax/src/lib.rs @@ -16,4 +16,5 @@ pub mod xml_entities; mod generated { mod derive_clone_in; mod derive_content_eq; + mod derive_content_hash; } diff --git a/crates/oxc_syntax/src/number.rs b/crates/oxc_syntax/src/number.rs index d55364c537954..1b9e6cd1f1ea7 100644 --- a/crates/oxc_syntax/src/number.rs +++ b/crates/oxc_syntax/src/number.rs @@ -1,10 +1,10 @@ use oxc_allocator::CloneIn; use oxc_ast_macros::ast; -use oxc_span::cmp::ContentEq; +use oxc_span::{cmp::ContentEq, hash::ContentHash}; #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] pub enum NumberBase { Float = 0, Decimal = 1, @@ -21,7 +21,7 @@ impl NumberBase { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] pub enum BigintBase { Decimal = 0, Binary = 1, diff --git a/crates/oxc_syntax/src/operator.rs b/crates/oxc_syntax/src/operator.rs index 3941230240d48..0e9855f657965 100644 --- a/crates/oxc_syntax/src/operator.rs +++ b/crates/oxc_syntax/src/operator.rs @@ -6,13 +6,13 @@ use ::{serde::Serialize, tsify::Tsify}; use oxc_allocator::CloneIn; use oxc_ast_macros::ast; -use oxc_span::cmp::ContentEq; +use oxc_span::{cmp::ContentEq, hash::ContentHash}; use crate::precedence::{GetPrecedence, Precedence}; #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum AssignmentOperator { #[serde(rename = "=")] @@ -92,7 +92,7 @@ impl AssignmentOperator { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum BinaryOperator { #[serde(rename = "==")] @@ -280,8 +280,8 @@ impl GetPrecedence for BinaryOperator { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum LogicalOperator { #[serde(rename = "||")] @@ -322,7 +322,7 @@ impl GetPrecedence for LogicalOperator { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum UnaryOperator { #[serde(rename = "-")] @@ -376,7 +376,7 @@ impl UnaryOperator { #[ast] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[generate_derive(CloneIn, ContentEq)] +#[generate_derive(CloneIn, ContentEq, ContentHash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum UpdateOperator { #[serde(rename = "++")] diff --git a/tasks/ast_tools/src/derives/content_hash.rs b/tasks/ast_tools/src/derives/content_hash.rs new file mode 100644 index 0000000000000..fe3b2a66bf085 --- /dev/null +++ b/tasks/ast_tools/src/derives/content_hash.rs @@ -0,0 +1,124 @@ +use itertools::Itertools; +use proc_macro2::TokenStream; +use quote::quote; + +use crate::{ + codegen::LateCtx, + schema::{EnumDef, GetGenerics, StructDef, ToType, TypeDef}, + util::ToIdent, +}; + +use super::{define_derive, Derive, DeriveOutput}; + +define_derive! { + pub struct DeriveContentHash; +} + +const IGNORE_FIELDS: [(/* field name */ &str, /* field type */ &str); 6] = [ + ("span", "Span"), + ("trailing_comma", "Span"), + ("this_span", "Span"), + ("scope_id", "ScopeId"), + ("symbol_id", "SymbolId"), + ("reference_id", "ReferenceId"), +]; + +impl Derive for DeriveContentHash { + fn trait_name() -> &'static str { + "ContentHash" + } + + fn derive(&mut self, def: &TypeDef, _: &LateCtx) -> TokenStream { + let (hasher, body) = match &def { + TypeDef::Enum(it) => derive_enum(it), + TypeDef::Struct(it) => derive_struct(it), + }; + + impl_content_hash(def, hasher, &body) + } + + fn prelude() -> TokenStream { + quote! { + #![allow(clippy::match_same_arms)] + + ///@@line_break + use std::{hash::Hasher, mem::discriminant}; + + ///@@line_break + use oxc_span::hash::ContentHash; + } + } +} + +fn derive_enum(def: &EnumDef) -> (&str, TokenStream) { + let mut body = quote! { + ContentHash::content_hash(&discriminant(self), state); + }; + + body.extend(if def.is_unit() { + TokenStream::default() + } else { + let mut non_exhaustive = false; + let matches = def + .all_variants() + .filter_map(|var| { + let ident = var.ident(); + if var.is_unit() { + non_exhaustive = true; + None + } else { + Some(quote!(Self :: #ident(it) => it.content_hash(state))) + } + }) + .collect_vec(); + let exhaust = non_exhaustive.then(|| quote!(_ => {})); + quote! { + match self { + #(#matches),* + #exhaust + } + } + }); + + ("state", body) +} + +fn derive_struct(def: &StructDef) -> (&str, TokenStream) { + if def.fields.is_empty() { + ("_", TokenStream::default()) + } else { + let fields = def + .fields + .iter() + .filter(|field| { + let Some(name) = field.name.as_ref() else { return false }; + !IGNORE_FIELDS + .iter() + .any(|it| name == it.0 && field.typ.name().inner_name() == it.1) + }) + .map(|field| { + let ident = field.ident(); + quote!(self.#ident.content_hash(state);) + }) + .collect_vec(); + if fields.is_empty() { + ("_", TokenStream::default()) + } else { + ("state", quote!(#(#fields)*)) + } + } +} + +fn impl_content_hash(def: &TypeDef, hasher_name: &str, body: &TokenStream) -> TokenStream { + let ty = def.to_type(); + let generics = def.generics(); + let hasher = hasher_name.to_ident(); + + quote! { + impl #generics ContentHash for #ty { + fn content_hash(&self, #hasher: &mut H) { + #body + } + } + } +} diff --git a/tasks/ast_tools/src/derives/mod.rs b/tasks/ast_tools/src/derives/mod.rs index 3d0e9e8ece676..cdcdb1ae6b337 100644 --- a/tasks/ast_tools/src/derives/mod.rs +++ b/tasks/ast_tools/src/derives/mod.rs @@ -5,10 +5,12 @@ use crate::{codegen::LateCtx, schema::TypeDef}; mod clone_in; mod content_eq; +mod content_hash; mod get_span; pub use clone_in::DeriveCloneIn; pub use content_eq::DeriveContentEq; +pub use content_hash::DeriveContentHash; pub use get_span::{DeriveGetSpan, DeriveGetSpanMut}; pub trait Derive { diff --git a/tasks/ast_tools/src/main.rs b/tasks/ast_tools/src/main.rs index d20cad20f6af3..6f4fc02d99c68 100644 --- a/tasks/ast_tools/src/main.rs +++ b/tasks/ast_tools/src/main.rs @@ -16,7 +16,7 @@ mod rust_ast; mod schema; mod util; -use derives::{DeriveCloneIn, DeriveContentEq, DeriveGetSpan, DeriveGetSpanMut}; +use derives::{DeriveCloneIn, DeriveContentEq, DeriveContentHash, DeriveGetSpan, DeriveGetSpanMut}; use fmt::cargo_fmt; use generators::{ AssertLayouts, AstBuilderGenerator, AstKindGenerator, Generator, GeneratorOutput, @@ -66,6 +66,7 @@ fn main() -> std::result::Result<(), Box> { .derive(DeriveGetSpan) .derive(DeriveGetSpanMut) .derive(DeriveContentEq) + .derive(DeriveContentHash) .generate(AssertLayouts) .generate(AstKindGenerator) .generate(AstBuilderGenerator)