Skip to content

Commit

Permalink
feat(transformer/typescript): if the binding exists, the identifier r…
Browse files Browse the repository at this point in the history
…eference is not renamed
  • Loading branch information
Dunqing committed May 23, 2024
1 parent 57d2bca commit 3c55da6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 16 deletions.
4 changes: 2 additions & 2 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ impl<'a> Traverse<'a> for Transformer<'a> {
self.x0_typescript.transform_identifier_reference(ident, ctx);
}

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

fn enter_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {
Expand Down
29 changes: 22 additions & 7 deletions crates/oxc_transformer/src/typescript/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use oxc_syntax::{
number::{NumberBase, ToJsInt32, ToJsString},
operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator},
};
use oxc_traverse::TraverseCtx;
use rustc_hash::FxHashMap;

use crate::context::Ctx;
Expand Down Expand Up @@ -37,6 +38,7 @@ impl<'a> TypeScriptEnum<'a> {
&mut self,
decl: &Box<'a, TSEnumDeclaration<'a>>,
is_export: bool,
ctx: &TraverseCtx<'a>,
) -> Option<Statement<'a>> {
if decl.modifiers.contains(ModifierKind::Declare) {
return None;
Expand All @@ -61,7 +63,7 @@ impl<'a> TypeScriptEnum<'a> {
// Foo[Foo["X"] = 0] = "X";
let enum_name = decl.id.name.clone();
let is_already_declared = self.enums.contains_key(&enum_name);
let statements = self.transform_ts_enum_members(&decl.members, &enum_name);
let statements = self.transform_ts_enum_members(&decl.members, &enum_name, ctx);
let body = self.ctx.ast.function_body(decl.span, self.ctx.ast.new_vec(), statements);
let r#type = FunctionType::FunctionExpression;
let callee = self.ctx.ast.plain_function(r#type, SPAN, None, params, Some(body));
Expand Down Expand Up @@ -128,6 +130,7 @@ impl<'a> TypeScriptEnum<'a> {
&mut self,
members: &Vec<'a, TSEnumMember<'a>>,
enum_name: &Atom<'a>,
ctx: &TraverseCtx<'a>,
) -> Vec<'a, Statement<'a>> {
let mut statements = self.ctx.ast.new_vec();
let mut prev_constant_value = Some(ConstantValue::Number(-1.0));
Expand All @@ -153,12 +156,24 @@ impl<'a> TypeScriptEnum<'a> {
None => {
prev_constant_value = None;
let mut new_initializer = self.ctx.ast.copy(initializer);
IdentifierReferenceRename::new(
enum_name.clone(),
previous_enum_members.clone(),
&self.ctx,
)
.visit_expression(&mut new_initializer);

// If the initializer is a binding identifier,
// and it is not a binding in the current scope and parent scopes,
// we need to rename it to the enum name. e.g. `d = c` to `d = A.c`
// same behavior in https://github.com/babel/babel/blob/610897a9a96c5e344e77ca9665df7613d2f88358/packages/babel-plugin-transform-typescript/src/enum.ts#L145-L150
let has_binding = matches!(
&new_initializer,
Expression::Identifier(ident) if ctx.scopes().has_binding(ctx.current_scope_id(), &ident.name)
);
if !has_binding {
IdentifierReferenceRename::new(
enum_name.clone(),
previous_enum_members.clone(),
&self.ctx,
)
.visit_expression(&mut new_initializer);
}

new_initializer
}
Some(constant_value) => {
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_transformer/src/typescript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ impl<'a> TypeScript<'a> {
self.annotations.transform_statements_on_exit(stmts);
}

pub fn transform_statement(&mut self, stmt: &mut Statement<'a>) {
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>, ctx: &TraverseCtx<'a>) {
let new_stmt = match stmt {
match_declaration!(Statement) => {
if let Declaration::TSEnumDeclaration(ts_enum_decl) = &stmt.to_declaration() {
self.r#enum.transform_ts_enum(ts_enum_decl, false)
self.r#enum.transform_ts_enum(ts_enum_decl, false, ctx)
} else {
None
}
Expand All @@ -150,7 +150,7 @@ impl<'a> TypeScript<'a> {
stmt.to_module_declaration_mut()
{
if let Some(Declaration::TSEnumDeclaration(ts_enum_decl)) = &decl.declaration {
self.r#enum.transform_ts_enum(ts_enum_decl, true)
self.r#enum.transform_ts_enum(ts_enum_decl, true, ctx)
} else {
None
}
Expand Down Expand Up @@ -180,7 +180,7 @@ impl<'a> TypeScript<'a> {
pub fn transform_identifier_reference(
&mut self,
ident: &mut IdentifierReference<'a>,
ctx: &TraverseCtx,
ctx: &TraverseCtx<'a>,
) {
if !ctx.parent().is_ts_interface_heritage() && !ctx.parent().is_ts_type_reference() {
self.reference_collector.visit_identifier_reference(ident);
Expand Down
5 changes: 2 additions & 3 deletions tasks/transform_conformance/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 4bd1b2c2

Passed: 309/351
Passed: 310/351

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

# babel-plugin-transform-typescript (123/154)
# babel-plugin-transform-typescript (124/154)
* enum/mix-references/input.ts
* enum/scoped/input.ts
* enum/ts5.0-const-foldable/input.ts
* exports/declared-types/input.ts
* imports/enum-value/input.ts
* imports/type-only-export-specifier-2/input.ts
* namespace/contentious-names/input.ts
* namespace/empty-removed/input.ts
Expand Down

0 comments on commit 3c55da6

Please sign in to comment.