Implement strict mode for qmldir modules
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlcontext_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQMLCONTEXT_P_H
43 #define QQMLCONTEXT_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qqmlcontext.h"
57
58 #include "qqmldata_p.h"
59 #include "qqmlintegercache_p.h"
60 #include "qqmltypenamecache_p.h"
61 #include "qqmlnotifier_p.h"
62 #include "qqmllist.h"
63 #include "qqmlscript_p.h"
64
65 #include <QtCore/qhash.h>
66 #include <QtQml/qjsvalue.h>
67 #include <QtCore/qset.h>
68
69 #include <private/qobject_p.h>
70 #include <private/qflagpointer_p.h>
71 #include <private/qqmlguard_p.h>
72
73 #include <private/qv8_p.h>
74
75
76 QT_BEGIN_NAMESPACE
77
78 class QV8Bindings;
79 class QQmlContext;
80 class QQmlExpression;
81 class QQmlEngine;
82 class QQmlExpression;
83 class QQmlExpressionPrivate;
84 class QQmlAbstractExpression;
85 class QV4Bindings;
86 class QQmlContextData;
87
88 class QQmlContextPrivate : public QObjectPrivate
89 {
90     Q_DECLARE_PUBLIC(QQmlContext)
91 public:
92     QQmlContextPrivate();
93
94     QQmlContextData *data;
95
96     QList<QVariant> propertyValues;
97     int notifyIndex;
98
99     static QQmlContextPrivate *get(QQmlContext *context) {
100         return static_cast<QQmlContextPrivate *>(QObjectPrivate::get(context));
101     }
102     static QQmlContext *get(QQmlContextPrivate *context) {
103         return static_cast<QQmlContext *>(context->q_func());
104     }
105
106     // Only used for debugging
107     QList<QPointer<QObject> > instances;
108
109     static int context_count(QQmlListProperty<QObject> *);
110     static QObject *context_at(QQmlListProperty<QObject> *, int);
111 };
112
113 class QQmlVME;
114 class QQmlComponentAttached;
115 class QQmlGuardedContextData;
116 class Q_QML_PRIVATE_EXPORT QQmlContextData
117 {
118 public:
119     QQmlContextData();
120     QQmlContextData(QQmlContext *);
121     void emitDestruction();
122     void clearContext();
123     void destroy();
124     void invalidate();
125
126     inline bool isValid() const {
127         return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
128     }
129
130     // My parent context and engine
131     QQmlContextData *parent;
132     QQmlEngine *engine;
133
134     void setParent(QQmlContextData *, bool parentTakesOwnership = false);
135     void refreshExpressions();
136
137     void addObject(QObject *);
138
139     QUrl resolvedUrl(const QUrl &);
140
141     // My containing QQmlContext.  If isInternal is true this owns publicContext.  
142     // If internal is false publicContext owns this.
143     QQmlContext *asQQmlContext();
144     QQmlContextPrivate *asQQmlContextPrivate();
145     quint32 isInternal:1;
146     quint32 ownedByParent:1; // unrelated to isInternal; parent context deletes children if true.
147     quint32 isJSContext:1;
148     quint32 isPragmaLibraryContext:1;
149     quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
150     quint32 hasEmittedDestruction:1;
151     quint32 isRootObjectInCreation:1;
152     quint32 dummy:25;
153     QQmlContext *publicContext;
154
155     // VME data that is constructing this context if any
156     void *activeVMEData;
157
158     // Property name cache
159     QQmlIntegerCache *propertyNames;
160
161     // Context object
162     QObject *contextObject;
163
164     // Any script blocks that exist on this context
165     QList<v8::Persistent<v8::Object> > importedScripts;
166
167     // Context base url
168     QUrl url;
169     QString urlString;
170
171     // List of imports that apply to this context
172     QQmlTypeNameCache *imports;
173
174     // My children
175     QQmlContextData *childContexts;
176
177     // My peers in parent's childContexts list
178     QQmlContextData  *nextChild;
179     QQmlContextData **prevChild;
180
181     // Expressions that use this context
182     QQmlAbstractExpression *expressions;
183
184     // Doubly-linked list of objects that are owned by this context
185     QQmlData *contextObjects;
186
187     // Doubly-linked list of context guards (XXX merge with contextObjects)
188     QQmlGuardedContextData *contextGuards;
189
190     // id guards
191     struct ContextGuard : public QQmlGuard<QObject>
192     {
193         inline ContextGuard();
194         inline ContextGuard &operator=(QObject *obj);
195         inline void objectDestroyed(QObject *);
196
197         inline bool wasSet() const;
198
199         QFlagPointer<QQmlContextData> context;
200         QQmlNotifier bindings;
201     };
202     ContextGuard *idValues;
203     int idValueCount;
204     void setIdProperty(int, QObject *);
205     void setIdPropertyData(QQmlIntegerCache *);
206
207     // Linked contexts. this owns linkedContext.
208     QQmlContextData *linkedContext;
209
210     // Linked list of uses of the Component attached property in this
211     // context
212     QQmlComponentAttached *componentAttached;
213
214     // Optimized binding objects.  Needed for deferred properties.
215     QV4Bindings *v4bindings;
216     QV8Bindings *v8bindings;
217
218     // Return the outermost id for obj, if any.
219     QString findObjectId(const QObject *obj) const;
220
221     static QQmlContextData *get(QQmlContext *context) {
222         return QQmlContextPrivate::get(context)->data;
223     }
224
225 private:
226     void refreshExpressionsRecursive(bool isGlobal);
227     void refreshExpressionsRecursive(QQmlAbstractExpression *);
228     ~QQmlContextData() {}
229 };
230
231 class QQmlGuardedContextData
232 {
233 public:
234     inline QQmlGuardedContextData();
235     inline QQmlGuardedContextData(QQmlContextData *);
236     inline ~QQmlGuardedContextData();
237
238     inline QQmlContextData *contextData();
239     inline void setContextData(QQmlContextData *);
240
241     inline bool isNull() const { return !m_contextData; }
242
243     inline operator QQmlContextData*() const { return m_contextData; }
244     inline QQmlContextData* operator->() const { return m_contextData; }
245     inline QQmlGuardedContextData &operator=(QQmlContextData *d);
246
247 private:
248     QQmlGuardedContextData &operator=(const QQmlGuardedContextData &);
249     QQmlGuardedContextData(const QQmlGuardedContextData &);
250     friend class QQmlContextData;
251
252     inline void clear();
253
254     QQmlContextData *m_contextData;
255     QQmlGuardedContextData  *m_next;
256     QQmlGuardedContextData **m_prev;
257 };
258
259 QQmlGuardedContextData::QQmlGuardedContextData()
260 : m_contextData(0), m_next(0), m_prev(0)
261 {
262 }
263
264 QQmlGuardedContextData::QQmlGuardedContextData(QQmlContextData *data)
265 : m_contextData(0), m_next(0), m_prev(0)
266 {
267     setContextData(data);
268 }
269
270 QQmlGuardedContextData::~QQmlGuardedContextData()
271 {
272     clear();
273 }
274
275 void QQmlGuardedContextData::setContextData(QQmlContextData *contextData)
276 {
277     clear();
278
279     if (contextData) {
280         m_contextData = contextData;
281         m_next = contextData->contextGuards;
282         if (m_next) m_next->m_prev = &m_next;
283         m_prev = &contextData->contextGuards;
284         contextData->contextGuards = this;
285     }
286 }
287
288 QQmlContextData *QQmlGuardedContextData::contextData()
289 {
290     return m_contextData;
291 }
292
293 void QQmlGuardedContextData::clear()
294 {
295     if (m_prev) {
296         *m_prev = m_next;
297         if (m_next) m_next->m_prev = m_prev;
298         m_contextData = 0;
299         m_next = 0;
300         m_prev = 0;
301     }
302 }
303
304 QQmlGuardedContextData &
305 QQmlGuardedContextData::operator=(QQmlContextData *d)
306 {
307     setContextData(d);
308     return *this;
309 }
310
311 QQmlContextData::ContextGuard::ContextGuard()
312 : context(0)
313 {
314 }
315
316 QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj)
317 {
318     QQmlGuard<QObject>::operator=(obj);
319     context.setFlag();
320     bindings.notify(); // For alias connections
321     return *this;
322 }
323
324 void QQmlContextData::ContextGuard::objectDestroyed(QObject *)
325 {
326     if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted)
327         bindings.notify();
328 }
329
330 bool QQmlContextData::ContextGuard::wasSet() const
331 {
332     return context.flag();
333 }
334
335 QT_END_NAMESPACE
336
337 #endif // QQMLCONTEXT_P_H