| Index: Source/bindings/core/v8/CallbackPromiseAdapter.h
|
| diff --git a/Source/bindings/core/v8/CallbackPromiseAdapter.h b/Source/bindings/core/v8/CallbackPromiseAdapter.h
|
| index 17260588d2c77d9a529edc98f18239c1e6cbef15..e1fdffcc146da1d68c0b98199633f62980d40226 100644
|
| --- a/Source/bindings/core/v8/CallbackPromiseAdapter.h
|
| +++ b/Source/bindings/core/v8/CallbackPromiseAdapter.h
|
| @@ -36,12 +36,88 @@
|
| #include "public/platform/WebPassOwnPtr.h"
|
| #include "wtf/OwnPtr.h"
|
| #include "wtf/PassOwnPtr.h"
|
| +#include "wtf/TypeTraits.h"
|
|
|
| namespace blink {
|
|
|
| -class CallbackPromiseAdapterBase {
|
| -public:
|
| - // The following templates should be gone once the repositories are merged
|
| +// CallbackPromiseAdapter is a WebCallbacks subclass and resolves / rejects the
|
| +// stored resolver when onSuccess / onError is called, respectively.
|
| +//
|
| +// Basically CallbackPromiseAdapter<S, T> is a subclass of
|
| +// WebCallbacks<S::WebType, T::WebType>. There are some exceptions:
|
| +// - If S or T don't have WebType (e.g. S = bool), a default WebType holder
|
| +// called trivial WebType holder is used. For example,
|
| +// CallbackPromiseAdapter<bool, void> is a subclass of
|
| +// WebCallbacks<bool, void>.
|
| +// - If a WebType is OwnPtr<T>, its corresponding type parameter on
|
| +// WebCallbacks is WebPassOwnPtr<T>, because WebCallbacks must be exposed to
|
| +// Chromium.
|
| +//
|
| +// When onSuccess is called with a S::WebType value, the value is passed to
|
| +// S::take and the resolver is resolved with its return value. Ditto for
|
| +// onError.
|
| +//
|
| +// ScriptPromiseResolver::resolve / reject will not be called when the execution
|
| +// context is stopped.
|
| +//
|
| +// Example:
|
| +// class MyClass {
|
| +// public:
|
| +// using WebType = OwnPtr<WebMyClass>;
|
| +// static PassRefPtr<MyClass> take(ScriptPromiseResolver* resolver,
|
| +// PassOwnPtr<WebMyClass> webInstance)
|
| +// {
|
| +// return MyClass::create(webInstance);
|
| +// }
|
| +// ...
|
| +// };
|
| +// class MyErrorClass {
|
| +// public:
|
| +// using WebType = const WebMyErrorClass&;
|
| +// static MyErrorClass take(ScriptPromiseResolver* resolver,
|
| +// const WebErrorClass& webError)
|
| +// {
|
| +// return MyErrorClass(webError);
|
| +// }
|
| +// ...
|
| +// };
|
| +// OwnPtr<WebCallbacks<WebPassOwnPtr<WebMyClass>, const WebMyErrorClass&>>
|
| +// callbacks = adoptPtr(new CallbackPromiseAdapter<MyClass, MyErrorClass>(
|
| +// resolver));
|
| +// ...
|
| +//
|
| +// OwnPtr<WebCallbacks<bool, const WebMyErrorClass&>> callbacks2 =
|
| +// adoptPtr(new CallbackPromiseAdapter<bool, MyErrorClass>(resolver));
|
| +// ...
|
| +//
|
| +//
|
| +// In order to implement the above exceptions, we have template classes below.
|
| +// OnSuccess and OnError provide onSuccess and onError implementation, and there
|
| +// are utility templates that provide
|
| +// - OwnPtr - WebPassOwnPtr translation ([Web]PassType[Impl], adopt, pass),
|
| +// - trivial WebType holder (TrivialWebTypeHolder).
|
| +
|
| +namespace internal {
|
| +
|
| +// This template is placed outside of CallbackPromiseAdapterInternal because
|
| +// explicit specialization is forbidden in a class scope.
|
| +template <typename T>
|
| +struct CallbackPromiseAdapterTrivialWebTypeHolder {
|
| + using WebType = T;
|
| + static T take(ScriptPromiseResolver*, const T& x) { return x; }
|
| +};
|
| +template <>
|
| +struct CallbackPromiseAdapterTrivialWebTypeHolder<void> {
|
| + using WebType = void;
|
| +};
|
| +
|
| +class CallbackPromiseAdapterInternal {
|
| +private:
|
| + template <typename T> static T webTypeHolderMatcher(typename WTF::RemoveReference<typename T::WebType>::Type*);
|
| + template <typename T> static CallbackPromiseAdapterTrivialWebTypeHolder<T> webTypeHolderMatcher(...);
|
| + template <typename T> using WebTypeHolder = decltype(webTypeHolderMatcher<T>(nullptr));
|
| +
|
| + // The following templates should be gone when the repositories are merged
|
| // and we can use C++11 libraries.
|
| template <typename T>
|
| struct PassTypeImpl {
|
| @@ -51,7 +127,6 @@ public:
|
| struct PassTypeImpl<OwnPtr<T>> {
|
| using Type = PassOwnPtr<T>;
|
| };
|
| -
|
| template <typename T>
|
| struct WebPassTypeImpl {
|
| using Type = T;
|
| @@ -60,205 +135,87 @@ public:
|
| struct WebPassTypeImpl<OwnPtr<T>> {
|
| using Type = WebPassOwnPtr<T>;
|
| };
|
| - template <typename T>
|
| - using PassType = typename PassTypeImpl<T>::Type;
|
| - template <typename T>
|
| - using WebPassType = typename WebPassTypeImpl<T>::Type;
|
| - template <typename T>
|
| - static T& adopt(T& x) { return x; }
|
| - template <typename T>
|
| - static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); }
|
| - template <typename T>
|
| - static PassType<T> pass(T& x) { return x; }
|
| - template <typename T>
|
| - static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); }
|
| -};
|
| -
|
| -
|
| -// TODO(yhirano): Add comments.
|
| -template<typename S, typename T>
|
| -class CallbackPromiseAdapter final
|
| - : public WebCallbacks<typename CallbackPromiseAdapterBase::WebPassType<typename S::WebType>, typename CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| -public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - void onSuccess(WebPassType<typename S::WebType> r) override
|
| - {
|
| - typename S::WebType result(adopt(r));
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve(S::take(m_resolver.get(), pass(result)));
|
| - }
|
| -
|
| - void onError(WebPassType<typename T::WebType> e) override
|
| - {
|
| - typename T::WebType error(adopt(e));
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject(T::take(m_resolver.get(), pass(error)));
|
| - }
|
| -
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| -};
|
| -
|
| -template<typename T>
|
| -class CallbackPromiseAdapter<void, T> final : public WebCallbacks<void, typename CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| -public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - void onSuccess() override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve();
|
| - }
|
| -
|
| - void onError(WebPassType<typename T::WebType> e) override
|
| - {
|
| - typename T::WebType error(adopt(e));
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject(T::take(m_resolver.get(), pass(error)));
|
| - }
|
| -
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| -};
|
| -
|
| -template<typename S>
|
| -class CallbackPromiseAdapter<S, void> final : public WebCallbacks<typename CallbackPromiseAdapterBase::WebPassType<typename S::WebType>, void>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| -public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - void onSuccess(WebPassType<typename S::WebType> r) override
|
| - {
|
| - typename S::WebType result(adopt(r));
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve(S::take(m_resolver.get(), pass(result)));
|
| - }
|
| -
|
| - void onError() override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject();
|
| - }
|
| -
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| -};
|
| -
|
| -template<typename T>
|
| -class CallbackPromiseAdapter<bool, T> final : public WebCallbacks<bool*, typename CallbackPromiseAdapterBase::WebPassType<typename T::WebType>>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| -public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - // TODO(nhiroki): onSuccess should take ownership of a bool object for
|
| - // consistency. (http://crbug.com/493531)
|
| - void onSuccess(bool* result) override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve(*result);
|
| - }
|
| -
|
| - void onError(WebPassType<typename T::WebType> e) override
|
| - {
|
| - typename T::WebType error(adopt(e));
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject(T::take(m_resolver.get(), pass(error)));
|
| - }
|
| + template <typename T> using PassType = typename PassTypeImpl<T>::Type;
|
| + template <typename T> using WebPassType = typename WebPassTypeImpl<T>::Type;
|
| + template <typename T> static T& adopt(T& x) { return x; }
|
| + template <typename T> static PassOwnPtr<T> adopt(WebPassOwnPtr<T>& x) { return x.release(); }
|
| + template <typename T> static PassType<T> pass(T& x) { return x; }
|
| + template <typename T> static PassOwnPtr<T> pass(OwnPtr<T>& x) { return x.release(); }
|
| +
|
| + template <typename S, typename T>
|
| + class Base : public WebCallbacks<WebPassType<typename S::WebType>, WebPassType<typename T::WebType>> {
|
| + public:
|
| + explicit Base(ScriptPromiseResolver* resolver) : m_resolver(resolver) {}
|
| + ScriptPromiseResolver* resolver() { return m_resolver; }
|
| +
|
| + private:
|
| + Persistent<ScriptPromiseResolver> m_resolver;
|
| + };
|
|
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| -};
|
| + template <typename S, typename T>
|
| + class OnSuccess : public Base<S, T> {
|
| + public:
|
| + explicit OnSuccess(ScriptPromiseResolver* resolver) : Base<S, T>(resolver) {}
|
| + void onSuccess(WebPassType<typename S::WebType> r) override
|
| + {
|
| + typename S::WebType result(adopt(r));
|
| + ScriptPromiseResolver* resolver = this->resolver();
|
| + if (!resolver->executionContext() || resolver->executionContext()->activeDOMObjectsAreStopped())
|
| + return;
|
| + resolver->resolve(S::take(resolver, pass(result)));
|
| + }
|
| + };
|
| + template <typename T>
|
| + class OnSuccess<WebTypeHolder<void>, T> : public Base<WebTypeHolder<void>, T> {
|
| + public:
|
| + explicit OnSuccess(ScriptPromiseResolver* resolver) : Base<WebTypeHolder<void>, T>(resolver) {}
|
| + void onSuccess() override
|
| + {
|
| + ScriptPromiseResolver* resolver = this->resolver();
|
| + if (!resolver->executionContext() || resolver->executionContext()->activeDOMObjectsAreStopped())
|
| + return;
|
| + resolver->resolve();
|
| + }
|
| + };
|
| + template <typename S, typename T>
|
| + class OnError : public OnSuccess<S, T> {
|
| + public:
|
| + explicit OnError(ScriptPromiseResolver* resolver) : OnSuccess<S, T>(resolver) {}
|
| + void onError(WebPassType<typename T::WebType> e) override
|
| + {
|
| + typename T::WebType result(adopt(e));
|
| + ScriptPromiseResolver* resolver = this->resolver();
|
| + if (!resolver->executionContext() || resolver->executionContext()->activeDOMObjectsAreStopped())
|
| + return;
|
| + resolver->reject(T::take(resolver, pass(result)));
|
| + }
|
| + };
|
| + template <typename S>
|
| + class OnError<S, WebTypeHolder<void>> : public OnSuccess<S, WebTypeHolder<void>> {
|
| + public:
|
| + explicit OnError(ScriptPromiseResolver* resolver) : OnSuccess<S, WebTypeHolder<void>>(resolver) {}
|
| + void onError() override
|
| + {
|
| + ScriptPromiseResolver* resolver = this->resolver();
|
| + if (!resolver->executionContext() || resolver->executionContext()->activeDOMObjectsAreStopped())
|
| + return;
|
| + resolver->reject();
|
| + }
|
| + };
|
|
|
| -template<>
|
| -class CallbackPromiseAdapter<void, void> final : public WebCallbacks<void, void>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - void onSuccess() override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve();
|
| - }
|
| -
|
| - void onError() override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject();
|
| - }
|
| -
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| + template <typename S, typename T>
|
| + class CallbackPromiseAdapter final : public OnError<WebTypeHolder<S>, WebTypeHolder<T>> {
|
| + WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| + public:
|
| + explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver) : OnError<WebTypeHolder<S>, WebTypeHolder<T>>(resolver) {}
|
| + };
|
| };
|
|
|
| -template<>
|
| -class CallbackPromiseAdapter<bool, void> final : public WebCallbacks<bool*, void>, public CallbackPromiseAdapterBase {
|
| - WTF_MAKE_NONCOPYABLE(CallbackPromiseAdapter);
|
| -public:
|
| - explicit CallbackPromiseAdapter(ScriptPromiseResolver* resolver)
|
| - : m_resolver(resolver)
|
| - {
|
| - ASSERT(m_resolver);
|
| - }
|
| - ~CallbackPromiseAdapter() override { }
|
| -
|
| - // TODO(nhiroki): onSuccess should take ownership of a bool object for
|
| - // consistency. (http://crbug.com/493531)
|
| - void onSuccess(bool* result) override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->resolve(*result);
|
| - }
|
| +} // namespace internal
|
|
|
| - void onError() override
|
| - {
|
| - if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| - m_resolver->reject();
|
| - }
|
| -
|
| -private:
|
| - Persistent<ScriptPromiseResolver> m_resolver;
|
| -};
|
| +template <typename S, typename T>
|
| +using CallbackPromiseAdapter = internal::CallbackPromiseAdapterInternal::CallbackPromiseAdapter<S, T>;
|
|
|
| } // namespace blink
|
|
|
|
|