18b3d4e604efafcb0392af3f807b05fda2966aa1
[WebKit-https.git] / Source / WebCore / bindings / IDLTypes.h
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include <heap/HandleTypes.h>
29 #include <wtf/Brigand.h>
30 #include <wtf/HashMap.h>
31 #include <wtf/StdLibExtras.h>
32 #include <wtf/text/WTFString.h>
33
34 #if ENABLE(WEBGL)
35 #include "WebGLAny.h"
36 #endif
37
38 namespace JSC {
39 class ArrayBuffer;
40 class ArrayBufferView;
41 class DataView;
42 class JSValue;
43 class JSObject;
44 template<typename> class Strong;
45 }
46
47 namespace WebCore {
48
49 class IDBKey;
50 class IDBKeyData;
51 class IDBValue;
52 class DOMPromise;
53
54 #if ENABLE(WEBGL)
55 class WebGLExtension;
56 #endif
57
58 template<typename T>
59 struct IDLType {
60     using ImplementationType = T;
61
62     using ParameterType = T;
63     using NullableParameterType = std::optional<ImplementationType>;
64
65     using InnerParameterType = T;
66     using NullableInnerParameterType = std::optional<ImplementationType>;
67
68     using NullableType = std::optional<ImplementationType>;
69     static NullableType nullValue() { return std::nullopt; }
70     static bool isNullValue(const NullableType& value) { return !value; }
71     static ImplementationType extractValueFromNullable(const NullableType& value) { return value.value(); }
72 };
73
74 // IDLUnsupportedType is a special type that serves as a base class for currently unsupported types.
75 struct IDLUnsupportedType : IDLType<void> { };
76
77 // IDLNull is a special type for use as a subtype in an IDLUnion that is nullable.
78 struct IDLNull : IDLType<std::nullptr_t> { };
79
80 struct IDLAny : IDLType<JSC::Strong<JSC::Unknown>> {
81     using ParameterType = JSC::JSValue;
82     using NullableParameterType = JSC::JSValue;
83
84     using NullableType = JSC::Strong<JSC::Unknown>;
85     static inline std::nullptr_t nullValue() { return nullptr; }
86     template<typename U> static inline bool isNullValue(U&& value) { return !value; }
87     template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
88 };
89
90 struct IDLVoid : IDLType<void> { };
91
92 struct IDLBoolean : IDLType<bool> { };
93
94 template<typename NumericType> struct IDLNumber : IDLType<NumericType> { };
95
96 template<typename IntegerType> struct IDLInteger : IDLNumber<IntegerType> { };
97 struct IDLByte : IDLInteger<int8_t> { };
98 struct IDLOctet : IDLInteger<uint8_t> { };
99 struct IDLShort : IDLInteger<int16_t> { };
100 struct IDLUnsignedShort : IDLInteger<uint16_t> { };
101 struct IDLLong : IDLInteger<int32_t> { };
102 struct IDLUnsignedLong : IDLInteger<uint32_t> { };
103 struct IDLLongLong : IDLInteger<int64_t> { };
104 struct IDLUnsignedLongLong : IDLInteger<uint64_t> { };
105
106 template<typename T> struct IDLClampAdaptor : IDLInteger<typename T::ImplementationType> {
107     using InnerType = T;
108 };
109
110 template<typename T> struct IDLEnforceRangeAdaptor : IDLInteger<typename T::ImplementationType> {
111     using InnerType = T;
112 };
113
114 template<typename FloatingPointType> struct IDLFloatingPoint : IDLNumber<FloatingPointType> { };
115 struct IDLFloat : IDLFloatingPoint<float> { };
116 struct IDLUnrestrictedFloat : IDLFloatingPoint<float> { };
117 struct IDLDouble : IDLFloatingPoint<double> { };
118 struct IDLUnrestrictedDouble : IDLFloatingPoint<double> { };
119
120 template<typename StringType> struct IDLString : IDLType<StringType> {
121     using ParameterType = const StringType&;
122     using NullableParameterType = const StringType&;
123
124     using NullableType = StringType;
125     static StringType nullValue() { return StringType(); }
126     static bool isNullValue(const StringType& value) { return value.isNull(); }
127     template <typename U> static U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
128 };
129 struct IDLDOMString : IDLString<String> { };
130 struct IDLByteString : IDLString<String> { };
131 struct IDLUSVString : IDLString<String> { };
132
133 template<typename T> struct IDLTreatNullAsEmptyAdaptor : IDLString<String> {
134     using InnerType = T;
135 };
136
137 template<typename T> struct IDLAtomicStringAdaptor : IDLString<AtomicString> {
138     using InnerType = T;
139 };
140
141 template<typename T> struct IDLRequiresExistingAtomicStringAdaptor : IDLString<AtomicString> {
142     using InnerType = T;
143 };
144
145 struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> {
146     using NullableType = JSC::Strong<JSC::JSObject>;
147
148     static inline std::nullptr_t nullValue() { return nullptr; }
149     template<typename U> static inline bool isNullValue(U&& value) { return !value; }
150     template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
151 };
152
153 template<typename T> struct IDLWrapper : IDLType<RefPtr<T>> {
154     using RawType = T;
155
156     using ParameterType = T&;
157     using NullableParameterType = T*;
158
159     using InnerParameterType = Ref<T>;
160     using NullableInnerParameterType = RefPtr<T>;
161
162     using NullableType = RefPtr<T>;
163     static inline std::nullptr_t nullValue() { return nullptr; }
164     template<typename U> static inline bool isNullValue(U&& value) { return !value; }
165     template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
166 };
167
168 template<typename T> struct IDLInterface : IDLWrapper<T> { };
169 template<typename T> struct IDLCallbackInterface : IDLWrapper<T> { };
170 template<typename T> struct IDLCallbackFunction : IDLWrapper<T> { };
171
172 template<typename T> struct IDLDictionary : IDLType<T> {
173     using ParameterType = const T&;
174     using NullableParameterType = const T&;
175 };
176
177 template<typename T> struct IDLEnumeration : IDLType<T> { };
178
179 template<typename T> struct IDLNullable : IDLType<typename T::NullableType> {
180     using InnerType = T;
181
182     using ParameterType = typename T::NullableParameterType;
183     using NullableParameterType = typename T::NullableParameterType;
184
185     using InnerParameterType = typename T::NullableInnerParameterType;
186     using NullableInnerParameterType = typename T::NullableInnerParameterType;
187
188     using NullableType = typename T::NullableType;
189     static inline auto nullValue() -> decltype(T::nullValue()) { return T::nullValue(); }
190     template<typename U> static inline bool isNullValue(U&& value) { return T::isNullValue(std::forward<U>(value)); }
191     template<typename U> static inline auto extractValueFromNullable(U&& value) -> decltype(T::extractValueFromNullable(std::forward<U>(value))) { return T::extractValueFromNullable(std::forward<U>(value)); }
192 };
193
194 template<typename T> struct IDLSequence : IDLType<Vector<typename T::ImplementationType>> {
195     using InnerType = T;
196
197     using ParameterType = const Vector<typename T::InnerParameterType>&;
198     using NullableParameterType = const std::optional<Vector<typename T::InnerParameterType>>&;
199 };
200
201 template<typename T> struct IDLFrozenArray : IDLType<Vector<typename T::ImplementationType>> {
202     using InnerType = T;
203
204     using ParameterType = const Vector<typename T::ImplementationType>&;
205     using NullableParameterType = const std::optional<Vector<typename T::ImplementationType>>&;
206 };
207
208 template<typename K, typename V> struct IDLRecord : IDLType<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>> {
209     using KeyType = K;
210     using ValueType = V;
211
212     using ParameterType = const Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>&;
213     using NullableParameterType = const std::optional<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>>&;
214 };
215
216 template<typename T> struct IDLPromise : IDLType<DOMPromise> {
217     using InnerType = T;
218 };
219
220 struct IDLError : IDLUnsupportedType { };
221 struct IDLDOMException : IDLUnsupportedType { };
222
223 template<typename... Ts>
224 struct IDLUnion : IDLType<Variant<typename Ts::ImplementationType...>> {
225     using TypeList = brigand::list<Ts...>;
226
227     using ParameterType = const Variant<typename Ts::ImplementationType...>&;
228     using NullableParameterType = const std::optional<Variant<typename Ts::ImplementationType...>>&;
229 };
230
231 template<typename T> struct IDLBufferSource : IDLWrapper<T> { };
232
233 struct IDLArrayBuffer : IDLBufferSource<JSC::ArrayBuffer> { };
234 // NOTE: WebIDL defines ArrayBufferView as an IDL union of all the TypedArray types.
235 //       and DataView. For convience in our implementation, we give it a distinct
236 //       type that maps to the shared based class of all those classes.
237 struct IDLArrayBufferView : IDLBufferSource<JSC::ArrayBufferView> { };
238 struct IDLDataView : IDLBufferSource<JSC::DataView> { };
239
240 template<typename T> struct IDLTypedArray : IDLBufferSource<T> { };
241 // NOTE: The specific typed array types are IDLTypedArray specialized on the typed array
242 //       implementation type, e.g. IDLFloat64Array is IDLTypedArray<JSC::Float64Array>
243
244
245 // Non-WebIDL extensions
246
247 struct IDLDate : IDLType<double> { 
248     using NullableType = double;
249     static double nullValue() { return std::numeric_limits<double>::quiet_NaN(); }
250     static bool isNullValue(double value) { return std::isnan(value); }
251     static double extractValueFromNullable(double value) { return value; }
252 };
253
254 struct IDLJSON : IDLType<String> { 
255     using ParameterType = const String&;
256     using NullableParameterType = const String&;
257
258     using NullableType = String;
259     static String nullValue() { return String(); }
260     static bool isNullValue(const String& value) { return value.isNull(); }
261     template <typename U> static U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
262 };
263
264 template<typename T> struct IDLSerializedScriptValue : IDLWrapper<T> { };
265 template<typename T> struct IDLEventListener : IDLWrapper<T> { };
266 template<typename T> struct IDLXPathNSResolver : IDLWrapper<T> { };
267
268 struct IDLIDBKey : IDLWrapper<IDBKey> { };
269 struct IDLIDBKeyData : IDLWrapper<IDBKeyData> { };
270 struct IDLIDBValue : IDLWrapper<IDBValue> { };
271
272 #if ENABLE(WEBGL)
273 struct IDLWebGLAny : IDLType<WebGLAny> { };
274 struct IDLWebGLExtension : IDLWrapper<WebGLExtension> { };
275 #endif
276
277 // Helper predicates
278
279 template<typename T>
280 struct IsIDLInterface : public std::integral_constant<bool, WTF::IsTemplate<T, IDLInterface>::value> { };
281
282 template<typename T>
283 struct IsIDLDictionary : public std::integral_constant<bool, WTF::IsTemplate<T, IDLDictionary>::value> { };
284
285 template<typename T>
286 struct IsIDLEnumeration : public std::integral_constant<bool, WTF::IsTemplate<T, IDLEnumeration>::value> { };
287
288 template<typename T>
289 struct IsIDLSequence : public std::integral_constant<bool, WTF::IsTemplate<T, IDLSequence>::value> { };
290
291 template<typename T>
292 struct IsIDLFrozenArray : public std::integral_constant<bool, WTF::IsTemplate<T, IDLFrozenArray>::value> { };
293
294 template<typename T>
295 struct IsIDLRecord : public std::integral_constant<bool, WTF::IsTemplate<T, IDLRecord>::value> { };
296
297 template<typename T>
298 struct IsIDLString : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value> { };
299
300 template<typename T>
301 struct IsIDLStringOrEnumeration : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value || WTF::IsTemplate<T, IDLEnumeration>::value> { };
302
303 template<typename T>
304 struct IsIDLNumber : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLNumber, T>::value> { };
305
306 template<typename T>
307 struct IsIDLInteger : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLInteger, T>::value> { };
308
309 template<typename T>
310 struct IsIDLFloatingPoint : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLFloatingPoint, T>::value> { };
311
312 template<typename T>
313 struct IsIDLTypedArray : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLTypedArray, T>::value> { };
314
315 } // namespace WebCore