@@ -762,8 +762,6 @@ impl<'a> Codegen<'a> {
762762 // and use self.print_str directly instead of returning intermediate strings
763763 #[ expect( clippy:: cast_possible_truncation, clippy:: cast_sign_loss, clippy:: cast_possible_wrap) ]
764764 fn print_minified_number ( & mut self , num : f64 , buffer : & mut dragonbox_ecma:: Buffer ) {
765- use cow_utils:: CowUtils ;
766-
767765 if num < 1000.0 && num. fract ( ) == 0.0 {
768766 self . print_str ( buffer. format ( num) ) ;
769767 self . need_space_before_dot = self . code_len ( ) ;
@@ -776,68 +774,112 @@ impl<'a> Codegen<'a> {
776774 s = & s[ 1 ..] ;
777775 }
778776
779- let s = s. cow_replacen ( "e+" , "e" , 1 ) ;
780-
781777 // Track the best candidate found so far
782- let mut best_candidate = s. clone ( ) ;
783- let mut best_len = best_candidate. len ( ) ;
784-
785- // Check hex format for integers
778+ // Check hex format for integers first
786779 if num. fract ( ) == 0.0 {
780+ // For integers, apply e+ replacement first, then check optimizations
781+ let s = if let Some ( ( prefix, suffix) ) = s. split_once ( "e+" ) {
782+ format ! ( "{prefix}e{suffix}" ) . into ( )
783+ } else {
784+ s. into ( )
785+ } ;
786+
787+ let mut best_candidate: std:: borrow:: Cow < ' _ , str > = s;
788+ let mut best_len = best_candidate. len ( ) ;
789+
787790 let hex_candidate = format ! ( "0x{:x}" , num as u128 ) ;
788791 if hex_candidate. len ( ) < best_len {
789792 best_candidate = hex_candidate. into ( ) ;
790793 best_len = best_candidate. len ( ) ;
791794 }
792- }
793-
794- // Check for scientific notation optimizations for numbers starting with ".0"
795- if best_candidate. starts_with ( ".0" ) {
796- if let Some ( ( i, _) ) = best_candidate[ 1 ..] . bytes ( ) . enumerate ( ) . find ( |( _, c) | * c != b'0' )
795+
796+ // Check for numbers ending with zeros (but not hex numbers)
797+ if best_candidate. ends_with ( '0' ) && !best_candidate. starts_with ( "0x" ) {
798+ if let Some ( len) = best_candidate. bytes ( ) . rev ( ) . position ( |c| c != b'0' ) {
799+ let base = & best_candidate[ 0 ..best_candidate. len ( ) - len] ;
800+ let scientific_candidate = format ! ( "{base}e{len}" ) ;
801+ if scientific_candidate. len ( ) < best_len {
802+ best_candidate = scientific_candidate. into ( ) ;
803+ best_len = best_candidate. len ( ) ;
804+ }
805+ }
806+ }
807+
808+ // Check for scientific notation optimization: `1.2e101` -> `12e100`
809+ if let Some ( ( integer, point, exponent) ) = best_candidate
810+ . split_once ( '.' )
811+ . and_then ( |( a, b) | b. split_once ( 'e' ) . map ( |e| ( a, e. 0 , e. 1 ) ) )
797812 {
798- let len = i + 1 ; // `+1` to include the dot.
799- let digits = & best_candidate[ len..] ;
800- let scientific_candidate = format ! ( "{digits}e-{}" , digits. len( ) + len - 1 ) ;
801- if scientific_candidate. len ( ) < best_len {
802- best_candidate = scientific_candidate. into ( ) ;
803- best_len = best_candidate. len ( ) ;
813+ let new_exp = exponent. parse :: < isize > ( ) . unwrap ( ) - point. len ( ) as isize ;
814+ let optimized_candidate = format ! ( "{integer}{point}e{new_exp}" ) ;
815+ if optimized_candidate. len ( ) < best_len {
816+ best_candidate = optimized_candidate. into ( ) ;
804817 }
805818 }
806- }
807-
808- // Check for numbers ending with zeros (but not hex numbers)
809- if best_candidate. ends_with ( '0' ) && !best_candidate. starts_with ( "0x" ) {
810- if let Some ( ( len, _) ) =
811- best_candidate. bytes ( ) . rev ( ) . enumerate ( ) . find ( |( _, c) | * c != b'0' )
819+
820+ // Print the best candidate and update need_space_before_dot
821+ if !best_candidate. bytes ( ) . any ( |b| matches ! ( b, b'.' | b'e' | b'x' ) ) {
822+ self . print_str ( & best_candidate) ;
823+ self . need_space_before_dot = self . code_len ( ) ;
824+ } else {
825+ self . print_str ( & best_candidate) ;
826+ }
827+ } else {
828+ // For non-integers, apply e+ replacement and check for ".0" optimizations
829+ let s = if let Some ( ( prefix, suffix) ) = s. split_once ( "e+" ) {
830+ format ! ( "{prefix}e{suffix}" ) . into ( )
831+ } else {
832+ s. into ( )
833+ } ;
834+
835+ let mut best_candidate: std:: borrow:: Cow < ' _ , str > = s;
836+ let mut best_len = best_candidate. len ( ) ;
837+
838+ // Check for scientific notation optimizations for numbers starting with ".0"
839+ if best_candidate. starts_with ( ".0" ) {
840+ if let Some ( i) = best_candidate[ 1 ..] . bytes ( ) . position ( |c| c != b'0' ) {
841+ let len = i + 1 ; // `+1` to include the dot.
842+ let digits = & best_candidate[ len..] ;
843+ let scientific_candidate = format ! ( "{digits}e-{}" , digits. len( ) + len - 1 ) ;
844+ if scientific_candidate. len ( ) < best_len {
845+ best_candidate = scientific_candidate. into ( ) ;
846+ best_len = best_candidate. len ( ) ;
847+ }
848+ }
849+ }
850+
851+ // Check for numbers ending with zeros
852+ if best_candidate. ends_with ( '0' ) {
853+ if let Some ( len) = best_candidate. bytes ( ) . rev ( ) . position ( |c| c != b'0' ) {
854+ let base = & best_candidate[ 0 ..best_candidate. len ( ) - len] ;
855+ let scientific_candidate = format ! ( "{base}e{len}" ) ;
856+ if scientific_candidate. len ( ) < best_len {
857+ best_candidate = scientific_candidate. into ( ) ;
858+ best_len = best_candidate. len ( ) ;
859+ }
860+ }
861+ }
862+
863+ // Check for scientific notation optimization: `1.2e101` -> `12e100`
864+ if let Some ( ( integer, point, exponent) ) = best_candidate
865+ . split_once ( '.' )
866+ . and_then ( |( a, b) | b. split_once ( 'e' ) . map ( |e| ( a, e. 0 , e. 1 ) ) )
812867 {
813- let base = & best_candidate[ 0 ..best_candidate. len ( ) - len] ;
814- let scientific_candidate = format ! ( "{base}e{len}" ) ;
815- if scientific_candidate. len ( ) < best_len {
816- best_candidate = scientific_candidate. into ( ) ;
817- best_len = best_candidate. len ( ) ;
868+ let new_exp = exponent. parse :: < isize > ( ) . unwrap ( ) - point. len ( ) as isize ;
869+ let optimized_candidate = format ! ( "{integer}{point}e{new_exp}" ) ;
870+ if optimized_candidate. len ( ) < best_len {
871+ best_candidate = optimized_candidate. into ( ) ;
818872 }
819873 }
820- }
821-
822- // Check for scientific notation optimization: `1.2e101` -> `12e100`
823- if let Some ( ( integer, point, exponent) ) = best_candidate
824- . split_once ( '.' )
825- . and_then ( |( a, b) | b. split_once ( 'e' ) . map ( |e| ( a, e. 0 , e. 1 ) ) )
826- {
827- let new_exp = exponent. parse :: < isize > ( ) . unwrap ( ) - point. len ( ) as isize ;
828- let optimized_candidate = format ! ( "{integer}{point}e{new_exp}" ) ;
829- if optimized_candidate. len ( ) < best_len {
830- best_candidate = optimized_candidate. into ( ) ;
874+
875+ // Print the best candidate and update need_space_before_dot
876+ if !best_candidate. bytes ( ) . any ( |b| matches ! ( b, b'.' | b'e' | b'x' ) ) {
877+ self . print_str ( & best_candidate) ;
878+ self . need_space_before_dot = self . code_len ( ) ;
879+ } else {
880+ self . print_str ( & best_candidate) ;
831881 }
832882 }
833-
834- // Print the best candidate
835- self . print_str ( & best_candidate) ;
836-
837- // Update need_space_before_dot based on the final output
838- if !best_candidate. bytes ( ) . any ( |b| matches ! ( b, b'.' | b'e' | b'x' ) ) {
839- self . need_space_before_dot = self . code_len ( ) ;
840- }
841883 }
842884
843885 fn add_source_mapping ( & mut self , span : Span ) {
0 commit comments