mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
fix(transformer): TS namespace transform do not track var decl names (#3501)
Don't track variable declaration or import binding names in TS namespace transform. Babel does, but it appears to be wrong. It's illegal to have a `var`/`let`/`const` declaration or import in same scope as a TS namespace declaration with same binding. https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAQTgMyhEcDkUCmBDAYxkwG4AoAOzxBwGcxCdE4BvAXzLIIgtvgCE4AXjgBGclRr1GcQSzJxFcADY54AD3Icyq+AGFhYidToMCTA-KUq1cTWW0A3PFDgARQ+Monp596wUlXTstMiA
This commit is contained in:
parent
8d2beff2fe
commit
837776e1ab
3 changed files with 42 additions and 57 deletions
|
|
@ -30,7 +30,7 @@ impl<'a> TypeScript<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Collect all binding names. Such as function name and class name.
|
||||
// Collect function/class/enum/namespace binding names
|
||||
let mut names: FxHashSet<Atom<'a>> = FxHashSet::default();
|
||||
|
||||
// Recreate the statements vec for memory efficiency.
|
||||
|
|
@ -59,12 +59,11 @@ impl<'a> TypeScript<'a> {
|
|||
}
|
||||
}
|
||||
new_stmts.push(Statement::TSModuleDeclaration(decl));
|
||||
continue;
|
||||
}
|
||||
match_module_declaration!(Statement) => {
|
||||
if let Statement::ExportNamedDeclaration(export_decl) = &stmt {
|
||||
if let Some(Declaration::TSModuleDeclaration(decl)) =
|
||||
&export_decl.declaration
|
||||
{
|
||||
Statement::ExportNamedDeclaration(ref export_decl) => {
|
||||
match &export_decl.declaration {
|
||||
Some(Declaration::TSModuleDeclaration(decl)) => {
|
||||
if !decl.modifiers.is_contains_declare() {
|
||||
if !self.options.allow_namespaces {
|
||||
self.ctx.error(namespace_not_supported(decl.span));
|
||||
|
|
@ -91,37 +90,32 @@ impl<'a> TypeScript<'a> {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stmt.to_module_declaration().bound_names(&mut |id| {
|
||||
names.insert(id.name.clone());
|
||||
});
|
||||
new_stmts.push(stmt);
|
||||
if let TSModuleDeclarationName::Identifier(id) = &decl.id {
|
||||
names.insert(id.name.clone());
|
||||
}
|
||||
}
|
||||
Some(decl) => match decl {
|
||||
Declaration::FunctionDeclaration(_)
|
||||
| Declaration::ClassDeclaration(_)
|
||||
| Declaration::TSEnumDeclaration(_) => {
|
||||
names.insert(decl.id().as_ref().unwrap().name.clone());
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Collect bindings from class, function, variable and enum declarations
|
||||
Statement::FunctionDeclaration(ref decl) => {
|
||||
names.insert(decl.id.as_ref().unwrap().name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::ClassDeclaration(ref decl) => {
|
||||
names.insert(decl.id.as_ref().unwrap().name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::TSEnumDeclaration(ref decl) => {
|
||||
names.insert(decl.id.name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::VariableDeclaration(ref decl) => {
|
||||
decl.bound_names(&mut |id| {
|
||||
names.insert(id.name.clone());
|
||||
});
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
_ => {
|
||||
new_stmts.push(stmt);
|
||||
// Collect bindings from class, function and enum declarations
|
||||
Statement::FunctionDeclaration(_)
|
||||
| Statement::ClassDeclaration(_)
|
||||
| Statement::TSEnumDeclaration(_) => {
|
||||
names.insert(stmt.to_declaration().id().as_ref().unwrap().name.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
|
||||
program.body = new_stmts;
|
||||
|
|
@ -185,24 +179,7 @@ impl<'a> TypeScript<'a> {
|
|||
}
|
||||
new_stmts.push(transformed);
|
||||
}
|
||||
}
|
||||
Statement::ClassDeclaration(ref decl) => {
|
||||
names.insert(decl.id.as_ref().unwrap().name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::FunctionDeclaration(ref decl) => {
|
||||
names.insert(decl.id.as_ref().unwrap().name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::TSEnumDeclaration(ref enum_decl) => {
|
||||
names.insert(enum_decl.id.name.clone());
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
Statement::VariableDeclaration(ref decl) => {
|
||||
decl.bound_names(&mut |id| {
|
||||
names.insert(id.name.clone());
|
||||
});
|
||||
new_stmts.push(stmt);
|
||||
continue;
|
||||
}
|
||||
Statement::ExportNamedDeclaration(export_decl) => {
|
||||
// NB: `ExportNamedDeclaration` with no declaration (e.g. `export {x}`) is not
|
||||
|
|
@ -252,14 +229,20 @@ impl<'a> TypeScript<'a> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Collect bindings from class, function and enum declarations
|
||||
Statement::ClassDeclaration(_)
|
||||
| Statement::FunctionDeclaration(_)
|
||||
| Statement::TSEnumDeclaration(_) => {
|
||||
names.insert(stmt.to_declaration().id().as_ref().unwrap().name.clone());
|
||||
}
|
||||
Statement::TSTypeAliasDeclaration(_)
|
||||
| Statement::TSInterfaceDeclaration(_)
|
||||
| Statement::TSImportEqualsDeclaration(_) => {}
|
||||
_ => {
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
| Statement::TSImportEqualsDeclaration(_) => continue,
|
||||
_ => {}
|
||||
}
|
||||
new_stmts.push(stmt);
|
||||
}
|
||||
|
||||
if new_stmts.is_empty() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 4bd1b2c2
|
||||
|
||||
Passed: 480/928
|
||||
Passed: 478/926
|
||||
|
||||
# All Passed:
|
||||
* babel-preset-react
|
||||
|
|
@ -445,7 +445,7 @@ Passed: 480/928
|
|||
* opts/optimizeConstEnums/input.ts
|
||||
* opts/rewriteImportExtensions/input.ts
|
||||
|
||||
# babel-plugin-transform-typescript (136/152)
|
||||
# babel-plugin-transform-typescript (134/150)
|
||||
* enum/mix-references/input.ts
|
||||
* enum/ts5.0-const-foldable/input.ts
|
||||
* exports/declared-types/input.ts
|
||||
|
|
|
|||
|
|
@ -91,5 +91,7 @@ pub(crate) const SKIP_TESTS: &[&str] = &[
|
|||
"typescript/test/fixtures/namespace/nested-shorthand-export/input.ts",
|
||||
"react-jsx-development/test/fixtures/cross-platform/self-inside-arrow/input.mjs",
|
||||
// Babel outputs is not correct
|
||||
"typescript/test/fixtures/namespace/clobber-import/input.ts",
|
||||
"typescript/test/fixtures/namespace/namespace-nested-module/input.ts",
|
||||
"typescript/test/fixtures/namespace/nested-destructuring/input.ts",
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in a new issue