refactor(semantic): move determining references flags for export specifier to visit_export_named_declaration (#7924)

``` ts
export type { a };
export { type b };
```

In the above cases, `a` and `b` are both type-only references. Before, we handled them in `visit_export_named_declaration` and `visit_export_specifier`, but it doesn't look intuitive due to we need to determine
if `ExportNamedSpecifier` is a type-only in `visit_export_specifier ` by checking if `current_reference_flags` is a type, and also needs to set it back before exit node.

This PR moves determining reference flags from `visit_export_specifier` to `visit_export_named_declaration` so that we don't need to check `current_reference_flags` and set it back because here we can always know the
 if `ExportSpecifierNamed` is type-only by `ExportNamedDeclaration::export_kind::is_type`.
This commit is contained in:
Dunqing 2024-12-16 02:26:53 +00:00
parent 596aead0e9
commit b8d2bd2eba

View file

@ -1865,10 +1865,20 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
if let Some(declaration) = &it.declaration {
self.visit_declaration(declaration);
}
if it.export_kind.is_type() {
self.current_reference_flags = ReferenceFlags::Type;
for specifier in &it.specifiers {
// `export type { a }` or `export { type a }` -> `a` is a type reference
if it.export_kind.is_type() || specifier.export_kind.is_type() {
self.current_reference_flags = ReferenceFlags::Type;
} else {
// If the export specifier is not a explicit type export, we consider it as a potential
// type and value reference. If it references to a value in the end, we would delete the
// `ReferenceFlags::Type` flag in `fn resolve_references_for_current_scope`.
self.current_reference_flags = ReferenceFlags::Read | ReferenceFlags::Type;
}
self.visit_export_specifier(specifier);
}
self.visit_export_specifiers(&it.specifiers);
if let Some(source) = &it.source {
self.visit_string_literal(source);
}
@ -1884,21 +1894,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
self.visit_span(&it.span);
self.current_node_flags |= NodeFlags::ExportSpecifier;
let prev_reference_flags = self.current_reference_flags;
// `export type { a }` or `export { type a }` -> `a` is a type reference
if prev_reference_flags.is_type() || it.export_kind.is_type() {
self.current_reference_flags = ReferenceFlags::Type;
} else {
// If the export specifier is not a explicit type export, we consider it as a potential
// type and value reference. If it references to a value in the end, we would delete the
// `ReferenceFlags::Type` flag in `fn resolve_references_for_current_scope`.
self.current_reference_flags = ReferenceFlags::Read | ReferenceFlags::Type;
}
self.visit_module_export_name(&it.local);
self.visit_module_export_name(&it.exported);
self.current_reference_flags = prev_reference_flags;
self.current_node_flags -= NodeFlags::ExportSpecifier;
self.leave_node(kind);