From 6189985e9e6d0af671d944ed1cee65cdbec0e856 Mon Sep 17 00:00:00 2001 From: Jose <48152124+JoSeBu1@users.noreply.github.com> Date: Sun, 17 Mar 2024 14:21:43 +0100 Subject: [PATCH] feat(linter): eslint/no-continue (#2742) Rule detail: https://eslint.org/docs/latest/rules/no-continue It's my first time in Rust, so I have a lot to learn from you. Maybe I do some silly mistakes. Sorry! --------- Co-authored-by: j.buendia --- crates/oxc_linter/src/rules.rs | 2 + .../src/rules/eslint/no_continue.rs | 70 +++++++++++++++++++ .../oxc_linter/src/snapshots/no_continue.snap | 31 ++++++++ 3 files changed, 103 insertions(+) create mode 100644 crates/oxc_linter/src/rules/eslint/no_continue.rs create mode 100644 crates/oxc_linter/src/snapshots/no_continue.snap diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 98e87b049..d1f46910c 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -56,6 +56,7 @@ mod eslint { pub mod no_const_assign; pub mod no_constant_binary_expression; pub mod no_constant_condition; + pub mod no_continue; pub mod no_control_regex; pub mod no_debugger; pub mod no_delete_var; @@ -372,6 +373,7 @@ oxc_macros::declare_all_lint_rules! { eslint::no_const_assign, eslint::no_constant_binary_expression, eslint::no_constant_condition, + eslint::no_continue, eslint::no_control_regex, eslint::no_debugger, eslint::no_delete_var, diff --git a/crates/oxc_linter/src/rules/eslint/no_continue.rs b/crates/oxc_linter/src/rules/eslint/no_continue.rs new file mode 100644 index 000000000..9dc83e109 --- /dev/null +++ b/crates/oxc_linter/src/rules/eslint/no_continue.rs @@ -0,0 +1,70 @@ +use crate::{context::LintContext, rule::Rule, AstNode}; +use oxc_ast::AstKind; +use oxc_diagnostics::{ + miette::{self, Diagnostic}, + thiserror::Error, +}; +use oxc_macros::declare_oxc_lint; +use oxc_span::Span; + +#[derive(Debug, Error, Diagnostic)] +#[error("eslint(no-continue): Unexpected use of `continue` statement.")] +#[diagnostic(severity(warning), help("Do not use the `continue` statement."))] +struct NoContinueDiagnostic(#[label] pub Span); + +#[derive(Debug, Default, Clone)] +pub struct NoContinue; + +declare_oxc_lint!( + /// ### What it does + /// Disallow `continue` statements + /// + /// ### Why is this bad? + /// The continue statement terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration. When used incorrectly it makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead. + /// + /// ### Example + /// ```javascript + /// var sum = 0, + // i; + // + // for(i = 0; i < 10; i++) { + // if(i >= 5) { + // continue; + // } + // + // sum += i; + // } + /// ``` + NoContinue, + style +); + +impl Rule for NoContinue { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + if let AstKind::ContinueStatement(continue_statement) = node.kind() { + ctx.diagnostic(NoContinueDiagnostic(Span::new( + continue_statement.span.start, + continue_statement.span.start + 8, + ))); + } + } +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + "var sum = 0, i; for(i = 0; i < 10; i++){ if(i > 5) { sum += i; } }", + "var sum = 0, i = 0; while(i < 10) { if(i > 5) { sum += i; } i++; }", + ]; + + let fail = vec![ + "var sum = 0, i; for(i = 0; i < 10; i++){ if(i <= 5) { continue; } sum += i; }", +"var sum = 0, i; myLabel: for(i = 0; i < 10; i++){ if(i <= 5) { continue myLabel; } sum += i; }", +"var sum = 0, i = 0; while(i < 10) { if(i <= 5) { i++; continue; } sum += i; i++; }", +"var sum = 0, i = 0; myLabel: while(i < 10) { if(i <= 5) { i++; continue myLabel; } sum += i; i++; }" + ]; + + Tester::new(NoContinue::NAME, pass, fail).test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/no_continue.snap b/crates/oxc_linter/src/snapshots/no_continue.snap new file mode 100644 index 000000000..25a6169f9 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_continue.snap @@ -0,0 +1,31 @@ +--- +source: crates/oxc_linter/src/tester.rs +expression: no_continue +--- + ⚠ eslint(no-continue): Unexpected use of `continue` statement. + ╭─[no_continue.tsx:1:55] + 1 │ var sum = 0, i; for(i = 0; i < 10; i++){ if(i <= 5) { continue; } sum += i; } + · ──────── + ╰──── + help: Do not use the `continue` statement. + + ⚠ eslint(no-continue): Unexpected use of `continue` statement. + ╭─[no_continue.tsx:1:64] + 1 │ var sum = 0, i; myLabel: for(i = 0; i < 10; i++){ if(i <= 5) { continue myLabel; } sum += i; } + · ──────── + ╰──── + help: Do not use the `continue` statement. + + ⚠ eslint(no-continue): Unexpected use of `continue` statement. + ╭─[no_continue.tsx:1:55] + 1 │ var sum = 0, i = 0; while(i < 10) { if(i <= 5) { i++; continue; } sum += i; i++; } + · ──────── + ╰──── + help: Do not use the `continue` statement. + + ⚠ eslint(no-continue): Unexpected use of `continue` statement. + ╭─[no_continue.tsx:1:64] + 1 │ var sum = 0, i = 0; myLabel: while(i < 10) { if(i <= 5) { i++; continue myLabel; } sum += i; i++; } + · ──────── + ╰──── + help: Do not use the `continue` statement.