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 (#8134)

fixes #7879 (comment)

TLDR is curently here:

https://github.com/oxc-project/oxc/blob/cdd121bfa4a66d5b2cf72a444f35e82daf81d11e/crates/oxc_semantic/src/builder.rs#L2130-L2135

`self.current_reference_flags.is_empty()` is not empty, which causes the current ref flags to be used (this is incorrect, we should be using a fresh version of reference flags). Buy setting ref flags to `None` on exit export node, this issue is avoided

`export` **BEFORE** the reference ( incorrect reference flags)

https://playground.oxc.rs/#eNpVjjuOwzAMRK8isElj7A/YxtttkVOkkR3aECCJBskkdgzdPZISG0ilGc3DcFbooQUXJmI1q/m3bJIZmII5fHx2lg9/p4hzTXWZsCL3N+RekB3qvRUxRyKDs2I8S61cEzRA0K7Al1geWaLaGVrlCzbgXdRNS08T7mYJHfnNKdsoA3GAdrBeMDUwWRbk3Jh1adn0jtYPUMsj5hOA8vP1/QuZ6OmMI5Yx2QQX3eCebLBx9K8FlYvK5I+ebiW9InckOX4uSOkBCrdvkw==

`export` **AFTER** the reference ( correct reference flags)

https://playground.oxc.rs/#eNpVjj2uwjAQhK9ibZMmen/Sa0JHwSlonLCJLNm70a6BhMh3xzEEQeUZz6fZWaCDBlwYWaJZzN6KSaYXDqb6+m6tVLsjHQmnknfeqpoDs8EpIp208Et6Q+I8Yum5ffTcqh3UwNAsIGdaH50p2gmaKGeswTuKm9aOR3yZObTsNxfFkvYsAZreesVUw2hFUXJj1mvLpl9o+YBoZcB8AlD/fn7/IRMdn3DAdUw2wZHr3YMNlgb/XFA4isL+4Pm6pheUljXHjwUp3QEtmnBd

this PR fixes this issue by resetting the reference flags after exising an export stmt
  • Loading branch information
camc314 committed Dec 27, 2024
1 parent 74572de commit 79af100
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 79af100

Please sign in to comment.