From d8b9909bd8df193306de7ff6f1204f3ac0963076 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Thu, 5 Sep 2024 01:50:18 +0000 Subject: [PATCH] fix(semantic): `IdentifierReference` within `TSPropertySignature` cannot reference type-only import binding (#5441) close: #5435 The behavior of `IdentifierReference` in `TSPropertySignature` is the same as in `TSTypeQuery`, both allow only reference value bindings and type-only import bindings. I still use `ReferenceFlags::TSTypeQuery` here because I want to avoid producing many changes unrelated to the bug in this PR. I will refactor it in the follow-up PR soon --- crates/oxc_semantic/src/builder.rs | 12 +++- .../signatures/property-with-type-import.snap | 64 +++++++++++++++++++ .../signatures/property-with-type-import.ts | 7 ++ .../signatures/property-computed-name.snap | 2 +- tasks/coverage/semantic_typescript.snap | 18 ------ 5 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.snap create mode 100644 crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.ts diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index a1715dcb1..47a9f0495 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -1830,6 +1830,14 @@ impl<'a> SemanticBuilder<'a> { AstKind::TSInterfaceHeritage(_) => { self.current_reference_flags = ReferenceFlags::Type; } + AstKind::TSPropertySignature(signature) => { + if signature.key.is_expression() { + // interface A { [prop]: string } + // ^^^^^ The property can reference value or [`SymbolFlags::TypeImport`] symbol + self.current_reference_flags = + ReferenceFlags::Read | ReferenceFlags::TSTypeQuery; // TODO: Should use another flag + } + } AstKind::TSTypeQuery(_) => { // type A = typeof a; // ^^^^^^^^ @@ -1962,8 +1970,10 @@ impl<'a> SemanticBuilder<'a> { } } AstKind::MemberExpression(_) + | AstKind::ExportNamedDeclaration(_) | AstKind::TSTypeQuery(_) - | AstKind::ExportNamedDeclaration(_) => { + // Clear the reference flags that are set in AstKind::PropertySignature + | AstKind::PropertyKey(_) => { self.current_reference_flags = ReferenceFlags::empty(); } AstKind::AssignmentTarget(_) => self.current_reference_flags -= ReferenceFlags::Write, diff --git a/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.snap b/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.snap new file mode 100644 index 000000000..9b43e0cc3 --- /dev/null +++ b/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.snap @@ -0,0 +1,64 @@ +--- +source: crates/oxc_semantic/tests/main.rs +input_file: crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.ts +--- +[ + { + "children": [ + { + "children": [], + "flags": "ScopeFlags(StrictMode)", + "id": 1, + "node": "TSTypeAliasDeclaration", + "symbols": [] + }, + { + "children": [], + "flags": "ScopeFlags(StrictMode)", + "id": 2, + "node": "TSInterfaceDeclaration", + "symbols": [] + } + ], + "flags": "ScopeFlags(StrictMode | Top)", + "id": 0, + "node": "Program", + "symbols": [ + { + "flags": "SymbolFlags(TypeImport)", + "id": 0, + "name": "X", + "node": "ImportDefaultSpecifier", + "references": [ + { + "flags": "ReferenceFlags(Type | TSTypeQuery)", + "id": 0, + "name": "X", + "node_id": 15 + } + ] + }, + { + "flags": "SymbolFlags(TypeAlias)", + "id": 1, + "name": "B", + "node": "TSTypeAliasDeclaration", + "references": [ + { + "flags": "ReferenceFlags(Type)", + "id": 1, + "name": "B", + "node_id": 19 + } + ] + }, + { + "flags": "SymbolFlags(Export | Interface)", + "id": 2, + "name": "A", + "node": "TSInterfaceDeclaration", + "references": [] + } + ] + } +] diff --git a/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.ts b/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.ts new file mode 100644 index 000000000..da4d768c6 --- /dev/null +++ b/crates/oxc_semantic/tests/fixtures/oxc/type-declarations/signatures/property-with-type-import.ts @@ -0,0 +1,7 @@ +import type X from 'mod'; + +type B = number; + +export interface A { + [X]: B +} \ No newline at end of file diff --git a/crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaration/signatures/property-computed-name.snap b/crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaration/signatures/property-computed-name.snap index adeb38b62..14f6fb3ef 100644 --- a/crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaration/signatures/property-computed-name.snap +++ b/crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaration/signatures/property-computed-name.snap @@ -31,7 +31,7 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/type-declaratio "node": "VariableDeclarator(x)", "references": [ { - "flags": "ReferenceFlags(Read)", + "flags": "ReferenceFlags(Read | TSTypeQuery)", "id": 0, "name": "x", "node_id": 14 diff --git a/tasks/coverage/semantic_typescript.snap b/tasks/coverage/semantic_typescript.snap index 43d97fbc8..0d3dc7641 100644 --- a/tasks/coverage/semantic_typescript.snap +++ b/tasks/coverage/semantic_typescript.snap @@ -12996,9 +12996,6 @@ rebuilt : ScopeId(0): ["A", "B"] Scope children mismatch: after transform: ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(3), ScopeId(5), ScopeId(7), ScopeId(8), ScopeId(10)] rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)] -Reference flags mismatch: -after transform: ReferenceId(12): ReferenceFlags(Type) -rebuilt : ReferenceId(0): ReferenceFlags(Read) Unresolved references mismatch: after transform: ["Extract", "Parameters"] rebuilt : [] @@ -14600,15 +14597,6 @@ rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(4), ScopeId(6), Sc Symbol reference IDs mismatch: after transform: SymbolId(0): [ReferenceId(0), ReferenceId(1), ReferenceId(2), ReferenceId(3)] rebuilt : SymbolId(0): [ReferenceId(0), ReferenceId(1), ReferenceId(2)] -Reference flags mismatch: -after transform: ReferenceId(1): ReferenceFlags(Type) -rebuilt : ReferenceId(0): ReferenceFlags(Read) -Reference flags mismatch: -after transform: ReferenceId(2): ReferenceFlags(Type) -rebuilt : ReferenceId(1): ReferenceFlags(Read) -Reference flags mismatch: -after transform: ReferenceId(3): ReferenceFlags(Type) -rebuilt : ReferenceId(2): ReferenceFlags(Read) tasks/coverage/typescript/tests/cases/compiler/interfaceImplementation5.ts semantic error: Bindings mismatch: @@ -31028,12 +31016,6 @@ rebuilt : SymbolId(2): [] Symbol reference IDs mismatch: after transform: SymbolId(4): [ReferenceId(12)] rebuilt : SymbolId(3): [] -Reference flags mismatch: -after transform: ReferenceId(1): ReferenceFlags(Type) -rebuilt : ReferenceId(0): ReferenceFlags(Read) -Reference flags mismatch: -after transform: ReferenceId(3): ReferenceFlags(Type) -rebuilt : ReferenceId(1): ReferenceFlags(Read) tasks/coverage/typescript/tests/cases/conformance/classes/classExpression.ts semantic error: Missing SymbolId: M