mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(semantic): ModuleRecord's indirect_export_entires missing reexported imports (#2792)
local_name has `name` and `span`. We can't directly compare ExportEntry's local_name and ImportEntry's local_name. because the span is never equal.
This commit is contained in:
parent
7b6a4d0690
commit
b6e493bd78
3 changed files with 45 additions and 16 deletions
|
|
@ -7,7 +7,7 @@ use oxc_ast::{ast::*, AstKind, Trivias, Visit};
|
|||
use oxc_diagnostics::Error;
|
||||
use oxc_span::{CompactStr, SourceType, Span};
|
||||
use oxc_syntax::{
|
||||
module_record::{ExportLocalName, ModuleRecord},
|
||||
module_record::{ExportImportName, ExportLocalName, ModuleRecord},
|
||||
operator::AssignmentOperator,
|
||||
};
|
||||
|
||||
|
|
@ -324,18 +324,20 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
|
||||
fn add_export_flag_for_export_identifier(&mut self) {
|
||||
self.module_record.local_export_entries.iter().for_each(|entry| match &entry.local_name {
|
||||
ExportLocalName::Name(name_span) => {
|
||||
self.module_record.indirect_export_entries.iter().for_each(|entry| {
|
||||
if let ExportImportName::Name(name) = &entry.import_name {
|
||||
if let Some(symbol_id) = self.symbols.get_symbol_id_from_name(name.name()) {
|
||||
self.symbols.union_flag(symbol_id, SymbolFlags::Export);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.module_record.local_export_entries.iter().for_each(|entry| {
|
||||
if let ExportLocalName::Name(name_span) = &entry.local_name {
|
||||
if let Some(symbol_id) = self.scope.get_root_binding(name_span.name()) {
|
||||
self.symbols.union_flag(symbol_id, SymbolFlags::Export);
|
||||
}
|
||||
}
|
||||
ExportLocalName::Default(span) => {
|
||||
if let Some(symbol_id) = self.symbols.get_symbol_id_from_span(span) {
|
||||
self.symbols.union_flag(symbol_id, SymbolFlags::Export);
|
||||
}
|
||||
}
|
||||
ExportLocalName::Null => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,15 +85,14 @@ impl ModuleRecordBuilder {
|
|||
for ee in export_entries {
|
||||
// a. If ee.[[ModuleRequest]] is null, then
|
||||
if ee.module_request.is_none() {
|
||||
let local_name = match &ee.local_name {
|
||||
ExportLocalName::Name(name) => Some(name),
|
||||
let found_import_entry = match &ee.local_name {
|
||||
ExportLocalName::Name(name) => self
|
||||
.module_record
|
||||
.import_entries
|
||||
.iter()
|
||||
.find(|entry| entry.local_name.name() == name.name()),
|
||||
_ => None,
|
||||
};
|
||||
let found_import_entry = self
|
||||
.module_record
|
||||
.import_entries
|
||||
.iter()
|
||||
.find(|import_entry| Some(&import_entry.local_name) == local_name);
|
||||
match found_import_entry {
|
||||
// i. If ee.[[LocalName]] is not an element of importedBoundNames, then
|
||||
None => {
|
||||
|
|
@ -130,6 +129,7 @@ impl ModuleRecordBuilder {
|
|||
ImportImportName::NamespaceObject => unreachable!(),
|
||||
},
|
||||
export_name: ee.export_name.clone(),
|
||||
span: ee.span,
|
||||
..ExportEntry::default()
|
||||
};
|
||||
self.append_indirect_export_entry(export_entry);
|
||||
|
|
|
|||
|
|
@ -248,4 +248,31 @@ mod module_record_tests {
|
|||
assert_eq!(module_record.local_export_entries.len(), 1);
|
||||
assert_eq!(module_record.local_export_entries[0], export_entry);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indirect_export_entries() {
|
||||
let module_record =
|
||||
build("import { x } from 'mod';export { x };export * as ns from 'mod';");
|
||||
assert_eq!(module_record.indirect_export_entries.len(), 2);
|
||||
assert_eq!(
|
||||
module_record.indirect_export_entries[0],
|
||||
ExportEntry {
|
||||
module_request: Some(NameSpan::new("mod".into(), Span::new(18, 23))),
|
||||
span: Span::new(33, 34),
|
||||
import_name: ExportImportName::Name(NameSpan::new("x".into(), Span::new(9, 10))),
|
||||
export_name: ExportExportName::Name(NameSpan::new("x".into(), Span::new(33, 34))),
|
||||
local_name: ExportLocalName::Null,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
module_record.indirect_export_entries[1],
|
||||
ExportEntry {
|
||||
module_request: Some(NameSpan::new("mod".into(), Span::new(57, 62))),
|
||||
span: Span::new(0, 0),
|
||||
import_name: ExportImportName::All,
|
||||
export_name: ExportExportName::Name(NameSpan::new("ns".into(), Span::new(49, 51))),
|
||||
local_name: ExportLocalName::Null,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue