From 1eb752a73045839162785f7bec2ffaa5d572de9f Mon Sep 17 00:00:00 2001 From: heygsc <1596920983@qq.com> Date: Tue, 6 Aug 2024 14:36:12 +0800 Subject: [PATCH 1/4] feat(linter): add fixer for eslint/for-direction --- .../src/rules/eslint/for_direction.rs | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/for_direction.rs b/crates/oxc_linter/src/rules/eslint/for_direction.rs index ecdd3789d4b91..5e5a28fe3e8f6 100644 --- a/crates/oxc_linter/src/rules/eslint/for_direction.rs +++ b/crates/oxc_linter/src/rules/eslint/for_direction.rs @@ -38,7 +38,8 @@ declare_oxc_lint!( /// for (var = 10; i >= 0; i++) {} /// ``` ForDirection, - correctness + correctness, + dangerous_fix ); impl Rule for ForDirection { @@ -66,7 +67,28 @@ impl Rule for ForDirection { let update_direction = get_update_direction(update, counter); if update_direction == wrong_direction { let update_span = get_update_span(update); - ctx.diagnostic(for_direction_diagnostic(test.span, update_span)); + let new_operator_str = match update { + Expression::UpdateExpression(update) => match update.operator { + UpdateOperator::Increment => "--", + UpdateOperator::Decrement => "++", + }, + Expression::AssignmentExpression(update) => match update.operator { + AssignmentOperator::Addition => "-=", + AssignmentOperator::Subtraction => "+=", + _ => return, + }, + _ => return, + }; + ctx.diagnostic_with_dangerous_fix( + for_direction_diagnostic(test.span, update_span), + |fix| { + // ++ -- += -= are both 2 in length + let start = update_span.start + 1; + let end = update_span.start + 3; + let span: Span = Span::new(start, end); + fix.replace(span, new_operator_str) + }, + ); } } } @@ -224,5 +246,14 @@ fn test() { ("for(var i = 0; 10 > i; i-=1){}", None), ]; - Tester::new(ForDirection::NAME, pass, fail).test_and_snapshot(); + let fix = vec![ + ("for(var i = 0; i < 10; i--){}", "for(var i = 0; i < 10; i++){}", None), + ("for(var i = 10; i > 0; i++){}", "for(var i = 10; i > 0; i--){}", None), + ("for(var i = 0; i < 10; i-=1){}", "for(var i = 0; i < 10; i+=1){}", None), + ("for(var i = 10; i > 0; i+=1){}", "for(var i = 10; i > 0; i-=1){}", None), + ("for(var i = 0; i < 10; i+=-1){}", "for(var i = 0; i < 10; i-=-1){}", None), + ("for(var i = 10; i > 0; i-=-1){}", "for(var i = 10; i > 0; i+=-1){}", None), + ]; + + Tester::new(ForDirection::NAME, pass, fail).expect_fix(fix).test_and_snapshot(); } From 0a7ce678f9dead187bbbb8fba8b0fdf86cce2108 Mon Sep 17 00:00:00 2001 From: heygsc <1596920983@qq.com> Date: Tue, 6 Aug 2024 15:12:16 +0800 Subject: [PATCH 2/4] fix typo --- crates/oxc_linter/src/rules/eslint/for_direction.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/for_direction.rs b/crates/oxc_linter/src/rules/eslint/for_direction.rs index 5e5a28fe3e8f6..668cd6e35b6de 100644 --- a/crates/oxc_linter/src/rules/eslint/for_direction.rs +++ b/crates/oxc_linter/src/rules/eslint/for_direction.rs @@ -81,12 +81,12 @@ impl Rule for ForDirection { }; ctx.diagnostic_with_dangerous_fix( for_direction_diagnostic(test.span, update_span), - |fix| { + |fixer| { // ++ -- += -= are both 2 in length let start = update_span.start + 1; let end = update_span.start + 3; let span: Span = Span::new(start, end); - fix.replace(span, new_operator_str) + fixer.replace(span, new_operator_str) }, ); } From e35a12574926a183f96d57e6fd2a9839eeefbe94 Mon Sep 17 00:00:00 2001 From: heygsc <1596920983@qq.com> Date: Tue, 6 Aug 2024 18:02:54 +0800 Subject: [PATCH 3/4] add variables of different lengths --- .../src/rules/eslint/for_direction.rs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/for_direction.rs b/crates/oxc_linter/src/rules/eslint/for_direction.rs index 668cd6e35b6de..bd9487b3aca8a 100644 --- a/crates/oxc_linter/src/rules/eslint/for_direction.rs +++ b/crates/oxc_linter/src/rules/eslint/for_direction.rs @@ -7,7 +7,7 @@ use oxc_ast::{ }; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; -use oxc_span::Span; +use oxc_span::{GetSpan, Span}; use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, UnaryOperator, UpdateOperator}; use crate::{context::LintContext, rule::Rule, AstNode}; @@ -67,6 +67,13 @@ impl Rule for ForDirection { let update_direction = get_update_direction(update, counter); if update_direction == wrong_direction { let update_span = get_update_span(update); + let start = match update { + Expression::UpdateExpression(update) => update.argument.span().end, + Expression::AssignmentExpression(update) => update.left.span().end, + _ => return, + }; + let end = start + 2; + let span: Span = Span::new(start, end); let new_operator_str = match update { Expression::UpdateExpression(update) => match update.operator { UpdateOperator::Increment => "--", @@ -81,13 +88,7 @@ impl Rule for ForDirection { }; ctx.diagnostic_with_dangerous_fix( for_direction_diagnostic(test.span, update_span), - |fixer| { - // ++ -- += -= are both 2 in length - let start = update_span.start + 1; - let end = update_span.start + 3; - let span: Span = Span::new(start, end); - fixer.replace(span, new_operator_str) - }, + |fixer| fixer.replace(span, new_operator_str), ); } } @@ -253,6 +254,9 @@ fn test() { ("for(var i = 10; i > 0; i+=1){}", "for(var i = 10; i > 0; i-=1){}", None), ("for(var i = 0; i < 10; i+=-1){}", "for(var i = 0; i < 10; i-=-1){}", None), ("for(var i = 10; i > 0; i-=-1){}", "for(var i = 10; i > 0; i+=-1){}", None), + // variables of different lengths + ("for(var ii = 0; ii < 10; ii--){}", "for(var ii = 0; ii < 10; ii++){}", None), + ("for(var ii = 10; ii > 0; ii+=1){}", "for(var ii = 10; ii > 0; ii-=1){}", None), ]; Tester::new(ForDirection::NAME, pass, fail).expect_fix(fix).test_and_snapshot(); From 0c1a97ab5a92e43558d022c8b8194c7609bf2ae2 Mon Sep 17 00:00:00 2001 From: heygsc <1596920983@qq.com> Date: Wed, 7 Aug 2024 10:26:46 +0800 Subject: [PATCH 4/4] refactor: logical order --- .../src/rules/eslint/for_direction.rs | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/for_direction.rs b/crates/oxc_linter/src/rules/eslint/for_direction.rs index bd9487b3aca8a..9648be1b1c503 100644 --- a/crates/oxc_linter/src/rules/eslint/for_direction.rs +++ b/crates/oxc_linter/src/rules/eslint/for_direction.rs @@ -67,28 +67,34 @@ impl Rule for ForDirection { let update_direction = get_update_direction(update, counter); if update_direction == wrong_direction { let update_span = get_update_span(update); - let start = match update { - Expression::UpdateExpression(update) => update.argument.span().end, - Expression::AssignmentExpression(update) => update.left.span().end, - _ => return, - }; - let end = start + 2; - let span: Span = Span::new(start, end); - let new_operator_str = match update { - Expression::UpdateExpression(update) => match update.operator { - UpdateOperator::Increment => "--", - UpdateOperator::Decrement => "++", - }, - Expression::AssignmentExpression(update) => match update.operator { - AssignmentOperator::Addition => "-=", - AssignmentOperator::Subtraction => "+=", - _ => return, - }, - _ => return, - }; ctx.diagnostic_with_dangerous_fix( for_direction_diagnostic(test.span, update_span), - |fixer| fixer.replace(span, new_operator_str), + |fixer| { + let mut start: u32 = 0; + if let Expression::UpdateExpression(update) = update { + start = update.argument.span().end; + } else if let Expression::AssignmentExpression(update) = update { + start = update.left.span().end; + } + let end = start + 2; + let span = Span::new(start, end); + let mut new_operator_str = ""; + if let Expression::UpdateExpression(update) = update { + if let UpdateOperator::Increment = update.operator { + new_operator_str = "--"; + } else if let UpdateOperator::Decrement = update.operator { + new_operator_str = "++"; + } + } else if let Expression::AssignmentExpression(update) = update { + if let AssignmentOperator::Addition = update.operator { + new_operator_str = "-="; + } else if let AssignmentOperator::Subtraction = update.operator + { + new_operator_str = "+="; + } + } + fixer.replace(span, new_operator_str) + }, ); } }