diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 80dfd277f..e6ece6045 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -1,6 +1,9 @@ //! Semantic Builder -use std::cell::{Cell, RefCell}; +use std::{ + cell::{Cell, RefCell}, + mem, +}; use rustc_hash::FxHashMap; @@ -1789,7 +1792,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { fn visit_simple_assignment_target(&mut self, it: &SimpleAssignmentTarget<'a>) { let kind = AstKind::SimpleAssignmentTarget(self.alloc(it)); self.enter_node(kind); - let prev_reference_flags = self.current_reference_flags; // Except that the read-write flags has been set in visit_assignment_expression // and visit_update_expression, this is always a write-only reference here. if !self.current_reference_flags.is_write() { @@ -1819,7 +1821,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { self.visit_member_expression(it.to_member_expression()); } } - self.current_reference_flags = prev_reference_flags; self.leave_node(kind); } @@ -1828,10 +1829,8 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { it: &AssignmentTargetPropertyIdentifier<'a>, ) { // NOTE: AstKind doesn't exists! - let prev_reference_flags = self.current_reference_flags; self.current_reference_flags = ReferenceFlags::Write; self.visit_identifier_reference(&it.binding); - self.current_reference_flags = prev_reference_flags; if let Some(init) = &it.init { self.visit_expression(init); } @@ -1850,10 +1849,8 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { ExportDefaultDeclarationKind::Identifier(it) => { // `export default ident` // ^^^^^ -> can reference both type/value symbols - let prev_reference_flags = self.current_reference_flags; self.current_reference_flags = ReferenceFlags::Read | ReferenceFlags::Type; self.visit_identifier_reference(it); - self.current_reference_flags = prev_reference_flags; } match_expression!(ExportDefaultDeclarationKind) => { self.visit_expression(it.to_expression()); @@ -1868,13 +1865,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { if let Some(declaration) = &it.declaration { self.visit_declaration(declaration); } - // let prev_reference_flags = self.current_reference_flags; if it.export_kind.is_type() { self.current_reference_flags = ReferenceFlags::Type; } self.visit_export_specifiers(&it.specifiers); - // self.current_reference_flags = prev_reference_flags; - if let Some(source) = &it.source { self.visit_string_literal(source); } @@ -1914,14 +1908,12 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { let kind = AstKind::TSExportAssignment(self.alloc(it)); self.enter_node(kind); self.visit_span(&it.span); - let prev_reference_flags = self.current_reference_flags; // export = a; // ^ can reference type/value symbols if it.expression.is_identifier_reference() { self.current_reference_flags = ReferenceFlags::Read | ReferenceFlags::Type; } self.visit_expression(&it.expression); - self.current_reference_flags = prev_reference_flags; self.leave_node(kind); } } @@ -2140,11 +2132,12 @@ impl<'a> SemanticBuilder<'a> { /// Resolve reference flags for the current ast node. #[inline] - fn resolve_reference_usages(&self) -> ReferenceFlags { + fn resolve_reference_usages(&mut self) -> ReferenceFlags { if self.current_reference_flags.is_empty() { ReferenceFlags::Read } else { - self.current_reference_flags + // Take the current reference flags so that we can reset it to empty + mem::take(&mut self.current_reference_flags) } } } diff --git a/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.snap b/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.snap new file mode 100644 index 000000000..70dd01211 --- /dev/null +++ b/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.snap @@ -0,0 +1,50 @@ +--- +source: crates/oxc_semantic/tests/main.rs +input_file: crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.ts +--- +[ + { + "children": [ + { + "children": [], + "flags": "ScopeFlags(StrictMode)", + "id": 1, + "node": "TSInterfaceDeclaration", + "symbols": [] + } + ], + "flags": "ScopeFlags(StrictMode | Top)", + "id": 0, + "node": "Program", + "symbols": [ + { + "flags": "SymbolFlags(Import)", + "id": 0, + "name": "forwardRef", + "node": "ImportSpecifier(forwardRef)", + "references": [ + { + "flags": "ReferenceFlags(Read)", + "id": 1, + "name": "forwardRef", + "node_id": 19 + } + ] + }, + { + "flags": "SymbolFlags(Interface)", + "id": 1, + "name": "MenuTriggerProps", + "node": "TSInterfaceDeclaration", + "references": [] + }, + { + "flags": "SymbolFlags(BlockScopedVariable | ConstVariable)", + "id": 2, + "name": "MenuTrigger", + "node": "VariableDeclarator(MenuTrigger)", + "references": [] + } + ] + } +] diff --git a/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.ts b/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.ts new file mode 100644 index 000000000..ec2b65bed --- /dev/null +++ b/crates/oxc_semantic/tests/fixtures/oxc/ts/exports/named/interface-heritage.ts @@ -0,0 +1,3 @@ +import { forwardRef } from "react"; +export interface MenuTriggerProps extends Object {} +export const MenuTrigger = forwardRef(); diff --git a/tasks/coverage/snapshots/semantic_typescript.snap b/tasks/coverage/snapshots/semantic_typescript.snap index 6a91b4dbe..1a981f99f 100644 --- a/tasks/coverage/snapshots/semantic_typescript.snap +++ b/tasks/coverage/snapshots/semantic_typescript.snap @@ -36818,9 +36818,6 @@ rebuilt : ScopeId(19): ["key", "obj"] Bindings mismatch: after transform: ScopeId(26): ["T", "a"] rebuilt : ScopeId(21): ["a"] -Reference flags mismatch for "Monkey": -after transform: ReferenceId(7): ReferenceFlags(Type) -rebuilt : ReferenceId(2): ReferenceFlags(Read) Unresolved references mismatch: after transform: ["Partial", "Readonly"] rebuilt : [] @@ -40376,9 +40373,6 @@ rebuilt : SymbolId(0): Span { start: 62, end: 63 } Symbol redeclarations mismatch for "B": after transform: SymbolId(1): [Span { start: 62, end: 63 }] rebuilt : SymbolId(0): [] -Reference flags mismatch for "B": -after transform: ReferenceId(1): ReferenceFlags(Type) -rebuilt : ReferenceId(0): ReferenceFlags(Read) tasks/coverage/typescript/tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts semantic error: Bindings mismatch: