diff --git a/CHANGELOG.md b/CHANGELOG.md index 1089099f296..6e9c30fb03f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -201,6 +201,15 @@ if no error diagnostics are emitted. - Fix [`noDuplicateCase`](https://docs.rome.tools/lint/rules/noDuplicateCase/) rule that erroneously reported as equals the strings literals `"'"` and `'"'` [#4706](https://github.com/rome/tools/issues/4706). +- Improve [`noInnerDeclarations`](https://docs.rome.tools/lint/rules/noInnerDeclarations/) + + Now, the rule doesn't report false-positives about ambient _TypeScript_ declarations. + For example, the following code is no longer reported by the rule: + + ```ts + declare var foo; + ``` + - Improve [`useEnumInitializers`](https://docs.rome.tools/lint/rules/useEnumInitializers/) The rule now reports all uninitialized members of an enum in a single diagnostic. diff --git a/crates/rome_js_analyze/src/analyzers/correctness/no_inner_declarations.rs b/crates/rome_js_analyze/src/analyzers/correctness/no_inner_declarations.rs index 49c253b3015..3446c40358d 100644 --- a/crates/rome_js_analyze/src/analyzers/correctness/no_inner_declarations.rs +++ b/crates/rome_js_analyze/src/analyzers/correctness/no_inner_declarations.rs @@ -1,9 +1,6 @@ use rome_analyze::{context::RuleContext, declare_rule, Ast, Rule, RuleDiagnostic}; use rome_console::markup; -use rome_js_syntax::{ - AnyJsDeclaration, JsExport, JsFileSource, JsFunctionBody, JsModuleItemList, JsScript, - JsStatementList, JsStaticInitializationBlockClassMember, -}; +use rome_js_syntax::{AnyJsDeclaration, JsFileSource, JsStatementList, JsSyntaxKind}; use rome_rowan::AstNode; use crate::control_flow::AnyJsControlFlowRoot; @@ -106,33 +103,55 @@ impl Rule for NoInnerDeclarations { fn run(ctx: &RuleContext) -> Self::Signals { let decl = ctx.query(); let parent = match decl { + AnyJsDeclaration::TsDeclareFunctionDeclaration(x) => { + if ctx.source_type::().is_module() { + // In strict mode (implied by esm), function declarations are block-scoped. + return None; + } + // ignore TsDeclareStatement + x.syntax().parent()?.parent()? + } AnyJsDeclaration::JsFunctionDeclaration(x) => { if ctx.source_type::().is_module() { // In strict mode (implied by esm), function declarations are block-scoped. - None - } else { - x.syntax().parent() + return None; } + x.syntax().parent()? } AnyJsDeclaration::JsVariableDeclaration(x) => { - if x.is_var() { - // ignore parent (JsVariableStatement or JsVariableDeclarationClause) - x.syntax().parent()?.parent() - } else { - None + if !x.is_var() { + return None; } + let mut parent = x.syntax().parent()?; + while matches!( + parent.kind(), + JsSyntaxKind::JS_VARIABLE_STATEMENT + | JsSyntaxKind::JS_VARIABLE_DECLARATION_CLAUSE + | JsSyntaxKind::TS_DECLARE_STATEMENT + ) { + parent = parent.parent()?; + } + parent + } + _ => { + return None; } - _ => None, - }?; - if JsExport::can_cast(parent.kind()) || JsModuleItemList::can_cast(parent.kind()) { + }; + if matches!( + parent.kind(), + JsSyntaxKind::JS_EXPORT + | JsSyntaxKind::TS_EXPORT_DECLARE_CLAUSE + | JsSyntaxKind::JS_MODULE_ITEM_LIST + ) { return None; } if let Some(stmt_list) = JsStatementList::cast(parent) { - let parent_kind = stmt_list.syntax().parent()?.kind(); - if JsFunctionBody::can_cast(parent_kind) - || JsScript::can_cast(parent_kind) - || JsStaticInitializationBlockClassMember::can_cast(parent_kind) - { + if matches!( + stmt_list.syntax().parent()?.kind(), + JsSyntaxKind::JS_FUNCTION_BODY + | JsSyntaxKind::JS_SCRIPT + | JsSyntaxKind::JS_STATIC_INITIALIZATION_BLOCK_CLASS_MEMBER + ) { return None; } } diff --git a/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts b/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts new file mode 100644 index 00000000000..0edbdfdb45f --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts @@ -0,0 +1,7 @@ +declare var x; + +export declare var y; + +declare function f(); + +export declare function g(); diff --git a/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts.snap b/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts.snap new file mode 100644 index 00000000000..b489b9fc5ee --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/correctness/noInnerDeclarations/valid-moduke.ts.snap @@ -0,0 +1,17 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: valid-moduke.ts +--- +# Input +```js +declare var x; + +export declare var y; + +declare function f(); + +export declare function g(); + +``` + +