diff --git a/crates/oxc_linter/src/rules/eslint/no_redeclare.rs b/crates/oxc_linter/src/rules/eslint/no_redeclare.rs index 8e770c79d28df..6a98ca7313022 100644 --- a/crates/oxc_linter/src/rules/eslint/no_redeclare.rs +++ b/crates/oxc_linter/src/rules/eslint/no_redeclare.rs @@ -1,10 +1,14 @@ use javascript_globals::GLOBALS; + use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; -use oxc_span::Span; +use oxc_span::{ModuleKind, Span}; use oxc_syntax::symbol::SymbolId; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; fn no_redeclare_diagnostic(name: &str, decl_span: Span, re_decl_span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("'{name}' is already defined.")).with_labels([ @@ -116,6 +120,11 @@ impl Rule for NoRedeclare { } } } + + fn should_run(&self, ctx: &ContextHost) -> bool { + // Modules run in their own scope, and don't conflict with existing globals + ctx.source_type().module_kind() == ModuleKind::Script + } } #[test] @@ -178,9 +187,23 @@ fn test() { ("type foo = 1; export function foo(): void; export function foo() { }", None), ]; - Tester::new(NoRedeclare::NAME, NoRedeclare::PLUGIN, pass, fail).test_and_snapshot(); + Tester::new(NoRedeclare::NAME, NoRedeclare::PLUGIN, pass, fail) + .change_rule_path_extension(".cts") + .test_and_snapshot(); let fail = vec![("var foo;", None, Some(serde_json::json!({ "globals": { "foo": false }})))]; - Tester::new(NoRedeclare::NAME, NoRedeclare::PLUGIN, vec![], fail).test(); + Tester::new(NoRedeclare::NAME, NoRedeclare::PLUGIN, vec![], fail) + .change_rule_path_extension(".cts") + .test(); + + let pass = vec![( + "import { performance } from 'node:perf_hooks'; (() => { performance })", + None, + Some(serde_json::json!({ "globals": { "performance": "readonly" }})), + )]; + + Tester::new(NoRedeclare::NAME, NoRedeclare::PLUGIN, pass, vec![]) + .change_rule_path_extension(".ts") + .test(); } diff --git a/crates/oxc_linter/src/snapshots/eslint_no_redeclare.snap b/crates/oxc_linter/src/snapshots/eslint_no_redeclare.snap index 711eae985dd5d..a9164ed3c33f6 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_redeclare.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_redeclare.snap @@ -2,7 +2,7 @@ source: crates/oxc_linter/src/tester.rs --- ⚠ eslint(no-redeclare): 'b' is already defined. - ╭─[no_redeclare.tsx:1:27] + ╭─[no_redeclare..cts:1:27] 1 │ switch(foo) { case a: var b = 3; · ┬ · ╰── 'b' is already defined. @@ -12,7 +12,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a = 3; var a = 10; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -20,7 +20,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a = {}; var a = []; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -28,7 +28,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── × Identifier `a` has already been declared - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a; function a() {} · ┬ ┬ · │ ╰── It can not be redeclared here @@ -36,7 +36,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:10] + ╭─[no_redeclare..cts:1:10] 1 │ function a() {} function a() {} · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -44,7 +44,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a = function() { }; var a = function() { } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -52,7 +52,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a = function() { }; var a = new Date(); · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -60,7 +60,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a = 3; var a = 10; var a = 15; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -68,7 +68,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:16] + ╭─[no_redeclare..cts:1:16] 1 │ var a = 3; var a = 10; var a = 15; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -76,7 +76,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a; var a; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -84,7 +84,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:12] + ╭─[no_redeclare..cts:1:12] 1 │ export var a; var a; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -92,7 +92,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:24] + ╭─[no_redeclare..cts:1:24] 1 │ class C { static { var a; var a; } } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -100,7 +100,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:24] + ╭─[no_redeclare..cts:1:24] 1 │ class C { static { var a; { var a; } } } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -108,7 +108,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:26] + ╭─[no_redeclare..cts:1:26] 1 │ class C { static { { var a; } var a; } } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -116,7 +116,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:26] + ╭─[no_redeclare..cts:1:26] 1 │ class C { static { { var a; } { var a; } } } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -124,25 +124,25 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'Object' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var Object = 0; var Object = 0; var globalThis = 0; · ────── ╰──── ⚠ eslint(no-redeclare): 'Object' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:21] + ╭─[no_redeclare..cts:1:21] 1 │ var Object = 0; var Object = 0; var globalThis = 0; · ────── ╰──── ⚠ eslint(no-redeclare): 'globalThis' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:37] + ╭─[no_redeclare..cts:1:37] 1 │ var Object = 0; var Object = 0; var globalThis = 0; · ────────── ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a; var {a = 0, b: Object = 0} = {}; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -150,13 +150,13 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'Object' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:23] + ╭─[no_redeclare..cts:1:23] 1 │ var a; var {a = 0, b: Object = 0} = {}; · ────── ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:5] + ╭─[no_redeclare..cts:1:5] 1 │ var a; var {a = 0, b: globalThis = 0} = {}; · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -164,13 +164,13 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'globalThis' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:23] + ╭─[no_redeclare..cts:1:23] 1 │ var a; var {a = 0, b: globalThis = 0} = {}; · ────────── ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:20] + ╭─[no_redeclare..cts:1:20] 1 │ function f() { var a; var a; } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -178,7 +178,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:12] + ╭─[no_redeclare..cts:1:12] 1 │ function f(a, b = 1) { var a; var b;} · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -186,7 +186,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'b' is already defined. - ╭─[no_redeclare.tsx:1:15] + ╭─[no_redeclare..cts:1:15] 1 │ function f(a, b = 1) { var a; var b;} · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -194,7 +194,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:20] + ╭─[no_redeclare..cts:1:20] 1 │ function f() { var a; if (test) { var a; } } · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -202,7 +202,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'a' is already defined. - ╭─[no_redeclare.tsx:1:10] + ╭─[no_redeclare..cts:1:10] 1 │ for (var a, a;;); · ┬ ┬ · │ ╰── It can not be redeclare here. @@ -210,19 +210,19 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint(no-redeclare): 'undefined' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:17] + ╭─[no_redeclare..cts:1:17] 1 │ export function undefined(): void; export function undefined() { } · ───────── ╰──── ⚠ eslint(no-redeclare): 'undefined' is already defined as a built-in global variable. - ╭─[no_redeclare.tsx:1:52] + ╭─[no_redeclare..cts:1:52] 1 │ export function undefined(): void; export function undefined() { } · ───────── ╰──── ⚠ eslint(no-redeclare): 'foo' is already defined. - ╭─[no_redeclare.tsx:1:6] + ╭─[no_redeclare..cts:1:6] 1 │ type foo = 1; export function foo(): void; export function foo() { } · ─┬─ ─┬─ · │ ╰── It can not be redeclare here.