From c637901868fb3a2708cbe4ecd9aa40a7ffc35fd7 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Wed, 2 Nov 2022 22:46:09 +0100 Subject: [PATCH 1/5] feat(rome_js_formatter): number literals, number types, bigint types --- .../expressions/number_literal_expression.rs | 6 +- .../src/ts/types/big_int_literal_type.rs | 19 +- .../src/ts/types/number_literal_type.rs | 4 +- crates/rome_js_formatter/src/utils/mod.rs | 1 + .../src/utils/number_utils.rs | 306 ++++++++++++++++ .../js/literal-numeric-separator/test.js.snap | 62 ---- .../specs/prettier/js/literal/number.js.snap | 327 ------------------ .../specs/prettier/js/range/boundary.js.snap | 6 +- .../consistent/simple-types.ts.snap | 85 ----- .../typescript/webhost/webtsc.ts.snap | 253 -------------- 10 files changed, 334 insertions(+), 735 deletions(-) create mode 100644 crates/rome_js_formatter/src/utils/number_utils.rs delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/literal-numeric-separator/test.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/literal/number.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/typeparams/consistent/simple-types.ts.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap diff --git a/crates/rome_js_formatter/src/js/expressions/number_literal_expression.rs b/crates/rome_js_formatter/src/js/expressions/number_literal_expression.rs index c970fd08667..37c5aad3eb3 100644 --- a/crates/rome_js_formatter/src/js/expressions/number_literal_expression.rs +++ b/crates/rome_js_formatter/src/js/expressions/number_literal_expression.rs @@ -1,7 +1,7 @@ use crate::prelude::*; +use crate::utils::number_utils::CleanedNumberLiteralText; use crate::parentheses::{is_member_object, NeedsParentheses}; -use rome_formatter::write; use rome_js_syntax::JsNumberLiteralExpression; use rome_js_syntax::{JsNumberLiteralExpressionFields, JsSyntaxNode}; @@ -15,9 +15,7 @@ impl FormatNodeRule for FormatJsNumberLiteralExpressi f: &mut JsFormatter, ) -> FormatResult<()> { let JsNumberLiteralExpressionFields { value_token } = node.as_fields(); - let value_token = value_token?; - - write![f, [value_token.format()]] + CleanedNumberLiteralText::from_number_literal_token(&value_token?).fmt(f) } fn needs_parentheses(&self, item: &JsNumberLiteralExpression) -> bool { diff --git a/crates/rome_js_formatter/src/ts/types/big_int_literal_type.rs b/crates/rome_js_formatter/src/ts/types/big_int_literal_type.rs index ce13b5562e8..f0a839232fd 100644 --- a/crates/rome_js_formatter/src/ts/types/big_int_literal_type.rs +++ b/crates/rome_js_formatter/src/ts/types/big_int_literal_type.rs @@ -1,6 +1,9 @@ +use std::borrow::Cow; + use crate::prelude::*; use crate::parentheses::NeedsParentheses; +use crate::utils::string_utils::ToAsciiLowercaseCow; use rome_formatter::write; use rome_js_syntax::{JsSyntaxNode, TsBigIntLiteralType, TsBigIntLiteralTypeFields}; @@ -13,8 +16,22 @@ impl FormatNodeRule for FormatTsBigIntLiteralType { minus_token, literal_token, } = node.as_fields(); + write![f, [minus_token.format()]]?; + let literal_token = literal_token?; - write![f, [minus_token.format(), literal_token.format()]] + let original = literal_token.text_trimmed(); + match original.to_ascii_lowercase_cow() { + Cow::Borrowed(_) => write![f, [literal_token.format()]], + Cow::Owned(lowercase) => { + write!( + f, + [format_replaced( + &literal_token, + &dynamic_text(&lowercase, literal_token.text_trimmed_range().start()) + )] + ) + } + } } fn needs_parentheses(&self, item: &TsBigIntLiteralType) -> bool { diff --git a/crates/rome_js_formatter/src/ts/types/number_literal_type.rs b/crates/rome_js_formatter/src/ts/types/number_literal_type.rs index e63b7b5b9fc..de334dce3bd 100644 --- a/crates/rome_js_formatter/src/ts/types/number_literal_type.rs +++ b/crates/rome_js_formatter/src/ts/types/number_literal_type.rs @@ -1,6 +1,7 @@ use crate::prelude::*; use crate::parentheses::NeedsParentheses; +use crate::utils::number_utils::CleanedNumberLiteralText; use rome_formatter::write; use rome_js_syntax::{JsSyntaxNode, TsNumberLiteralType, TsNumberLiteralTypeFields}; @@ -13,7 +14,8 @@ impl FormatNodeRule for FormatTsNumberLiteralType { minus_token, literal_token, } = node.as_fields(); - write![f, [minus_token.format(), literal_token.format()]] + write![f, [minus_token.format()]]?; + CleanedNumberLiteralText::from_number_literal_token(&literal_token?).fmt(f) } fn needs_parentheses(&self, item: &TsNumberLiteralType) -> bool { diff --git a/crates/rome_js_formatter/src/utils/mod.rs b/crates/rome_js_formatter/src/utils/mod.rs index 413ea7fbd3e..0767648d752 100644 --- a/crates/rome_js_formatter/src/utils/mod.rs +++ b/crates/rome_js_formatter/src/utils/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod array; mod assignment_like; mod binary_like_expression; mod conditional; +pub mod number_utils; pub mod string_utils; pub(crate) mod format_class; diff --git a/crates/rome_js_formatter/src/utils/number_utils.rs b/crates/rome_js_formatter/src/utils/number_utils.rs new file mode 100644 index 00000000000..3ce9d97ddee --- /dev/null +++ b/crates/rome_js_formatter/src/utils/number_utils.rs @@ -0,0 +1,306 @@ +use crate::prelude::*; +use crate::utils::string_utils::ToAsciiLowercaseCow; +use crate::JsFormatContext; +use crate::JsFormatter; +use rome_formatter::trivia::format_replaced; +use rome_formatter::Format; +use rome_formatter::FormatResult; +use rome_js_syntax::JsSyntaxKind::JS_NUMBER_LITERAL; +use rome_js_syntax::JsSyntaxKind::TS_NUMBER_LITERAL_TYPE; +use rome_js_syntax::JsSyntaxToken; +use std::borrow::Cow; +use std::num::NonZeroUsize; + +pub struct CleanedNumberLiteralText<'token> { + token: &'token JsSyntaxToken, + text: Cow<'token, str>, +} + +impl Format for CleanedNumberLiteralText<'_> { + fn fmt(&self, f: &mut JsFormatter) -> FormatResult<()> { + format_replaced( + self.token, + &syntax_token_cow_slice( + self.text.clone(), + self.token, + self.token.text_trimmed_range().start(), + ), + ) + .fmt(f) + } +} + +impl<'token> CleanedNumberLiteralText<'token> { + pub fn from_number_literal_token(token: &'token JsSyntaxToken) -> Self { + debug_assert!(matches!( + &token.kind(), + JS_NUMBER_LITERAL | TS_NUMBER_LITERAL_TYPE + )); + CleanedNumberLiteralText { + token: &token, + text: format_trimmed_number(token.text_trimmed()), + } + } +} + +struct FormatNumberLiteralState { + curr: Option<(usize, char)>, + location: FormatNumberLiteralLocation, +} +enum FormatNumberLiteralLocation { + InIntegerPart, + InDecimalPart(FormatNumberLiteralDecimalPart), + InExponent(FormatNumberLiteralExponent), +} +use FormatNumberLiteralLocation::*; +struct FormatNumberLiteralDecimalPart { + dot_index: usize, + last_non_zero_index: Option, +} +struct FormatNumberLiteralExponent { + e_index: usize, + is_negative: bool, + first_digit_index: Option, + first_non_zero_index: Option, +} +// Regex-free version of https://github.com/prettier/prettier/blob/ca246afacee8e6d5db508dae01730c9523bbff1d/src/common/util.js#L341-L356 +fn format_trimmed_number(text: &str) -> Cow { + let text = text.to_ascii_lowercase_cow(); + let mut copied_or_ignored_chars = 0usize; + let mut iter = text.chars().enumerate(); + let mut state = FormatNumberLiteralState { + curr: iter.next(), + location: InIntegerPart, + }; + // Will be filled only if and when the first place that needs reformatting is detected. + let mut cleaned_text = String::new(); + + // Look at only the start of the text and make sure numbers always start with a digit. Add 0 if missing. + if let Some((_, '+' | '-')) = state.curr { + state.curr = iter.next(); + } + if let Some((curr_index, '.')) = state.curr { + cleaned_text.push_str(&text[copied_or_ignored_chars..curr_index]); + copied_or_ignored_chars = curr_index; + cleaned_text.push('0'); + } + + // Loop over the rest of the text, applying the remaining rules. + // Treating the end of string like another character instead of dealing with None will simplify matching a lot. + let null_terminator = (text.len(), '\0'); + loop { + // Look for termination of the decimal part or exponent and see if we need to print it differently. + match (&state.location, state.curr.unwrap_or(null_terminator)) { + ( + InDecimalPart(FormatNumberLiteralDecimalPart { + dot_index, + last_non_zero_index: None, + }), + (curr_index, 'e' | '\0'), + ) => { + // The decimal part equals zero, ignore it completely. + // Caveat: Prettier still prints a single `.0` unless there was *only* a trailing dot. + if curr_index > dot_index + 1 { + cleaned_text.push_str(&text[copied_or_ignored_chars..=*dot_index]); + cleaned_text.push('0'); + } else { + cleaned_text.push_str(&text[copied_or_ignored_chars..*dot_index]); + } + copied_or_ignored_chars = curr_index; + } + ( + InDecimalPart(FormatNumberLiteralDecimalPart { + last_non_zero_index: Some(last_non_zero_index), + .. + }), + (curr_index, 'e' | '\0'), + ) if last_non_zero_index.get() < curr_index - 1 => { + // The decimal part ends with at least one zero, ignore them but copy the part from the dot until the last non-zero. + cleaned_text.push_str(&text[copied_or_ignored_chars..=last_non_zero_index.get()]); + copied_or_ignored_chars = curr_index; + } + ( + InExponent(FormatNumberLiteralExponent { + e_index, + first_non_zero_index: None, + .. + }), + (curr_index, '\0'), + ) => { + // The exponent equals zero, ignore it completely. + cleaned_text.push_str(&text[copied_or_ignored_chars..*e_index]); + copied_or_ignored_chars = curr_index; + } + ( + InExponent(FormatNumberLiteralExponent { + e_index, + is_negative, + first_digit_index: Some(first_digit_index), + first_non_zero_index: Some(first_non_zero_index), + }), + (curr_index, '\0'), + ) if (first_digit_index.get() > e_index + 1 && !is_negative) + || (first_non_zero_index.get() > first_digit_index.get()) => + { + // The exponent begins with a plus or at least one zero, ignore them but copy the part from the first non-zero until the end. + cleaned_text.push_str(&text[copied_or_ignored_chars..=*e_index]); + if *is_negative { + cleaned_text.push('-'); + } + cleaned_text.push_str(&text[first_non_zero_index.get()..curr_index]); + copied_or_ignored_chars = curr_index; + } + _ => {} + } + + // Update location info after the current char + match state { + // Cases entering or remaining in decimal part + FormatNumberLiteralState { + curr: Some((curr_index, '.')), + .. + } => { + state.location = InDecimalPart(FormatNumberLiteralDecimalPart { + dot_index: curr_index, + last_non_zero_index: None, + }); + } + FormatNumberLiteralState { + location: InDecimalPart(decimal_part), + curr: Some((curr_index, '1'..='9')), + } => { + state.location = InDecimalPart(FormatNumberLiteralDecimalPart { + last_non_zero_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), + ..decimal_part + }); + } + // Cases entering or remaining in exponent + FormatNumberLiteralState { + curr: Some((curr_index, 'e')), + .. + } => { + state.location = InExponent(FormatNumberLiteralExponent { + e_index: curr_index, + is_negative: false, + first_digit_index: None, + first_non_zero_index: None, + }); + } + FormatNumberLiteralState { + location: InExponent(exponent), + curr: Some((_, '-')), + } => { + state.location = InExponent(FormatNumberLiteralExponent { + is_negative: true, + ..exponent + }); + } + FormatNumberLiteralState { + location: + InExponent( + exponent @ FormatNumberLiteralExponent { + first_digit_index: None, + .. + }, + ), + curr: Some((curr_index, curr_char @ '0'..='9')), + } => { + state.location = InExponent(FormatNumberLiteralExponent { + first_digit_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), + first_non_zero_index: if curr_char != '0' { + Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }) + } else { + None + }, + ..exponent + }); + } + FormatNumberLiteralState { + location: + InExponent( + exponent @ FormatNumberLiteralExponent { + first_non_zero_index: None, + .. + }, + ), + curr: Some((curr_index, '1'..='9')), + } => { + state.location = InExponent(FormatNumberLiteralExponent { + first_non_zero_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), + ..exponent + }); + } + _ => {} + } + + // Repeat or exit + match state.curr { + None | Some((_, 'x') /* hex bailout */) => break, + Some(_) => state.curr = iter.next(), + } + } + + if cleaned_text.is_empty() { + text + } else { + // Append any unconsidered text + cleaned_text.push_str(&text[copied_or_ignored_chars..]); + Cow::Owned(cleaned_text) + } +} + +#[cfg(test)] +mod tests { + use std::borrow::Cow; + + use super::format_trimmed_number; + + #[test] + fn removes_unnecessary_plus_and_zeros_from_scientific_notation() { + assert_eq!("1e2", format_trimmed_number("1e02")); + assert_eq!("1e2", format_trimmed_number("1e+2")); + } + + #[test] + fn removes_unnecessary_scientific_notation() { + assert_eq!("1", format_trimmed_number("1e0")); + assert_eq!("1", format_trimmed_number("1e-0")); + } + #[test] + fn does_not_get_bamboozled_by_hex() { + assert_eq!("0xe0", format_trimmed_number("0xe0")); + assert_eq!("0x10e0", format_trimmed_number("0x10e0")); + } + + #[test] + fn makes_sure_numbers_always_start_with_a_digit() { + assert_eq!("0.2", format_trimmed_number(".2")); + } + + #[test] + fn removes_extraneous_trailing_decimal_zeroes() { + assert_eq!("0.1", format_trimmed_number("0.10")); + } + #[test] + fn keeps_one_trailing_decimal_zero() { + assert_eq!("0.0", format_trimmed_number("0.00")); + } + + #[test] + fn removes_trailing_dot() { + assert_eq!("1", format_trimmed_number("1.")); + } + + #[test] + fn cleans_all_at_once() { + assert_eq!("0.0", format_trimmed_number(".00e-0")); + } + + #[test] + fn keeps_the_input_string_if_no_change_needed() { + assert!(matches!( + format_trimmed_number("0.1e2"), + Cow::Borrowed("0.1e2") + )); + } +} diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/literal-numeric-separator/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/literal-numeric-separator/test.js.snap deleted file mode 100644 index 39423113ed0..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/literal-numeric-separator/test.js.snap +++ /dev/null @@ -1,62 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -1_1 -1_1.1_1 -0o1_1 -0o0_11 -1.1_0_1e1 -1.1_0_1E1 -.1_1 -0x1_1 -0xa_1 -0xA_1 -0b01_1 -0b0_1_1 -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -3,10 +3,10 @@ - 0o1_1; - 0o0_11; - 1.1_0_1e1; --1.1_0_1e1; --0.1_1; -+1.1_0_1E1; -+.1_1; - 0x1_1; --0xa_1; - 0xa_1; -+0xA_1; - 0b01_1; - 0b0_1_1; -``` - -# Output - -```js -1_1; -1_1.1_1; -0o1_1; -0o0_11; -1.1_0_1e1; -1.1_0_1E1; -.1_1; -0x1_1; -0xa_1; -0xA_1; -0b01_1; -0b0_1_1; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/literal/number.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/literal/number.js.snap deleted file mode 100644 index 3bfc4c22924..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/literal/number.js.snap +++ /dev/null @@ -1,327 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -// parentheses around numeric literal should be preserved -function test5() { - return (100).toString(); -} - -0 -1 - -0.1 -1.1 - -.1 -1. - -0b1 -0B1 -0o1 -0O1 -0x1 -0X1 - -0x123abcdef456ABCDEF -0X123abcdef456ABCDEF -0xdeadbeef; - -0b111000 -0b000111 -0B111000 -0B000111 -0o111000 -0o000111 -0O111000 -0O000111 -0x111000 -0x000111 -0X111000 -0X000111 - -1e1 -1e+1 -1e-1 -1.e1 -.1e1 -1.1e1 -1.1e0010 -.1e+0010 -.1e-0010 - -1E1 -1E+1 -1E-1 -1.E1 -.1E1 -1.1E1 -1.1E0010 -.1E+0010 -.1E-0010 - -0.5e0 -0.5e00 -0.5e+0 -0.5e+00 -0.5e-0 -0.5e-00 - -1 -1.00500 -1.0 -1.5 -1.50 -0 -0.00500 -0.0 -0.0000 -.0 -500600.001230045000 -1.00500e60 -1.0e60 -0.00500e60 -0.0e60 -0.0000e60 -.0e60 -0.e60 -0e60 -500600.001230045000e60 -10 -9700 -10e100 -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -9,80 +9,80 @@ - 0.1; - 1.1; - --0.1; --1; -+.1; -+1.; - --0b1; - 0b1; -+0B1; - 0o1; --0o1; -+0O1; - 0x1; --0x1; -+0X1; - --0x123abcdef456abcdef; --0x123abcdef456abcdef; -+0x123abcdef456ABCDEF; -+0X123abcdef456ABCDEF; - 0xdeadbeef; - --0b111000; --0b000111; - 0b111000; - 0b000111; --0o111000; --0o000111; -+0B111000; -+0B000111; - 0o111000; - 0o000111; -+0O111000; -+0O000111; - 0x111000; - 0x000111; --0x111000; --0x000111; -+0X111000; -+0X000111; - - 1e1; --1e1; -+1e+1; - 1e-1; --1e1; --0.1e1; -+1.e1; -+.1e1; - 1.1e1; --1.1e10; --0.1e10; --0.1e-10; -+1.1e0010; -+.1e+0010; -+.1e-0010; - --1e1; --1e1; --1e-1; --1e1; --0.1e1; --1.1e1; --1.1e10; --0.1e10; --0.1e-10; -+1E1; -+1E+1; -+1E-1; -+1.E1; -+.1E1; -+1.1E1; -+1.1E0010; -+.1E+0010; -+.1E-0010; - --0.5; --0.5; --0.5; --0.5; --0.5; --0.5; -+0.5e0; -+0.5e00; -+0.5e+0; -+0.5e+00; -+0.5e-0; -+0.5e-00; - - 1; --1.005; -+1.00500; - 1.0; --1.5; - 1.5; -+1.50; - 0; --0.005; -+0.00500; - 0.0; --0.0; --0.0; --500600.001230045; --1.005e60; -+0.0000; -+.0; -+500600.001230045000; -+1.00500e60; - 1.0e60; --0.005e60; -+0.00500e60; - 0.0e60; --0.0e60; --0.0e60; --0e60; -+0.0000e60; -+.0e60; -+0.e60; - 0e60; --500600.001230045e60; -+500600.001230045000e60; - 10; - 9700; - 10e100; -``` - -# Output - -```js -// parentheses around numeric literal should be preserved -function test5() { - return (100).toString(); -} - -0; -1; - -0.1; -1.1; - -.1; -1.; - -0b1; -0B1; -0o1; -0O1; -0x1; -0X1; - -0x123abcdef456ABCDEF; -0X123abcdef456ABCDEF; -0xdeadbeef; - -0b111000; -0b000111; -0B111000; -0B000111; -0o111000; -0o000111; -0O111000; -0O000111; -0x111000; -0x000111; -0X111000; -0X000111; - -1e1; -1e+1; -1e-1; -1.e1; -.1e1; -1.1e1; -1.1e0010; -.1e+0010; -.1e-0010; - -1E1; -1E+1; -1E-1; -1.E1; -.1E1; -1.1E1; -1.1E0010; -.1E+0010; -.1E-0010; - -0.5e0; -0.5e00; -0.5e+0; -0.5e+00; -0.5e-0; -0.5e-00; - -1; -1.00500; -1.0; -1.5; -1.50; -0; -0.00500; -0.0; -0.0000; -.0; -500600.001230045000; -1.00500e60; -1.0e60; -0.00500e60; -0.0e60; -0.0000e60; -.0e60; -0.e60; -0e60; -500600.001230045000e60; -10; -9700; -10e100; -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/range/boundary.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/range/boundary.js.snap index e2a26707300..0a12204bd64 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/range/boundary.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/range/boundary.js.snap @@ -1,5 +1,7 @@ --- source: crates/rome_js_formatter/tests/prettier_tests.rs +info: + test_file: js/range/boundary.js --- # Input @@ -21,7 +23,7 @@ foo = 1.0000;bar = 1.0000;baz=1.0000; -foo = 1.0; -bar = 1.0; -baz = 1.0; -+foo = 1.0000;bar = 1.0000;baz=1.0000; ++foo = 1.0000;bar = 1.0;baz=1.0000; // The range will be 13~26 // `foo` ends at 13, should not format // `bar` ends at 26, should format @@ -30,7 +32,7 @@ foo = 1.0000;bar = 1.0000;baz=1.0000; # Output ```js -foo = 1.0000;bar = 1.0000;baz=1.0000; +foo = 1.0000;bar = 1.0;baz=1.0000; // The range will be 13~26 // `foo` ends at 13, should not format // `bar` ends at 26, should format diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeparams/consistent/simple-types.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeparams/consistent/simple-types.ts.snap deleted file mode 100644 index 741f2702f0d..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeparams/consistent/simple-types.ts.snap +++ /dev/null @@ -1,85 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo5: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo6: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo7: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo8: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = a; -const foo9: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<"STRING"> = a; -const foo10: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = a; -const foo11: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beef> = a; -const foo12: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beefn> = a; -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -18,7 +18,7 @@ - a; - const foo10: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = - a; --const foo11: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xdeed_beef> = -+const foo11: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beef> = - a; --const foo12: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xdeed_beefn> = -+const foo12: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beefn> = - a; -``` - -# Output - -```js -const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo5: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo6: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo7: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo8: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - a; -const foo9: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<"STRING"> = - a; -const foo10: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = - a; -const foo11: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beef> = - a; -const foo12: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beefn> = - a; -``` - - -# Lines exceeding max width of 80 characters -``` - 1: const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 3: const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 5: const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 7: const foo4: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 9: const foo5: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 11: const foo6: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 13: const foo7: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 15: const foo8: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo = - 17: const foo9: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<"STRING"> = - 19: const foo10: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = - 21: const foo11: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beef> = - 23: const foo12: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0xDeeD_Beefn> = -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap deleted file mode 100644 index bdc00425873..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/webhost/webtsc.ts.snap +++ /dev/null @@ -1,253 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs ---- - -# Input - -```js -/// - -namespace TypeScript.WebTsc { - - declare var RealActiveXObject: { new (s: string): any }; - - function getWScriptSystem() { - const fso = new RealActiveXObject("Scripting.FileSystemObject"); - - const fileStream = new ActiveXObject("ADODB.Stream"); - fileStream.Type = 2 /*text*/; - - const args: string[] = []; - for (let i = 0; i < WScript.Arguments.length; i++) { - args[i] = WScript.Arguments.Item(i); - } - return { - args: args, - newLine: "\r\n", - write(s: string): void { - WScript.StdOut.Write(s); - }, - writeErr(s: string): void { - WScript.StdErr.Write(s); - }, - readFile(fileName: string, encoding?: string): string { - if (!fso.FileExists(fileName)) { - return undefined; - } - fileStream.Open(); - try { - if (encoding) { - fileStream.Charset = encoding; - fileStream.LoadFromFile(fileName); - } - else { - // Load file and read the first two bytes into a string with no interpretation - fileStream.Charset = "x-ansi"; - fileStream.LoadFromFile(fileName); - const bom = fileStream.ReadText(2) || ""; - // Position must be at 0 before encoding can be changed - fileStream.Position = 0; - // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 - fileStream.Charset = bom.length >= 2 && (bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE || bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF) ? "unicode" : "utf-8"; - } - // ReadText method always strips byte order mark from resulting string - return fileStream.ReadText(); - } - catch (e) { - throw e; - } - finally { - fileStream.Close(); - } - }, - writeFile(fileName: string, data: string): boolean { - const f = fso.CreateTextFile(fileName, true); - f.Write(data); - f.Close(); - return true; - }, - resolvePath(path: string): string { - return fso.GetAbsolutePathName(path); - }, - fileExists(path: string): boolean { - return fso.FileExists(path); - }, - directoryExists(path: string) { - return fso.FolderExists(path); - }, - createDirectory(directoryName: string) { - if (!this.directoryExists(directoryName)) { - fso.CreateFolder(directoryName); - } - }, - getExecutingFilePath() { - return WScript.ScriptFullName; - }, - getCurrentDirectory() { - return ""; - }, - getMemoryUsage() { - return 0; - }, - exit(exitCode?: number): void { - WScript.Quit(exitCode); - }, - useCaseSensitiveFileNames: false - }; - } - - export function prepareCompiler(currentDir: string, stdOut: ITextWriter, stdErr: ITextWriter) { - const shell = new RealActiveXObject("WScript.Shell"); - shell.CurrentDirectory = currentDir; - WScript.ScriptFullName = currentDir + "\\tc.js"; - WScript.StdOut = stdOut; - WScript.StdErr = stdErr; - sys = getWScriptSystem(); - - return (commandLine: string) => { - ts.executeCommandLine(commandLine.split(" ")); - }; - } -} -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -41,8 +41,8 @@ - // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 - fileStream.Charset = - bom.length >= 2 && -- ((bom.charCodeAt(0) === 0xff && bom.charCodeAt(1) === 0xfe) || -- (bom.charCodeAt(0) === 0xfe && bom.charCodeAt(1) === 0xff)) -+ ((bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || -+ (bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF)) - ? "unicode" - : "utf-8"; - } -``` - -# Output - -```js -/// - -namespace TypeScript.WebTsc { - declare var RealActiveXObject: { new (s: string): any }; - - function getWScriptSystem() { - const fso = new RealActiveXObject("Scripting.FileSystemObject"); - - const fileStream = new ActiveXObject("ADODB.Stream"); - fileStream.Type = 2 /*text*/; - - const args: string[] = []; - for (let i = 0; i < WScript.Arguments.length; i++) { - args[i] = WScript.Arguments.Item(i); - } - return { - args: args, - newLine: "\r\n", - write(s: string): void { - WScript.StdOut.Write(s); - }, - writeErr(s: string): void { - WScript.StdErr.Write(s); - }, - readFile(fileName: string, encoding?: string): string { - if (!fso.FileExists(fileName)) { - return undefined; - } - fileStream.Open(); - try { - if (encoding) { - fileStream.Charset = encoding; - fileStream.LoadFromFile(fileName); - } else { - // Load file and read the first two bytes into a string with no interpretation - fileStream.Charset = "x-ansi"; - fileStream.LoadFromFile(fileName); - const bom = fileStream.ReadText(2) || ""; - // Position must be at 0 before encoding can be changed - fileStream.Position = 0; - // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 - fileStream.Charset = - bom.length >= 2 && - ((bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE) || - (bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF)) - ? "unicode" - : "utf-8"; - } - // ReadText method always strips byte order mark from resulting string - return fileStream.ReadText(); - } catch (e) { - throw e; - } finally { - fileStream.Close(); - } - }, - writeFile(fileName: string, data: string): boolean { - const f = fso.CreateTextFile(fileName, true); - f.Write(data); - f.Close(); - return true; - }, - resolvePath(path: string): string { - return fso.GetAbsolutePathName(path); - }, - fileExists(path: string): boolean { - return fso.FileExists(path); - }, - directoryExists(path: string) { - return fso.FolderExists(path); - }, - createDirectory(directoryName: string) { - if (!this.directoryExists(directoryName)) { - fso.CreateFolder(directoryName); - } - }, - getExecutingFilePath() { - return WScript.ScriptFullName; - }, - getCurrentDirectory() { - return ""; - }, - getMemoryUsage() { - return 0; - }, - exit(exitCode?: number): void { - WScript.Quit(exitCode); - }, - useCaseSensitiveFileNames: false, - }; - } - - export function prepareCompiler( - currentDir: string, - stdOut: ITextWriter, - stdErr: ITextWriter, - ) { - const shell = new RealActiveXObject("WScript.Shell"); - shell.CurrentDirectory = currentDir; - WScript.ScriptFullName = currentDir + "\\tc.js"; - WScript.StdOut = stdOut; - WScript.StdErr = stdErr; - sys = getWScriptSystem(); - - return (commandLine: string) => { - ts.executeCommandLine(commandLine.split(" ")); - }; - } -} -``` - - -# Lines exceeding max width of 80 characters -``` - 35: // Load file and read the first two bytes into a string with no interpretation - 41: // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8 -``` - From 071d153afb0954deca0a590fd060ae8a4f7340af Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Thu, 3 Nov 2022 11:07:56 +0100 Subject: [PATCH 2/5] small cleanups --- .../src/ts/types/number_literal_type.rs | 9 +++++++-- .../rome_js_formatter/src/utils/number_utils.rs | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/crates/rome_js_formatter/src/ts/types/number_literal_type.rs b/crates/rome_js_formatter/src/ts/types/number_literal_type.rs index de334dce3bd..9543ef59c77 100644 --- a/crates/rome_js_formatter/src/ts/types/number_literal_type.rs +++ b/crates/rome_js_formatter/src/ts/types/number_literal_type.rs @@ -14,8 +14,13 @@ impl FormatNodeRule for FormatTsNumberLiteralType { minus_token, literal_token, } = node.as_fields(); - write![f, [minus_token.format()]]?; - CleanedNumberLiteralText::from_number_literal_token(&literal_token?).fmt(f) + write![ + f, + [ + minus_token.format(), + CleanedNumberLiteralText::from_number_literal_token(&literal_token?) + ] + ] } fn needs_parentheses(&self, item: &TsNumberLiteralType) -> bool { diff --git a/crates/rome_js_formatter/src/utils/number_utils.rs b/crates/rome_js_formatter/src/utils/number_utils.rs index 3ce9d97ddee..a72c05b395f 100644 --- a/crates/rome_js_formatter/src/utils/number_utils.rs +++ b/crates/rome_js_formatter/src/utils/number_utils.rs @@ -75,7 +75,7 @@ fn format_trimmed_number(text: &str) -> Cow { // Will be filled only if and when the first place that needs reformatting is detected. let mut cleaned_text = String::new(); - // Look at only the start of the text and make sure numbers always start with a digit. Add 0 if missing. + // Look at only the start of the text, ignore any sign, and make sure numbers always start with a digit. Add 0 if missing. if let Some((_, '+' | '-')) = state.curr { state.curr = iter.next(); } @@ -170,7 +170,10 @@ fn format_trimmed_number(text: &str) -> Cow { curr: Some((curr_index, '1'..='9')), } => { state.location = InDecimalPart(FormatNumberLiteralDecimalPart { - last_non_zero_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), + last_non_zero_index: Some(unsafe { + // We've already entered InDecimalPart, so curr_index must be >0 + NonZeroUsize::new_unchecked(curr_index) + }), ..decimal_part }); } @@ -206,9 +209,15 @@ fn format_trimmed_number(text: &str) -> Cow { curr: Some((curr_index, curr_char @ '0'..='9')), } => { state.location = InExponent(FormatNumberLiteralExponent { - first_digit_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), + first_digit_index: Some(unsafe { + // We've already entered InExponent, so curr_index must be >0 + NonZeroUsize::new_unchecked(curr_index) + }), first_non_zero_index: if curr_char != '0' { - Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }) + Some(unsafe { + // We've already entered InExponent, so curr_index must be >0 + NonZeroUsize::new_unchecked(curr_index) + }) } else { None }, From 0aea8cd1dddd735bc0988eeab61df744cfe6bb8a Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Thu, 3 Nov 2022 12:17:08 +0100 Subject: [PATCH 3/5] None-terminated string instead of null-terminated string --- .../rome_js_formatter/src/utils/number_utils.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/rome_js_formatter/src/utils/number_utils.rs b/crates/rome_js_formatter/src/utils/number_utils.rs index a72c05b395f..8c6c5d0b71e 100644 --- a/crates/rome_js_formatter/src/utils/number_utils.rs +++ b/crates/rome_js_formatter/src/utils/number_utils.rs @@ -86,17 +86,19 @@ fn format_trimmed_number(text: &str) -> Cow { } // Loop over the rest of the text, applying the remaining rules. - // Treating the end of string like another character instead of dealing with None will simplify matching a lot. - let null_terminator = (text.len(), '\0'); loop { + let curr_or_none_terminator_char = match state.curr { + Some((curr_index, curr_char)) => (curr_index, Some(curr_char)), + None => (text.len(), None), + }; // Look for termination of the decimal part or exponent and see if we need to print it differently. - match (&state.location, state.curr.unwrap_or(null_terminator)) { + match (&state.location, curr_or_none_terminator_char) { ( InDecimalPart(FormatNumberLiteralDecimalPart { dot_index, last_non_zero_index: None, }), - (curr_index, 'e' | '\0'), + (curr_index, Some('e') | None), ) => { // The decimal part equals zero, ignore it completely. // Caveat: Prettier still prints a single `.0` unless there was *only* a trailing dot. @@ -113,7 +115,7 @@ fn format_trimmed_number(text: &str) -> Cow { last_non_zero_index: Some(last_non_zero_index), .. }), - (curr_index, 'e' | '\0'), + (curr_index, Some('e') | None), ) if last_non_zero_index.get() < curr_index - 1 => { // The decimal part ends with at least one zero, ignore them but copy the part from the dot until the last non-zero. cleaned_text.push_str(&text[copied_or_ignored_chars..=last_non_zero_index.get()]); @@ -125,7 +127,7 @@ fn format_trimmed_number(text: &str) -> Cow { first_non_zero_index: None, .. }), - (curr_index, '\0'), + (curr_index, None), ) => { // The exponent equals zero, ignore it completely. cleaned_text.push_str(&text[copied_or_ignored_chars..*e_index]); @@ -138,7 +140,7 @@ fn format_trimmed_number(text: &str) -> Cow { first_digit_index: Some(first_digit_index), first_non_zero_index: Some(first_non_zero_index), }), - (curr_index, '\0'), + (curr_index, None), ) if (first_digit_index.get() > e_index + 1 && !is_negative) || (first_non_zero_index.get() > first_digit_index.get()) => { From 684df3fce23edcc2ed8a87f5dfb3753f9087440c Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Thu, 3 Nov 2022 13:23:00 +0100 Subject: [PATCH 4/5] clean up unnecessary struct --- .../src/utils/number_utils.rs | 112 ++++++++---------- 1 file changed, 47 insertions(+), 65 deletions(-) diff --git a/crates/rome_js_formatter/src/utils/number_utils.rs b/crates/rome_js_formatter/src/utils/number_utils.rs index 8c6c5d0b71e..f42f92f98b1 100644 --- a/crates/rome_js_formatter/src/utils/number_utils.rs +++ b/crates/rome_js_formatter/src/utils/number_utils.rs @@ -43,16 +43,12 @@ impl<'token> CleanedNumberLiteralText<'token> { } } -struct FormatNumberLiteralState { - curr: Option<(usize, char)>, - location: FormatNumberLiteralLocation, -} -enum FormatNumberLiteralLocation { +enum FormatNumberLiteralState { InIntegerPart, InDecimalPart(FormatNumberLiteralDecimalPart), InExponent(FormatNumberLiteralExponent), } -use FormatNumberLiteralLocation::*; +use FormatNumberLiteralState::*; struct FormatNumberLiteralDecimalPart { dot_index: usize, last_non_zero_index: Option, @@ -68,18 +64,17 @@ fn format_trimmed_number(text: &str) -> Cow { let text = text.to_ascii_lowercase_cow(); let mut copied_or_ignored_chars = 0usize; let mut iter = text.chars().enumerate(); - let mut state = FormatNumberLiteralState { - curr: iter.next(), - location: InIntegerPart, - }; + let mut curr = iter.next(); + let mut state = InIntegerPart; + // Will be filled only if and when the first place that needs reformatting is detected. let mut cleaned_text = String::new(); // Look at only the start of the text, ignore any sign, and make sure numbers always start with a digit. Add 0 if missing. - if let Some((_, '+' | '-')) = state.curr { - state.curr = iter.next(); + if let Some((_, '+' | '-')) = curr { + curr = iter.next(); } - if let Some((curr_index, '.')) = state.curr { + if let Some((curr_index, '.')) = curr { cleaned_text.push_str(&text[copied_or_ignored_chars..curr_index]); copied_or_ignored_chars = curr_index; cleaned_text.push('0'); @@ -87,12 +82,13 @@ fn format_trimmed_number(text: &str) -> Cow { // Loop over the rest of the text, applying the remaining rules. loop { - let curr_or_none_terminator_char = match state.curr { + // We use a None pseudo-char at the end of the string to simplify the match cases that follow + let curr_or_none_terminator_char = match curr { Some((curr_index, curr_char)) => (curr_index, Some(curr_char)), None => (text.len(), None), }; // Look for termination of the decimal part or exponent and see if we need to print it differently. - match (&state.location, curr_or_none_terminator_char) { + match (&state, curr_or_none_terminator_char) { ( InDecimalPart(FormatNumberLiteralDecimalPart { dot_index, @@ -155,62 +151,49 @@ fn format_trimmed_number(text: &str) -> Cow { _ => {} } - // Update location info after the current char - match state { + // Update state after the current char + match (&state, curr) { // Cases entering or remaining in decimal part - FormatNumberLiteralState { - curr: Some((curr_index, '.')), - .. - } => { - state.location = InDecimalPart(FormatNumberLiteralDecimalPart { + (_, Some((curr_index, '.'))) => { + state = InDecimalPart(FormatNumberLiteralDecimalPart { dot_index: curr_index, last_non_zero_index: None, }); } - FormatNumberLiteralState { - location: InDecimalPart(decimal_part), - curr: Some((curr_index, '1'..='9')), - } => { - state.location = InDecimalPart(FormatNumberLiteralDecimalPart { + (InDecimalPart(decimal_part), Some((curr_index, '1'..='9'))) => { + state = InDecimalPart(FormatNumberLiteralDecimalPart { last_non_zero_index: Some(unsafe { // We've already entered InDecimalPart, so curr_index must be >0 NonZeroUsize::new_unchecked(curr_index) }), - ..decimal_part + ..*decimal_part }); } // Cases entering or remaining in exponent - FormatNumberLiteralState { - curr: Some((curr_index, 'e')), - .. - } => { - state.location = InExponent(FormatNumberLiteralExponent { + (_, Some((curr_index, 'e'))) => { + state = InExponent(FormatNumberLiteralExponent { e_index: curr_index, is_negative: false, first_digit_index: None, first_non_zero_index: None, }); } - FormatNumberLiteralState { - location: InExponent(exponent), - curr: Some((_, '-')), - } => { - state.location = InExponent(FormatNumberLiteralExponent { + (InExponent(exponent), Some((_, '-'))) => { + state = InExponent(FormatNumberLiteralExponent { is_negative: true, - ..exponent + ..*exponent }); } - FormatNumberLiteralState { - location: - InExponent( - exponent @ FormatNumberLiteralExponent { - first_digit_index: None, - .. - }, - ), - curr: Some((curr_index, curr_char @ '0'..='9')), - } => { - state.location = InExponent(FormatNumberLiteralExponent { + ( + InExponent( + exponent @ FormatNumberLiteralExponent { + first_digit_index: None, + .. + }, + ), + Some((curr_index, curr_char @ '0'..='9')), + ) => { + state = InExponent(FormatNumberLiteralExponent { first_digit_index: Some(unsafe { // We've already entered InExponent, so curr_index must be >0 NonZeroUsize::new_unchecked(curr_index) @@ -223,31 +206,30 @@ fn format_trimmed_number(text: &str) -> Cow { } else { None }, - ..exponent + ..*exponent }); } - FormatNumberLiteralState { - location: - InExponent( - exponent @ FormatNumberLiteralExponent { - first_non_zero_index: None, - .. - }, - ), - curr: Some((curr_index, '1'..='9')), - } => { - state.location = InExponent(FormatNumberLiteralExponent { + ( + InExponent( + exponent @ FormatNumberLiteralExponent { + first_non_zero_index: None, + .. + }, + ), + Some((curr_index, '1'..='9')), + ) => { + state = InExponent(FormatNumberLiteralExponent { first_non_zero_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), - ..exponent + ..*exponent }); } _ => {} } // Repeat or exit - match state.curr { + match curr { None | Some((_, 'x') /* hex bailout */) => break, - Some(_) => state.curr = iter.next(), + Some(_) => curr = iter.next(), } } From 9ad278edea131695a7d9fac83a61278180452e1b Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Thu, 3 Nov 2022 14:33:12 +0100 Subject: [PATCH 5/5] lint --- .../src/utils/number_utils.rs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/rome_js_formatter/src/utils/number_utils.rs b/crates/rome_js_formatter/src/utils/number_utils.rs index f42f92f98b1..a96582586db 100644 --- a/crates/rome_js_formatter/src/utils/number_utils.rs +++ b/crates/rome_js_formatter/src/utils/number_utils.rs @@ -37,16 +37,16 @@ impl<'token> CleanedNumberLiteralText<'token> { JS_NUMBER_LITERAL | TS_NUMBER_LITERAL_TYPE )); CleanedNumberLiteralText { - token: &token, + token, text: format_trimmed_number(token.text_trimmed()), } } } enum FormatNumberLiteralState { - InIntegerPart, - InDecimalPart(FormatNumberLiteralDecimalPart), - InExponent(FormatNumberLiteralExponent), + IntegerPart, + DecimalPart(FormatNumberLiteralDecimalPart), + Exponent(FormatNumberLiteralExponent), } use FormatNumberLiteralState::*; struct FormatNumberLiteralDecimalPart { @@ -65,7 +65,7 @@ fn format_trimmed_number(text: &str) -> Cow { let mut copied_or_ignored_chars = 0usize; let mut iter = text.chars().enumerate(); let mut curr = iter.next(); - let mut state = InIntegerPart; + let mut state = IntegerPart; // Will be filled only if and when the first place that needs reformatting is detected. let mut cleaned_text = String::new(); @@ -90,7 +90,7 @@ fn format_trimmed_number(text: &str) -> Cow { // Look for termination of the decimal part or exponent and see if we need to print it differently. match (&state, curr_or_none_terminator_char) { ( - InDecimalPart(FormatNumberLiteralDecimalPart { + DecimalPart(FormatNumberLiteralDecimalPart { dot_index, last_non_zero_index: None, }), @@ -107,7 +107,7 @@ fn format_trimmed_number(text: &str) -> Cow { copied_or_ignored_chars = curr_index; } ( - InDecimalPart(FormatNumberLiteralDecimalPart { + DecimalPart(FormatNumberLiteralDecimalPart { last_non_zero_index: Some(last_non_zero_index), .. }), @@ -118,7 +118,7 @@ fn format_trimmed_number(text: &str) -> Cow { copied_or_ignored_chars = curr_index; } ( - InExponent(FormatNumberLiteralExponent { + Exponent(FormatNumberLiteralExponent { e_index, first_non_zero_index: None, .. @@ -130,7 +130,7 @@ fn format_trimmed_number(text: &str) -> Cow { copied_or_ignored_chars = curr_index; } ( - InExponent(FormatNumberLiteralExponent { + Exponent(FormatNumberLiteralExponent { e_index, is_negative, first_digit_index: Some(first_digit_index), @@ -155,13 +155,13 @@ fn format_trimmed_number(text: &str) -> Cow { match (&state, curr) { // Cases entering or remaining in decimal part (_, Some((curr_index, '.'))) => { - state = InDecimalPart(FormatNumberLiteralDecimalPart { + state = DecimalPart(FormatNumberLiteralDecimalPart { dot_index: curr_index, last_non_zero_index: None, }); } - (InDecimalPart(decimal_part), Some((curr_index, '1'..='9'))) => { - state = InDecimalPart(FormatNumberLiteralDecimalPart { + (DecimalPart(decimal_part), Some((curr_index, '1'..='9'))) => { + state = DecimalPart(FormatNumberLiteralDecimalPart { last_non_zero_index: Some(unsafe { // We've already entered InDecimalPart, so curr_index must be >0 NonZeroUsize::new_unchecked(curr_index) @@ -171,21 +171,21 @@ fn format_trimmed_number(text: &str) -> Cow { } // Cases entering or remaining in exponent (_, Some((curr_index, 'e'))) => { - state = InExponent(FormatNumberLiteralExponent { + state = Exponent(FormatNumberLiteralExponent { e_index: curr_index, is_negative: false, first_digit_index: None, first_non_zero_index: None, }); } - (InExponent(exponent), Some((_, '-'))) => { - state = InExponent(FormatNumberLiteralExponent { + (Exponent(exponent), Some((_, '-'))) => { + state = Exponent(FormatNumberLiteralExponent { is_negative: true, ..*exponent }); } ( - InExponent( + Exponent( exponent @ FormatNumberLiteralExponent { first_digit_index: None, .. @@ -193,7 +193,7 @@ fn format_trimmed_number(text: &str) -> Cow { ), Some((curr_index, curr_char @ '0'..='9')), ) => { - state = InExponent(FormatNumberLiteralExponent { + state = Exponent(FormatNumberLiteralExponent { first_digit_index: Some(unsafe { // We've already entered InExponent, so curr_index must be >0 NonZeroUsize::new_unchecked(curr_index) @@ -210,7 +210,7 @@ fn format_trimmed_number(text: &str) -> Cow { }); } ( - InExponent( + Exponent( exponent @ FormatNumberLiteralExponent { first_non_zero_index: None, .. @@ -218,7 +218,7 @@ fn format_trimmed_number(text: &str) -> Cow { ), Some((curr_index, '1'..='9')), ) => { - state = InExponent(FormatNumberLiteralExponent { + state = Exponent(FormatNumberLiteralExponent { first_non_zero_index: Some(unsafe { NonZeroUsize::new_unchecked(curr_index) }), ..*exponent });