Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions crates/oxc_linter/src/rules/eslint/no_redeclare.rs
Original file line number Diff line number Diff line change
@@ -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([
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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();
}
60 changes: 30 additions & 30 deletions crates/oxc_linter/src/snapshots/eslint_no_redeclare.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -12,217 +12,217 @@ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

× 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
· ╰── `a` has already been declared here
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'b' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
· ╰── 'a' is already defined.
╰────

⚠ 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.
Expand Down
Loading