mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter/eslint): Implement no-label-var (#4087)
Rule Detail: [link](https://eslint.org/docs/latest/rules/no-label-var) Co-authored-by: Don Isaac <donald.isaac@gmail.com>
This commit is contained in:
parent
2a169d1969
commit
7ec0c0bdd4
3 changed files with 107 additions and 0 deletions
|
|
@ -75,6 +75,7 @@ mod eslint {
|
|||
pub mod no_inner_declarations;
|
||||
pub mod no_irregular_whitespace;
|
||||
pub mod no_iterator;
|
||||
pub mod no_label_var;
|
||||
pub mod no_loss_of_precision;
|
||||
pub mod no_multi_str;
|
||||
pub mod no_new;
|
||||
|
|
@ -452,6 +453,7 @@ oxc_macros::declare_all_lint_rules! {
|
|||
eslint::no_case_declarations,
|
||||
eslint::no_class_assign,
|
||||
eslint::no_multi_str,
|
||||
eslint::no_label_var,
|
||||
eslint::require_await,
|
||||
eslint::no_compare_neg_zero,
|
||||
eslint::no_cond_assign,
|
||||
|
|
|
|||
79
crates/oxc_linter/src/rules/eslint/no_label_var.rs
Normal file
79
crates/oxc_linter/src/rules/eslint/no_label_var.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use oxc_ast::AstKind;
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::Span;
|
||||
|
||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
||||
|
||||
fn no_label_var_diagnostic(x0: &str, span0: Span, span1: Span) -> OxcDiagnostic {
|
||||
OxcDiagnostic::warn(format!(
|
||||
"eslint(no-label-var): Found identifier '{x0}' with the same name as a label."
|
||||
))
|
||||
.with_labels([
|
||||
span0.label(format!("Identifier '{x0}' found here.")),
|
||||
span1.label("Label with the same name."),
|
||||
])
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct NoLabelVar;
|
||||
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
///
|
||||
/// Disallow labels that share a name with a variable.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// This rule aims to create clearer code by disallowing the bad practice of creating a label
|
||||
/// that shares a name with a variable that is in scope.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```javascript
|
||||
/// var x = foo;
|
||||
/// function bar() {
|
||||
/// x:
|
||||
/// for (;;) {
|
||||
/// break x;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
NoLabelVar,
|
||||
style,
|
||||
);
|
||||
|
||||
impl Rule for NoLabelVar {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
let AstKind::LabeledStatement(labeled_stmt) = node.kind() else { return };
|
||||
|
||||
if let Some(symbol_id) =
|
||||
ctx.scopes().find_binding(node.scope_id(), &labeled_stmt.label.name)
|
||||
{
|
||||
let decl_span = ctx.symbols().get_span(symbol_id);
|
||||
let label_decl = labeled_stmt.span.start;
|
||||
ctx.diagnostic(no_label_var_diagnostic(
|
||||
&labeled_stmt.label.name,
|
||||
decl_span,
|
||||
Span::new(label_decl, label_decl + 1),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec![
|
||||
"function bar() { q: for(;;) { break q; } } function foo () { var q = t; }",
|
||||
"function bar() { var x = foo; q: for(;;) { break q; } }",
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
"var x = foo; function bar() { x: for(;;) { break x; } }",
|
||||
"function bar() { var x = foo; x: for(;;) { break x; } }",
|
||||
"function bar(x) { x: for(;;) { break x; } }",
|
||||
];
|
||||
|
||||
Tester::new(NoLabelVar::NAME, pass, fail).test_and_snapshot();
|
||||
}
|
||||
26
crates/oxc_linter/src/snapshots/no_label_var.snap
Normal file
26
crates/oxc_linter/src/snapshots/no_label_var.snap
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
---
|
||||
⚠ eslint(no-label-var): Found identifier 'x' with the same name as a label.
|
||||
╭─[no_label_var.tsx:1:5]
|
||||
1 │ var x = foo; function bar() { x: for(;;) { break x; } }
|
||||
· ┬ ┬
|
||||
· │ ╰── Label with the same name.
|
||||
· ╰── Identifier 'x' found here.
|
||||
╰────
|
||||
|
||||
⚠ eslint(no-label-var): Found identifier 'x' with the same name as a label.
|
||||
╭─[no_label_var.tsx:1:22]
|
||||
1 │ function bar() { var x = foo; x: for(;;) { break x; } }
|
||||
· ┬ ┬
|
||||
· │ ╰── Label with the same name.
|
||||
· ╰── Identifier 'x' found here.
|
||||
╰────
|
||||
|
||||
⚠ eslint(no-label-var): Found identifier 'x' with the same name as a label.
|
||||
╭─[no_label_var.tsx:1:14]
|
||||
1 │ function bar(x) { x: for(;;) { break x; } }
|
||||
· ┬ ┬
|
||||
· │ ╰── Label with the same name.
|
||||
· ╰── Identifier 'x' found here.
|
||||
╰────
|
||||
Loading…
Reference in a new issue