Add QFastMetaBuilder
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecompiler_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVECOMPILER_P_H
43 #define QDECLARATIVECOMPILER_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 "qdeclarative.h"
57 #include "qdeclarativeerror.h"
58 #include "private/qv8_p.h"
59 #include "private/qdeclarativeinstruction_p.h"
60 #include "private/qdeclarativeparser_p.h"
61 #include "private/qdeclarativeengine_p.h"
62 #include "private/qbitfield_p.h"
63 #include "private/qdeclarativepropertycache_p.h"
64 #include "private/qdeclarativeintegercache_p.h"
65 #include "private/qdeclarativetypenamecache_p.h"
66 #include "private/qdeclarativetypeloader_p.h"
67
68 #include <QtCore/qbytearray.h>
69 #include <QtCore/qset.h>
70 #include <QtCore/QCoreApplication>
71
72 QT_BEGIN_NAMESPACE
73
74 class QDeclarativeEngine;
75 class QDeclarativeComponent;
76 class QDeclarativeContext;
77 class QDeclarativeContextData;
78
79 class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup
80 {
81 public:
82     QDeclarativeCompiledData(QDeclarativeEngine *engine);
83     virtual ~QDeclarativeCompiledData();
84
85     QString name;
86     QUrl url;
87     QDeclarativeTypeNameCache *importCache;
88
89     struct TypeReference 
90     {
91         TypeReference()
92         : type(0), typePropertyCache(0), component(0) {}
93
94         QString className;
95         QDeclarativeType *type;
96         QDeclarativePropertyCache *typePropertyCache;
97         QDeclarativeCompiledData *component;
98
99         QObject *createInstance(QDeclarativeContextData *, const QBitField &, QList<QDeclarativeError> *) const;
100         const QMetaObject *metaObject() const;
101         QDeclarativePropertyCache *propertyCache() const;
102         QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
103     };
104     QList<TypeReference> types;
105
106     QList<v8::Persistent<v8::Array> > v8bindings;
107
108     const QMetaObject *root;
109     QAbstractDynamicMetaObject rootData;
110     QDeclarativePropertyCache *rootPropertyCache;
111     QList<QString> primitives;
112     QList<QByteArray> datas;
113     QByteArray bytecode;
114     QList<QJSValue *> cachedClosures;
115     QList<QDeclarativePropertyCache *> propertyCaches;
116     QList<QDeclarativeIntegerCache *> contextCaches;
117     QList<QDeclarativeScriptData *> scripts;
118     QList<QUrl> urls;
119
120     void dumpInstructions();
121
122     int addInstruction(const QDeclarativeInstruction &instr);
123     int nextInstructionIndex();
124     QDeclarativeInstruction *instruction(int index);
125
126 protected:
127     virtual void clear(); // From QDeclarativeCleanup
128
129 private:
130     void dump(QDeclarativeInstruction *, int idx = -1);
131     QDeclarativeCompiledData(const QDeclarativeCompiledData &other);
132     QDeclarativeCompiledData &operator=(const QDeclarativeCompiledData &other);
133     QByteArray packData;
134     friend class QDeclarativeCompiler;
135     int pack(const char *, size_t);
136
137     int indexForString(const QString &);
138     int indexForByteArray(const QByteArray &);
139     int indexForUrl(const QUrl &);
140 };
141
142 namespace QDeclarativeCompilerTypes {
143     struct BindingContext 
144     {
145         BindingContext()
146             : stack(0), owner(0), object(0) {}
147         BindingContext(QDeclarativeParser::Object *o)
148             : stack(0), owner(0), object(o) {}
149         BindingContext incr() const {
150             BindingContext rv(object);
151             rv.stack = stack + 1;
152             return rv;
153         }
154         bool isSubContext() const { return stack != 0; }
155         int stack;
156         int owner;
157         QDeclarativeParser::Object *object;
158     };
159
160     struct BindingReference : public QDeclarativePool::Class 
161     {
162         BindingReference() : nextReference(0) {}
163
164         QDeclarativeParser::Variant expression;
165         QDeclarativeParser::Property *property;
166         QDeclarativeParser::Value *value;
167
168         enum DataType { QtScript, V4, V8 };
169         DataType dataType;
170
171         int compiledIndex;
172
173         QString rewrittenExpression;
174         BindingContext bindingContext;
175
176         BindingReference *nextReference;
177     };
178
179     struct IdList : public QFieldList<QDeclarativeParser::Object, 
180                                       &QDeclarativeParser::Object::nextIdObject>
181     {
182         QDeclarativeParser::Object *value(const QString &id) const {
183             for (QDeclarativeParser::Object *o = first(); o; o = next(o)) {
184                 if (o->id == id)
185                     return o;
186             }
187             return 0;
188         }
189     };
190
191     // Contains all the incremental compiler state about a component.  As
192     // a single QML file can have multiple components defined, there may be
193     // more than one of these for each compile
194     struct ComponentCompileState : public QDeclarativePool::Class
195     {
196         ComponentCompileState() 
197         : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
198
199         IdList ids;
200         int parserStatusCount;
201         int pushedProperties;
202         bool nested;
203
204         QByteArray compiledBindingData;
205         QString v8BindingProgram;
206         int v8BindingProgramLine;
207         int v8BindingProgramIndex;
208
209         typedef QDeclarativeCompilerTypes::BindingReference B;
210         typedef QFieldList<B, &B::nextReference> BindingReferenceList;
211         BindingReferenceList bindings;
212         typedef QDeclarativeParser::Object O;
213         typedef QFieldList<O, &O::nextAliasingObject> AliasingObjectsList;
214         AliasingObjectsList aliasingObjects;
215         QDeclarativeParser::Object *root;
216     };
217 };
218
219 class QMetaObjectBuilder;
220 class Q_AUTOTEST_EXPORT QDeclarativeCompiler
221 {
222     Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
223 public:
224     QDeclarativeCompiler(QDeclarativePool *);
225
226     bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
227
228     bool isError() const;
229     QList<QDeclarativeError> errors() const;
230
231     static bool isAttachedPropertyName(const QString &);
232     static bool isSignalPropertyName(const QString &);
233     static bool isAttachedPropertyName(const QStringRef &);
234     static bool isSignalPropertyName(const QStringRef &);
235
236     int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
237     const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
238     int rewriteBinding(const QString& expression, const QString& name); // for QDeclarativeCustomParser::rewriteBinding
239
240 private:
241     static void reset(QDeclarativeCompiledData *);
242
243     void compileTree(QDeclarativeParser::Object *tree);
244
245
246     bool buildObject(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
247     bool buildComponent(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
248     bool buildSubObject(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
249     bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, 
250                      const QDeclarativeCompilerTypes::BindingContext &);
251     bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, 
252                        const QDeclarativeCompilerTypes::BindingContext &);
253     bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
254                                   QDeclarativeParser::Property *prop, 
255                                   QDeclarativeParser::Object *obj, 
256                                   const QDeclarativeCompilerTypes::BindingContext &);
257     bool buildIdProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
258     bool buildAttachedProperty(QDeclarativeParser::Property *prop, 
259                                QDeclarativeParser::Object *obj,
260                                const QDeclarativeCompilerTypes::BindingContext &ctxt);
261     bool buildGroupedProperty(QDeclarativeParser::Property *prop,
262                               QDeclarativeParser::Object *obj,
263                               const QDeclarativeCompilerTypes::BindingContext &ctxt);
264     bool buildValueTypeProperty(QObject *type, 
265                                 QDeclarativeParser::Object *obj, 
266                                 QDeclarativeParser::Object *baseObj,
267                                 const QDeclarativeCompilerTypes::BindingContext &ctxt);
268     bool buildListProperty(QDeclarativeParser::Property *prop,
269                            QDeclarativeParser::Object *obj,
270                            const QDeclarativeCompilerTypes::BindingContext &ctxt);
271     bool buildScriptStringProperty(QDeclarativeParser::Property *prop,
272                                    QDeclarativeParser::Object *obj,
273                                    const QDeclarativeCompilerTypes::BindingContext &ctxt);
274     bool buildPropertyAssignment(QDeclarativeParser::Property *prop,
275                                  QDeclarativeParser::Object *obj,
276                                  const QDeclarativeCompilerTypes::BindingContext &ctxt);
277     bool buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
278                                        QDeclarativeParser::Object *obj,
279                                        QDeclarativeParser::Value *value,
280                                        const QDeclarativeCompilerTypes::BindingContext &ctxt);
281     bool buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
282                                    QDeclarativeParser::Object *obj,
283                                    QDeclarativeParser::Object *baseObj,
284                                    QDeclarativeParser::Value *value,
285                                    const QDeclarativeCompilerTypes::BindingContext &ctxt);
286     bool buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
287                                         QDeclarativeParser::Object *obj,
288                                         QDeclarativeParser::Value *value,
289                                         const QDeclarativeCompilerTypes::BindingContext &ctxt);
290     bool doesPropertyExist(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
291     bool testLiteralAssignment(QDeclarativeParser::Property *prop,
292                                QDeclarativeParser::Value *value);
293     bool testQualifiedEnumAssignment(const QMetaProperty &prop,
294                                      QDeclarativeParser::Object *obj,
295                                      QDeclarativeParser::Value *value,
296                                      bool *isAssignment);
297     enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
298     bool mergeDynamicMetaProperties(QDeclarativeParser::Object *obj);
299     bool buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode);
300     bool checkDynamicMeta(QDeclarativeParser::Object *obj);
301     bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop,
302                       const QDeclarativeCompilerTypes::BindingContext &ctxt);
303     bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
304     bool compileAlias(QFastMetaBuilder &, 
305                       QByteArray &data,
306                       QDeclarativeParser::Object *obj, 
307                       int propIndex, int aliasIndex,
308                       QDeclarativeParser::Object::DynamicProperty &);
309     bool completeComponentBuild();
310     bool checkValidId(QDeclarativeParser::Value *, const QString &);
311
312
313     void genObject(QDeclarativeParser::Object *obj);
314     void genObjectBody(QDeclarativeParser::Object *obj);
315     void genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *);
316     void genComponent(QDeclarativeParser::Object *obj);
317     void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
318     void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
319     void genPropertyAssignment(QDeclarativeParser::Property *prop, 
320                                QDeclarativeParser::Object *obj,
321                                QDeclarativeParser::Property *valueTypeProperty = 0);
322     void genLiteralAssignment(QDeclarativeParser::Property *prop,
323                               QDeclarativeParser::Value *value);
324     void genBindingAssignment(QDeclarativeParser::Value *binding, 
325                               QDeclarativeParser::Property *prop, 
326                               QDeclarativeParser::Object *obj,
327                               QDeclarativeParser::Property *valueTypeProperty = 0);
328     int genContextCache();
329
330     int genValueTypeData(QDeclarativeParser::Property *prop, QDeclarativeParser::Property *valueTypeProp);
331     int genPropertyData(QDeclarativeParser::Property *prop);
332
333     int componentTypeRef();
334
335     static QDeclarativeType *toQmlType(QDeclarativeParser::Object *from);
336     bool canCoerce(int to, QDeclarativeParser::Object *from);
337
338     QString elementName(QDeclarativeParser::Object *);
339
340     QStringList deferredProperties(QDeclarativeParser::Object *);
341
342     QDeclarativePropertyCache::Data *property(QDeclarativeParser::Object *, int);
343     QDeclarativePropertyCache::Data *property(QDeclarativeParser::Object *, const QStringRef &, 
344                                               bool *notInRevision = 0);
345     QDeclarativePropertyCache::Data *signal(QDeclarativeParser::Object *, const QStringRef &, 
346                                             bool *notInRevision = 0);
347     int indexOfProperty(QDeclarativeParser::Object *, const QStringRef &, bool *notInRevision = 0);
348     int indexOfProperty(QDeclarativeParser::Object *, const QString &, bool *notInRevision = 0);
349     int indexOfSignal(QDeclarativeParser::Object *, const QString &, bool *notInRevision = 0);
350
351     void addId(const QString &, QDeclarativeParser::Object *);
352
353     void dumpStats();
354
355     void addBindingReference(QDeclarativeCompilerTypes::BindingReference *);
356
357     QDeclarativeCompilerTypes::ComponentCompileState *compileState;
358
359     QDeclarativePool *pool;
360
361     QDeclarativeCompilerTypes::ComponentCompileState *componentState(QDeclarativeParser::Object *);
362     void saveComponentState();
363
364     QList<QDeclarativeError> exceptions;
365     QDeclarativeCompiledData *output;
366     QDeclarativeEngine *engine;
367     QDeclarativeEnginePrivate *enginePrivate;
368     QDeclarativeParser::Object *unitRoot;
369     QDeclarativeTypeData *unit;
370
371
372     // Compiler component statistics.  Only collected if QML_COMPILER_STATS=1
373     struct ComponentStat
374     {
375         ComponentStat() : ids(0), objects(0) {}
376
377         int lineNumber;
378
379         int ids;
380         QList<QDeclarativeParser::LocationSpan> scriptBindings;
381         QList<QDeclarativeParser::LocationSpan> optimizedBindings;
382         int objects;
383     };
384     struct ComponentStats : public QDeclarativePool::Class
385     {
386         ComponentStat componentStat;
387         QList<ComponentStat> savedComponentStats;
388     };
389     ComponentStats *componentStats;
390 };
391
392 QT_END_NAMESPACE
393
394 #endif // QDECLARATIVECOMPILER_P_H