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 <j.buendia>
This commit is contained in:
Jose 2024-03-17 14:21:43 +01:00 committed by GitHub
parent 91e8a71214
commit 6189985e9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 103 additions and 0 deletions

View file

@ -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,

View file

@ -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();
}

View file

@ -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.