mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(linter): support rest params for prefer_promise_reject_errors (#8468)
fixed: https://github.com/oxc-project/oxc/pull/8254#issuecomment-2587461210
This commit is contained in:
parent
de5b28809a
commit
c6260c278b
2 changed files with 64 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
use oxc_allocator::Box;
|
use oxc_allocator::Box;
|
||||||
|
use oxc_ast::ast::MemberExpression;
|
||||||
use oxc_ast::{
|
use oxc_ast::{
|
||||||
ast::{Argument, CallExpression, Expression, FormalParameters},
|
ast::{Argument, CallExpression, Expression, FormalParameters},
|
||||||
AstKind,
|
AstKind,
|
||||||
|
|
@ -136,15 +137,13 @@ fn check_reject_call(call_expr: &CallExpression, ctx: &LintContext, allow_empty_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::float_cmp, clippy::cast_precision_loss)]
|
||||||
fn check_reject_in_function(
|
fn check_reject_in_function(
|
||||||
params: &Box<'_, FormalParameters<'_>>,
|
params: &Box<'_, FormalParameters<'_>>,
|
||||||
ctx: &LintContext,
|
ctx: &LintContext,
|
||||||
allow_empty_reject: bool,
|
allow_empty_reject: bool,
|
||||||
) {
|
) {
|
||||||
if params.parameters_count() <= 1 {
|
if params.items.len() >= 2 {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some(reject_arg) = params.items[1].pattern.get_binding_identifier() else {
|
let Some(reject_arg) = params.items[1].pattern.get_binding_identifier() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -157,10 +156,46 @@ fn check_reject_in_function(
|
||||||
check_reject_call(call_expr, ctx, allow_empty_reject);
|
check_reject_call(call_expr, ctx, allow_empty_reject);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(rest_param) = ¶ms.rest else { return };
|
||||||
|
let Some(rest_arg) = rest_param.argument.get_binding_identifier() else { return };
|
||||||
|
let rest_index = (1 - params.items.len()) as f64;
|
||||||
|
for reference in ctx.symbol_references(rest_arg.symbol_id()) {
|
||||||
|
let node = ctx.nodes().get_node(reference.node_id());
|
||||||
|
|
||||||
|
if !matches!(node.kind(), AstKind::IdentifierReference(_)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(parent) = ctx.nodes().parent_node(reference.node_id()) else { continue };
|
||||||
|
let AstKind::MemberExpression(MemberExpression::ComputedMemberExpression(member_expr)) =
|
||||||
|
parent.kind()
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Expression::NumericLiteral(literal) = &member_expr.expression else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if literal.value != rest_index {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(node) = ctx.nodes().parent_node(parent.id()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let AstKind::CallExpression(call_expr) = node.kind() {
|
||||||
|
check_reject_call(call_expr, ctx, allow_empty_reject);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_undefined(arg: &Argument) -> bool {
|
fn is_undefined(arg: &Argument) -> bool {
|
||||||
match arg.as_expression().map(oxc_ast::ast::Expression::get_inner_expression) {
|
match arg.as_expression().map(Expression::get_inner_expression) {
|
||||||
Some(Expression::Identifier(ident)) => ident.name == "undefined",
|
Some(Expression::Identifier(ident)) => ident.name == "undefined",
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +231,12 @@ fn test() {
|
||||||
("Promise.reject(foo.bar ??= 5)", None),
|
("Promise.reject(foo.bar ??= 5)", None),
|
||||||
("Promise.reject(foo[bar] ??= 5)", None),
|
("Promise.reject(foo[bar] ??= 5)", None),
|
||||||
("class C { #reject; foo() { Promise.#reject(5); } }", None),
|
("class C { #reject; foo() { Promise.#reject(5); } }", None),
|
||||||
("class C { #error; foo() { Promise.reject(this.#error); } }", None)
|
("class C { #error; foo() { Promise.reject(this.#error); } }", None),
|
||||||
|
("new Promise(function (resolve, ...rest) { rest[0](new Error('')); });", None),
|
||||||
|
("new Promise(function (...rest) { rest[0](new Error('')); });", None),
|
||||||
|
("new Promise(function (...rest) { rest[1](new Error('')); });", None),
|
||||||
|
// This is fundamentally false, but we can not recognize the value of `i`.
|
||||||
|
("new Promise(function (resolve, ...rest) { rest[i](5); });", None),
|
||||||
];
|
];
|
||||||
|
|
||||||
let fail = vec; });", None),
|
||||||
|
("new Promise(function (...rest) { rest[1](5); });", None),
|
||||||
];
|
];
|
||||||
|
|
||||||
Tester::new(PreferPromiseRejectErrors::NAME, PreferPromiseRejectErrors::PLUGIN, pass, fail)
|
Tester::new(PreferPromiseRejectErrors::NAME, PreferPromiseRejectErrors::PLUGIN, pass, fail)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
---
|
---
|
||||||
source: crates/oxc_linter/src/tester.rs
|
source: crates/oxc_linter/src/tester.rs
|
||||||
assertion_line: 356
|
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
|
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
|
||||||
╭─[prefer_promise_reject_errors.tsx:1:1]
|
╭─[prefer_promise_reject_errors.tsx:1:1]
|
||||||
|
|
@ -240,3 +238,15 @@ snapshot_kind: text
|
||||||
1 │ Promise.reject(foo &&= 5)
|
1 │ Promise.reject(foo &&= 5)
|
||||||
· ─────────────────────────
|
· ─────────────────────────
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
|
||||||
|
╭─[prefer_promise_reject_errors.tsx:1:43]
|
||||||
|
1 │ new Promise(function (resolve, ...rest) { rest[0](5); });
|
||||||
|
· ──────────
|
||||||
|
╰────
|
||||||
|
|
||||||
|
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
|
||||||
|
╭─[prefer_promise_reject_errors.tsx:1:34]
|
||||||
|
1 │ new Promise(function (...rest) { rest[1](5); });
|
||||||
|
· ──────────
|
||||||
|
╰────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue