From 7dd0f5ec564931841b08d9612ec02d8863778cfb Mon Sep 17 00:00:00 2001 From: shulaoda Date: Sun, 29 Sep 2024 14:47:44 +0800 Subject: [PATCH 1/4] feat(linter): implement no-callback-in-promise --- crates/oxc_linter/src/rules.rs | 2 + .../rules/promise/no_callback_in_promise.rs | 193 ++++++++++++++++++ .../src/snapshots/no_callback_in_promise.snap | 74 +++++++ 3 files changed, 269 insertions(+) create mode 100644 crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs create mode 100644 crates/oxc_linter/src/snapshots/no_callback_in_promise.snap diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index b1fbdff96088a..4680894cb2a6c 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -471,6 +471,7 @@ mod tree_shaking { mod promise { pub mod avoid_new; pub mod catch_or_return; + pub mod no_callback_in_promise; pub mod no_new_statics; pub mod no_return_in_finally; pub mod param_names; @@ -765,6 +766,7 @@ oxc_macros::declare_all_lint_rules! { oxc::uninvoked_array_callback, promise::avoid_new, promise::catch_or_return, + promise::no_callback_in_promise, promise::no_new_statics, promise::no_return_in_finally, promise::param_names, diff --git a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs new file mode 100644 index 0000000000000..8ccb33179d979 --- /dev/null +++ b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs @@ -0,0 +1,193 @@ +use oxc_ast::{ + ast::{Expression, MemberExpression}, + AstKind, +}; +use oxc_diagnostics::OxcDiagnostic; +use oxc_macros::declare_oxc_lint; +use oxc_span::{GetSpan, Span}; + +use crate::{context::LintContext, rule::Rule, AstNode}; + +static CALLBACKS: [&str; 4] = ["done", "cb", "callback", "next"]; + +fn no_callback_in_promise_diagnostic(span: Span) -> OxcDiagnostic { + OxcDiagnostic::warn("Avoid calling back inside of a promise").with_label(span) +} + +#[derive(Debug, Default, Clone)] +pub struct NoCallbackInPromise(Box); + +#[derive(Debug, Default, Clone)] +pub struct NoCallbackInPromiseConfig { + exceptions: Vec, +} + +impl std::ops::Deref for NoCallbackInPromise { + type Target = NoCallbackInPromiseConfig; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +declare_oxc_lint!( + /// ### What it does + /// + /// Disallows calling a callback function (`cb()`) inside a `Promise.prototype.then()` + /// or `Promise.prototype.catch()`. + /// + /// ### Why is this bad? + /// + /// Directly invoking a callback inside a `then()` or `catch()` method can lead to + /// unexpected behavior, such as the callback being called multiple times. Additionally, + /// mixing the callback and promise paradigms in this way can make the code confusing + /// and harder to maintain. + /// + /// ### Examples + /// + /// Examples of **incorrect** code for this rule: + /// ```js + /// function callback(err, data) { + /// console.log('Callback got called with:', err, data) + /// throw new Error('My error') + /// } + /// + /// Promise.resolve() + /// .then(() => callback(null, 'data')) + /// .catch((err) => callback(err.message, null)) + /// ``` + /// + /// Examples of **correct** code for this rule: + /// ```js + /// Promise.resolve() + /// .then(() => setTimeout(() => callback(null, 'data'), 0)) + /// .catch((err) => setTimeout(() => callback(err.message, null), 0)) + /// ``` + NoCallbackInPromise, + correctness, +); + +impl Rule for NoCallbackInPromise { + fn from_configuration(value: serde_json::Value) -> Self { + Self(Box::new(NoCallbackInPromiseConfig { + exceptions: value + .get(0) + .and_then(|v| v.get("exceptions")) + .and_then(serde_json::Value::as_array) + .map(|v| { + v.iter() + .filter_map(serde_json::Value::as_str) + .map(ToString::to_string) + .collect() + }) + .unwrap_or_default(), + })) + } + + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + if !self.is_callback(node) { + if Self::has_promise_callback(node) { + let Some(call_expr) = node.kind().as_call_expression() else { + return; + }; + + let Some(id) = call_expr.arguments.first().and_then(|arg| { + arg.as_expression().and_then(Expression::get_identifier_reference) + }) else { + return; + }; + + let name = id.name.as_str(); + if !self.exceptions.iter().any(|exception| exception == name) + && CALLBACKS.contains(&name) + { + ctx.diagnostic(no_callback_in_promise_diagnostic(id.span)); + } + } + } else if ctx + .nodes() + .iter_parents(node.id()) + .skip(1) + .any(|node| Self::is_inside_promise(node, ctx)) + { + ctx.diagnostic(no_callback_in_promise_diagnostic(node.span())); + } + } +} + +impl NoCallbackInPromise { + fn is_inside_promise(node: &AstNode, ctx: &LintContext) -> bool { + if !matches!(node.kind(), AstKind::Function(_) | AstKind::ArrowFunctionExpression(_)) + || !matches!(ctx.nodes().parent_kind(node.id()), Some(AstKind::Argument(_))) + { + return false; + } + + ctx.nodes().iter_parents(node.id()).nth(2).is_some_and(Self::has_promise_callback) + } + + fn has_promise_callback(node: &AstNode) -> bool { + let AstKind::CallExpression(call_expr) = node.kind() else { + return false; + }; + + matches!( + call_expr + .callee + .as_member_expression() + .and_then(MemberExpression::static_property_name), + Some("then" | "catch") + ) + } + + fn is_callback(&self, node: &AstNode) -> bool { + let AstKind::CallExpression(call_expr) = node.kind() else { + return false; + }; + + call_expr.callee.get_identifier_reference().is_some_and(|id| { + let callbacks: Vec<_> = CALLBACKS + .iter() + .filter(|&&item| !self.exceptions.iter().any(|exception| exception == item)) + .collect(); + + callbacks.contains(&&id.name.as_str()) + }) + } +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + ("function thing(cb) { cb() }", None), + ("doSomething(function(err) { cb(err) })", None), + ("function thing(callback) { callback() }", None), + ("doSomething(function(err) { callback(err) })", None), + ("let thing = (cb) => cb()", None), + ("doSomething(err => cb(err))", None), + ("a.then(() => next())", Some(serde_json::json!([{ "exceptions": ["next"] }]))), + ( + "a.then(() => next()).catch((err) => next(err))", + Some(serde_json::json!([{ "exceptions": ["next"] }])), + ), + ("a.then(next)", Some(serde_json::json!([{ "exceptions": ["next"] }]))), + ("a.then(next).catch(next)", Some(serde_json::json!([{ "exceptions": ["next"] }]))), + ]; + + let fail = vec![ + ("a.then(cb)", None), + ("a.then(() => cb())", None), + ("a.then(function(err) { cb(err) })", None), + ("a.then(function(data) { cb(data) }, function(err) { cb(err) })", None), + ("a.catch(function(err) { cb(err) })", None), + ("a.then(callback)", None), + ("a.then(() => callback())", None), + ("a.then(function(err) { callback(err) })", None), + ("a.then(function(data) { callback(data) }, function(err) { callback(err) })", None), + ("a.catch(function(err) { callback(err) })", None), + ]; + + Tester::new(NoCallbackInPromise::NAME, pass, fail).test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap new file mode 100644 index 0000000000000..5382440b571fd --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap @@ -0,0 +1,74 @@ +--- +source: crates/oxc_linter/src/tester.rs +--- + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:8] + 1 │ a.then(cb) + · ── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:14] + 1 │ a.then(() => cb()) + · ──── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:24] + 1 │ a.then(function(err) { cb(err) }) + · ─────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:25] + 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) + · ──────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:53] + 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) + · ─────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:25] + 1 │ a.catch(function(err) { cb(err) }) + · ─────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:8] + 1 │ a.then(callback) + · ──────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:14] + 1 │ a.then(() => callback()) + · ────────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:24] + 1 │ a.then(function(err) { callback(err) }) + · ───────────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:25] + 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) + · ────────────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:59] + 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) + · ───────────── + ╰──── + + ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise + ╭─[no_callback_in_promise.tsx:1:25] + 1 │ a.catch(function(err) { callback(err) }) + · ───────────── + ╰──── From 9b97d0300401a39e85a870d90d47634406879140 Mon Sep 17 00:00:00 2001 From: shulaoda Date: Sun, 6 Oct 2024 09:06:43 +0800 Subject: [PATCH 2/4] chore: follow the suggestions --- .../rules/promise/no_callback_in_promise.rs | 57 +++++++++---------- .../src/snapshots/no_callback_in_promise.snap | 12 ++++ 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs index 8ccb33179d979..2aa6bb9bb9f1a 100644 --- a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs +++ b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs @@ -4,14 +4,14 @@ use oxc_ast::{ }; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; -use oxc_span::{GetSpan, Span}; +use oxc_span::{CompactStr, GetSpan, Span}; use crate::{context::LintContext, rule::Rule, AstNode}; -static CALLBACKS: [&str; 4] = ["done", "cb", "callback", "next"]; - fn no_callback_in_promise_diagnostic(span: Span) -> OxcDiagnostic { - OxcDiagnostic::warn("Avoid calling back inside of a promise").with_label(span) + OxcDiagnostic::warn("Avoid calling back inside of a promise") + .with_help("Use `then` and `catch` directly, avoid callbacks") + .with_label(span) } #[derive(Debug, Default, Clone)] @@ -19,7 +19,7 @@ pub struct NoCallbackInPromise(Box); #[derive(Debug, Default, Clone)] pub struct NoCallbackInPromiseConfig { - exceptions: Vec, + callbacks: Vec, } impl std::ops::Deref for NoCallbackInPromise { @@ -60,8 +60,8 @@ declare_oxc_lint!( /// Examples of **correct** code for this rule: /// ```js /// Promise.resolve() - /// .then(() => setTimeout(() => callback(null, 'data'), 0)) - /// .catch((err) => setTimeout(() => callback(err.message, null), 0)) + /// .then((data) => { console.log(data) }) + /// .catch((err) => { console.error(err) }) /// ``` NoCallbackInPromise, correctness, @@ -69,18 +69,23 @@ declare_oxc_lint!( impl Rule for NoCallbackInPromise { fn from_configuration(value: serde_json::Value) -> Self { + let default_callbacks: Vec = + ["done", "cb", "callback", "next"].map(Into::into).to_vec(); + + let exceptions: Vec = value + .get(0) + .and_then(|v| v.get("exceptions")) + .and_then(serde_json::Value::as_array) + .map(|v| { + v.iter().filter_map(serde_json::Value::as_str).map(ToString::to_string).collect() + }) + .unwrap_or_default(); + Self(Box::new(NoCallbackInPromiseConfig { - exceptions: value - .get(0) - .and_then(|v| v.get("exceptions")) - .and_then(serde_json::Value::as_array) - .map(|v| { - v.iter() - .filter_map(serde_json::Value::as_str) - .map(ToString::to_string) - .collect() - }) - .unwrap_or_default(), + callbacks: default_callbacks + .into_iter() + .filter(|item| !exceptions.contains(&item.to_string())) + .collect(), })) } @@ -98,9 +103,7 @@ impl Rule for NoCallbackInPromise { }; let name = id.name.as_str(); - if !self.exceptions.iter().any(|exception| exception == name) - && CALLBACKS.contains(&name) - { + if self.callbacks.contains(&name.into()) { ctx.diagnostic(no_callback_in_promise_diagnostic(id.span)); } } @@ -145,14 +148,10 @@ impl NoCallbackInPromise { return false; }; - call_expr.callee.get_identifier_reference().is_some_and(|id| { - let callbacks: Vec<_> = CALLBACKS - .iter() - .filter(|&&item| !self.exceptions.iter().any(|exception| exception == item)) - .collect(); - - callbacks.contains(&&id.name.as_str()) - }) + call_expr + .callee + .get_identifier_reference() + .is_some_and(|id| self.callbacks.contains(&id.name.as_str().into())) } } diff --git a/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap index 5382440b571fd..28c8352f12f4f 100644 --- a/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap +++ b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap @@ -6,69 +6,81 @@ source: crates/oxc_linter/src/tester.rs 1 │ a.then(cb) · ── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:14] 1 │ a.then(() => cb()) · ──── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:24] 1 │ a.then(function(err) { cb(err) }) · ─────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) · ──────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:53] 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) · ─────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.catch(function(err) { cb(err) }) · ─────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:8] 1 │ a.then(callback) · ──────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:14] 1 │ a.then(() => callback()) · ────────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:24] 1 │ a.then(function(err) { callback(err) }) · ───────────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) · ────────────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:59] 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) · ───────────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.catch(function(err) { callback(err) }) · ───────────── ╰──── + help: Use `then` and `catch` directly, avoid callbacks From a4e7332884debce3e6769db0581807c50b641843 Mon Sep 17 00:00:00 2001 From: dalaoshu Date: Mon, 7 Oct 2024 21:11:09 +0800 Subject: [PATCH 3/4] chore: correct help message Co-authored-by: Don Isaac --- crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs index 2aa6bb9bb9f1a..febf92add2bd5 100644 --- a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs +++ b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs @@ -10,7 +10,7 @@ use crate::{context::LintContext, rule::Rule, AstNode}; fn no_callback_in_promise_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Avoid calling back inside of a promise") - .with_help("Use `then` and `catch` directly, avoid callbacks") + .with_help("Use `then` and `catch` directly") .with_label(span) } From 67d39f0b8f2ada4b2c639316e13e35bb2804b348 Mon Sep 17 00:00:00 2001 From: shulaoda Date: Mon, 7 Oct 2024 21:50:31 +0800 Subject: [PATCH 4/4] chore: follow the suggestions --- .../rules/promise/no_callback_in_promise.rs | 60 +++++++++---------- .../src/snapshots/no_callback_in_promise.snap | 24 ++++---- 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs index febf92add2bd5..507eda7786b10 100644 --- a/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs +++ b/crates/oxc_linter/src/rules/promise/no_callback_in_promise.rs @@ -1,5 +1,5 @@ use oxc_ast::{ - ast::{Expression, MemberExpression}, + ast::{CallExpression, Expression, MemberExpression}, AstKind, }; use oxc_diagnostics::OxcDiagnostic; @@ -17,11 +17,17 @@ fn no_callback_in_promise_diagnostic(span: Span) -> OxcDiagnostic { #[derive(Debug, Default, Clone)] pub struct NoCallbackInPromise(Box); -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct NoCallbackInPromiseConfig { callbacks: Vec, } +impl Default for NoCallbackInPromiseConfig { + fn default() -> Self { + Self { callbacks: vec!["callback".into(), "cb".into(), "done".into(), "next".into()] } + } +} + impl std::ops::Deref for NoCallbackInPromise { type Target = NoCallbackInPromiseConfig; @@ -69,8 +75,7 @@ declare_oxc_lint!( impl Rule for NoCallbackInPromise { fn from_configuration(value: serde_json::Value) -> Self { - let default_callbacks: Vec = - ["done", "cb", "callback", "next"].map(Into::into).to_vec(); + let mut default_config = NoCallbackInPromiseConfig::default(); let exceptions: Vec = value .get(0) @@ -81,21 +86,23 @@ impl Rule for NoCallbackInPromise { }) .unwrap_or_default(); - Self(Box::new(NoCallbackInPromiseConfig { - callbacks: default_callbacks - .into_iter() - .filter(|item| !exceptions.contains(&item.to_string())) - .collect(), - })) + default_config.callbacks.retain(|item| !exceptions.contains(&item.to_string())); + + Self(Box::new(default_config)) } fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { - if !self.is_callback(node) { - if Self::has_promise_callback(node) { - let Some(call_expr) = node.kind().as_call_expression() else { - return; - }; + let Some(call_expr) = node.kind().as_call_expression() else { + return; + }; + + let is_not_callback = call_expr + .callee + .get_identifier_reference() + .map_or(true, |id| self.callbacks.binary_search(&id.name.as_str().into()).is_err()); + if is_not_callback { + if Self::has_promise_callback(call_expr) { let Some(id) = call_expr.arguments.first().and_then(|arg| { arg.as_expression().and_then(Expression::get_identifier_reference) }) else { @@ -103,7 +110,7 @@ impl Rule for NoCallbackInPromise { }; let name = id.name.as_str(); - if self.callbacks.contains(&name.into()) { + if self.callbacks.binary_search(&name.into()).is_ok() { ctx.diagnostic(no_callback_in_promise_diagnostic(id.span)); } } @@ -126,14 +133,12 @@ impl NoCallbackInPromise { return false; } - ctx.nodes().iter_parents(node.id()).nth(2).is_some_and(Self::has_promise_callback) + ctx.nodes().iter_parents(node.id()).nth(2).is_some_and(|node| { + node.kind().as_call_expression().is_some_and(Self::has_promise_callback) + }) } - fn has_promise_callback(node: &AstNode) -> bool { - let AstKind::CallExpression(call_expr) = node.kind() else { - return false; - }; - + fn has_promise_callback(call_expr: &CallExpression) -> bool { matches!( call_expr .callee @@ -142,17 +147,6 @@ impl NoCallbackInPromise { Some("then" | "catch") ) } - - fn is_callback(&self, node: &AstNode) -> bool { - let AstKind::CallExpression(call_expr) = node.kind() else { - return false; - }; - - call_expr - .callee - .get_identifier_reference() - .is_some_and(|id| self.callbacks.contains(&id.name.as_str().into())) - } } #[test] diff --git a/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap index 28c8352f12f4f..6306f9b89fe0c 100644 --- a/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap +++ b/crates/oxc_linter/src/snapshots/no_callback_in_promise.snap @@ -6,81 +6,81 @@ source: crates/oxc_linter/src/tester.rs 1 │ a.then(cb) · ── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:14] 1 │ a.then(() => cb()) · ──── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:24] 1 │ a.then(function(err) { cb(err) }) · ─────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) · ──────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:53] 1 │ a.then(function(data) { cb(data) }, function(err) { cb(err) }) · ─────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.catch(function(err) { cb(err) }) · ─────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:8] 1 │ a.then(callback) · ──────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:14] 1 │ a.then(() => callback()) · ────────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:24] 1 │ a.then(function(err) { callback(err) }) · ───────────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) · ────────────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:59] 1 │ a.then(function(data) { callback(data) }, function(err) { callback(err) }) · ───────────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly ⚠ eslint-plugin-promise(no-callback-in-promise): Avoid calling back inside of a promise ╭─[no_callback_in_promise.tsx:1:25] 1 │ a.catch(function(err) { callback(err) }) · ───────────── ╰──── - help: Use `then` and `catch` directly, avoid callbacks + help: Use `then` and `catch` directly