diff --git a/crates/oxc_formatter/src/formatter/token/number.rs b/crates/oxc_formatter/src/formatter/token/number.rs index 25ecb769ad46e..8879671b9852a 100644 --- a/crates/oxc_formatter/src/formatter/token/number.rs +++ b/crates/oxc_formatter/src/formatter/token/number.rs @@ -117,6 +117,14 @@ pub fn format_trimmed_number(text: &str, options: NumberFormatOptions) -> Cow<'_ use FormatNumberLiteralState::{DecimalPart, Exponent, IntegerPart}; let text = text.cow_to_ascii_lowercase(); + + // Bail out for numbers with numeric separators (underscores). + // Prettier's regex-based approach preserves them implicitly because `\d` doesn't match `_`. + // The only transformation that still applies is adding a leading zero (`.1_1` → `0.1_1`). + if text.contains('_') { + return if text.starts_with('.') { Cow::Owned(format!("0{text}")) } else { text }; + } + let mut copied_or_ignored_chars = 0usize; let mut iter = text.bytes().enumerate(); let mut curr = iter.next(); diff --git a/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js b/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js new file mode 100644 index 0000000000000..d4fc689e07cca --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js @@ -0,0 +1,4 @@ +// Issue #18968 - numeric separators should be preserved +const x = 123.000_000_000_000_000_000_000_0; +const y = 1_000_000; +const z = 0.000_1; diff --git a/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js.snap b/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js.snap new file mode 100644 index 0000000000000..1d97730f46912 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/literal/numeric-separator.js.snap @@ -0,0 +1,27 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +// Issue #18968 - numeric separators should be preserved +const x = 123.000_000_000_000_000_000_000_0; +const y = 1_000_000; +const z = 0.000_1; + +==================== Output ==================== +------------------ +{ printWidth: 80 } +------------------ +// Issue #18968 - numeric separators should be preserved +const x = 123.000_000_000_000_000_000_000_0; +const y = 1_000_000; +const z = 0.000_1; + +------------------- +{ printWidth: 100 } +------------------- +// Issue #18968 - numeric separators should be preserved +const x = 123.000_000_000_000_000_000_000_0; +const y = 1_000_000; +const z = 0.000_1; + +===================== End =====================