mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(transformer/typescript): if the binding exists, the identifier reference is not renamed (#3387)
Related: https://github.com/oxc-project/oxc/discussions/3251#discussioncomment-9528247
This commit is contained in:
parent
d4371e8f95
commit
241e8d1899
4 changed files with 30 additions and 16 deletions
|
|
@ -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>) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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));
|
||||
|
|
@ -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));
|
||||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 4bd1b2c2
|
||||
|
||||
Passed: 313/351
|
||||
Passed: 314/351
|
||||
|
||||
# All Passed:
|
||||
* babel-preset-react
|
||||
|
|
@ -21,12 +21,11 @@ Passed: 313/351
|
|||
* opts/optimizeConstEnums/input.ts
|
||||
* opts/rewriteImportExtensions/input.ts
|
||||
|
||||
# babel-plugin-transform-typescript (127/154)
|
||||
# babel-plugin-transform-typescript (128/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/empty-removed/input.ts
|
||||
* namespace/mutable-fail/input.ts
|
||||
|
|
|
|||
Loading…
Reference in a new issue