From c3d8a85eb5ab75e1ab4fc3044aab320ea98132c7 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Sat, 27 Apr 2024 22:08:02 +0800 Subject: [PATCH] feat(semantic): report that enum member must have initializer (#3113) See https://www.typescriptlang.org/play/?target=99#code/KYOwrgtgBAglDeAoKKoEMoF4oFk0BcALAOgGcBLEACgEYBKAGmVQCMmBfRRUSKAIQTMUGbACIaAJgDMopqihtEnRABtg+KADMwIAMZYoVOlgB8USVIDc3cNADCg+SK07dRuaw6IgA --- crates/oxc_semantic/src/checker/typescript.rs | 30 +++++++++++++++++++ .../transform_conformance/typescript.snap.md | 18 ++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/crates/oxc_semantic/src/checker/typescript.rs b/crates/oxc_semantic/src/checker/typescript.rs index 48b069832..b0e690231 100644 --- a/crates/oxc_semantic/src/checker/typescript.rs +++ b/crates/oxc_semantic/src/checker/typescript.rs @@ -25,6 +25,7 @@ impl EarlyErrorTypeScript { check_ts_type_parameter_declaration(declaration, ctx); } AstKind::TSModuleDeclaration(decl) => check_ts_module_declaration(decl, ctx), + AstKind::TSEnumDeclaration(decl) => check_ts_enum_declaration(decl, ctx), _ => {} } } @@ -158,3 +159,32 @@ fn check_ts_module_declaration<'a>(decl: &TSModuleDeclaration<'a>, ctx: &Semanti } } } + +fn check_ts_enum_declaration(decl: &TSEnumDeclaration<'_>, ctx: &SemanticBuilder<'_>) { + #[derive(Debug, Error, Diagnostic)] + #[error("Enum member must have initializer.")] + #[diagnostic()] + struct EnumMemberMustHaveInitializer(#[label] Span); + + let mut need_initializer = false; + + decl.members.iter().for_each(|member| { + if let Some(initializer) = &member.initializer { + need_initializer = !matches!( + initializer, + // A = 1 + Expression::NumericLiteral(_) + // B = A + | Expression::Identifier(_) + // C = E.D + | Expression::MemberExpression(_) + // D = 1 + 2 + | Expression::BinaryExpression(_) + // E = -1 + | Expression::UnaryExpression(_) + ); + } else if need_initializer { + ctx.error(EnumMemberMustHaveInitializer(member.span)); + } + }); +} diff --git a/tasks/transform_conformance/typescript.snap.md b/tasks/transform_conformance/typescript.snap.md index e06414256..663a7982e 100644 --- a/tasks/transform_conformance/typescript.snap.md +++ b/tasks/transform_conformance/typescript.snap.md @@ -983,14 +983,16 @@ var A = (A => { ``` # babel/packages/babel-plugin-transform-typescript/test/fixtures/enum/non-foldable-constant/input.ts -```typescript -var E = (E => { - const a = Math.sin(1); - E[E['a'] = a] = 'a'; - const b = 1 + a; - E[E['b'] = b] = 'b'; - return E; -})(E || {}); +```error + + × Enum member must have initializer. + ╭─[babel/packages/babel-plugin-transform-typescript/test/fixtures/enum/non-foldable-constant/input.ts:3:5] + 2 │ a = Math.sin(1), + 3 │ b, + · ─ + 4 │ } + ╰──── + ```