Commit 92614bc0 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Clean up IDLNullable and NativeValutTraits<IDLNullable<T>>

Issue 798467: It's not yet clear what ImplType should be, but we
technically don't need both of ImplType and ResultType.  We can
implement IDLNullabe without ResultType.

At this moment, ImplType looks implementation helper used only by
IDLXxx and NativeValueTraits.  ImplType doesn't look a public API.

Issue 798470: It's reasonable that NullValue() is defined iff
type T can represent IDL null value.  We can tell whether
base::Optional is necessary or not by looking at existence of
NullValue().

Issue 798471: This patch requires NullValue() only in
NativeValueTraits and not in IDLXxx.  IDLXxx is a simple tag
type just like the original design.

Bug: 798467, 798470, 798471
Change-Id: I08e3cf54f3059ec308b4b455045c0bc1cfd5967b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2002551
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732345}
parent 8142143b
...@@ -8,12 +8,13 @@ ...@@ -8,12 +8,13 @@
#include <type_traits> #include <type_traits>
#include "base/optional.h" #include "base/optional.h"
#include "base/template_util.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h" #include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
...@@ -22,6 +23,9 @@ class EventListener; ...@@ -22,6 +23,9 @@ class EventListener;
class ScriptPromise; class ScriptPromise;
class ScriptValue; class ScriptValue;
// The type names below are named as "IDL" prefix + Web IDL type name.
// https://heycam.github.io/webidl/#dfn-type-name
// Boolean // Boolean
struct IDLBoolean final : public IDLBaseHelper<bool> {}; struct IDLBoolean final : public IDLBaseHelper<bool> {};
...@@ -144,6 +148,10 @@ struct IDLSequence final : public IDLBase { ...@@ -144,6 +148,10 @@ struct IDLSequence final : public IDLBase {
using ImplType = VectorOf<typename NativeValueTraits<T>::ImplType>; using ImplType = VectorOf<typename NativeValueTraits<T>::ImplType>;
}; };
// Frozen array types
template <typename T>
using IDLArray = IDLSequence<T>;
// Record // Record
template <typename Key, typename Value> template <typename Key, typename Value>
struct IDLRecord final : public IDLBase { struct IDLRecord final : public IDLBase {
...@@ -156,45 +164,25 @@ struct IDLRecord final : public IDLBase { ...@@ -156,45 +164,25 @@ struct IDLRecord final : public IDLBase {
VectorOfPairs<String, typename NativeValueTraits<Value>::ImplType>; VectorOfPairs<String, typename NativeValueTraits<Value>::ImplType>;
}; };
// Nullable (T?). // Nullable
// https://heycam.github.io/webidl/#idl-nullable-type template <typename InnerType, typename SFINAEHelper = void>
// Types without a built-in notion of nullability are mapped to
// base::Optional<T>.
template <typename InnerType, typename = void>
struct IDLNullable final : public IDLBase { struct IDLNullable final : public IDLBase {
private: using ImplType =
using InnerTraits = NativeValueTraits<InnerType>; base::Optional<typename NativeValueTraits<InnerType>::ImplType>;
using InnerResultType =
decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(),
v8::Local<v8::Value>(),
std::declval<ExceptionState&>()));
public:
using ResultType = base::Optional<std::decay_t<InnerResultType>>;
using ImplType = ResultType;
static inline ResultType NullValue() { return base::nullopt; }
}; };
template <typename InnerType> template <typename InnerType>
struct IDLNullable<InnerType, struct IDLNullable<
decltype(void(NativeValueTraits<InnerType>::NullValue()))> InnerType,
base::void_t<decltype(NativeValueTraits<InnerType>::NullValue)>>
final : public IDLBase { final : public IDLBase {
private: using ImplType = typename NativeValueTraits<InnerType>::ImplType;
using InnerTraits = NativeValueTraits<InnerType>;
using InnerResultType =
decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(),
v8::Local<v8::Value>(),
std::declval<ExceptionState&>()));
public:
using ResultType = InnerResultType;
using ImplType = typename InnerTraits::ImplType;
static inline ResultType NullValue() { return InnerTraits::NullValue(); }
}; };
// EventHandler types // EventHandler types
struct IDLEventHandler : public IDLBaseHelper<EventListener*> {}; struct IDLEventHandler final : public IDLBaseHelper<EventListener> {};
struct IDLOnBeforeUnloadEventHandler : public IDLBaseHelper<EventListener*> {}; struct IDLOnBeforeUnloadEventHandler final
struct IDLOnErrorEventHandler : public IDLBaseHelper<EventListener*> {}; : public IDLBaseHelper<EventListener> {};
struct IDLOnErrorEventHandler final : public IDLBaseHelper<EventListener> {};
} // namespace blink } // namespace blink
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
namespace blink { namespace blink {
// This is the base type for all WebIDL types, such as the ones defined in // This is the base type for all Web IDL types, such as the ones defined in
// idl_types.h. It is defined in a separate location to avoid circular header // idl_types.h. It is defined in a separate location to avoid circular header
// inclusions when one only needs to check if a type inherits from IDLBase. // inclusions when one only needs to check if a type inherits from IDLBase.
struct IDLBase { struct IDLBase {
...@@ -18,7 +18,7 @@ struct IDLBase { ...@@ -18,7 +18,7 @@ struct IDLBase {
// can inherit from IDLBaseHelper to avoid having to set ImplType on its own. // can inherit from IDLBaseHelper to avoid having to set ImplType on its own.
// //
// Example: // Example:
// struct MyType<double> final : public IDLBaseHelper<double> {}; // struct IDLDouble final : public IDLBaseHelper<double> {};
template <typename T> template <typename T>
struct IDLBaseHelper : public IDLBase { struct IDLBaseHelper : public IDLBase {
using ImplType = T; using ImplType = T;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include <type_traits> #include <type_traits>
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_element.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element.h"
...@@ -142,14 +143,14 @@ static_assert( ...@@ -142,14 +143,14 @@ static_assert(
static_assert(std::is_base_of<IDLBase, IDLNullable<IDLDouble>>::value, static_assert(std::is_base_of<IDLBase, IDLNullable<IDLDouble>>::value,
"IDLNullable should have IDLBase as a base class"); "IDLNullable should have IDLBase as a base class");
static_assert(std::is_same<IDLNullable<IDLDouble>::ResultType, static_assert(std::is_same<IDLNullable<IDLDouble>::ImplType,
base::Optional<double>>::value, base::Optional<double>>::value,
"double? corresponds to base::Optional<double>"); "double? corresponds to base::Optional<double>");
static_assert(std::is_same<IDLNullable<Element>::ResultType, Element*>::value, static_assert(std::is_same<IDLNullable<Element>::ImplType, Element>::value,
"Element? doesn't require a base::Optional<> wrapper"); "Element? doesn't require a base::Optional<> wrapper");
static_assert(std::is_same<IDLNullable<IDLString>::ResultType, String>::value, static_assert(std::is_same<IDLNullable<IDLString>::ImplType, String>::value,
"DOMString? doesn't require a base::Optional<> wrapper"); "DOMString? doesn't require a base::Optional<> wrapper");
static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ResultType, static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ImplType,
StringOrStringSequence>::value, StringOrStringSequence>::value,
"(union type)? doesn't require a base::Optional<> wrapper"); "(union type)? doesn't require a base::Optional<> wrapper");
......
...@@ -893,6 +893,8 @@ struct NativeValueTraits< ...@@ -893,6 +893,8 @@ struct NativeValueTraits<
<< "is not yet implemented."; << "is not yet implemented.";
return nullptr; return nullptr;
} }
static constexpr T* NullValue() { return nullptr; }
}; };
// Dictionary // Dictionary
...@@ -907,6 +909,8 @@ struct NativeValueTraits< ...@@ -907,6 +909,8 @@ struct NativeValueTraits<
ExceptionState& exception_state) { ExceptionState& exception_state) {
return T::Create(isolate, value, exception_state); return T::Create(isolate, value, exception_state);
} }
static constexpr T* NullValue() { return nullptr; }
}; };
// Interface // Interface
...@@ -937,24 +941,49 @@ struct NativeValueTraits< ...@@ -937,24 +941,49 @@ struct NativeValueTraits<
}; };
// Nullable // Nullable
//
// Types without a built-in notion of nullability are mapped to
// base::Optional<T>.
template <typename InnerType> template <typename InnerType>
struct NativeValueTraits<IDLNullable<InnerType>> struct NativeValueTraits<IDLNullable<InnerType>>
: public NativeValueTraitsBase<IDLNullable<InnerType>> { : public NativeValueTraitsBase<IDLNullable<InnerType>> {
// https://heycam.github.io/webidl/#es-nullable-type // https://heycam.github.io/webidl/#es-nullable-type
static typename IDLNullable<InnerType>::ResultType NativeValue( using ImplType =
v8::Isolate* isolate, base::Optional<typename NativeValueTraits<InnerType>::ImplType>;
v8::Local<v8::Value> v8_value,
ExceptionState& exception_state) { static ImplType NativeValue(v8::Isolate* isolate,
if (v8_value->IsNullOrUndefined()) v8::Local<v8::Value> value,
return IDLNullable<InnerType>::NullValue(); ExceptionState& exception_state) {
return NativeValueTraits<InnerType>::NativeValue(isolate, v8_value, if (value->IsNullOrUndefined())
return base::nullopt;
return NativeValueTraits<InnerType>::NativeValue(isolate, value,
exception_state); exception_state);
} }
}; };
template <typename InnerType>
struct NativeValueTraits<
IDLNullable<InnerType>,
base::void_t<decltype(NativeValueTraits<InnerType>::NullValue)>>
: public NativeValueTraitsBase<IDLNullable<InnerType>> {
// https://heycam.github.io/webidl/#es-nullable-type
using ImplType = typename NativeValueTraits<InnerType>::ImplType;
static decltype(auto) NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
if (value->IsNullOrUndefined())
return NativeValueTraits<InnerType>::NullValue();
return NativeValueTraits<InnerType>::NativeValue(isolate, value,
exception_state);
}
};
// IDLNullable<IDLNullable<T>> must not be used.
template <typename T>
struct NativeValueTraits<IDLNullable<IDLNullable<T>>>;
// EventHandler // EventHandler
template <> template <>
struct NativeValueTraits<IDLEventHandler> struct CORE_EXPORT NativeValueTraits<IDLEventHandler>
: public NativeValueTraitsBase<IDLEventHandler> { : public NativeValueTraitsBase<IDLEventHandler> {
static EventListener* NativeValue(v8::Isolate* isolate, static EventListener* NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value, v8::Local<v8::Value> value,
...@@ -962,7 +991,7 @@ struct NativeValueTraits<IDLEventHandler> ...@@ -962,7 +991,7 @@ struct NativeValueTraits<IDLEventHandler>
}; };
template <> template <>
struct NativeValueTraits<IDLOnBeforeUnloadEventHandler> struct CORE_EXPORT NativeValueTraits<IDLOnBeforeUnloadEventHandler>
: public NativeValueTraitsBase<IDLOnBeforeUnloadEventHandler> { : public NativeValueTraitsBase<IDLOnBeforeUnloadEventHandler> {
static EventListener* NativeValue(v8::Isolate* isolate, static EventListener* NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value, v8::Local<v8::Value> value,
...@@ -970,13 +999,22 @@ struct NativeValueTraits<IDLOnBeforeUnloadEventHandler> ...@@ -970,13 +999,22 @@ struct NativeValueTraits<IDLOnBeforeUnloadEventHandler>
}; };
template <> template <>
struct NativeValueTraits<IDLOnErrorEventHandler> struct CORE_EXPORT NativeValueTraits<IDLOnErrorEventHandler>
: public NativeValueTraitsBase<IDLOnErrorEventHandler> { : public NativeValueTraitsBase<IDLOnErrorEventHandler> {
static EventListener* NativeValue(v8::Isolate* isolate, static EventListener* NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value, v8::Local<v8::Value> value,
ExceptionState& exception_state); ExceptionState& exception_state);
}; };
// EventHandler and its family are nullable, so IDLNullable<IDLEventHandler>
// must not be used.
template <>
struct NativeValueTraits<IDLNullable<IDLEventHandler>>;
template <>
struct NativeValueTraits<IDLNullable<IDLOnBeforeUnloadEventHandler>>;
template <>
struct NativeValueTraits<IDLNullable<IDLOnErrorEventHandler>>;
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_IMPL_H_ #endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_IMPL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment