Skip to content

Commit

Permalink
fix(semantic): reference flags not correctly resolved when after an e…
Browse files Browse the repository at this point in the history
…xport stmt
  • Loading branch information
camc314 committed Dec 27, 2024
1 parent 6b51e6d commit ca9fba8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,14 @@ fn test() {
// ",
// None,
// ),
(
"import { Bar } from './bar';
export type { Baz } from './baz';
export class Foo extends Bar {}
",
None,
),
];

let fail = vec![
Expand Down
28 changes: 15 additions & 13 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1861,25 +1861,27 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
self.visit_declaration(declaration);
}

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);
}

if let Some(source) = &it.source {
self.visit_string_literal(source);
self.visit_export_specifiers(&it.specifiers);
} else {
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);
}
}
if let Some(with_clause) = &it.with_clause {
self.visit_with_clause(with_clause);
}

self.leave_node(kind);
}

Expand Down
43 changes: 43 additions & 0 deletions crates/oxc_semantic/tests/fixtures/oxc/ts/issue-7879.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: crates/oxc_semantic/tests/main.rs
input_file: crates/oxc_semantic/tests/fixtures/oxc/ts/issue-7879.ts
---
[
{
"children": [
{
"children": [],
"flags": "ScopeFlags(StrictMode)",
"id": 1,
"node": "Class(Foo)",
"symbols": []
}
],
"flags": "ScopeFlags(StrictMode | Top)",
"id": 0,
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(Import)",
"id": 0,
"name": "Bar",
"node": "ImportSpecifier(Bar)",
"references": [
{
"flags": "ReferenceFlags(Read)",
"id": 0,
"name": "Bar",
"node_id": 17
}
]
},
{
"flags": "SymbolFlags(Class)",
"id": 1,
"name": "Foo",
"node": "Class(Foo)",
"references": []
}
]
}
]
4 changes: 4 additions & 0 deletions crates/oxc_semantic/tests/fixtures/oxc/ts/issue-7879.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Bar } from "./bar";
export type { Baz } from "./baz";

export class Foo extends Bar {}

0 comments on commit ca9fba8

Please sign in to comment.