Bumping manifests a=b2g-bump
[gecko.git] / dom / bindings / BindingDeclarations.h
blob0e6a022fac178add566b7fb1aaeb4197c0db2625
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* vim: set ts=2 sw=2 et tw=79: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /**
8 * A header for declaring various things that binding implementation headers
9 * might need. The idea is to make binding implementation headers safe to
10 * include anywhere without running into include hell like we do with
11 * BindingUtils.h
13 #ifndef mozilla_dom_BindingDeclarations_h__
14 #define mozilla_dom_BindingDeclarations_h__
16 #include "nsStringGlue.h"
17 #include "js/Value.h"
18 #include "js/RootingAPI.h"
19 #include "mozilla/Maybe.h"
20 #include "nsCOMPtr.h"
21 #include "nsTArray.h"
22 #include "nsAutoPtr.h" // for nsRefPtr member variables
23 #include "mozilla/dom/DOMString.h"
24 #include "mozilla/dom/OwningNonNull.h"
26 class nsWrapperCache;
28 namespace mozilla {
29 namespace dom {
31 // Struct that serves as a base class for all dictionaries. Particularly useful
32 // so we can use IsBaseOf to detect dictionary template arguments.
33 struct DictionaryBase
35 protected:
36 bool ParseJSON(JSContext* aCx, const nsAString& aJSON,
37 JS::MutableHandle<JS::Value> aVal);
39 bool StringifyToJSON(JSContext* aCx,
40 JS::MutableHandle<JS::Value> aValue,
41 nsAString& aJSON);
42 private:
43 // aString is expected to actually be an nsAString*. Should only be
44 // called from StringifyToJSON.
45 static bool AppendJSONToString(const jschar* aJSONData, uint32_t aDataLength,
46 void* aString);
49 // Struct that serves as a base class for all typed arrays and array buffers and
50 // array buffer views. Particularly useful so we can use IsBaseOf to detect
51 // typed array/buffer/view template arguments.
52 struct AllTypedArraysBase {
55 // Struct that serves as a base class for all owning unions.
56 // Particularly useful so we can use IsBaseOf to detect owning union
57 // template arguments.
58 struct AllOwningUnionBase {
62 struct EnumEntry {
63 const char* value;
64 size_t length;
67 class MOZ_STACK_CLASS GlobalObject
69 public:
70 GlobalObject(JSContext* aCx, JSObject* aObject);
72 JSObject* Get() const
74 return mGlobalJSObject;
77 nsISupports* GetAsSupports() const;
79 // The context that this returns is not guaranteed to be in the compartment of
80 // the object returned from Get(), in fact it's generally in the caller's
81 // compartment.
82 JSContext* Context() const
84 return mCx;
87 bool Failed() const
89 return !Get();
92 protected:
93 JS::Rooted<JSObject*> mGlobalJSObject;
94 JSContext* mCx;
95 mutable nsISupports* mGlobalObject;
96 mutable nsCOMPtr<nsISupports> mGlobalObjectRef;
99 // Class for representing optional arguments.
100 template<typename T, typename InternalType>
101 class Optional_base
103 public:
104 Optional_base()
107 explicit Optional_base(const T& aValue)
109 mImpl.emplace(aValue);
112 template<typename T1, typename T2>
113 explicit Optional_base(const T1& aValue1, const T2& aValue2)
115 mImpl.emplace(aValue1, aValue2);
118 bool WasPassed() const
120 return mImpl.isSome();
123 // Return InternalType here so we can work with it usefully.
124 InternalType& Construct()
126 mImpl.emplace();
127 return *mImpl;
130 template <class T1>
131 InternalType& Construct(const T1 &t1)
133 mImpl.emplace(t1);
134 return *mImpl;
137 template <class T1, class T2>
138 InternalType& Construct(const T1 &t1, const T2 &t2)
140 mImpl.emplace(t1, t2);
141 return *mImpl;
144 void Reset()
146 mImpl.reset();
149 const T& Value() const
151 return *mImpl;
154 // Return InternalType here so we can work with it usefully.
155 InternalType& Value()
157 return *mImpl;
160 // And an explicit way to get the InternalType even if we're const.
161 const InternalType& InternalValue() const
163 return *mImpl;
166 // If we ever decide to add conversion operators for optional arrays
167 // like the ones Nullable has, we'll need to ensure that Maybe<> has
168 // the boolean before the actual data.
170 private:
171 // Forbid copy-construction and assignment
172 Optional_base(const Optional_base& other) MOZ_DELETE;
173 const Optional_base &operator=(const Optional_base &other) MOZ_DELETE;
175 protected:
176 Maybe<InternalType> mImpl;
179 template<typename T>
180 class Optional : public Optional_base<T, T>
182 public:
183 Optional() :
184 Optional_base<T, T>()
187 explicit Optional(const T& aValue) :
188 Optional_base<T, T>(aValue)
192 template<typename T>
193 class Optional<JS::Handle<T> > :
194 public Optional_base<JS::Handle<T>, JS::Rooted<T> >
196 public:
197 Optional() :
198 Optional_base<JS::Handle<T>, JS::Rooted<T> >()
201 explicit Optional(JSContext* cx) :
202 Optional_base<JS::Handle<T>, JS::Rooted<T> >()
204 this->Construct(cx);
207 Optional(JSContext* cx, const T& aValue) :
208 Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
211 // Override the const Value() to return the right thing so we're not
212 // returning references to temporaries.
213 JS::Handle<T> Value() const
215 return *this->mImpl;
218 // And we have to override the non-const one too, since we're
219 // shadowing the one on the superclass.
220 JS::Rooted<T>& Value()
222 return *this->mImpl;
226 // A specialization of Optional for JSObject* to make sure that when someone
227 // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
228 // it can be traced safely.
229 template<>
230 class Optional<JSObject*> : public Optional_base<JSObject*, JSObject*>
232 public:
233 Optional() :
234 Optional_base<JSObject*, JSObject*>()
237 explicit Optional(JSObject* aValue) :
238 Optional_base<JSObject*, JSObject*>(aValue)
241 // Don't allow us to have an uninitialized JSObject*
242 JSObject*& Construct()
244 // The Android compiler sucks and thinks we're trying to construct
245 // a JSObject* from an int if we don't cast here. :(
246 return Optional_base<JSObject*, JSObject*>::Construct(
247 static_cast<JSObject*>(nullptr));
250 template <class T1>
251 JSObject*& Construct(const T1& t1)
253 return Optional_base<JSObject*, JSObject*>::Construct(t1);
257 // A specialization of Optional for JS::Value to make sure no one ever uses it.
258 template<>
259 class Optional<JS::Value>
261 private:
262 Optional() MOZ_DELETE;
264 explicit Optional(JS::Value aValue) MOZ_DELETE;
267 // A specialization of Optional for NonNull that lets us get a T& from Value()
268 template<typename U> class NonNull;
269 template<typename T>
270 class Optional<NonNull<T> > : public Optional_base<T, NonNull<T> >
272 public:
273 // We want our Value to actually return a non-const reference, even
274 // if we're const. At least for things that are normally pointer
275 // types...
276 T& Value() const
278 return *this->mImpl->get();
281 // And we have to override the non-const one too, since we're
282 // shadowing the one on the superclass.
283 NonNull<T>& Value()
285 return *this->mImpl;
289 // A specialization of Optional for OwningNonNull that lets us get a
290 // T& from Value()
291 template<typename T>
292 class Optional<OwningNonNull<T> > : public Optional_base<T, OwningNonNull<T> >
294 public:
295 // We want our Value to actually return a non-const reference, even
296 // if we're const. At least for things that are normally pointer
297 // types...
298 T& Value() const
300 return *this->mImpl->get();
303 // And we have to override the non-const one too, since we're
304 // shadowing the one on the superclass.
305 OwningNonNull<T>& Value()
307 return *this->mImpl;
311 // Specialization for strings.
312 // XXXbz we can't pull in FakeString here, because it depends on internal
313 // strings. So we just have to forward-declare it and reimplement its
314 // ToAStringPtr.
316 namespace binding_detail {
317 struct FakeString;
318 } // namespace binding_detail
320 template<>
321 class Optional<nsAString>
323 public:
324 Optional() : mPassed(false) {}
326 bool WasPassed() const
328 return mPassed;
331 void operator=(const nsAString* str)
333 MOZ_ASSERT(str);
334 mStr = str;
335 mPassed = true;
338 // If this code ever goes away, remove the comment pointing to it in the
339 // FakeString class in BindingUtils.h.
340 void operator=(const binding_detail::FakeString* str)
342 MOZ_ASSERT(str);
343 mStr = reinterpret_cast<const nsString*>(str);
344 mPassed = true;
347 const nsAString& Value() const
349 MOZ_ASSERT(WasPassed());
350 return *mStr;
353 private:
354 // Forbid copy-construction and assignment
355 Optional(const Optional& other) MOZ_DELETE;
356 const Optional &operator=(const Optional &other) MOZ_DELETE;
358 bool mPassed;
359 const nsAString* mStr;
362 template<class T>
363 class NonNull
365 public:
366 NonNull()
367 #ifdef DEBUG
368 : inited(false)
369 #endif
372 // This is no worse than get() in terms of const handling.
373 operator T&() const {
374 MOZ_ASSERT(inited);
375 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
376 return *ptr;
379 operator T*() const {
380 MOZ_ASSERT(inited);
381 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
382 return ptr;
385 void operator=(T* t) {
386 ptr = t;
387 MOZ_ASSERT(ptr);
388 #ifdef DEBUG
389 inited = true;
390 #endif
393 template<typename U>
394 void operator=(U* t) {
395 ptr = t->ToAStringPtr();
396 MOZ_ASSERT(ptr);
397 #ifdef DEBUG
398 inited = true;
399 #endif
402 T** Slot() {
403 #ifdef DEBUG
404 inited = true;
405 #endif
406 return &ptr;
409 T* Ptr() {
410 MOZ_ASSERT(inited);
411 MOZ_ASSERT(ptr, "NonNull<T> was set to null");
412 return ptr;
415 // Make us work with smart-ptr helpers that expect a get()
416 T* get() const {
417 MOZ_ASSERT(inited);
418 MOZ_ASSERT(ptr);
419 return ptr;
422 protected:
423 T* ptr;
424 #ifdef DEBUG
425 bool inited;
426 #endif
429 // Class for representing sequences in arguments. We use a non-auto array
430 // because that allows us to use sequences of sequences and the like. This
431 // needs to be fallible because web content controls the length of the array,
432 // and can easily try to create very large lengths.
433 template<typename T>
434 class Sequence : public FallibleTArray<T>
436 public:
437 Sequence() : FallibleTArray<T>()
441 inline nsWrapperCache*
442 GetWrapperCache(nsWrapperCache* cache)
444 return cache;
447 inline nsWrapperCache*
448 GetWrapperCache(void* p)
450 return nullptr;
453 // Helper template for smart pointers to resolve ambiguity between
454 // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
455 template <template <typename> class SmartPtr, typename T>
456 inline nsWrapperCache*
457 GetWrapperCache(const SmartPtr<T>& aObject)
459 return GetWrapperCache(aObject.get());
462 struct ParentObject {
463 template<class T>
464 ParentObject(T* aObject) :
465 mObject(aObject),
466 mWrapperCache(GetWrapperCache(aObject)),
467 mUseXBLScope(false)
470 template<class T, template<typename> class SmartPtr>
471 ParentObject(const SmartPtr<T>& aObject) :
472 mObject(aObject.get()),
473 mWrapperCache(GetWrapperCache(aObject.get())),
474 mUseXBLScope(false)
477 ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
478 mObject(aObject),
479 mWrapperCache(aCache),
480 mUseXBLScope(false)
483 nsISupports* const mObject;
484 nsWrapperCache* const mWrapperCache;
485 bool mUseXBLScope;
488 } // namespace dom
489 } // namespace mozilla
491 #endif // mozilla_dom_BindingDeclarations_h__