0

[Promise]: Disambiguate catch and reject callbacks.

Previously, Promise::Then/Catch would take a |RejectCb| that handles a rejection, which should not be
misinterpreted as the rejection cb (callback to trigger a rejection) returned
by ManualPromiseResolver::GetRejectCallback().
This CL fixes the ambiguity and renames it CatchCb. Similarly, ResolveCb becomes ThenCb.

Note: ECMAScript defines promise constructor: Promise(function(resolve, reject){})
where |reject| is the rejection callback similar to ManualPromiseResolver::GetRejectCallback().
Meanwhile, it defines p.then(onFulfilled[, onRejected]).

Bug: 906125
Change-Id: Ia402d38eed205c80365ce6e1fd2947ffab272a28
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1814705
Reviewed-by: Alex Clarke <alexclarke@chromium.org>
Reviewed-by: François Doray <fdoray@chromium.org>
Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698479}
This commit is contained in:
Etienne Pierre-doray
2019-09-20 15:00:52 +00:00
committed by Commit Bot
parent 5a09ff549c
commit 03a160d37f
3 changed files with 143 additions and 146 deletions

@ -127,22 +127,22 @@ class Promise : public internal::BasePromise {
//
// |task_runner| is const-ref to avoid bloat due the destructor (which posts a
// task).
template <typename RejectCb>
template <typename CatchCb>
auto CatchOn(const scoped_refptr<TaskRunner>& task_runner,
const Location& from_here,
RejectCb on_reject) noexcept {
CatchCb on_reject) noexcept {
DCHECK(!on_reject.is_null());
// Extract properties from the |on_reject| callback.
using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;
using CatchCallbackTraits = internal::CallbackTraits<CatchCb>;
using CatchCallbackArgT = typename CatchCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<ResolveType,
NoReject, // We've caught the reject case.
typename RejectCallbackTraits::ResolveType,
typename RejectCallbackTraits::RejectType>;
typename CatchCallbackTraits::ResolveType,
typename CatchCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -153,13 +153,13 @@ class Promise : public internal::BasePromise {
static_assert(ReturnedPromiseTraits::valid,
"Ambiguous promise resolve type");
static_assert(
internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
std::is_void<RejectCallbackArgT>::value,
internal::IsValidPromiseArg<RejectType, CatchCallbackArgT>::value ||
std::is_void<CatchCallbackArgT>::value,
"|on_reject| callback must accept Promise::RejectType or void.");
static_assert(
!std::is_reference<RejectCallbackArgT>::value ||
std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value,
!std::is_reference<CatchCallbackArgT>::value ||
std::is_const<std::remove_reference_t<CatchCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -168,7 +168,7 @@ class Promise : public internal::BasePromise {
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceClosure, // Never called.
OnceCallback<typename RejectCallbackTraits::SignatureType>,
OnceCallback<typename CatchCallbackTraits::SignatureType>,
internal::NoCallback, RejectType,
Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
@ -176,28 +176,28 @@ class Promise : public internal::BasePromise {
internal::ToCallbackBase(std::move(on_reject)))));
}
template <typename RejectCb>
template <typename CatchCb>
auto CatchOn(const TaskTraits& traits,
const Location& from_here,
RejectCb&& on_reject) noexcept {
CatchCb&& on_reject) noexcept {
return CatchOn(CreateTaskRunner(traits), from_here,
std::forward<RejectCb>(on_reject));
std::forward<CatchCb>(on_reject));
}
template <typename RejectCb>
auto CatchHere(const Location& from_here, RejectCb&& on_reject) noexcept {
template <typename CatchCb>
auto CatchHere(const Location& from_here, CatchCb&& on_reject) noexcept {
DCHECK(!on_reject.is_null());
// Extract properties from the |on_reject| callback.
using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;
using CatchCallbackTraits = internal::CallbackTraits<CatchCb>;
using CatchCallbackArgT = typename CatchCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<ResolveType,
NoReject, // We've caught the reject case.
typename RejectCallbackTraits::ResolveType,
typename RejectCallbackTraits::RejectType>;
typename CatchCallbackTraits::ResolveType,
typename CatchCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -208,13 +208,13 @@ class Promise : public internal::BasePromise {
static_assert(ReturnedPromiseTraits::valid,
"Ambiguous promise resolve type");
static_assert(
internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
std::is_void<RejectCallbackArgT>::value,
internal::IsValidPromiseArg<RejectType, CatchCallbackArgT>::value ||
std::is_void<CatchCallbackArgT>::value,
"|on_reject| callback must accept Promise::RejectType or void.");
static_assert(
!std::is_reference<RejectCallbackArgT>::value ||
std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value,
!std::is_reference<CatchCallbackArgT>::value ||
std::is_const<std::remove_reference_t<CatchCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -223,7 +223,7 @@ class Promise : public internal::BasePromise {
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceClosure, // Never called.
OnceCallback<typename RejectCallbackTraits::SignatureType>,
OnceCallback<typename CatchCallbackTraits::SignatureType>,
internal::NoCallback, RejectType,
Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
@ -244,23 +244,22 @@ class Promise : public internal::BasePromise {
//
// |task_runner| is const-ref to avoid bloat due the destructor (which posts a
// task).
template <typename ResolveCb>
template <typename ThenCb>
auto ThenOn(const scoped_refptr<TaskRunner>& task_runner,
const Location& from_here,
ResolveCb on_resolve) noexcept {
ThenCb on_resolve) noexcept {
DCHECK(!on_resolve.is_null());
// Extract properties from the |on_resolve| callback.
using ResolveCallbackTraits =
internal::CallbackTraits<std::decay_t<ResolveCb>>;
using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;
using ThenCallbackTraits = internal::CallbackTraits<std::decay_t<ThenCb>>;
using ThenCallbackArgT = typename ThenCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<NoResolve, // We've caught the resolve case.
RejectType,
typename ResolveCallbackTraits::ResolveType,
typename ResolveCallbackTraits::RejectType>;
typename ThenCallbackTraits::ResolveType,
typename ThenCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -269,13 +268,13 @@ class Promise : public internal::BasePromise {
"Ambiguous promise reject type");
static_assert(
internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
std::is_void<ResolveCallbackArgT>::value,
internal::IsValidPromiseArg<ResolveType, ThenCallbackArgT>::value ||
std::is_void<ThenCallbackArgT>::value,
"|on_resolve| callback must accept Promise::ResolveType or void.");
static_assert(
!std::is_reference<ResolveCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ResolveCallbackArgT>>::value,
!std::is_reference<ThenCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ThenCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -283,7 +282,7 @@ class Promise : public internal::BasePromise {
task_runner, from_here, abstract_promise_.get(),
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceCallback<typename ResolveCallbackTraits::SignatureType>,
OnceCallback<typename ThenCallbackTraits::SignatureType>,
OnceClosure, ResolveType, internal::NoCallback,
Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
@ -291,29 +290,28 @@ class Promise : public internal::BasePromise {
OnceClosure())));
}
template <typename ResolveCb>
template <typename ThenCb>
auto ThenOn(const TaskTraits& traits,
const Location& from_here,
ResolveCb&& on_resolve) noexcept {
ThenCb&& on_resolve) noexcept {
return ThenOn(CreateTaskRunner(traits), from_here,
std::forward<ResolveCb>(on_resolve));
std::forward<ThenCb>(on_resolve));
}
template <typename ResolveCb>
auto ThenHere(const Location& from_here, ResolveCb&& on_resolve) noexcept {
template <typename ThenCb>
auto ThenHere(const Location& from_here, ThenCb&& on_resolve) noexcept {
DCHECK(!on_resolve.is_null());
// Extract properties from the |on_resolve| callback.
using ResolveCallbackTraits =
internal::CallbackTraits<std::decay_t<ResolveCb>>;
using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;
using ThenCallbackTraits = internal::CallbackTraits<std::decay_t<ThenCb>>;
using ThenCallbackArgT = typename ThenCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<NoResolve, // We've caught the resolve case.
RejectType,
typename ResolveCallbackTraits::ResolveType,
typename ResolveCallbackTraits::RejectType>;
typename ThenCallbackTraits::ResolveType,
typename ThenCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -322,13 +320,13 @@ class Promise : public internal::BasePromise {
"Ambiguous promise reject type");
static_assert(
internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
std::is_void<ResolveCallbackArgT>::value,
internal::IsValidPromiseArg<ResolveType, ThenCallbackArgT>::value ||
std::is_void<ThenCallbackArgT>::value,
"|on_resolve| callback must accept Promise::ResolveType or void.");
static_assert(
!std::is_reference<ResolveCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ResolveCallbackArgT>>::value,
!std::is_reference<ThenCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ThenCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -336,7 +334,7 @@ class Promise : public internal::BasePromise {
from_here, abstract_promise_.get(),
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceCallback<typename ResolveCallbackTraits::SignatureType>,
OnceCallback<typename ThenCallbackTraits::SignatureType>,
OnceClosure, ResolveType, internal::NoCallback,
Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
@ -364,26 +362,26 @@ class Promise : public internal::BasePromise {
//
// |task_runner| is const-ref to avoid bloat due the destructor (which posts a
// task).
template <typename ResolveCb, typename RejectCb>
template <typename ThenCb, typename CatchCb>
auto ThenOn(const scoped_refptr<TaskRunner>& task_runner,
const Location& from_here,
ResolveCb on_resolve,
RejectCb on_reject) noexcept {
ThenCb on_resolve,
CatchCb on_reject) noexcept {
DCHECK(!on_resolve.is_null());
DCHECK(!on_reject.is_null());
// Extract properties from the |on_resolve| and |on_reject| callbacks.
using ResolveCallbackTraits = internal::CallbackTraits<ResolveCb>;
using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;
using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;
using ThenCallbackTraits = internal::CallbackTraits<ThenCb>;
using CatchCallbackTraits = internal::CallbackTraits<CatchCb>;
using ThenCallbackArgT = typename ThenCallbackTraits::ArgType;
using CatchCallbackArgT = typename CatchCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<typename ResolveCallbackTraits::ResolveType,
typename ResolveCallbackTraits::RejectType,
typename RejectCallbackTraits::ResolveType,
typename RejectCallbackTraits::RejectType>;
internal::PromiseCombiner<typename ThenCallbackTraits::ResolveType,
typename ThenCallbackTraits::RejectType,
typename CatchCallbackTraits::ResolveType,
typename CatchCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -395,23 +393,23 @@ class Promise : public internal::BasePromise {
"compatible types.");
static_assert(
internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
std::is_void<ResolveCallbackArgT>::value,
internal::IsValidPromiseArg<ResolveType, ThenCallbackArgT>::value ||
std::is_void<ThenCallbackArgT>::value,
"|on_resolve| callback must accept Promise::ResolveType or void.");
static_assert(
internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
std::is_void<RejectCallbackArgT>::value,
internal::IsValidPromiseArg<RejectType, CatchCallbackArgT>::value ||
std::is_void<CatchCallbackArgT>::value,
"|on_reject| callback must accept Promise::RejectType or void.");
static_assert(
!std::is_reference<ResolveCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ResolveCallbackArgT>>::value,
!std::is_reference<ThenCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ThenCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
static_assert(
!std::is_reference<RejectCallbackArgT>::value ||
std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value,
!std::is_reference<CatchCallbackArgT>::value ||
std::is_const<std::remove_reference_t<CatchCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -419,43 +417,43 @@ class Promise : public internal::BasePromise {
task_runner, from_here, abstract_promise_.get(),
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceCallback<typename ResolveCallbackTraits::SignatureType>,
OnceCallback<typename RejectCallbackTraits::SignatureType>,
OnceCallback<typename ThenCallbackTraits::SignatureType>,
OnceCallback<typename CatchCallbackTraits::SignatureType>,
ResolveType, RejectType, Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
internal::ToCallbackBase(std::move(on_resolve)),
internal::ToCallbackBase(std::move(on_reject)))));
}
template <typename ResolveCb, typename RejectCb>
template <typename ThenCb, typename CatchCb>
auto ThenOn(const TaskTraits& traits,
const Location& from_here,
ResolveCb on_resolve,
RejectCb on_reject) noexcept {
ThenCb on_resolve,
CatchCb on_reject) noexcept {
return ThenOn(CreateTaskRunner(traits), from_here,
std::forward<ResolveCb>(on_resolve),
std::forward<RejectCb>(on_reject));
std::forward<ThenCb>(on_resolve),
std::forward<CatchCb>(on_reject));
}
template <typename ResolveCb, typename RejectCb>
template <typename ThenCb, typename CatchCb>
auto ThenHere(const Location& from_here,
ResolveCb on_resolve,
RejectCb on_reject) noexcept {
ThenCb on_resolve,
CatchCb on_reject) noexcept {
DCHECK(!on_resolve.is_null());
DCHECK(!on_reject.is_null());
// Extract properties from the |on_resolve| and |on_reject| callbacks.
using ResolveCallbackTraits = internal::CallbackTraits<ResolveCb>;
using RejectCallbackTraits = internal::CallbackTraits<RejectCb>;
using ResolveCallbackArgT = typename ResolveCallbackTraits::ArgType;
using RejectCallbackArgT = typename RejectCallbackTraits::ArgType;
using ThenCallbackTraits = internal::CallbackTraits<ThenCb>;
using CatchCallbackTraits = internal::CallbackTraits<CatchCb>;
using ThenCallbackArgT = typename ThenCallbackTraits::ArgType;
using CatchCallbackArgT = typename CatchCallbackTraits::ArgType;
// Compute the resolve and reject types of the returned Promise.
using ReturnedPromiseTraits =
internal::PromiseCombiner<typename ResolveCallbackTraits::ResolveType,
typename ResolveCallbackTraits::RejectType,
typename RejectCallbackTraits::ResolveType,
typename RejectCallbackTraits::RejectType>;
internal::PromiseCombiner<typename ThenCallbackTraits::ResolveType,
typename ThenCallbackTraits::RejectType,
typename CatchCallbackTraits::ResolveType,
typename CatchCallbackTraits::RejectType>;
using ReturnedPromiseResolveT = typename ReturnedPromiseTraits::ResolveType;
using ReturnedPromiseRejectT = typename ReturnedPromiseTraits::RejectType;
@ -467,23 +465,23 @@ class Promise : public internal::BasePromise {
"compatible types.");
static_assert(
internal::IsValidPromiseArg<ResolveType, ResolveCallbackArgT>::value ||
std::is_void<ResolveCallbackArgT>::value,
internal::IsValidPromiseArg<ResolveType, ThenCallbackArgT>::value ||
std::is_void<ThenCallbackArgT>::value,
"|on_resolve| callback must accept Promise::ResolveType or void.");
static_assert(
internal::IsValidPromiseArg<RejectType, RejectCallbackArgT>::value ||
std::is_void<RejectCallbackArgT>::value,
internal::IsValidPromiseArg<RejectType, CatchCallbackArgT>::value ||
std::is_void<CatchCallbackArgT>::value,
"|on_reject| callback must accept Promise::RejectType or void.");
static_assert(
!std::is_reference<ResolveCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ResolveCallbackArgT>>::value,
!std::is_reference<ThenCallbackArgT>::value ||
std::is_const<std::remove_reference_t<ThenCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
static_assert(
!std::is_reference<RejectCallbackArgT>::value ||
std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value,
!std::is_reference<CatchCallbackArgT>::value ||
std::is_const<std::remove_reference_t<CatchCallbackArgT>>::value,
"Google C++ Style: References in function parameters must be const.");
return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>(
@ -491,8 +489,8 @@ class Promise : public internal::BasePromise {
from_here, abstract_promise_.get(),
internal::PromiseExecutor::Data(
in_place_type_t<internal::ThenAndCatchExecutor<
OnceCallback<typename ResolveCallbackTraits::SignatureType>,
OnceCallback<typename RejectCallbackTraits::SignatureType>,
OnceCallback<typename ThenCallbackTraits::SignatureType>,
OnceCallback<typename CatchCallbackTraits::SignatureType>,
ResolveType, RejectType, Resolved<ReturnedPromiseResolveT>,
Rejected<ReturnedPromiseRejectT>>>(),
internal::ToCallbackBase(std::move(on_resolve)),

@ -8,14 +8,14 @@ namespace base {
namespace internal {
bool ThenAndCatchExecutorCommon::IsCancelled() const {
if (!resolve_callback_.is_null()) {
if (!then_callback_.is_null()) {
// If there is both a resolve and a reject executor they must be canceled
// at the same time.
DCHECK(reject_callback_.is_null() ||
reject_callback_.IsCancelled() == resolve_callback_.IsCancelled());
return resolve_callback_.IsCancelled();
DCHECK(catch_callback_.is_null() ||
catch_callback_.IsCancelled() == then_callback_.IsCancelled());
return then_callback_.IsCancelled();
}
return reject_callback_.IsCancelled();
return catch_callback_.IsCancelled();
}
void ThenAndCatchExecutorCommon::Execute(AbstractPromise* promise,
@ -23,16 +23,16 @@ void ThenAndCatchExecutorCommon::Execute(AbstractPromise* promise,
ExecuteCallback execute_catch) {
AbstractPromise* prerequisite = promise->GetOnlyPrerequisite();
if (prerequisite->IsResolved()) {
if (ProcessNullCallback(resolve_callback_, prerequisite, promise))
if (ProcessNullCallback(then_callback_, prerequisite, promise))
return;
execute_then(prerequisite, promise, &resolve_callback_);
execute_then(prerequisite, promise, &then_callback_);
} else {
DCHECK(prerequisite->IsRejected());
if (ProcessNullCallback(reject_callback_, prerequisite, promise))
if (ProcessNullCallback(catch_callback_, prerequisite, promise))
return;
execute_catch(prerequisite, promise, &reject_callback_);
execute_catch(prerequisite, promise, &catch_callback_);
}
}

@ -17,11 +17,11 @@ namespace internal {
// Exists to reduce template bloat.
class BASE_EXPORT ThenAndCatchExecutorCommon {
public:
ThenAndCatchExecutorCommon(internal::CallbackBase&& resolve_executor,
internal::CallbackBase&& reject_executor) noexcept
: resolve_callback_(std::move(resolve_executor)),
reject_callback_(std::move(reject_executor)) {
DCHECK(!resolve_callback_.is_null() || !reject_callback_.is_null());
ThenAndCatchExecutorCommon(internal::CallbackBase&& then_callback,
internal::CallbackBase&& catch_callback) noexcept
: then_callback_(std::move(then_callback)),
catch_callback_(std::move(catch_callback)) {
DCHECK(!then_callback_.is_null() || !catch_callback_.is_null());
}
~ThenAndCatchExecutorCommon() = default;
@ -44,24 +44,23 @@ class BASE_EXPORT ThenAndCatchExecutorCommon {
AbstractPromise* arg,
AbstractPromise* result);
CallbackBase resolve_callback_;
CallbackBase reject_callback_;
CallbackBase then_callback_;
CallbackBase catch_callback_;
};
// Tag signals no callback which is used to eliminate dead code.
struct NoCallback {};
template <typename ResolveOnceCallback,
typename RejectOnceCallback,
template <typename ThenOnceCallback,
typename CatchOnceCallback,
typename ArgResolve,
typename ArgReject,
typename ResolveStorage,
typename RejectStorage>
class ThenAndCatchExecutor {
public:
using ResolveReturnT =
typename CallbackTraits<ResolveOnceCallback>::ReturnType;
using RejectReturnT = typename CallbackTraits<RejectOnceCallback>::ReturnType;
using ThenReturnT = typename CallbackTraits<ThenOnceCallback>::ReturnType;
using CatchReturnT = typename CallbackTraits<CatchOnceCallback>::ReturnType;
using PrerequisiteCouldResolve =
std::integral_constant<bool,
!std::is_same<ArgResolve, NoCallback>::value>;
@ -69,8 +68,8 @@ class ThenAndCatchExecutor {
std::integral_constant<bool, !std::is_same<ArgReject, NoCallback>::value>;
ThenAndCatchExecutor(CallbackBase&& resolve_callback,
CallbackBase&& reject_callback) noexcept
: common_(std::move(resolve_callback), std::move(reject_callback)) {}
CallbackBase&& catch_callback) noexcept
: common_(std::move(resolve_callback), std::move(catch_callback)) {}
bool IsCancelled() const { return common_.IsCancelled(); }
@ -85,29 +84,29 @@ class ThenAndCatchExecutor {
#if DCHECK_IS_ON()
PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const {
return common_.resolve_callback_.is_null()
return common_.then_callback_.is_null()
? PromiseExecutor::ArgumentPassingType::kNoCallback
: CallbackTraits<ResolveOnceCallback>::argument_passing_type;
: CallbackTraits<ThenOnceCallback>::argument_passing_type;
}
PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const {
return common_.reject_callback_.is_null()
return common_.catch_callback_.is_null()
? PromiseExecutor::ArgumentPassingType::kNoCallback
: CallbackTraits<RejectOnceCallback>::argument_passing_type;
: CallbackTraits<CatchOnceCallback>::argument_passing_type;
}
bool CanResolve() const {
return (!common_.resolve_callback_.is_null() &&
PromiseCallbackTraits<ResolveReturnT>::could_resolve) ||
(!common_.reject_callback_.is_null() &&
PromiseCallbackTraits<RejectReturnT>::could_resolve);
return (!common_.then_callback_.is_null() &&
PromiseCallbackTraits<ThenReturnT>::could_resolve) ||
(!common_.catch_callback_.is_null() &&
PromiseCallbackTraits<CatchReturnT>::could_resolve);
}
bool CanReject() const {
return (!common_.resolve_callback_.is_null() &&
PromiseCallbackTraits<ResolveReturnT>::could_reject) ||
(!common_.reject_callback_.is_null() &&
PromiseCallbackTraits<RejectReturnT>::could_reject);
return (!common_.then_callback_.is_null() &&
PromiseCallbackTraits<ThenReturnT>::could_reject) ||
(!common_.catch_callback_.is_null() &&
PromiseCallbackTraits<CatchReturnT>::could_reject);
}
#endif
@ -121,8 +120,8 @@ class ThenAndCatchExecutor {
static void ExecuteCatch(AbstractPromise* prerequisite,
AbstractPromise* promise,
CallbackBase* reject_callback) {
ExecuteCatchInternal(prerequisite, promise, reject_callback,
CallbackBase* catch_callback) {
ExecuteCatchInternal(prerequisite, promise, catch_callback,
PrerequisiteCouldReject());
}
@ -134,11 +133,11 @@ class ThenAndCatchExecutor {
// binary size overhead of moving a scoped_refptr<> about. We respect
// the onceness of the callback and RunHelper will overwrite the callback
// with the result.
using RepeatingResolveCB =
typename ToRepeatingCallback<ResolveOnceCallback>::value;
using RepeatingThenCB =
typename ToRepeatingCallback<ThenOnceCallback>::value;
RunHelper<
RepeatingResolveCB, Resolved<ArgResolve>, ResolveStorage,
RejectStorage>::Run(*static_cast<RepeatingResolveCB*>(resolve_callback),
RepeatingThenCB, Resolved<ArgResolve>, ResolveStorage,
RejectStorage>::Run(*static_cast<RepeatingThenCB*>(resolve_callback),
prerequisite, promise);
}
@ -151,23 +150,23 @@ class ThenAndCatchExecutor {
static void ExecuteCatchInternal(AbstractPromise* prerequisite,
AbstractPromise* promise,
CallbackBase* reject_callback,
CallbackBase* catch_callback,
std::true_type can_reject) {
// Internally RunHelper uses const RepeatingCallback<>& to avoid the
// binary size overhead of moving a scoped_refptr<> about. We respect
// the onceness of the callback and RunHelper will overwrite the callback
// with the result.
using RepeatingRejectCB =
typename ToRepeatingCallback<RejectOnceCallback>::value;
using RepeatingCatchCB =
typename ToRepeatingCallback<CatchOnceCallback>::value;
RunHelper<
RepeatingRejectCB, Rejected<ArgReject>, ResolveStorage,
RejectStorage>::Run(*static_cast<RepeatingRejectCB*>(reject_callback),
RepeatingCatchCB, Rejected<ArgReject>, ResolveStorage,
RejectStorage>::Run(*static_cast<RepeatingCatchCB*>(catch_callback),
prerequisite, promise);
}
static void ExecuteCatchInternal(AbstractPromise* prerequisite,
AbstractPromise* promise,
CallbackBase* reject_callback,
CallbackBase* catch_callback,
std::false_type can_reject) {
// |prerequisite| can't reject so don't generate dead code.
}