From d7a5d8c101fe37db6d8cfc34bb95f5a2673e22d9 Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Wed, 29 Nov 2023 14:24:08 +0100 Subject: [PATCH] fix(js_semantic): add semantic scope to mapped types (#958) --- CHANGELOG.md | 2 ++ .../noRedeclare/valid-mapped-types.ts | 9 ++++++ .../noRedeclare/valid-mapped-types.ts.snap | 19 +++++++++++++ crates/biome_js_semantic/src/events.rs | 28 +++++++++++++++---- .../src/content/docs/internals/changelog.mdx | 2 ++ 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts create mode 100644 crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e2cfe8447d..7f6f27ab8b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom - Fix [#918](https://github.com/biomejs/biome/issues/918), [useSimpleNumberKeys](https://biomejs.dev/linter/rules/use-simple-number-keys) no longer repports false positive on comments. Contributed by @kalleep +- Fix [#953](https://github.com/biomejs/biome/issues/953), [noRedeclare](https://biomejs.dev/linter/rules/no-redeclare) no longer reports type parameters with the same name in different mapped types as redeclarations. Contributed by @Conaclos + ### Parser ## 1.4.0 (2023-11-27) diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts b/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts new file mode 100644 index 000000000000..36dbd412a773 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts @@ -0,0 +1,9 @@ +// See https://github.com/biomejs/biome/issues/953 +type X = never; +type Y = never; +export const MyMappingPbToGql: { + [key in X]: never; +} = {}; +export const MyOtherMappingPbToGql: { + [key in Y]: never; +} = {}; diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts.snap b/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts.snap new file mode 100644 index 000000000000..2198a0068e97 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noRedeclare/valid-mapped-types.ts.snap @@ -0,0 +1,19 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: valid-mapped-types.ts +--- +# Input +```js +// See https://github.com/biomejs/biome/issues/953 +type X = never; +type Y = never; +export const MyMappingPbToGql: { + [key in X]: never; +} = {}; +export const MyOtherMappingPbToGql: { + [key in Y]: never; +} = {}; + +``` + + diff --git a/crates/biome_js_semantic/src/events.rs b/crates/biome_js_semantic/src/events.rs index fc629d7d0c19..df575105b237 100644 --- a/crates/biome_js_semantic/src/events.rs +++ b/crates/biome_js_semantic/src/events.rs @@ -279,6 +279,7 @@ impl SemanticEventExtractor { /// See [SemanticEvent] for a more detailed description of which events [SyntaxNode] generates. #[inline] pub fn enter(&mut self, node: &JsSyntaxNode) { + // If you push a scope for a given node type, don't forget to also update `Self::leave`. match node.kind() { JS_IDENTIFIER_BINDING | TS_IDENTIFIER_BINDING | TS_TYPE_PARAMETER_NAME => { self.enter_identifier_binding(&AnyJsIdentifierBinding::unwrap_cast(node.clone())); @@ -355,9 +356,15 @@ impl SemanticEventExtractor { fn enter_any_type(&mut self, node: &AnyTsType) { if node.in_conditional_true_type() { self.push_conditional_true_scope(node); - } else if let Some(node) = node.as_ts_function_type() { + return; + } + let node = node.syntax(); + if matches!( + node.kind(), + JsSyntaxKind::TS_FUNCTION_TYPE | JsSyntaxKind::TS_MAPPED_TYPE + ) { self.push_scope( - node.syntax().text_range(), + node.text_range(), ScopeHoisting::DontHoistDeclarationsToParent, false, ); @@ -589,8 +596,9 @@ impl SemanticEventExtractor { #[inline] pub fn leave(&mut self, node: &JsSyntaxNode) { match node.kind() { - JS_MODULE | JS_SCRIPT => self.pop_scope(node.text_range()), - JS_FUNCTION_DECLARATION + JS_MODULE + | JS_SCRIPT + | JS_FUNCTION_DECLARATION | JS_FUNCTION_EXPORT_DEFAULT_DECLARATION | JS_FUNCTION_EXPRESSION | JS_ARROW_FUNCTION_EXPRESSION @@ -636,8 +644,14 @@ impl SemanticEventExtractor { fn leave_any_type(&mut self, node: &AnyTsType) { if node.in_conditional_true_type() { self.pop_scope(node.syntax().text_range()); - } else if let Some(node) = node.as_ts_function_type() { - self.pop_scope(node.syntax().text_range()); + return; + } + let node = node.syntax(); + if matches!( + node.kind(), + JsSyntaxKind::TS_FUNCTION_TYPE | JsSyntaxKind::TS_MAPPED_TYPE + ) { + self.pop_scope(node.text_range()); } } @@ -922,6 +936,8 @@ impl Iterator for SemanticEventIterator { if let Some(e) = self.extractor.pop() { break Some(e); } else { + // Check that every scope was pop. + debug_assert!(self.extractor.scopes.is_empty()); break None; } } diff --git a/website/src/content/docs/internals/changelog.mdx b/website/src/content/docs/internals/changelog.mdx index 84a64c86bc6d..f7839e84ae1b 100644 --- a/website/src/content/docs/internals/changelog.mdx +++ b/website/src/content/docs/internals/changelog.mdx @@ -56,6 +56,8 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom - Fix [#918](https://github.com/biomejs/biome/issues/918), [useSimpleNumberKeys](https://biomejs.dev/linter/rules/use-simple-number-keys) no longer repports false positive on comments. Contributed by @kalleep +- Fix [#953](https://github.com/biomejs/biome/issues/953), [noRedeclare](https://biomejs.dev/linter/rules/no-redeclare) no longer reports type parameters with the same name in different mapped types as redeclarations. Contributed by @Conaclos + ### Parser ## 1.4.0 (2023-11-27)