mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(parser): preserve default import names in reexports (#28442)
Record `default` as the imported name when reexporting a default import, including aliases and exports declared before the import. Validated with scoped Rust checks, full conformance, parser bindings, allocation tracking. AI-assisted (Codex).
This commit is contained in:
1 parent
10e9fc7f81
commit
342151609b
2 files changed
+32
-7
No files matched your search
@@ -163,12 +163,9 @@ impl<'a> ModuleRecordBuilder<'a> {
|
||||
ImportImportName::Name(name) => {
|
||||
ExportImportName::Name(name.clone())
|
||||
}
|
||||
// `import d from "mod"`
|
||||
// `export { d }`
|
||||
// ^ this is local_name of ie
|
||||
ImportImportName::Default(_) => {
|
||||
ExportImportName::Name(ie.local_name.clone())
|
||||
}
|
||||
ImportImportName::Default(span) => ExportImportName::Name(
|
||||
NameSpan::new("default".into(), *span),
|
||||
),
|
||||
ImportImportName::NamespaceObject => unreachable!(),
|
||||
},
|
||||
export_name: ee.export_name.clone(),
|
||||
@@ -714,6 +711,34 @@ mod module_record_tests {
|
||||
assert_eq!(module_record.indirect_export_entries[0], export_entry);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reexport_imported_default() {
|
||||
for (source, exported) in [
|
||||
("import d from 'mod'; export { d };", "d"),
|
||||
("export { d as renamed }; import d from 'mod';", "renamed"),
|
||||
("import d from 'mod'; export { d as default };", "default"),
|
||||
] {
|
||||
let allocator = Allocator::default();
|
||||
let ret = Parser::new(&allocator, source, SourceType::mjs()).parse();
|
||||
assert!(ret.diagnostics.is_empty());
|
||||
assert!(ret.module_record.local_export_entries.is_empty());
|
||||
assert_eq!(ret.module_record.indirect_export_entries.len(), 1);
|
||||
let entry = &ret.module_record.indirect_export_entries[0];
|
||||
let import_start = u32::try_from(source.find("import d").unwrap()).unwrap() + 7;
|
||||
assert_eq!(
|
||||
entry.import_name,
|
||||
ExportImportName::Name(NameSpan::new(
|
||||
"default".into(),
|
||||
Span::sized(import_start, 1),
|
||||
))
|
||||
);
|
||||
let ExportExportName::Name(name) = &entry.export_name else { panic!() };
|
||||
assert_eq!(name.name, exported);
|
||||
assert_eq!(entry.module_request.as_ref().unwrap().name, "mod");
|
||||
assert!(matches!(entry.local_name, ExportLocalName::Null));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indirect_export_entries() {
|
||||
let allocator = Allocator::default();
|
||||
|
||||
@@ -801,7 +801,7 @@ describe("UTF-16 span", () => {
|
||||
"importName": {
|
||||
"end": 13,
|
||||
"kind": "Name",
|
||||
"name": "x",
|
||||
"name": "default",
|
||||
"start": 12,
|
||||
},
|
||||
"isType": false,
|
||||
|
||||
Reference in new issue
Block a user