@@ -5,9 +5,9 @@ use oxc_ast::{
55use oxc_diagnostics:: OxcDiagnostic ;
66
77use oxc_macros:: declare_oxc_lint;
8- use oxc_span:: Span ;
8+ use oxc_span:: { GetSpan , Span } ;
99
10- use crate :: { ast_util:: is_method_call, context:: LintContext , rule:: Rule , AstNode } ;
10+ use crate :: { ast_util:: is_method_call, context:: LintContext , fixer :: Fix , rule:: Rule , AstNode } ;
1111
1212fn no_single_promise_in_promise_methods_diagnostic ( span0 : Span , x1 : & str ) -> OxcDiagnostic {
1313 OxcDiagnostic :: warn ( format ! ( "eslint-plugin-unicorn(no-single-promise-in-promise-methods): Wrapping single-element array with `Promise.{x1}()` is unnecessary." ) )
@@ -57,7 +57,23 @@ impl Rule for NoSinglePromiseInPromiseMethods {
5757 return ;
5858 } ;
5959
60- if !is_promise_method_with_single_element_array ( call_expr) {
60+ if !is_promise_method_with_single_argument ( call_expr) {
61+ return ;
62+ }
63+ let Some ( first_argument) = call_expr. arguments [ 0 ] . as_expression ( ) else {
64+ return ;
65+ } ;
66+ let first_argument = first_argument. without_parenthesized ( ) ;
67+ let Expression :: ArrayExpression ( first_argument_array_expr) = first_argument else {
68+ return ;
69+ } ;
70+
71+ if first_argument_array_expr. elements . len ( ) != 1 {
72+ return ;
73+ }
74+
75+ let first = & first_argument_array_expr. elements [ 0 ] ;
76+ if !first. is_expression ( ) {
6177 return ;
6278 }
6379
@@ -68,34 +84,33 @@ impl Rule for NoSinglePromiseInPromiseMethods {
6884 . static_property_info ( )
6985 . expect ( "callee is a static property" ) ;
7086
71- ctx. diagnostic ( no_single_promise_in_promise_methods_diagnostic ( info. 0 , info. 1 ) ) ;
87+ let diagnostic = no_single_promise_in_promise_methods_diagnostic ( info. 0 , info. 1 ) ;
88+ ctx. diagnostic_with_fix ( diagnostic, || {
89+ let elem_text = first. span ( ) . source_text ( ctx. source_text ( ) ) ;
90+
91+ let is_directly_in_await = ctx
92+ . semantic ( )
93+ . nodes ( )
94+ // get first non-parenthesis parent node
95+ . iter_parents ( node. id ( ) )
96+ . skip ( 1 ) // first node is the call expr
97+ . find ( |parent| !matches ! ( parent. kind( ) , AstKind :: ParenthesizedExpression ( _) ) )
98+ // check if it's an `await ...` expression
99+ . is_some_and ( |parent| matches ! ( parent. kind( ) , AstKind :: AwaitExpression ( _) ) ) ;
100+
101+ let call_span = call_expr. span ;
102+
103+ if is_directly_in_await {
104+ Fix :: new ( elem_text, call_span)
105+ } else {
106+ Fix :: new ( format ! ( "Promise.resolve({elem_text})" ) , call_span)
107+ }
108+ } ) ;
72109 }
73110}
74111
75- fn is_promise_method_with_single_element_array ( call_expr : & CallExpression ) -> bool {
76- if !is_method_call (
77- call_expr,
78- Some ( & [ "Promise" ] ) ,
79- Some ( & [ "all" , "any" , "race" ] ) ,
80- Some ( 1 ) ,
81- Some ( 1 ) ,
82- ) {
83- return false ;
84- }
85-
86- let Some ( first_argument) = call_expr. arguments [ 0 ] . as_expression ( ) else {
87- return false ;
88- } ;
89- let first_argument = first_argument. without_parenthesized ( ) ;
90- let Expression :: ArrayExpression ( first_argument_array_expr) = first_argument else {
91- return false ;
92- } ;
93-
94- if first_argument_array_expr. elements . len ( ) != 1 {
95- return false ;
96- }
97-
98- first_argument_array_expr. elements [ 0 ] . is_expression ( )
112+ fn is_promise_method_with_single_argument ( call_expr : & CallExpression ) -> bool {
113+ is_method_call ( call_expr, Some ( & [ "Promise" ] ) , Some ( & [ "all" , "any" , "race" ] ) , Some ( 1 ) , Some ( 1 ) )
99114}
100115
101116#[ test]
@@ -183,5 +198,13 @@ fn test() {
183198 "Promise.all([null]).then()" ,
184199 ] ;
185200
186- Tester :: new ( NoSinglePromiseInPromiseMethods :: NAME , pass, fail) . test_and_snapshot ( ) ;
201+ let fix = vec ! [
202+ ( "Promise.all([null]).then()" , "Promise.resolve(null).then()" , None ) ,
203+ ( "let x = await Promise.all([foo()])" , "let x = await foo()" , None ) ,
204+ ( "let x = await (Promise.all([foo()]))" , "let x = await (foo())" , None ) ,
205+ ] ;
206+
207+ Tester :: new ( NoSinglePromiseInPromiseMethods :: NAME , pass, fail)
208+ . expect_fix ( fix)
209+ . test_and_snapshot ( ) ;
187210}
0 commit comments