From 3b248b3615696a3e231caa96d0de69c06b78dc68 Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Sun, 18 Aug 2024 15:09:36 +0200 Subject: [PATCH] refactor(noNodejsModules): ignore type-only imports (#3674) --- CHANGELOG.md | 12 +++++++++++ .../src/lint/correctness/no_nodejs_modules.rs | 11 +++++++++- .../correctness/noNodejsModules/valid.ts | 2 ++ .../correctness/noNodejsModules/valid.ts.snap | 2 ++ crates/biome_js_syntax/src/import_ext.rs | 20 +++++++++---------- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f2160844187..1cd671096ff3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -282,6 +282,18 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Jayllyz +- [noNodejsModules](https://biomejs.dev/linter/rules/no-nodejs-modules/) now ignores type-only imports ([#1674](https://github.com/biomejs/biome/issues/1674)). + + The rule no longer reports type-only imports such as: + + ```ts + import type assert from "assert"; + import type * as assert2 from "assert"; + ``` + + Contributed by @Conaclos + + #### Bug fixes - Don't request alt text for elements hidden from assistive technologies ([#3316](https://github.com/biomejs/biome/issues/3316)). Contributed by @robintown diff --git a/crates/biome_js_analyze/src/lint/correctness/no_nodejs_modules.rs b/crates/biome_js_analyze/src/lint/correctness/no_nodejs_modules.rs index 8ee7266a8173..9d5ce826d630 100644 --- a/crates/biome_js_analyze/src/lint/correctness/no_nodejs_modules.rs +++ b/crates/biome_js_analyze/src/lint/correctness/no_nodejs_modules.rs @@ -3,7 +3,8 @@ use biome_analyze::{ context::RuleContext, declare_lint_rule, Ast, Rule, RuleDiagnostic, RuleSource, }; use biome_console::markup; -use biome_js_syntax::{inner_string_text, AnyJsImportLike}; +use biome_js_syntax::{inner_string_text, AnyJsImportClause, AnyJsImportLike}; +use biome_rowan::AstNode; use biome_rowan::TextRange; declare_lint_rule! { @@ -48,6 +49,14 @@ impl Rule for NoNodejsModules { if node.is_in_ts_module_declaration() { return None; } + if let AnyJsImportLike::JsModuleSource(module_source) = &node { + if let Some(import_clause) = module_source.parent::() { + if import_clause.type_token().is_some() { + // Ignore type-only imports + return None; + } + } + } let module_name = node.module_name_token()?; is_node_builtin_module(&inner_string_text(&module_name)) .then_some(module_name.text_trimmed_range()) diff --git a/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts b/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts index 2cf05c93d405..00c890516837 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts +++ b/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts @@ -1 +1,3 @@ +import type assert from "assert"; +import type * as assert2 from "assert"; declare module "node:fs" {} \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts.snap b/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts.snap index 40259c4ee532..e79f09d03cf5 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts.snap +++ b/crates/biome_js_analyze/tests/specs/correctness/noNodejsModules/valid.ts.snap @@ -4,5 +4,7 @@ expression: valid.ts --- # Input ```ts +import type assert from "assert"; +import type * as assert2 from "assert"; declare module "node:fs" {} ``` diff --git a/crates/biome_js_syntax/src/import_ext.rs b/crates/biome_js_syntax/src/import_ext.rs index 880fbc2befcb..f7bc740cb06a 100644 --- a/crates/biome_js_syntax/src/import_ext.rs +++ b/crates/biome_js_syntax/src/import_ext.rs @@ -2,8 +2,7 @@ use crate::{ inner_string_text, AnyJsBinding, AnyJsImportClause, AnyJsModuleSource, AnyJsNamedImportSpecifier, JsCallExpression, JsDefaultImportSpecifier, JsImport, JsImportAssertion, JsImportCallExpression, JsModuleSource, JsNamedImportSpecifier, - JsNamespaceImportSpecifier, JsShorthandNamedImportSpecifier, JsSyntaxToken, - TsExternalModuleDeclaration, + JsNamespaceImportSpecifier, JsShorthandNamedImportSpecifier, JsSyntaxKind, JsSyntaxToken, }; use biome_rowan::{ declare_node_union, AstNode, SyntaxError, SyntaxNodeOptionExt, SyntaxResult, TokenText, @@ -312,9 +311,11 @@ impl AnyJsImportLike { } /// Check whether the js import specifier like is in a ts module declaration: + /// /// ```ts - /// declare "abc" {} + /// declare module "abc" {} /// ``` + /// /// ## Examples /// /// ``` @@ -333,14 +334,11 @@ impl AnyJsImportLike { /// ``` pub fn is_in_ts_module_declaration(&self) -> bool { // It first has to be a JsModuleSource - if !matches!(self, AnyJsImportLike::JsModuleSource(_)) { - return false; - } - // Then test whether its parent is a TsExternalModuleDeclaration - if let Some(parent_syntax_kind) = self.syntax().parent().kind() { - return TsExternalModuleDeclaration::can_cast(parent_syntax_kind); - } - false + matches!(self, AnyJsImportLike::JsModuleSource(_)) + && matches!( + self.syntax().parent().kind(), + Some(JsSyntaxKind::TS_EXTERNAL_MODULE_DECLARATION) + ) } }