Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/mozapps/extensions/AddonManagerStartup-inlines.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef AddonManagerStartup_inlines_h
7
#define AddonManagerStartup_inlines_h
8
9
#include "jsapi.h"
10
#include "nsJSUtils.h"
11
12
#include "mozilla/Maybe.h"
13
#include "mozilla/Move.h"
14
15
namespace mozilla {
16
17
class ArrayIterElem;
18
class PropertyIterElem;
19
20
21
/*****************************************************************************
22
 * Object iterator base classes
23
 *****************************************************************************/
24
25
template<class T, class PropertyType>
26
class MOZ_STACK_CLASS BaseIter {
27
public:
28
  typedef T SelfType;
29
30
  PropertyType begin() const
31
0
  {
32
0
    PropertyType elem(Self());
33
0
    return std::move(elem);
34
0
  }
Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::begin() const
Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::begin() const
35
36
  PropertyType end() const
37
0
  {
38
0
    PropertyType elem(Self());
39
0
    return elem.End();
40
0
  }
Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::end() const
Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::end() const
41
42
0
  void* Context() const { return mContext; }
43
44
protected:
45
  BaseIter(JSContext* cx, JS::HandleObject object, void* context = nullptr)
46
    : mCx(cx)
47
    , mObject(object)
48
    , mContext(context)
49
0
  {}
Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::BaseIter(JSContext*, JS::Handle<JSObject*>, void*)
Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::BaseIter(JSContext*, JS::Handle<JSObject*>, void*)
50
51
  const SelfType& Self() const
52
0
  {
53
0
    return *static_cast<const SelfType*>(this);
54
0
  }
Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::Self() const
Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::Self() const
55
  SelfType& Self()
56
  {
57
    return *static_cast<SelfType*>(this);
58
  }
59
60
  JSContext* mCx;
61
62
  JS::HandleObject mObject;
63
64
  void* mContext;
65
};
66
67
template<class T, class IterType>
68
class MOZ_STACK_CLASS BaseIterElem {
69
public:
70
  typedef T SelfType;
71
72
  explicit BaseIterElem(const IterType& iter, uint32_t index = 0)
73
    : mIter(iter)
74
    , mIndex(index)
75
0
  {}
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::BaseIterElem(mozilla::PropertyIter const&, unsigned int)
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::BaseIterElem(mozilla::ArrayIter const&, unsigned int)
76
77
  uint32_t Length() const
78
0
  {
79
0
    return mIter.Length();
80
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Length() const
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Length() const
81
82
  JS::Value Value()
83
0
  {
84
0
    JS::RootedValue value(mIter.mCx, JS::UndefinedValue());
85
0
86
0
    auto& self = Self();
87
0
    if (!self.GetValue(&value)) {
88
0
      JS_ClearPendingException(mIter.mCx);
89
0
    }
90
0
91
0
    return value;
92
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Value()
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Value()
93
94
0
  SelfType& operator*() { return Self(); }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator*()
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator*()
95
96
  SelfType& operator++()
97
0
  {
98
0
    MOZ_ASSERT(mIndex < Length());
99
0
    mIndex++;
100
0
    return Self();
101
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator++()
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator++()
102
103
  bool operator!=(const SelfType& other) const
104
0
  {
105
0
    return &mIter != &other.mIter || mIndex != other.mIndex;
106
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator!=(mozilla::PropertyIterElem const&) const
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator!=(mozilla::ArrayIterElem const&) const
107
108
109
  SelfType End() const
110
0
  {
111
0
    SelfType end(mIter);
112
0
    end.mIndex = Length();
113
0
    return std::move(end);
114
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::End() const
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::End() const
115
116
0
  void* Context() const { return mIter.Context(); }
117
118
protected:
119
  const SelfType& Self() const
120
  {
121
    return *static_cast<const SelfType*>(this);
122
  }
123
0
  SelfType& Self() {
124
0
    return *static_cast<SelfType*>(this);
125
0
  }
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Self()
Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Self()
126
127
  const IterType& mIter;
128
129
  uint32_t mIndex;
130
};
131
132
133
/*****************************************************************************
134
 * Property iteration
135
 *****************************************************************************/
136
137
class MOZ_STACK_CLASS PropertyIter
138
  : public BaseIter<PropertyIter, PropertyIterElem>
139
{
140
  friend class PropertyIterElem;
141
  friend class BaseIterElem<PropertyIterElem, PropertyIter>;
142
143
public:
144
  PropertyIter(JSContext* cx, JS::HandleObject object, void* context = nullptr)
145
    : BaseIter(cx, object, context)
146
    , mIds(cx, JS::IdVector(cx))
147
0
  {
148
0
    if (!JS_Enumerate(cx, object, &mIds)) {
149
0
      JS_ClearPendingException(cx);
150
0
    }
151
0
  }
152
153
  PropertyIter(const PropertyIter& other)
154
    : PropertyIter(other.mCx, other.mObject, other.mContext)
155
0
  {}
156
157
  PropertyIter& operator=(const PropertyIter& other)
158
0
  {
159
0
    MOZ_ASSERT(other.mObject == mObject);
160
0
    mCx = other.mCx;
161
0
    mContext = other.mContext;
162
0
163
0
    mIds.clear();
164
0
    if (!JS_Enumerate(mCx, mObject, &mIds)) {
165
0
      JS_ClearPendingException(mCx);
166
0
    }
167
0
    return *this;
168
0
  }
169
170
  int32_t Length() const
171
0
  {
172
0
    return mIds.length();
173
0
  }
174
175
protected:
176
  JS::Rooted<JS::IdVector> mIds;
177
};
178
179
class MOZ_STACK_CLASS PropertyIterElem
180
  : public BaseIterElem<PropertyIterElem, PropertyIter>
181
{
182
  friend class BaseIterElem<PropertyIterElem, PropertyIter>;
183
184
public:
185
  using BaseIterElem::BaseIterElem;
186
187
  PropertyIterElem(const PropertyIterElem& other)
188
    : BaseIterElem(other.mIter, other.mIndex)
189
0
  {}
190
191
  jsid Id()
192
0
  {
193
0
    MOZ_ASSERT(mIndex < mIter.mIds.length());
194
0
195
0
    return mIter.mIds[mIndex];
196
0
  }
197
198
  const nsAString& Name()
199
0
  {
200
0
    if(mName.isNothing()) {
201
0
      mName.emplace();
202
0
      mName.ref().init(mIter.mCx, Id());
203
0
    }
204
0
    return mName.ref();
205
0
  }
206
207
0
  JSContext* Cx() { return mIter.mCx; }
208
209
protected:
210
  bool GetValue(JS::MutableHandleValue value)
211
0
  {
212
0
    MOZ_ASSERT(mIndex < Length());
213
0
    JS::Rooted<jsid> id(mIter.mCx, Id());
214
0
215
0
    return JS_GetPropertyById(mIter.mCx, mIter.mObject, id, value);
216
0
  }
217
218
private:
219
  Maybe<nsAutoJSString> mName;
220
};
221
222
223
/*****************************************************************************
224
 * Array iteration
225
 *****************************************************************************/
226
227
class MOZ_STACK_CLASS ArrayIter
228
  : public BaseIter<ArrayIter, ArrayIterElem>
229
{
230
  friend class ArrayIterElem;
231
  friend class BaseIterElem<ArrayIterElem, ArrayIter>;
232
233
public:
234
  ArrayIter(JSContext* cx, JS::HandleObject object)
235
    : BaseIter(cx, object)
236
    , mLength(0)
237
0
  {
238
0
    bool isArray;
239
0
    if (!JS_IsArrayObject(cx, object, &isArray) || !isArray) {
240
0
      JS_ClearPendingException(cx);
241
0
      return;
242
0
    }
243
0
244
0
    if (!JS_GetArrayLength(cx, object, &mLength)) {
245
0
      JS_ClearPendingException(cx);
246
0
    }
247
0
  }
248
249
  uint32_t Length() const
250
0
  {
251
0
    return mLength;
252
0
  }
253
254
private:
255
  uint32_t mLength;
256
};
257
258
class MOZ_STACK_CLASS ArrayIterElem
259
  : public BaseIterElem<ArrayIterElem, ArrayIter>
260
{
261
  friend class BaseIterElem<ArrayIterElem, ArrayIter>;
262
263
public:
264
  using BaseIterElem::BaseIterElem;
265
266
  ArrayIterElem(const ArrayIterElem& other)
267
    : BaseIterElem(other.mIter, other.mIndex)
268
0
  {}
269
270
protected:
271
  bool
272
  GetValue(JS::MutableHandleValue value)
273
0
  {
274
0
    MOZ_ASSERT(mIndex < Length());
275
0
    return JS_GetElement(mIter.mCx, mIter.mObject, mIndex, value);
276
0
  }
277
};
278
279
}
280
281
#endif // AddonManagerStartup_inlines_h