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 "StringAdaptors.h"
29#include <JavaScriptCore/HandleTypes.h>
30#include <JavaScriptCore/Strong.h>
31#include <wtf/Brigand.h>
32#include <wtf/HashMap.h>
33#include <wtf/StdLibExtras.h>
34#include <wtf/text/WTFString.h>
35
36#if ENABLE(WEBGL)
37#include "WebGLAny.h"
38#endif
39
40namespace JSC {
41class ArrayBuffer;
42class ArrayBufferView;
43class DataView;
44class JSValue;
45class JSObject;
46template<typename> class Strong;
47}
48
49namespace WebCore {
50
51class IDBKey;
52class IDBKeyData;
53class IDBValue;
54class JSWindowProxy;
55class DOMPromise;
56class ScheduledAction;
57
58#if ENABLE(WEBGL)
59class WebGLExtension;
60#endif
61
62template<typename T>
63struct IDLType {
64 using ImplementationType = T;
65 using StorageType = T;
66
67 using ParameterType = T;
68 using NullableParameterType = Optional<ImplementationType>;
69
70 using InnerParameterType = T;
71 using NullableInnerParameterType = Optional<ImplementationType>;
72
73 using NullableType = Optional<ImplementationType>;
74 static NullableType nullValue() { return WTF::nullopt; }
75 static bool isNullValue(const NullableType& value) { return !value; }
76 static ImplementationType extractValueFromNullable(const NullableType& value) { return value.value(); }
77};
78
79// IDLUnsupportedType is a special type that serves as a base class for currently unsupported types.
80struct IDLUnsupportedType : IDLType<void> { };
81
82// IDLNull is a special type for use as a subtype in an IDLUnion that is nullable.
83struct IDLNull : IDLType<std::nullptr_t> { };
84
85struct IDLAny : IDLType<JSC::Strong<JSC::Unknown>> {
86 using ParameterType = JSC::JSValue;
87 using NullableParameterType = JSC::JSValue;
88
89 using NullableType = JSC::Strong<JSC::Unknown>;
90 static inline std::nullptr_t nullValue() { return nullptr; }
91 template<typename U> static inline bool isNullValue(U&& value) { return !value; }
92 template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
93};
94
95struct IDLVoid : IDLType<void> { };
96
97struct IDLBoolean : IDLType<bool> { };
98
99template<typename NumericType> struct IDLNumber : IDLType<NumericType> { };
100
101template<typename IntegerType> struct IDLInteger : IDLNumber<IntegerType> { };
102struct IDLByte : IDLInteger<int8_t> { };
103struct IDLOctet : IDLInteger<uint8_t> { };
104struct IDLShort : IDLInteger<int16_t> { };
105struct IDLUnsignedShort : IDLInteger<uint16_t> { };
106struct IDLLong : IDLInteger<int32_t> { };
107struct IDLUnsignedLong : IDLInteger<uint32_t> { };
108struct IDLLongLong : IDLInteger<int64_t> { };
109struct IDLUnsignedLongLong : IDLInteger<uint64_t> { };
110
111template<typename T> struct IDLClampAdaptor : IDLInteger<typename T::ImplementationType> {
112 using InnerType = T;
113};
114
115template<typename T> struct IDLEnforceRangeAdaptor : IDLInteger<typename T::ImplementationType> {
116 using InnerType = T;
117};
118
119template<typename FloatingPointType> struct IDLFloatingPoint : IDLNumber<FloatingPointType> { };
120struct IDLFloat : IDLFloatingPoint<float> { };
121struct IDLUnrestrictedFloat : IDLFloatingPoint<float> { };
122struct IDLDouble : IDLFloatingPoint<double> { };
123struct IDLUnrestrictedDouble : IDLFloatingPoint<double> { };
124
125template<typename StringType> struct IDLString : IDLType<StringType> {
126 using ParameterType = const StringType&;
127 using NullableParameterType = const StringType&;
128
129 using NullableType = StringType;
130 static StringType nullValue() { return StringType(); }
131 static bool isNullValue(const StringType& value) { return value.isNull(); }
132 static bool isNullValue(const UncachedString& value) { return value.string.isNull(); }
133 static bool isNullValue(const OwnedString& value) { return value.string.isNull(); }
134 template <typename U> static U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
135};
136struct IDLDOMString : IDLString<String> { };
137struct IDLByteString : IDLString<String> { };
138struct IDLUSVString : IDLString<String> { };
139
140template<typename T> struct IDLTreatNullAsEmptyAdaptor : IDLString<String> {
141 using InnerType = T;
142};
143
144template<typename T> struct IDLAtomStringAdaptor : IDLString<AtomString> {
145 using InnerType = T;
146};
147
148template<typename T> struct IDLRequiresExistingAtomStringAdaptor : IDLString<AtomString> {
149 using InnerType = T;
150};
151
152struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> {
153 using NullableType = JSC::Strong<JSC::JSObject>;
154
155 static inline NullableType nullValue() { return { }; }
156 template<typename U> static inline bool isNullValue(U&& value) { return !value; }
157 template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
158};
159
160template<typename T> struct IDLWrapper : IDLType<RefPtr<T>> {
161 using RawType = T;
162
163 using StorageType = Ref<T>;
164
165 using ParameterType = T&;
166 using NullableParameterType = T*;
167
168 using InnerParameterType = Ref<T>;
169 using NullableInnerParameterType = RefPtr<T>;
170
171 using NullableType = RefPtr<T>;
172 static inline std::nullptr_t nullValue() { return nullptr; }
173 template<typename U> static inline bool isNullValue(U&& value) { return !value; }
174 template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
175};
176
177template<typename T> struct IDLInterface : IDLWrapper<T> { };
178template<typename T> struct IDLCallbackInterface : IDLWrapper<T> { };
179template<typename T> struct IDLCallbackFunction : IDLWrapper<T> { };
180
181template<typename T> struct IDLDictionary : IDLType<T> {
182 using ParameterType = const T&;
183 using NullableParameterType = const T&;
184};
185
186template<typename T> struct IDLEnumeration : IDLType<T> { };
187
188template<typename T> struct IDLNullable : IDLType<typename T::NullableType> {
189 using InnerType = T;
190
191 using ParameterType = typename T::NullableParameterType;
192 using NullableParameterType = typename T::NullableParameterType;
193
194 using InnerParameterType = typename T::NullableInnerParameterType;
195 using NullableInnerParameterType = typename T::NullableInnerParameterType;
196
197 using NullableType = typename T::NullableType;
198 static inline auto nullValue() -> decltype(T::nullValue()) { return T::nullValue(); }
199 template<typename U> static inline bool isNullValue(U&& value) { return T::isNullValue(std::forward<U>(value)); }
200 template<typename U> static inline auto extractValueFromNullable(U&& value) -> decltype(T::extractValueFromNullable(std::forward<U>(value))) { return T::extractValueFromNullable(std::forward<U>(value)); }
201};
202
203template<typename T> struct IDLSequence : IDLType<Vector<typename T::ImplementationType>> {
204 using InnerType = T;
205
206 using ParameterType = const Vector<typename T::InnerParameterType>&;
207 using NullableParameterType = const Optional<Vector<typename T::InnerParameterType>>&;
208};
209
210template<typename T> struct IDLFrozenArray : IDLType<Vector<typename T::ImplementationType>> {
211 using InnerType = T;
212
213 using ParameterType = const Vector<typename T::ImplementationType>&;
214 using NullableParameterType = const Optional<Vector<typename T::ImplementationType>>&;
215};
216
217template<typename K, typename V> struct IDLRecord : IDLType<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>> {
218 using KeyType = K;
219 using ValueType = V;
220
221 using ParameterType = const Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>&;
222 using NullableParameterType = const Optional<Vector<WTF::KeyValuePair<typename K::ImplementationType, typename V::ImplementationType>>>&;
223};
224
225template<typename T> struct IDLPromise : IDLWrapper<DOMPromise> {
226 using InnerType = T;
227};
228
229struct IDLError : IDLUnsupportedType { };
230struct IDLDOMException : IDLUnsupportedType { };
231
232template<typename... Ts>
233struct IDLUnion : IDLType<Variant<typename Ts::ImplementationType...>> {
234 using TypeList = brigand::list<Ts...>;
235
236 using ParameterType = const Variant<typename Ts::ImplementationType...>&;
237 using NullableParameterType = const Optional<Variant<typename Ts::ImplementationType...>>&;
238};
239
240template<typename T> struct IDLBufferSource : IDLWrapper<T> { };
241
242struct IDLArrayBuffer : IDLBufferSource<JSC::ArrayBuffer> { };
243// NOTE: WebIDL defines ArrayBufferView as an IDL union of all the TypedArray types.
244// and DataView. For convience in our implementation, we give it a distinct
245// type that maps to the shared based class of all those classes.
246struct IDLArrayBufferView : IDLBufferSource<JSC::ArrayBufferView> { };
247struct IDLDataView : IDLBufferSource<JSC::DataView> { };
248
249template<typename T> struct IDLTypedArray : IDLBufferSource<T> { };
250// NOTE: The specific typed array types are IDLTypedArray specialized on the typed array
251// implementation type, e.g. IDLFloat64Array is IDLTypedArray<JSC::Float64Array>
252
253
254// Non-WebIDL extensions
255
256struct IDLDate : IDLType<double> {
257 using NullableType = double;
258 static double nullValue() { return std::numeric_limits<double>::quiet_NaN(); }
259 static bool isNullValue(double value) { return std::isnan(value); }
260 static double extractValueFromNullable(double value) { return value; }
261};
262
263struct IDLJSON : IDLType<String> {
264 using ParameterType = const String&;
265 using NullableParameterType = const String&;
266
267 using NullableType = String;
268 static String nullValue() { return String(); }
269 static bool isNullValue(const String& value) { return value.isNull(); }
270 template <typename U> static U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
271};
272
273struct IDLScheduledAction : IDLType<std::unique_ptr<ScheduledAction>> { };
274template<typename T> struct IDLSerializedScriptValue : IDLWrapper<T> { };
275template<typename T> struct IDLEventListener : IDLWrapper<T> { };
276template<typename T> struct IDLXPathNSResolver : IDLWrapper<T> { };
277
278struct IDLIDBKey : IDLWrapper<IDBKey> { };
279struct IDLIDBKeyData : IDLWrapper<IDBKeyData> { };
280struct IDLIDBValue : IDLWrapper<IDBValue> { };
281
282#if ENABLE(WEBGL)
283struct IDLWebGLAny : IDLType<WebGLAny> { };
284struct IDLWebGLExtension : IDLWrapper<WebGLExtension> { };
285#endif
286
287// Helper predicates
288
289template<typename T>
290struct IsIDLInterface : public std::integral_constant<bool, WTF::IsTemplate<T, IDLInterface>::value> { };
291
292template<typename T>
293struct IsIDLDictionary : public std::integral_constant<bool, WTF::IsTemplate<T, IDLDictionary>::value> { };
294
295template<typename T>
296struct IsIDLEnumeration : public std::integral_constant<bool, WTF::IsTemplate<T, IDLEnumeration>::value> { };
297
298template<typename T>
299struct IsIDLSequence : public std::integral_constant<bool, WTF::IsTemplate<T, IDLSequence>::value> { };
300
301template<typename T>
302struct IsIDLFrozenArray : public std::integral_constant<bool, WTF::IsTemplate<T, IDLFrozenArray>::value> { };
303
304template<typename T>
305struct IsIDLRecord : public std::integral_constant<bool, WTF::IsTemplate<T, IDLRecord>::value> { };
306
307template<typename T>
308struct IsIDLString : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value> { };
309
310template<typename T>
311struct IsIDLStringOrEnumeration : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLString, T>::value || WTF::IsTemplate<T, IDLEnumeration>::value> { };
312
313template<typename T>
314struct IsIDLNumber : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLNumber, T>::value> { };
315
316template<typename T>
317struct IsIDLInteger : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLInteger, T>::value> { };
318
319template<typename T>
320struct IsIDLFloatingPoint : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLFloatingPoint, T>::value> { };
321
322template<typename T>
323struct IsIDLTypedArray : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLTypedArray, T>::value> { };
324
325} // namespace WebCore
326