From 819801e28bae6b4fbf7b09beab3518d6aa7d09e0 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Fri, 6 Sep 2024 22:46:15 -0400 Subject: [PATCH 1/8] Add no-plusplus rule --- crates/oxc_linter/src/rules.rs | 2 + .../src/rules/eslint/no_plusplus.rs | 102 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 crates/oxc_linter/src/rules/eslint/no_plusplus.rs diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index a58d924ad6694..73b0b8663d348 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -90,6 +90,7 @@ mod eslint { pub mod no_new_wrappers; pub mod no_nonoctal_decimal_escape; pub mod no_obj_calls; + pub mod no_plusplus; pub mod no_proto; pub mod no_prototype_builtins; pub mod no_redeclare; @@ -548,6 +549,7 @@ oxc_macros::declare_all_lint_rules! { eslint::no_new_wrappers, eslint::no_nonoctal_decimal_escape, eslint::no_obj_calls, + eslint::no_plusplus, eslint::no_proto, eslint::no_prototype_builtins, eslint::no_redeclare, diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs new file mode 100644 index 0000000000000..d48f9b9f88f00 --- /dev/null +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -0,0 +1,102 @@ +use oxc_diagnostics::OxcDiagnostic; +use oxc_macros::declare_oxc_lint; +use oxc_span::Span; + +use crate::{ + context::LintContext, + fixer::{RuleFix, RuleFixer}, + rule::Rule, + AstNode, +}; + +#[derive(Debug, Default, Clone)] +pub struct NoPlusplus; + +declare_oxc_lint!( + /// ### What it does + /// + /// + /// ### Why is this bad? + /// + /// + /// ### Examples + /// + /// Examples of **incorrect** code for this rule: + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// ``` + /// + /// Examples of **correct** code for this rule: + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// ``` + NoPlusplus, + restriction, +); + +impl Rule for NoPlusplus { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {} +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + ("var foo = 0; foo=+1;", None), + ("var foo = 0; foo=+1;", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ( + "for (i = 0; i < l; i++) { console.log(i); }", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ( + "for (var i = 0, j = i + 1; j < example.length; i++, j++) {}", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ("for (;; i--, foo());", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ("for (;; foo(), --i);", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ( + "for (;; foo(), ++i, bar);", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ( + "for (;; i++, (++j, k--));", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ( + "for (;; foo(), (bar(), i++), baz());", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ( + "for (;; (--i, j += 2), bar = j + 1);", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ( + "for (;; a, (i--, (b, ++j, c)), d);", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ]; + + let fail = vec![ + ("var foo = 0; foo++;", None), + ("var foo = 0; foo--;", None), + ("for (i = 0; i < l; i++) { console.log(i); }", None), + ("for (i = 0; i < l; foo, i++) { console.log(i); }", None), + ("var foo = 0; foo++;", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ( + "for (i = 0; i < l; i++) { v++; }", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ("for (i++;;);", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ("for (;--i;);", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ("for (;;) ++i;", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ("for (;; i = j++);", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ("for (;; i++, f(--j));", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), + ( + "for (;; foo + (i++, bar));", + Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }])), + ), + ]; + + Tester::new(NoPlusplus::NAME, pass, fail).test_and_snapshot(); +} From b67b785143a13b6441a2186b9ef8131ca1f2b5d6 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Fri, 6 Sep 2024 23:04:18 -0400 Subject: [PATCH 2/8] Add diagnostic --- .../src/rules/eslint/no_plusplus.rs | 63 ++++++++++++++++--- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index d48f9b9f88f00..2e585321120c3 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -1,13 +1,22 @@ +use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{ - context::LintContext, - fixer::{RuleFix, RuleFixer}, - rule::Rule, - AstNode, -}; +use crate::{context::LintContext, rule::Rule, AstNode}; + +fn no_plusplus_diagnostic(span: Span, operator: &str) -> OxcDiagnostic { + let diagnostic = + OxcDiagnostic::warn(format!("Unary operator '{}' used.", operator)).with_label(span); + + if operator == "++" { + return diagnostic.with_help("Use the assignment expression `+=` instead."); + } else if operator == "--" { + return diagnostic.with_help("Use the assignment expression `-=` instead."); + } + + diagnostic +} #[derive(Debug, Default, Clone)] pub struct NoPlusplus; @@ -15,27 +24,63 @@ pub struct NoPlusplus; declare_oxc_lint!( /// ### What it does /// + /// Disallow the unary operators `++`` and `--`. /// /// ### Why is this bad? /// + /// Because the unary `++` and `--` operators are subject to automatic semicolon insertion, differences in whitespace + /// can change the semantics of source code. For example, these two code blocks are not equivalent: + /// + /// ```js + /// var i = 10; + /// var j = 20; + /// + /// i ++ + /// j + /// // => i = 11, j = 20 + /// ``` + /// + /// ```js + /// var i = 10; + /// var j = 20; + /// + /// i + /// ++ + /// j + /// // => i = 10, j = 21 + /// ``` /// /// ### Examples /// /// Examples of **incorrect** code for this rule: /// ```js - /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// var x = 0; x++; + /// var y = 0; y--; + /// for (i = 0; i < l; i++) { + /// doSomething(i); + /// } /// ``` /// /// Examples of **correct** code for this rule: /// ```js - /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// var x = 0; x += 1; + /// var y = 0; y -= 1; + /// for (i = 0; i < l; i += 1) { + /// doSomething(i); + /// } /// ``` NoPlusplus, restriction, ); impl Rule for NoPlusplus { - fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {} + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + let AstKind::UpdateExpression(expr) = node.kind() else { + return; + }; + + ctx.diagnostic(no_plusplus_diagnostic(expr.span, expr.operator.as_str())); + } } #[test] From f04d61c889853a6cfebfc2baacf56c0a51d13aeb Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Sat, 7 Sep 2024 00:31:48 -0400 Subject: [PATCH 3/8] Add checking for for-loop updates --- .../src/rules/eslint/no_plusplus.rs | 76 ++++++++++++- .../oxc_linter/src/snapshots/no_plusplus.snap | 100 ++++++++++++++++++ 2 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 crates/oxc_linter/src/snapshots/no_plusplus.snap diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index 2e585321120c3..4ac63ee8bb99d 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -1,4 +1,4 @@ -use oxc_ast::AstKind; +use oxc_ast::{ast::Expression, AstKind}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; @@ -10,16 +10,19 @@ fn no_plusplus_diagnostic(span: Span, operator: &str) -> OxcDiagnostic { OxcDiagnostic::warn(format!("Unary operator '{}' used.", operator)).with_label(span); if operator == "++" { - return diagnostic.with_help("Use the assignment expression `+=` instead."); + return diagnostic.with_help("Use the assignment operator `+=` instead."); } else if operator == "--" { - return diagnostic.with_help("Use the assignment expression `-=` instead."); + return diagnostic.with_help("Use the assignment operator `-=` instead."); } diagnostic } #[derive(Debug, Default, Clone)] -pub struct NoPlusplus; +pub struct NoPlusplus { + /// Whether to allow `++` and `--` in for loop afterthoughts. + allow_for_loop_afterthoughts: bool, +} declare_oxc_lint!( /// ### What it does @@ -74,21 +77,84 @@ declare_oxc_lint!( ); impl Rule for NoPlusplus { + fn from_configuration(value: serde_json::Value) -> Self { + let obj = value.get(0); + Self { + allow_for_loop_afterthoughts: obj + .and_then(|v| v.get("allowForLoopAfterthoughts")) + .and_then(serde_json::Value::as_bool) + .unwrap_or(false), + } + } + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { let AstKind::UpdateExpression(expr) = node.kind() else { return; }; + if self.allow_for_loop_afterthoughts && is_for_loop_afterthought(node, ctx) { + return; + } + ctx.diagnostic(no_plusplus_diagnostic(expr.span, expr.operator.as_str())); } } +/// Whether the given AST node is a ++ or -- inside of a for-loop update. +fn is_for_statement_update(node: &AstNode, ctx: &LintContext) -> bool { + let Some(parent) = ctx.nodes().parent_node(node.id()) else { + return false; + }; + let AstKind::ForStatement(for_stmt) = parent.kind() else { + return false; + }; + + for_stmt.update.as_ref().is_some_and(|update| is_eq_node_expr(node, update)) +} + +/// Checks if the given node is equivalent to the given expression (i.e., they have the same span). +fn is_eq_node_expr(node: &AstNode, expr: &Expression) -> bool { + // TODO: This logic should be moved to somewhere more general and shared across rules and expanded + // to cover all expressions and node types + let node_span = match node.kind() { + AstKind::UpdateExpression(expr) => expr.span, + AstKind::SequenceExpression(expr) => expr.span, + _ => return false, + }; + let expr_span = match expr { + Expression::UpdateExpression(expr) => expr.span, + Expression::SequenceExpression(expr) => expr.span, + _ => return false, + }; + node_span == expr_span +} + +/// Determines whether the given node is considered to be a for loop "afterthought" by the logic of this rule. +/// In particular, it returns `true` if the given node is either: +/// - The update node of a `ForStatement`: for (;; i++) {} +/// - An operand of a sequence expression that is the update node: for (;; foo(), i++) {} +/// - An operand of a sequence expression that is child of another sequence expression, etc., +/// up to the sequence expression that is the update node: for (;; foo(), (bar(), (baz(), i++))) {} +fn is_for_loop_afterthought(node: &AstNode, ctx: &LintContext) -> bool { + if let Some(parent) = ctx.nodes().parent_node(node.id()) { + match parent.kind() { + AstKind::SequenceExpression(_) => return is_for_loop_afterthought(parent, ctx), + AstKind::ParenthesizedExpression(_) => return is_for_loop_afterthought(parent, ctx), + _ => (), + } + } + + is_for_statement_update(node, ctx) +} + #[test] fn test() { use crate::tester::Tester; let pass = vec![ ("var foo = 0; foo=+1;", None), + ("var foo = 0; foo+=1;", None), + ("var foo = 0; foo-=1;", None), ("var foo = 0; foo=+1;", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), ( "for (i = 0; i < l; i++) { console.log(i); }", @@ -125,6 +191,8 @@ fn test() { let fail = vec![ ("var foo = 0; foo++;", None), ("var foo = 0; foo--;", None), + ("var foo = 0; --foo;", None), + ("var foo = 0; ++foo;", None), ("for (i = 0; i < l; i++) { console.log(i); }", None), ("for (i = 0; i < l; foo, i++) { console.log(i); }", None), ("var foo = 0; foo++;", Some(serde_json::json!([{ "allowForLoopAfterthoughts": true }]))), diff --git a/crates/oxc_linter/src/snapshots/no_plusplus.snap b/crates/oxc_linter/src/snapshots/no_plusplus.snap new file mode 100644 index 0000000000000..3c4b6fa40c243 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_plusplus.snap @@ -0,0 +1,100 @@ +--- +source: crates/oxc_linter/src/tester.rs +--- + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:14] + 1 │ var foo = 0; foo++; + · ───── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '--' used. + ╭─[no_plusplus.tsx:1:14] + 1 │ var foo = 0; foo--; + · ───── + ╰──── + help: Use the assignment operator `-=` instead. + + ⚠ eslint(no-plusplus): Unary operator '--' used. + ╭─[no_plusplus.tsx:1:14] + 1 │ var foo = 0; --foo; + · ───── + ╰──── + help: Use the assignment operator `-=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:14] + 1 │ var foo = 0; ++foo; + · ───── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:20] + 1 │ for (i = 0; i < l; i++) { console.log(i); } + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:25] + 1 │ for (i = 0; i < l; foo, i++) { console.log(i); } + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:14] + 1 │ var foo = 0; foo++; + · ───── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:27] + 1 │ for (i = 0; i < l; i++) { v++; } + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:6] + 1 │ for (i++;;); + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '--' used. + ╭─[no_plusplus.tsx:1:7] + 1 │ for (;--i;); + · ─── + ╰──── + help: Use the assignment operator `-=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:10] + 1 │ for (;;) ++i; + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:13] + 1 │ for (;; i = j++); + · ─── + ╰──── + help: Use the assignment operator `+=` instead. + + ⚠ eslint(no-plusplus): Unary operator '--' used. + ╭─[no_plusplus.tsx:1:16] + 1 │ for (;; i++, f(--j)); + · ─── + ╰──── + help: Use the assignment operator `-=` instead. + + ⚠ eslint(no-plusplus): Unary operator '++' used. + ╭─[no_plusplus.tsx:1:16] + 1 │ for (;; foo + (i++, bar)); + · ─── + ╰──── + help: Use the assignment operator `+=` instead. From 2e9bee7f7438e02c9820dfcc4998444343ce84e5 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Sat, 7 Sep 2024 00:40:05 -0400 Subject: [PATCH 4/8] Apply lint fixes --- crates/oxc_linter/src/rules/eslint/no_plusplus.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index 4ac63ee8bb99d..89448d11f7eae 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -7,7 +7,7 @@ use crate::{context::LintContext, rule::Rule, AstNode}; fn no_plusplus_diagnostic(span: Span, operator: &str) -> OxcDiagnostic { let diagnostic = - OxcDiagnostic::warn(format!("Unary operator '{}' used.", operator)).with_label(span); + OxcDiagnostic::warn(format!("Unary operator '{operator}' used.")).with_label(span); if operator == "++" { return diagnostic.with_help("Use the assignment operator `+=` instead."); @@ -138,8 +138,9 @@ fn is_eq_node_expr(node: &AstNode, expr: &Expression) -> bool { fn is_for_loop_afterthought(node: &AstNode, ctx: &LintContext) -> bool { if let Some(parent) = ctx.nodes().parent_node(node.id()) { match parent.kind() { - AstKind::SequenceExpression(_) => return is_for_loop_afterthought(parent, ctx), - AstKind::ParenthesizedExpression(_) => return is_for_loop_afterthought(parent, ctx), + AstKind::SequenceExpression(_) | AstKind::ParenthesizedExpression(_) => { + return is_for_loop_afterthought(parent, ctx) + } _ => (), } } From 8f66c40ddf01f9a3687ba8d53ce76d49b24c38af Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Mon, 9 Sep 2024 00:04:45 -0400 Subject: [PATCH 5/8] Simplify is_for_loop_afterthought --- .../src/rules/eslint/no_plusplus.rs | 49 ++++--------------- 1 file changed, 9 insertions(+), 40 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index 89448d11f7eae..e40e0f9577217 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::Expression, AstKind}; +use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; @@ -92,7 +92,8 @@ impl Rule for NoPlusplus { return; }; - if self.allow_for_loop_afterthoughts && is_for_loop_afterthought(node, ctx) { + if self.allow_for_loop_afterthoughts && is_for_loop_afterthought(node, ctx).unwrap_or(false) + { return; } @@ -100,52 +101,20 @@ impl Rule for NoPlusplus { } } -/// Whether the given AST node is a ++ or -- inside of a for-loop update. -fn is_for_statement_update(node: &AstNode, ctx: &LintContext) -> bool { - let Some(parent) = ctx.nodes().parent_node(node.id()) else { - return false; - }; - let AstKind::ForStatement(for_stmt) = parent.kind() else { - return false; - }; - - for_stmt.update.as_ref().is_some_and(|update| is_eq_node_expr(node, update)) -} - -/// Checks if the given node is equivalent to the given expression (i.e., they have the same span). -fn is_eq_node_expr(node: &AstNode, expr: &Expression) -> bool { - // TODO: This logic should be moved to somewhere more general and shared across rules and expanded - // to cover all expressions and node types - let node_span = match node.kind() { - AstKind::UpdateExpression(expr) => expr.span, - AstKind::SequenceExpression(expr) => expr.span, - _ => return false, - }; - let expr_span = match expr { - Expression::UpdateExpression(expr) => expr.span, - Expression::SequenceExpression(expr) => expr.span, - _ => return false, - }; - node_span == expr_span -} - /// Determines whether the given node is considered to be a for loop "afterthought" by the logic of this rule. /// In particular, it returns `true` if the given node is either: /// - The update node of a `ForStatement`: for (;; i++) {} /// - An operand of a sequence expression that is the update node: for (;; foo(), i++) {} /// - An operand of a sequence expression that is child of another sequence expression, etc., /// up to the sequence expression that is the update node: for (;; foo(), (bar(), (baz(), i++))) {} -fn is_for_loop_afterthought(node: &AstNode, ctx: &LintContext) -> bool { - if let Some(parent) = ctx.nodes().parent_node(node.id()) { - match parent.kind() { - AstKind::SequenceExpression(_) | AstKind::ParenthesizedExpression(_) => { - return is_for_loop_afterthought(parent, ctx) - } - _ => (), - } +fn is_for_loop_afterthought(node: &AstNode, ctx: &LintContext) -> Option { + let mut cur = ctx.nodes().parent_node(node.id())?; + + while let AstKind::SequenceExpression(_) | AstKind::ParenthesizedExpression(_) = cur.kind() { + cur = ctx.nodes().parent_node(cur.id())?; } - is_for_statement_update(node, ctx) + Some(matches!(cur.kind(), AstKind::ForStatement(stmt) if stmt.update.is_some())) } #[test] From a63dccf7878c9aed28b12e8094a504898a72b979 Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 11 Sep 2024 13:09:42 -0400 Subject: [PATCH 6/8] Update crates/oxc_linter/src/rules/eslint/no_plusplus.rs --- crates/oxc_linter/src/rules/eslint/no_plusplus.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index e40e0f9577217..3b7e600476f8d 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -68,7 +68,7 @@ declare_oxc_lint!( /// ```js /// var x = 0; x += 1; /// var y = 0; y -= 1; - /// for (i = 0; i < l; i += 1) { + /// for (let i = 0; i < l; i += 1) { /// doSomething(i); /// } /// ``` From bec01d5a08ff8a9c8eef0531b32d3cec1d136e25 Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 11 Sep 2024 13:09:51 -0400 Subject: [PATCH 7/8] Update crates/oxc_linter/src/rules/eslint/no_plusplus.rs --- crates/oxc_linter/src/rules/eslint/no_plusplus.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index 3b7e600476f8d..90e0a5ca2f169 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -74,6 +74,7 @@ declare_oxc_lint!( /// ``` NoPlusplus, restriction, + pending ); impl Rule for NoPlusplus { From 29ab4f8f3f0b3f8cde6596be8bcb6d396a721e2a Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 11 Sep 2024 13:10:01 -0400 Subject: [PATCH 8/8] Update crates/oxc_linter/src/rules/eslint/no_plusplus.rs --- crates/oxc_linter/src/rules/eslint/no_plusplus.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs index 90e0a5ca2f169..aaf0c91f68597 100644 --- a/crates/oxc_linter/src/rules/eslint/no_plusplus.rs +++ b/crates/oxc_linter/src/rules/eslint/no_plusplus.rs @@ -59,7 +59,7 @@ declare_oxc_lint!( /// ```js /// var x = 0; x++; /// var y = 0; y--; - /// for (i = 0; i < l; i++) { + /// for (let i = 0; i < l; i++) { /// doSomething(i); /// } /// ```