Skip to content

Commit

Permalink
fix(transformer/typescript): incorrect enum-related symbol_id/`refe…
Browse files Browse the repository at this point in the history
…rence_id` (#4660)

part of #4581
  • Loading branch information
Dunqing committed Aug 6, 2024
1 parent 03c643a commit 3987665
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 32 deletions.
36 changes: 24 additions & 12 deletions crates/oxc_transformer/src/typescript/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -238,7 +250,7 @@ impl<'a> TypeScriptEnum<'a> {
);
if !has_binding {
IdentifierReferenceRename::new(
enum_name.clone(),
param.name.clone(),
previous_enum_members.clone(),
ctx,
)
Expand Down Expand Up @@ -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()
};
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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);
Expand Down
22 changes: 2 additions & 20 deletions tasks/transform_conformance/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 12619ffe

Passed: 435/927
Passed: 453/927

# All Passed:
* babel-preset-react
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 3987665

Please sign in to comment.