diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 4a3add94fa46c..6471984a02cc3 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -68,10 +68,17 @@ pub struct TSThisParameter<'a> { #[scope] #[derive(Debug)] #[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, ContentEq, ESTree)] +#[estree(add_ts_def = " + interface TSEnumBody extends Span { + type: 'TSEnumBody'; + members: TSEnumMember[]; + } +")] pub struct TSEnumDeclaration<'a> { pub span: Span, pub id: BindingIdentifier<'a>, #[scope(enter_before)] + #[estree(rename = "body", via = TSEnumDeclarationBody)] pub members: Vec<'a, TSEnumMember<'a>>, /// `true` for const enums pub r#const: bool, diff --git a/crates/oxc_ast/src/generated/derive_estree.rs b/crates/oxc_ast/src/generated/derive_estree.rs index 017065b1b8956..d2899bcf7bc0f 100644 --- a/crates/oxc_ast/src/generated/derive_estree.rs +++ b/crates/oxc_ast/src/generated/derive_estree.rs @@ -2303,7 +2303,7 @@ impl ESTree for TSEnumDeclaration<'_> { state.serialize_field("start", &self.span.start); state.serialize_field("end", &self.span.end); state.serialize_field("id", &self.id); - state.serialize_field("members", &self.members); + state.serialize_field("body", &crate::serialize::TSEnumDeclarationBody(self)); state.serialize_field("const", &self.r#const); state.serialize_field("declare", &self.declare); state.end(); diff --git a/crates/oxc_ast/src/serialize.rs b/crates/oxc_ast/src/serialize.rs index c3891c4ce74b8..c5871219bb771 100644 --- a/crates/oxc_ast/src/serialize.rs +++ b/crates/oxc_ast/src/serialize.rs @@ -823,6 +823,41 @@ impl ESTree for TSModuleDeclarationGlobal<'_, '_> { } } +/// Serializer for `body` field of `TSEnumDeclaration`. +/// This field is derived from `members` field. +/// +/// `Span` indicates within braces `{ ... }`. +/// ```ignore +/// enum Foo { ... } +/// | | TSEnumDeclaration.span +/// | | TSEnumBody.span +/// ^^ id_end + 1 for space +/// ``` +/// NOTE: + 1 is not sufficient for all cases, e.g. `enum Foo{}`, `enum Foo {}`, etc. +/// We may need to reconsider adding `TSEnumBody` as Rust AST. +#[ast_meta] +#[estree( + ts_type = "TSEnumBody", + raw_deser = " + const tsEnumDeclMembers = DESER[Vec](POS_OFFSET.members); + const bodyStart = THIS.id.end + 1; + {type: 'TSEnumBody', start: bodyStart, end: THIS.end, members: tsEnumDeclMembers} + " +)] +pub struct TSEnumDeclarationBody<'a, 'b>(pub &'b TSEnumDeclaration<'a>); + +impl ESTree for TSEnumDeclarationBody<'_, '_> { + fn serialize(&self, serializer: S) { + let mut state = serializer.serialize_struct(); + state.serialize_field("type", &JsonSafeString("TSEnumBody")); + let body_start = self.0.id.span.end + 1; + state.serialize_field("start", &body_start); + state.serialize_field("end", &self.0.span.end); + state.serialize_field("members", &self.0.members); + state.end(); + } +} + // -------------------- // Comments // -------------------- diff --git a/napi/parser/deserialize-js.js b/napi/parser/deserialize-js.js index e3f8a2ccc3cf5..0baa99bd3c736 100644 --- a/napi/parser/deserialize-js.js +++ b/napi/parser/deserialize-js.js @@ -1287,12 +1287,16 @@ function deserializeTSThisParameter(pos) { } function deserializeTSEnumDeclaration(pos) { + const end = deserializeU32(pos + 4), + id = deserializeBindingIdentifier(pos + 8); + const tsEnumDeclMembers = deserializeVecTSEnumMember(pos + 40); + const bodyStart = id.end + 1; return { type: 'TSEnumDeclaration', start: deserializeU32(pos), - end: deserializeU32(pos + 4), - id: deserializeBindingIdentifier(pos + 8), - members: deserializeVecTSEnumMember(pos + 40), + end, + id, + body: { type: 'TSEnumBody', start: bodyStart, end: end, members: tsEnumDeclMembers }, const: deserializeBool(pos + 72), declare: deserializeBool(pos + 73), }; diff --git a/napi/parser/deserialize-ts.js b/napi/parser/deserialize-ts.js index 5b7575dba3fd7..0e6452f598e6d 100644 --- a/napi/parser/deserialize-ts.js +++ b/napi/parser/deserialize-ts.js @@ -1360,12 +1360,16 @@ function deserializeTSThisParameter(pos) { } function deserializeTSEnumDeclaration(pos) { + const end = deserializeU32(pos + 4), + id = deserializeBindingIdentifier(pos + 8); + const tsEnumDeclMembers = deserializeVecTSEnumMember(pos + 40); + const bodyStart = id.end + 1; return { type: 'TSEnumDeclaration', start: deserializeU32(pos), - end: deserializeU32(pos + 4), - id: deserializeBindingIdentifier(pos + 8), - members: deserializeVecTSEnumMember(pos + 40), + end, + id, + body: { type: 'TSEnumBody', start: bodyStart, end: end, members: tsEnumDeclMembers }, const: deserializeBool(pos + 72), declare: deserializeBool(pos + 73), }; diff --git a/npm/oxc-types/types.d.ts b/npm/oxc-types/types.d.ts index 352efeb4a1629..65bd75c91fb15 100644 --- a/npm/oxc-types/types.d.ts +++ b/npm/oxc-types/types.d.ts @@ -935,11 +935,16 @@ export interface TSThisParameter extends Span { export interface TSEnumDeclaration extends Span { type: 'TSEnumDeclaration'; id: BindingIdentifier; - members: Array; + body: TSEnumBody; const: boolean; declare: boolean; } +export interface TSEnumBody extends Span { + type: 'TSEnumBody'; + members: TSEnumMember[]; +} + export interface TSEnumMember extends Span { type: 'TSEnumMember'; id: TSEnumMemberName; diff --git a/tasks/coverage/snapshots/estree_typescript.snap b/tasks/coverage/snapshots/estree_typescript.snap index d327fb5267f91..809012c27df4a 100644 --- a/tasks/coverage/snapshots/estree_typescript.snap +++ b/tasks/coverage/snapshots/estree_typescript.snap @@ -2,7 +2,7 @@ commit: 15392346 estree_typescript Summary: AST Parsed : 10619/10725 (99.01%) -Positive Passed: 5495/10725 (51.24%) +Positive Passed: 5506/10725 (51.34%) Mismatch: tasks/coverage/typescript/tests/cases/compiler/APISample_Watch.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/APISample_WatchWithDefaults.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/APISample_WatchWithOwnWatchHost.ts @@ -1026,7 +1026,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/dynamicNames.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/dynamicNamesErrors.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/elaboratedErrorsOnNullableTargets01.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/elementAccessExpressionInternalComments.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts tasks/coverage/typescript/tests/cases/compiler/elidedJSImport1.ts Unexpected estree file content error: 1 != 2 @@ -1058,7 +1057,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/emitSuperCallBeforeEmit Mismatch: tasks/coverage/typescript/tests/cases/compiler/emitSuperCallBeforeEmitPropertyDeclarationAndParameterPropertyDeclaration1ES6.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/emitTopOfFileTripleSlashCommentOnNotEmittedNodeIfRemoveCommentsIsFalse.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/emptyEnum.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/emptyModuleName.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.ts @@ -1101,7 +1099,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithInfinityPropert Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithNaNProperty.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithNegativeInfinityProperty.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithNonLiteralStringInitializer.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithPrimitiveName.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithQuotedElementName1.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithQuotedElementName2.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/enumWithUnicodeEscape1.ts @@ -1343,10 +1340,10 @@ tasks/coverage/typescript/tests/cases/compiler/fakeInfinity1.ts serde_json::from_str(oxc_json) error: number out of range at line 32 column 27 tasks/coverage/typescript/tests/cases/compiler/fakeInfinity2.ts -serde_json::from_str(oxc_json) error: number out of range at line 41 column 29 +serde_json::from_str(oxc_json) error: number out of range at line 45 column 31 tasks/coverage/typescript/tests/cases/compiler/fakeInfinity3.ts -serde_json::from_str(oxc_json) error: number out of range at line 41 column 29 +serde_json::from_str(oxc_json) error: number out of range at line 45 column 31 Mismatch: tasks/coverage/typescript/tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/fatArrowSelf.ts @@ -1560,7 +1557,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/importedModuleClassName Mismatch: tasks/coverage/typescript/tests/cases/compiler/inKeywordAndUnknown.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/indexClassByNumber.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/indexIntoEnum.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/indexSignatureAndMappedType.ts Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/indexSignatureMustHaveTypeAnnotation.ts Unexpected token @@ -2375,7 +2371,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/outModuleConcatES6.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/outModuleConcatUmd.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/outModuleTripleSlashRefs.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/overEagerReturnTypeSpecialization.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/overload2.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/overloadAssignmentCompat.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/overloadCrash.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/overloadGenericFunctionWithRestArgs.ts @@ -3316,7 +3311,6 @@ Unexpected estree file content error: 1 != 2 Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnum1.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnum2.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnum3.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnum4.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnumPropertyAccess1.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts @@ -3474,7 +3468,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/es2023/intlNumberFor Mismatch: tasks/coverage/typescript/tests/cases/conformance/es2024/sharedMemory.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/Symbols/symbolProperty60.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/Symbols/symbolProperty61.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/Symbols/symbolType19.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/Symbols/symbolType20.ts Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/es6/arrowFunction/disallowLineTerminatorBeforeArrow.ts Line terminator not permitted before arrow @@ -4262,7 +4255,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/thisKeyw Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeAssertions/constAssertionOnEnum.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeAssertions/constAssertions.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/TypeGuardWithEnumUnion.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardEnums.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThis.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardIntersectionTypes.ts @@ -4463,7 +4455,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/externalModules/verb Mismatch: tasks/coverage/typescript/tests/cases/conformance/externalModules/verbatimModuleSyntaxInternalImportEquals.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/externalModules/verbatimModuleSyntaxNoElisionCJS.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/externalModules/verbatimModuleSyntaxRestrictionsCJS.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/externalModules/verbatimModuleSyntaxRestrictionsESM.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/fixSignatureCaching.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/functions/functionImplementationErrors.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/functions/functionImplementations.ts @@ -5093,8 +5084,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/E Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts An enum member cannot have a numeric name. Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration1.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration2.d.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration2.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration3.d.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration3.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnumDeclaration5.ts