@@ -73,7 +73,7 @@ declare_oxc_lint!(
7373 PreferNumberProperties ,
7474 unicorn,
7575 restriction,
76- pending
76+ fix
7777) ;
7878
7979impl Rule for PreferNumberProperties {
@@ -100,40 +100,45 @@ impl Rule for PreferNumberProperties {
100100 } ;
101101
102102 if GLOBAL_OBJECT_NAMES . contains ( & ident_name. name . as_str ( ) ) {
103- match member_expr. static_property_name ( ) {
104- Some ( "NaN" ) if self . check_nan => {
105- ctx. diagnostic ( prefer_number_properties_diagnostic (
106- member_expr. span ( ) ,
107- "NaN" ,
108- ) ) ;
109- }
110- Some ( "Infinity" ) if self . check_infinity => {
111- ctx. diagnostic ( prefer_number_properties_diagnostic (
112- member_expr. span ( ) ,
113- "Infinity" ,
114- ) ) ;
115- }
116- _ => { }
103+ let Some ( name) = member_expr. static_property_name ( ) else { return } ;
104+ if ( name == "NaN" && self . check_nan )
105+ || ( name == "Infinity" && self . check_infinity )
106+ {
107+ ctx. diagnostic_with_fix (
108+ prefer_number_properties_diagnostic ( member_expr. span ( ) , name) ,
109+ |fixer| fixer. replace ( ident_name. span , "Number" ) ,
110+ ) ;
117111 }
118112 }
119113 }
120114 AstKind :: IdentifierReference ( ident_ref)
121115 if ctx. is_reference_to_global_variable ( ident_ref) =>
122116 {
123- match ident_ref. name . as_str ( ) {
124- "NaN" if self . check_nan => {
125- ctx. diagnostic ( prefer_number_properties_diagnostic (
126- ident_ref. span ,
127- & ident_ref. name ,
128- ) ) ;
129- }
130- "Infinity" if self . check_infinity => {
131- ctx. diagnostic ( prefer_number_properties_diagnostic (
132- ident_ref. span ,
133- & ident_ref. name ,
134- ) ) ;
135- }
136- _ => { }
117+ if ( ident_ref. name . as_str ( ) == "NaN" && self . check_nan )
118+ || ( ident_ref. name . as_str ( ) == "Infinity" && self . check_infinity )
119+ || ( matches ! (
120+ ident_ref. name. as_str( ) ,
121+ "isNaN" | "isFinite" | "parseFloat" | "parseInt"
122+ ) && matches ! (
123+ ctx. nodes( ) . parent_kind( node. id( ) ) ,
124+ Some ( AstKind :: ObjectProperty ( _) )
125+ ) )
126+ {
127+ ctx. diagnostic_with_fix (
128+ prefer_number_properties_diagnostic ( ident_ref. span , & ident_ref. name ) ,
129+ |fixer| match ctx. nodes ( ) . parent_kind ( node. id ( ) ) {
130+ Some ( AstKind :: ObjectProperty ( object_property) )
131+ if object_property. shorthand =>
132+ {
133+ fixer. insert_text_before (
134+ & ident_ref. span ,
135+ format ! ( "{}: Number." , ident_ref. name. as_str( ) ) ,
136+ )
137+ }
138+ Some ( _) => fixer. insert_text_before ( & ident_ref. span , "Number." ) ,
139+ None => unreachable ! ( ) ,
140+ } ,
141+ ) ;
137142 }
138143 }
139144 AstKind :: CallExpression ( call_expr) => {
@@ -148,10 +153,20 @@ impl Rule for PreferNumberProperties {
148153 }
149154 }
150155
151- ctx. diagnostic ( prefer_number_properties_diagnostic (
152- call_expr. callee . span ( ) ,
153- ident_name,
154- ) ) ;
156+ ctx. diagnostic_with_fix (
157+ prefer_number_properties_diagnostic ( call_expr. callee . span ( ) , ident_name) ,
158+ |fixer| match & call_expr. callee {
159+ Expression :: Identifier ( ident) => {
160+ fixer. insert_text_before ( & ident. span , "Number." )
161+ }
162+ match_member_expression ! ( Expression ) => {
163+ let member_expr = call_expr. callee . to_member_expression ( ) ;
164+
165+ fixer. replace ( member_expr. object ( ) . span ( ) , "Number" )
166+ }
167+ _ => unreachable ! ( ) ,
168+ } ,
169+ ) ;
155170 }
156171 }
157172 _ => { }
@@ -402,27 +417,27 @@ function inner() {
402417 ( r"self.parseFloat(foo);" , None ) ,
403418 ( r"globalThis.NaN" , None ) ,
404419 ( r"-globalThis.Infinity" , Some ( json!( [ { "checkInfinity" : true } ] ) ) ) ,
405- // (
406- // r"const options = {
407- // normalize: parseFloat,
408- // parseInt,
409- // };
420+ (
421+ r"const options = {
422+ normalize: parseFloat,
423+ parseInt,
424+ };
410425
411- // run(foo, options);",
412- // None,
413- // ),
426+ run(foo, options);" ,
427+ None ,
428+ ) ,
414429 ] ;
415430
416- let _fix = vec ! [
431+ let fix = vec ! [
417432 (
418433 r#"const a = parseInt("10", 2);
419434 const b = parseFloat("10.5");
420435 const c = isNaN(10);
421436 const d = isFinite(10);"# ,
422437 r#"const a = Number.parseInt("10", 2);
423438 const b = Number.parseFloat("10.5");
424- const c = isNaN(10);
425- const d = isFinite(10);"# ,
439+ const c = Number. isNaN(10);
440+ const d = Number. isFinite(10);"# ,
426441 None :: <Value >,
427442 ) ,
428443 ( "const foo = NaN;" , "const foo = Number.NaN;" , None ) ,
@@ -439,5 +454,6 @@ function inner() {
439454 ] ;
440455
441456 Tester :: new ( PreferNumberProperties :: NAME , PreferNumberProperties :: PLUGIN , pass, fail)
457+ . expect_fix ( fix)
442458 . test_and_snapshot ( ) ;
443459}
0 commit comments