From fac6271298a369325291ec9eda7457ad2ce89bab Mon Sep 17 00:00:00 2001 From: burlinchen Date: Sat, 10 Aug 2024 11:35:21 +0800 Subject: [PATCH 01/10] fix(linter): improve no-zero-fractions rule for member expressions - Added a check for parent nodes that are MemberExpressions - If a parent node is a MemberExpression, the fixed number is now wrapped in parentheses to maintain correct syntax --- .../src/rules/unicorn/no_zero_fractions.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index da07fe5bddb82..fa0dc14d6dc0c 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -66,7 +66,18 @@ impl Rule for NoZeroFractions { } else { zero_fraction(number_literal.span, &fmt) }, - |fixer| fixer.replace(number_literal.span, fmt), + |fixer| { + let mut fixed = fmt.clone(); + + if (ctx.nodes() + .parent_node(node.id()) + .map_or(false, |parent_node: &AstNode<'a>| { + matches!(parent_node.kind(), AstKind::MemberExpression(_)) + })) { + fixed = format!("({})", fixed); + }; + fixer.replace(number_literal.span, fmt) + }, ); } } From d518230785c20e92639d91181f752c9430f2bb10 Mon Sep 17 00:00:00 2001 From: burlinchen Date: Sat, 10 Aug 2024 15:35:36 +0800 Subject: [PATCH 02/10] feat(linter): improve no-zero-fractions rule This commit enhances the no-zero-fractions rule in the unicorn linter: - Add support for scientific notation (e.g., 1e10, 1.e10) - Improve handling of member expressions - Introduce is_decimal_integer utility function - Update test cases and snapshots to reflect new behavior - Fix various edge cases in number formatting These changes make the rule more robust and consistent with the original ESLint implementation, especially for scientific notation and member expressions. --- .../src/rules/unicorn/no_zero_fractions.rs | 40 +++++++++++-------- .../src/snapshots/no_zero_fractions.snap | 6 +-- crates/oxc_linter/src/utils/unicorn.rs | 2 + .../oxc_linter/src/utils/unicorn/numeric.rs | 13 ++++++ 4 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 crates/oxc_linter/src/utils/unicorn/numeric.rs diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index fa0dc14d6dc0c..bd20210c5806a 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -3,7 +3,7 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{context::LintContext, rule::Rule, utils::is_decimal_integer, AstNode}; fn zero_fraction(span0: Span, x1: &str) -> OxcDiagnostic { OxcDiagnostic::warn("Don't use a zero fraction in the number.") @@ -69,20 +69,29 @@ impl Rule for NoZeroFractions { |fixer| { let mut fixed = fmt.clone(); - if (ctx.nodes() - .parent_node(node.id()) - .map_or(false, |parent_node: &AstNode<'a>| { - matches!(parent_node.kind(), AstKind::MemberExpression(_)) - })) { + if (ctx.nodes().parent_node(node.id()).map_or( + false, + |parent_node: &AstNode<'a>| { + matches!(parent_node.kind(), AstKind::MemberExpression(_)) + }, + ) && is_decimal_integer(&fmt)) + { fixed = format!("({})", fixed); }; - fixer.replace(number_literal.span, fmt) + fixer.replace(number_literal.span, fixed) }, ); } } fn format_raw(raw: &str) -> Option<(String, bool)> { + // Check if the string contains 'e' or 'E' (scientific notation) + if let Some((base, exp)) = raw.split_once(['e', 'E']) { + // Process the base part + let (formatted_base, has_fraction) = format_raw(base)?; + // Recombine the scientific notation + return Some((format!("{}e{}", formatted_base, exp), has_fraction)); + } let (before, after_and_dot) = raw.split_once('.')?; let mut after_parts = after_and_dot.splitn(2, |c: char| !c.is_ascii_digit() && c != '_'); let dot_and_fractions = after_parts.next()?; @@ -157,19 +166,16 @@ fn test() { (r"const foo = 1.", r"const foo = 1"), (r"const foo = +1.", r"const foo = +1"), (r"const foo = -1.", r"const foo = -1"), - // maybe todo - // In the following tests, the comments did not pass the fixer. - - // (r"const foo = 1.e10", r"const foo = 1e10"), - // (r"const foo = +1.e-10", r"const foo = +1e-10"), - // (r"const foo = -1.e+10", r"const foo = -1e+10"), + (r"const foo = 1.e10", r"const foo = 1e10"), + (r"const foo = +1.e-10", r"const foo = +1e-10"), + (r"const foo = -1.e+10", r"const foo = -1e+10"), (r"const foo = (1.).toString()", r"const foo = (1).toString()"), - // (r"1.00.toFixed(2)", r"(1).toFixed(2)"), - // (r"1.00 .toFixed(2)", r"(1) .toFixed(2)"), + (r"1.00.toFixed(2)", r"(1).toFixed(2)"), + (r"1.00 .toFixed(2)", r"(1) .toFixed(2)"), (r"(1.00).toFixed(2)", r"(1).toFixed(2)"), - // (r"1.00?.toFixed(2)", r"(1)?.toFixed(2)"), + (r"1.00?.toFixed(2)", r"(1)?.toFixed(2)"), (r"a = .0;", r"a = 0;"), - // (r"a = .0.toString()", r"a = (0).toString()"), + (r"a = .0.toString()", r"a = (0).toString()"), // (r"function foo(){return.0}", r"function foo(){return 0}"), // (r"function foo(){return.0.toString()}", r"function foo(){return (0).toString()}"), // (r"function foo(){return.0+.1}", r"function foo(){return 0+.1}"), diff --git a/crates/oxc_linter/src/snapshots/no_zero_fractions.snap b/crates/oxc_linter/src/snapshots/no_zero_fractions.snap index f15723687116b..9dbb67fb685f1 100644 --- a/crates/oxc_linter/src/snapshots/no_zero_fractions.snap +++ b/crates/oxc_linter/src/snapshots/no_zero_fractions.snap @@ -83,21 +83,21 @@ source: crates/oxc_linter/src/tester.rs 1 │ const foo = 1.e10 · ───── ╰──── - help: Replace the number literal with `110` + help: Replace the number literal with `1e10` ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a dangling dot in the number. ╭─[no_zero_fractions.tsx:1:14] 1 │ const foo = +1.e-10 · ────── ╰──── - help: Replace the number literal with `1-10` + help: Replace the number literal with `1e-10` ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a dangling dot in the number. ╭─[no_zero_fractions.tsx:1:14] 1 │ const foo = -1.e+10 · ────── ╰──── - help: Replace the number literal with `1+10` + help: Replace the number literal with `1e+10` ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a dangling dot in the number. ╭─[no_zero_fractions.tsx:1:14] diff --git a/crates/oxc_linter/src/utils/unicorn.rs b/crates/oxc_linter/src/utils/unicorn.rs index c4a324608e5e8..0b336b964ff7b 100644 --- a/crates/oxc_linter/src/utils/unicorn.rs +++ b/crates/oxc_linter/src/utils/unicorn.rs @@ -1,4 +1,5 @@ mod boolean; +mod numeric; use oxc_ast::{ ast::{ BindingPatternKind, Expression, FormalParameters, FunctionBody, LogicalExpression, @@ -10,6 +11,7 @@ use oxc_semantic::AstNode; use oxc_syntax::operator::LogicalOperator; pub use self::boolean::*; +pub use self::numeric::*; use crate::LintContext; pub fn is_node_value_not_dom_node(expr: &Expression) -> bool { diff --git a/crates/oxc_linter/src/utils/unicorn/numeric.rs b/crates/oxc_linter/src/utils/unicorn/numeric.rs new file mode 100644 index 0000000000000..d1998a450c992 --- /dev/null +++ b/crates/oxc_linter/src/utils/unicorn/numeric.rs @@ -0,0 +1,13 @@ +use lazy_static::lazy_static; +use regex::Regex; + +// Determine whether this node is a decimal integer literal. +// Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/utils/ast-utils.js#L1237 +lazy_static! { + static ref DECIMAL_INTEGER_PATTERN: Regex = + Regex::new(r"^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$").unwrap(); +} + +pub fn is_decimal_integer(text: &str) -> bool { + DECIMAL_INTEGER_PATTERN.is_match(text) +} From 5e4996bc0ed89d14d2966d84b29288fc3a609321 Mon Sep 17 00:00:00 2001 From: burlinchen Date: Sat, 10 Aug 2024 16:04:50 +0800 Subject: [PATCH 03/10] chore(linter): Refactor `NoZeroFractions` rule for improved formatting and clarity - Simplified the condition that checks for decimal integers within member expressions by removing unnecessary parentheses around the formatted string. - Updated string formatting in `format_raw` function to use the shorthand `{variable}` syntax instead of `{}` with positional arguments. --- .../src/rules/unicorn/no_zero_fractions.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index bd20210c5806a..4b4ae2b005288 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -69,14 +69,11 @@ impl Rule for NoZeroFractions { |fixer| { let mut fixed = fmt.clone(); - if (ctx.nodes().parent_node(node.id()).map_or( - false, - |parent_node: &AstNode<'a>| { - matches!(parent_node.kind(), AstKind::MemberExpression(_)) - }, - ) && is_decimal_integer(&fmt)) + if ctx.nodes().parent_node(node.id()).map_or(false, |parent_node: &AstNode<'a>| { + matches!(parent_node.kind(), AstKind::MemberExpression(_)) + }) && is_decimal_integer(&fmt) { - fixed = format!("({})", fixed); + fixed = format!("({fixed})"); }; fixer.replace(number_literal.span, fixed) }, @@ -90,7 +87,7 @@ fn format_raw(raw: &str) -> Option<(String, bool)> { // Process the base part let (formatted_base, has_fraction) = format_raw(base)?; // Recombine the scientific notation - return Some((format!("{}e{}", formatted_base, exp), has_fraction)); + return Some((format!("{formatted_base}e{exp}"), has_fraction)); } let (before, after_and_dot) = raw.split_once('.')?; let mut after_parts = after_and_dot.splitn(2, |c: char| !c.is_ascii_digit() && c != '_'); From 44d9fb4dddd8c6790bb89e92b652ff29961df76d Mon Sep 17 00:00:00 2001 From: burlinchen Date: Mon, 12 Aug 2024 11:42:47 +0800 Subject: [PATCH 04/10] fix(linter): improve no-zero-fractions rule - Handle special cases where a space is needed after certain keywords (return, throw, typeof) to prevent the number from being interpreted as a property access - Add tests for these special cases - Update existing tests to cover more scenarios --- .../src/rules/unicorn/no_zero_fractions.rs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index 4b4ae2b005288..2f79a6b20e881 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -75,6 +75,19 @@ impl Rule for NoZeroFractions { { fixed = format!("({fixed})"); }; + + // Handle special cases where a space is needed after certain keywords + // to prevent the number from being interpreted as a property access + let start = number_literal.span.start.saturating_sub(6); + let end = number_literal.span.start; + let token = ctx.source_range(oxc_span::Span::new(start, end)).to_string(); + if token.ends_with("return") + || token.ends_with("throw") + || token.ends_with("typeof") + { + fixed = format!(" {fixed}"); + } + fixer.replace(number_literal.span, fixed) }, ); @@ -173,9 +186,15 @@ fn test() { (r"1.00?.toFixed(2)", r"(1)?.toFixed(2)"), (r"a = .0;", r"a = 0;"), (r"a = .0.toString()", r"a = (0).toString()"), - // (r"function foo(){return.0}", r"function foo(){return 0}"), - // (r"function foo(){return.0.toString()}", r"function foo(){return (0).toString()}"), - // (r"function foo(){return.0+.1}", r"function foo(){return 0+.1}"), + (r"function foo(){return.0}", r"function foo(){return 0}"), + (r"function foo(){return.0.toString()}", r"function foo(){return (0).toString()}"), + (r"function foo(){return.0+.1}", r"function foo(){return 0+.1}"), + (r"typeof.0", r"typeof 0"), + (r"function foo(){typeof.0.toString()}", r"function foo(){typeof (0).toString()}"), + (r"typeof.0+.1", r"typeof 0+.1"), + (r"function foo(){throw.0;}", r"function foo(){throw 0;}"), + (r"function foo(){typeof.0.toString()}", r"function foo(){typeof (0).toString()}"), + (r"function foo() {throw.0+.1;}", r"function foo() {throw 0+.1;}"), ]; Tester::new(NoZeroFractions::NAME, pass, fail).expect_fix(fix).test_and_snapshot(); From de2cf762fcea344538f935355858738e9aa3b8df Mon Sep 17 00:00:00 2001 From: burlinchen Date: Mon, 12 Aug 2024 11:53:41 +0800 Subject: [PATCH 05/10] fix(linter): add 'void' keyword support to no-zero-fractions rule - Include 'void' in the list of keywords that require a space before the number to prevent misinterpretation as property access - Add test cases for 'void' keyword scenarios --- crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index 2f79a6b20e881..56c5ceac46acd 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -84,6 +84,7 @@ impl Rule for NoZeroFractions { if token.ends_with("return") || token.ends_with("throw") || token.ends_with("typeof") + || token.ends_with("void") { fixed = format!(" {fixed}"); } @@ -194,7 +195,10 @@ fn test() { (r"typeof.0+.1", r"typeof 0+.1"), (r"function foo(){throw.0;}", r"function foo(){throw 0;}"), (r"function foo(){typeof.0.toString()}", r"function foo(){typeof (0).toString()}"), - (r"function foo() {throw.0+.1;}", r"function foo() {throw 0+.1;}"), + (r"function foo(){throw.0+.1;}", r"function foo(){throw 0+.1;}"), + (r"void.0", r"void 0"), + (r"function foo(){void.0.toString()}", r"function foo(){void (0).toString()}"), + (r"function foo(){void.0+.1;}", r"function foo(){void 0+.1;}"), ]; Tester::new(NoZeroFractions::NAME, pass, fail).expect_fix(fix).test_and_snapshot(); From 783a8b1c67aebe00d426dbaa4b2b9d10097b243c Mon Sep 17 00:00:00 2001 From: burlinchen Date: Tue, 13 Aug 2024 19:18:26 +0800 Subject: [PATCH 06/10] refactor(linter): remove `is_decimal_integer` utility and simplify `no-zero-fractions` rule - Removed the `is_decimal_integer` function and related `numeric.rs` utility, as it was no longer necessary. - Simplified the `no-zero-fractions` rule by directly checking for non-dangling dots instead of using the removed utility. - Updated the logic for fixing number formatting to remove redundant checks. --- .../src/rules/unicorn/no_zero_fractions.rs | 8 ++++---- crates/oxc_linter/src/utils/unicorn.rs | 2 -- crates/oxc_linter/src/utils/unicorn/numeric.rs | 13 ------------- 3 files changed, 4 insertions(+), 19 deletions(-) delete mode 100644 crates/oxc_linter/src/utils/unicorn/numeric.rs diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index 56c5ceac46acd..f82b4e1f232ea 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -1,9 +1,9 @@ -use oxc_ast::AstKind; +use oxc_ast::{ast::NumberBase, AstKind}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, utils::is_decimal_integer, AstNode}; +use crate::{context::LintContext, rule::Rule, AstNode}; fn zero_fraction(span0: Span, x1: &str) -> OxcDiagnostic { OxcDiagnostic::warn("Don't use a zero fraction in the number.") @@ -67,11 +67,11 @@ impl Rule for NoZeroFractions { zero_fraction(number_literal.span, &fmt) }, |fixer| { - let mut fixed = fmt.clone(); + let mut fixed = fmt; if ctx.nodes().parent_node(node.id()).map_or(false, |parent_node: &AstNode<'a>| { matches!(parent_node.kind(), AstKind::MemberExpression(_)) - }) && is_decimal_integer(&fmt) + }) && !is_dangling_dot { fixed = format!("({fixed})"); }; diff --git a/crates/oxc_linter/src/utils/unicorn.rs b/crates/oxc_linter/src/utils/unicorn.rs index 0b336b964ff7b..c4a324608e5e8 100644 --- a/crates/oxc_linter/src/utils/unicorn.rs +++ b/crates/oxc_linter/src/utils/unicorn.rs @@ -1,5 +1,4 @@ mod boolean; -mod numeric; use oxc_ast::{ ast::{ BindingPatternKind, Expression, FormalParameters, FunctionBody, LogicalExpression, @@ -11,7 +10,6 @@ use oxc_semantic::AstNode; use oxc_syntax::operator::LogicalOperator; pub use self::boolean::*; -pub use self::numeric::*; use crate::LintContext; pub fn is_node_value_not_dom_node(expr: &Expression) -> bool { diff --git a/crates/oxc_linter/src/utils/unicorn/numeric.rs b/crates/oxc_linter/src/utils/unicorn/numeric.rs deleted file mode 100644 index d1998a450c992..0000000000000 --- a/crates/oxc_linter/src/utils/unicorn/numeric.rs +++ /dev/null @@ -1,13 +0,0 @@ -use lazy_static::lazy_static; -use regex::Regex; - -// Determine whether this node is a decimal integer literal. -// Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/utils/ast-utils.js#L1237 -lazy_static! { - static ref DECIMAL_INTEGER_PATTERN: Regex = - Regex::new(r"^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$").unwrap(); -} - -pub fn is_decimal_integer(text: &str) -> bool { - DECIMAL_INTEGER_PATTERN.is_match(text) -} From 2c81c45f42d6d32ecbaa7948549e5dc1ce6f6a8b Mon Sep 17 00:00:00 2001 From: burlinchen Date: Tue, 13 Aug 2024 19:36:30 +0800 Subject: [PATCH 07/10] chore(linter): fmt --- crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index f82b4e1f232ea..e26de87eff5a0 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::NumberBase, AstKind}; +use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; From 599af691d86fd855de48d5d4236e190b018f87b0 Mon Sep 17 00:00:00 2001 From: burlinchen Date: Wed, 14 Aug 2024 08:50:18 +0800 Subject: [PATCH 08/10] fix(unicorn/no-zero-fractions): improve handling of member expressions and decimal integers - Refactored logic in the `NoZeroFractions` rule to ensure proper handling of cases where the numeric value is a decimal integer and part of a member expression. - Added a clone of the format string to avoid mutating the original `fmt`. - Introduced checks for `is_decimal_integer` and `is_member_expression` to better control the formatting of the fixed value. - Updated test cases to cover additional scenarios, including fixing fractional values like `1.010.toFixed(2)` to `1.01.toFixed(2)`. --- .../src/rules/unicorn/no_zero_fractions.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index e26de87eff5a0..abacd141012cb 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -67,14 +67,16 @@ impl Rule for NoZeroFractions { zero_fraction(number_literal.span, &fmt) }, |fixer| { - let mut fixed = fmt; - - if ctx.nodes().parent_node(node.id()).map_or(false, |parent_node: &AstNode<'a>| { - matches!(parent_node.kind(), AstKind::MemberExpression(_)) - }) && !is_dangling_dot - { + let mut fixed = fmt.clone(); + let is_decimal_integer = fmt.parse::().is_ok(); + let is_member_expression = + ctx.nodes().parent_node(node.id()).map_or(false, |parent_node| { + matches!(parent_node.kind(), AstKind::MemberExpression(_)) + }); + + if is_member_expression && is_decimal_integer { fixed = format!("({fixed})"); - }; + } // Handle special cases where a space is needed after certain keywords // to prevent the number from being interpreted as a property access @@ -182,6 +184,7 @@ fn test() { (r"const foo = -1.e+10", r"const foo = -1e+10"), (r"const foo = (1.).toString()", r"const foo = (1).toString()"), (r"1.00.toFixed(2)", r"(1).toFixed(2)"), + (r"1.010.toFixed(2)", r"1.01.toFixed(2)"), (r"1.00 .toFixed(2)", r"(1) .toFixed(2)"), (r"(1.00).toFixed(2)", r"(1).toFixed(2)"), (r"1.00?.toFixed(2)", r"(1)?.toFixed(2)"), From bfa2fb5813c1b44be1e82ced45fbe98862506a0f Mon Sep 17 00:00:00 2001 From: burlinchen Date: Fri, 16 Aug 2024 08:53:22 +0800 Subject: [PATCH 09/10] feat(linter): Enhance no_zero_fractions rule handling - Add TODO for more complex token checks and semicolon handling - Prepare for special keyword cases requiring space after fixed value --- crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index abacd141012cb..8857060deed82 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -76,6 +76,11 @@ impl Rule for NoZeroFractions { if is_member_expression && is_decimal_integer { fixed = format!("({fixed})"); + // TODO: checks the type and value of tokenBefore: + // If tokenBefore is a Punctuator (e.g., a symbol like ;, ], or )), it determines whether a semicolon is necessary based on the context (e.g., the type of the last block node). + // If the token type is in tokenTypesNeedsSemicolon, it returns true (semicolon needed). + // Special cases like Template strings, ObjectExpression blocks, and certain Identifier cases are handled explicitly. + // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/77f32e5a6b2df542cf50dfbd371054f2cd8ce2d6/rules/no-zero-fractions.js#L56 } // Handle special cases where a space is needed after certain keywords From 4d4acd2c990e9964f1a8e9342a021dcfdb0bab82 Mon Sep 17 00:00:00 2001 From: burlinchen Date: Fri, 16 Aug 2024 08:59:09 +0800 Subject: [PATCH 10/10] feat(linter): Enhance no_zero_fractions rule handling - Add TODO for more complex token checks and --- crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index 8857060deed82..5ceb10aabbd95 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -79,7 +79,7 @@ impl Rule for NoZeroFractions { // TODO: checks the type and value of tokenBefore: // If tokenBefore is a Punctuator (e.g., a symbol like ;, ], or )), it determines whether a semicolon is necessary based on the context (e.g., the type of the last block node). // If the token type is in tokenTypesNeedsSemicolon, it returns true (semicolon needed). - // Special cases like Template strings, ObjectExpression blocks, and certain Identifier cases are handled explicitly. + // Special cases like Template strings, ObjectExpression blocks, and certain Identifier cases are handled explicitly. // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/77f32e5a6b2df542cf50dfbd371054f2cd8ce2d6/rules/no-zero-fractions.js#L56 }