fix(transformer/typescript): incorrect enum-related symbol_id/reference_id (#4660)

part of #4581
This commit is contained in:
Dunqing 2024-08-06 02:57:19 +00:00
parent 03c643a8af
commit 3987665490
2 changed files with 26 additions and 32 deletions

View file

@ -82,12 +82,13 @@ impl<'a> TypeScriptEnum<'a> {
func_scope_id,
AstNodeId::DUMMY,
);
ctx.scopes_mut().add_binding(func_scope_id, enum_name.to_compact_str(), param_symbol_id);
let ident = BindingIdentifier {
span: decl.id.span,
name: decl.id.name.clone(),
symbol_id: Cell::new(Some(param_symbol_id)),
};
let kind = ast.binding_pattern_kind_from_binding_identifier(ident);
let kind = ast.binding_pattern_kind_from_binding_identifier(ident.clone());
let id = ast.binding_pattern(kind, Option::<TSTypeAnnotation>::None, false);
// ((Foo) => {
@ -102,7 +103,8 @@ impl<'a> TypeScriptEnum<'a> {
// Foo[Foo["X"] = 0] = "X";
let is_already_declared = self.enums.contains_key(&enum_name);
let statements = self.transform_ts_enum_members(&decl.members, enum_name.clone(), ctx);
let statements = self.transform_ts_enum_members(&decl.members, &ident, ctx);
let body = ast.alloc_function_body(decl.span, ast.vec(), statements);
let callee = Expression::FunctionExpression(ctx.alloc(Function {
r#type: FunctionType::FunctionExpression,
@ -187,19 +189,29 @@ impl<'a> TypeScriptEnum<'a> {
Some(stmt)
}
#[allow(clippy::needless_pass_by_value)]
fn transform_ts_enum_members(
&mut self,
members: &Vec<'a, TSEnumMember<'a>>,
enum_name: Atom<'a>,
ctx: &TraverseCtx<'a>,
param: &BindingIdentifier<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Vec<'a, Statement<'a>> {
// TODO: Set `span` and `references_id` on all `IdentifierReference`s created here
let create_identifier_reference = |ctx: &mut TraverseCtx<'a>| {
let ident = ctx.create_reference_id(
param.span,
param.name.clone(),
param.symbol_id.get(),
ReferenceFlag::Read,
);
ctx.ast.expression_from_identifier_reference(ident)
};
let ast = ctx.ast;
let mut statements = ast.vec();
let mut prev_constant_value = Some(ConstantValue::Number(-1.0));
let mut previous_enum_members = self.enums.entry(enum_name.clone()).or_default().clone();
let mut previous_enum_members = self.enums.entry(param.name.clone()).or_default().clone();
let mut prev_member_name: Option<Atom<'a>> = None;
for member in members {
@ -238,7 +250,7 @@ impl<'a> TypeScriptEnum<'a> {
);
if !has_binding {
IdentifierReferenceRename::new(
enum_name.clone(),
param.name.clone(),
previous_enum_members.clone(),
ctx,
)
@ -276,7 +288,7 @@ impl<'a> TypeScriptEnum<'a> {
}
} else if let Some(prev_member_name) = prev_member_name {
let self_ref = {
let obj = ast.expression_identifier_reference(SPAN, &enum_name);
let obj = create_identifier_reference(ctx);
let expr = ctx.ast.expression_string_literal(SPAN, prev_member_name);
ast.member_expression_computed(SPAN, obj, expr, false).into()
};
@ -292,7 +304,7 @@ impl<'a> TypeScriptEnum<'a> {
// Foo["x"] = init
let member_expr = {
let obj = ast.expression_identifier_reference(SPAN, &enum_name);
let obj = create_identifier_reference(ctx);
let expr = ast.expression_string_literal(SPAN, member_name);
ast.member_expression_computed(SPAN, obj, expr, false)
@ -304,7 +316,7 @@ impl<'a> TypeScriptEnum<'a> {
// Foo[Foo["x"] = init] = "x"
if !is_str {
let member_expr = {
let obj = ast.expression_identifier_reference(SPAN, &enum_name);
let obj = create_identifier_reference(ctx);
ast.member_expression_computed(SPAN, obj, expr, false)
};
let left = ast.simple_assignment_target_member_expression(member_expr);
@ -317,9 +329,9 @@ impl<'a> TypeScriptEnum<'a> {
statements.push(ast.statement_expression(member.span, expr));
}
self.enums.insert(enum_name.clone(), previous_enum_members.clone());
self.enums.insert(param.name.clone(), previous_enum_members.clone());
let enum_ref = ast.expression_identifier_reference(SPAN, enum_name);
let enum_ref = create_identifier_reference(ctx);
// return Foo;
let return_stmt = ast.statement_return(SPAN, Some(enum_ref));
statements.push(return_stmt);

View file

@ -1,6 +1,6 @@
commit: 12619ffe
Passed: 435/927
Passed: 453/927
# All Passed:
* babel-preset-react
@ -445,33 +445,15 @@ Passed: 435/927
* opts/optimizeConstEnums/input.ts
* opts/rewriteImportExtensions/input.ts
# babel-plugin-transform-typescript (91/151)
# babel-plugin-transform-typescript (109/151)
* class/accessor-allowDeclareFields-false/input.ts
* class/accessor-allowDeclareFields-true/input.ts
* enum/boolean-value/input.ts
* enum/const/input.ts
* enum/constant-folding/input.ts
* enum/enum-merging-inner-references/input.ts
* enum/enum-merging-inner-references-shadow/input.ts
* enum/export/input.ts
* enum/inferred/input.ts
* enum/inner-references/input.ts
* enum/mix-references/input.ts
* enum/non-foldable-constant/input.ts
* enum/non-scoped/input.ts
* enum/outer-references/input.ts
* enum/scoped/input.ts
* enum/string-value/input.ts
* enum/string-value-template/input.ts
* enum/string-values-computed/input.ts
* enum/ts5.0-const-foldable/input.ts
* exports/declared-types/input.ts
* exports/export-const-enums/input.ts
* exports/export-import=/input.ts
* exports/interface/input.ts
* imports/elide-type-referenced-in-imports-equal-no/input.ts
* imports/enum-id/input.ts
* imports/enum-value/input.ts
* imports/import=-module/input.ts
* imports/only-remove-type-imports/input.ts
* imports/type-only-export-specifier-2/input.ts