Skip to content

Commit

Permalink
refactor(semantic): move determining references flags for export spec…
Browse files Browse the repository at this point in the history
…ifier 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`.
  • Loading branch information
Dunqing committed Dec 16, 2024
1 parent dec5fb1 commit 6e4cf14
Showing 1 changed file with 13 additions and 14 deletions.
27 changes: 13 additions & 14 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down

0 comments on commit 6e4cf14

Please sign in to comment.