Skip to content

Commit 3c55da6

Browse files
committed
feat(transformer/typescript): if the binding exists, the identifier reference is not renamed
1 parent 57d2bca commit 3c55da6

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

crates/oxc_transformer/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ impl<'a> Traverse<'a> for Transformer<'a> {
234234
self.x0_typescript.transform_identifier_reference(ident, ctx);
235235
}
236236

237-
fn enter_statement(&mut self, stmt: &mut Statement<'a>, _ctx: &mut TraverseCtx<'a>) {
238-
self.x0_typescript.transform_statement(stmt);
237+
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
238+
self.x0_typescript.transform_statement(stmt, ctx);
239239
}
240240

241241
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {

crates/oxc_transformer/src/typescript/enum.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use oxc_syntax::{
77
number::{NumberBase, ToJsInt32, ToJsString},
88
operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator},
99
};
10+
use oxc_traverse::TraverseCtx;
1011
use rustc_hash::FxHashMap;
1112

1213
use crate::context::Ctx;
@@ -37,6 +38,7 @@ impl<'a> TypeScriptEnum<'a> {
3738
&mut self,
3839
decl: &Box<'a, TSEnumDeclaration<'a>>,
3940
is_export: bool,
41+
ctx: &TraverseCtx<'a>,
4042
) -> Option<Statement<'a>> {
4143
if decl.modifiers.contains(ModifierKind::Declare) {
4244
return None;
@@ -61,7 +63,7 @@ impl<'a> TypeScriptEnum<'a> {
6163
// Foo[Foo["X"] = 0] = "X";
6264
let enum_name = decl.id.name.clone();
6365
let is_already_declared = self.enums.contains_key(&enum_name);
64-
let statements = self.transform_ts_enum_members(&decl.members, &enum_name);
66+
let statements = self.transform_ts_enum_members(&decl.members, &enum_name, ctx);
6567
let body = self.ctx.ast.function_body(decl.span, self.ctx.ast.new_vec(), statements);
6668
let r#type = FunctionType::FunctionExpression;
6769
let callee = self.ctx.ast.plain_function(r#type, SPAN, None, params, Some(body));
@@ -128,6 +130,7 @@ impl<'a> TypeScriptEnum<'a> {
128130
&mut self,
129131
members: &Vec<'a, TSEnumMember<'a>>,
130132
enum_name: &Atom<'a>,
133+
ctx: &TraverseCtx<'a>,
131134
) -> Vec<'a, Statement<'a>> {
132135
let mut statements = self.ctx.ast.new_vec();
133136
let mut prev_constant_value = Some(ConstantValue::Number(-1.0));
@@ -153,12 +156,24 @@ impl<'a> TypeScriptEnum<'a> {
153156
None => {
154157
prev_constant_value = None;
155158
let mut new_initializer = self.ctx.ast.copy(initializer);
156-
IdentifierReferenceRename::new(
157-
enum_name.clone(),
158-
previous_enum_members.clone(),
159-
&self.ctx,
160-
)
161-
.visit_expression(&mut new_initializer);
159+
160+
// If the initializer is a binding identifier,
161+
// and it is not a binding in the current scope and parent scopes,
162+
// we need to rename it to the enum name. e.g. `d = c` to `d = A.c`
163+
// same behavior in https://github.com/babel/babel/blob/610897a9a96c5e344e77ca9665df7613d2f88358/packages/babel-plugin-transform-typescript/src/enum.ts#L145-L150
164+
let has_binding = matches!(
165+
&new_initializer,
166+
Expression::Identifier(ident) if ctx.scopes().has_binding(ctx.current_scope_id(), &ident.name)
167+
);
168+
if !has_binding {
169+
IdentifierReferenceRename::new(
170+
enum_name.clone(),
171+
previous_enum_members.clone(),
172+
&self.ctx,
173+
)
174+
.visit_expression(&mut new_initializer);
175+
}
176+
162177
new_initializer
163178
}
164179
Some(constant_value) => {

crates/oxc_transformer/src/typescript/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ impl<'a> TypeScript<'a> {
136136
self.annotations.transform_statements_on_exit(stmts);
137137
}
138138

139-
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>) {
139+
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>, ctx: &TraverseCtx<'a>) {
140140
let new_stmt = match stmt {
141141
match_declaration!(Statement) => {
142142
if let Declaration::TSEnumDeclaration(ts_enum_decl) = &stmt.to_declaration() {
143-
self.r#enum.transform_ts_enum(ts_enum_decl, false)
143+
self.r#enum.transform_ts_enum(ts_enum_decl, false, ctx)
144144
} else {
145145
None
146146
}
@@ -150,7 +150,7 @@ impl<'a> TypeScript<'a> {
150150
stmt.to_module_declaration_mut()
151151
{
152152
if let Some(Declaration::TSEnumDeclaration(ts_enum_decl)) = &decl.declaration {
153-
self.r#enum.transform_ts_enum(ts_enum_decl, true)
153+
self.r#enum.transform_ts_enum(ts_enum_decl, true, ctx)
154154
} else {
155155
None
156156
}
@@ -180,7 +180,7 @@ impl<'a> TypeScript<'a> {
180180
pub fn transform_identifier_reference(
181181
&mut self,
182182
ident: &mut IdentifierReference<'a>,
183-
ctx: &TraverseCtx,
183+
ctx: &TraverseCtx<'a>,
184184
) {
185185
if !ctx.parent().is_ts_interface_heritage() && !ctx.parent().is_ts_type_reference() {
186186
self.reference_collector.visit_identifier_reference(ident);

tasks/transform_conformance/babel.snap.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
commit: 4bd1b2c2
22

3-
Passed: 309/351
3+
Passed: 310/351
44

55
# All Passed:
66
* babel-preset-react
@@ -21,12 +21,11 @@ Passed: 309/351
2121
* opts/optimizeConstEnums/input.ts
2222
* opts/rewriteImportExtensions/input.ts
2323

24-
# babel-plugin-transform-typescript (123/154)
24+
# babel-plugin-transform-typescript (124/154)
2525
* enum/mix-references/input.ts
2626
* enum/scoped/input.ts
2727
* enum/ts5.0-const-foldable/input.ts
2828
* exports/declared-types/input.ts
29-
* imports/enum-value/input.ts
3029
* imports/type-only-export-specifier-2/input.ts
3130
* namespace/contentious-names/input.ts
3231
* namespace/empty-removed/input.ts

0 commit comments

Comments
 (0)