fix(isolated-declarations): strip re-export attributes (#25090)

## Summary

- transform declaration-less named exports instead of cloning them unchanged
- preserve re-export specifiers, source, and type modifiers while omitting import attributes from declaration output
- retain existing empty-export marker behavior

Stacked on #25089.
This commit is contained in:
camc314 committed 2026-07-29 17:25:26 +00:00
1 parent ecc666a4b1
commit 468b970613
4 files changed
+39 -11

No files matched your search

+12 -5
View File
@@ -285,16 +285,23 @@ impl<'a> IsolatedDeclarations<'a> {
transformed_count += 1;
need_empty_export_marker = false;
}
ModuleDeclaration::ExportAllDeclaration(decl) => {
let new_decl = self.transform_export_all_declaration(decl);
self.scope.visit_export_all_declaration(&new_decl);
transformed_stmts[idx] =
Some(Statement::ExportAllDeclaration(new_decl));
transformed_count += 1;
need_empty_export_marker = false;
}
ModuleDeclaration::ExportNamedDeclaration(decl) => {
if decl.declaration.is_none() {
need_empty_export_marker = false;
}
if let Some(new_decl) = self.transform_export_named_declaration(decl) {
self.scope.visit_export_named_declaration(&new_decl);
transformed_stmts[idx] =
Some(Statement::ExportNamedDeclaration(new_decl));
} else if decl.declaration.is_none() {
need_empty_export_marker = false;
self.scope.visit_export_named_declaration(decl);
transformed_stmts[idx] = Some(stmt.clone_in(self.allocator()));
} else {
// Declaration couldn't be transformed; preserve as-is
transformed_stmts[idx] = Some(stmt.clone_in(self.allocator()));
@@ -304,7 +311,7 @@ impl<'a> IsolatedDeclarations<'a> {
ModuleDeclaration::ImportDeclaration(_) => {
// We must transform this in the end, because we need to know all references
}
module_declaration => {
module_declaration @ ModuleDeclaration::TSNamespaceExportDeclaration(_) => {
self.scope.visit_module_declaration(module_declaration);
transformed_stmts[idx] = Some(stmt.clone_in(self.allocator()));
transformed_count += 1;
+22 -5
View File
@@ -6,18 +6,35 @@ use oxc_str::Str;
use crate::{IsolatedDeclarations, diagnostics::default_export_inferred};
impl<'a> IsolatedDeclarations<'a> {
pub(crate) fn transform_export_all_declaration(
&self,
prev_decl: &ExportAllDeclaration<'a>,
) -> ArenaBox<'a, ExportAllDeclaration<'a>> {
ExportAllDeclaration::boxed(
prev_decl.span,
prev_decl.exported.clone_in(self.allocator()),
prev_decl.source.clone(),
None,
prev_decl.export_kind,
self,
)
}
pub(crate) fn transform_export_named_declaration(
&mut self,
prev_decl: &ExportNamedDeclaration<'a>,
) -> Option<ArenaBox<'a, ExportNamedDeclaration<'a>>> {
let decl = self.transform_declaration(prev_decl.declaration.as_ref()?, false)?;
let declaration = match &prev_decl.declaration {
Some(decl) => Some(self.transform_declaration(decl, false)?),
None => None,
};
Some(ExportNamedDeclaration::boxed(
prev_decl.span,
Some(decl),
[],
None,
ImportOrExportKind::Value,
declaration,
prev_decl.specifiers.clone_in(self.allocator()),
prev_decl.source.clone(),
prev_decl.export_kind,
None,
self,
))
@@ -10,3 +10,5 @@ export { Foo as "non-identifier" } from "./foo";
// Re-export with import attributes
export { data } from "./data.json" with { type: "json" };
export * from "./data.json" with { type: "json" };
export * as data from "./data.json" with { type: "json" };
@@ -9,4 +9,6 @@ export type { Foo } from "./foo";
export { type Foo, Bar } from "./foo";
export { "default" as Foo } from "./foo";
export { Foo as "non-identifier" } from "./foo";
export { data } from "./data.json" with { type: "json" };
export { data } from "./data.json";
export * from "./data.json";
export * as data from "./data.json";