Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecompiler_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 QtDeclarative 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 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 "qdeclarativeinstruction_p.h"
60 #include "qdeclarativescript_p.h"
61 #include "qdeclarativeengine_p.h"
62 #include <private/qbitfield_p.h>
63 #include "qdeclarativepropertycache_p.h"
64 #include "qdeclarativeintegercache_p.h"
65 #include "qdeclarativetypenamecache_p.h"
66 #include "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,
80                                                    public QDeclarativeCleanup
81 {
82 public:
83     QDeclarativeCompiledData(QDeclarativeEngine *engine);
84     virtual ~QDeclarativeCompiledData();
85
86     QDeclarativeEngine *engine;
87
88     QString name;
89     QUrl url;
90     QDeclarativeTypeNameCache *importCache;
91
92     struct TypeReference 
93     {
94         TypeReference()
95         : type(0), typePropertyCache(0), component(0) {}
96
97         QString className;
98         QDeclarativeType *type;
99         QDeclarativePropertyCache *typePropertyCache;
100         QDeclarativeCompiledData *component;
101
102         const QMetaObject *metaObject() const;
103         QDeclarativePropertyCache *propertyCache() const;
104         QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
105     };
106     QList<TypeReference> types;
107
108     QList<v8::Persistent<v8::Array> > v8bindings;
109
110     const QMetaObject *root;
111     QAbstractDynamicMetaObject rootData;
112     QDeclarativePropertyCache *rootPropertyCache;
113     QList<QString> primitives;
114     QList<QByteArray> datas;
115     QByteArray bytecode;
116     QList<QDeclarativePropertyCache *> propertyCaches;
117     QList<QDeclarativeIntegerCache *> contextCaches;
118     QList<QDeclarativeScriptData *> scripts;
119     QList<QUrl> urls;
120
121     struct Instruction {
122 #define QML_INSTR_DATA_TYPEDEF(I, FMT) typedef QDeclarativeInstructionData<QDeclarativeInstruction::I> I;
123     FOR_EACH_QML_INSTR(QML_INSTR_DATA_TYPEDEF)
124 #undef QML_INSTR_DATA_TYPEDEF
125     private:
126         Instruction();
127     };
128
129     void dumpInstructions();
130
131     template <int Instr>
132     int addInstruction(const QDeclarativeInstructionData<Instr> &data)
133     {
134         QDeclarativeInstruction genericInstr;
135         QDeclarativeInstructionMeta<Instr>::setData(genericInstr, data);
136         return addInstructionHelper(static_cast<QDeclarativeInstruction::Type>(Instr), genericInstr);
137     }
138     int nextInstructionIndex();
139     QDeclarativeInstruction *instruction(int index);
140     QDeclarativeInstruction::Type instructionType(const QDeclarativeInstruction *instr);
141
142     bool isInitialized() const { return hasEngine(); }
143     void initialize(QDeclarativeEngine *);
144
145 protected:
146     virtual void destroy(); // From QDeclarativeRefCount
147     virtual void clear(); // From QDeclarativeCleanup
148
149 private:
150     friend class QDeclarativeCompiler;
151
152     int addInstructionHelper(QDeclarativeInstruction::Type type, QDeclarativeInstruction &instr);
153     void dump(QDeclarativeInstruction *, int idx = -1);
154     QDeclarativeCompiledData(const QDeclarativeCompiledData &other);
155     QDeclarativeCompiledData &operator=(const QDeclarativeCompiledData &other);
156     QByteArray packData;
157     int pack(const char *, size_t);
158
159     int indexForString(const QString &);
160     int indexForByteArray(const QByteArray &);
161     int indexForUrl(const QUrl &);
162 };
163
164 namespace QDeclarativeCompilerTypes {
165     struct BindingContext 
166     {
167         BindingContext()
168             : stack(0), owner(0), object(0) {}
169         BindingContext(QDeclarativeScript::Object *o)
170             : stack(0), owner(0), object(o) {}
171         BindingContext incr() const {
172             BindingContext rv(object);
173             rv.stack = stack + 1;
174             return rv;
175         }
176         bool isSubContext() const { return stack != 0; }
177         int stack;
178         int owner;
179         QDeclarativeScript::Object *object;
180     };
181
182     struct BindingReference
183     {
184         enum DataType { QtScript, V4, V8,
185                         Tr, TrId };
186         DataType dataType;
187     };
188
189     struct JSBindingReference : public QDeclarativePool::Class,
190                                 public BindingReference
191     {
192         JSBindingReference() : nextReference(0) {}
193
194         QDeclarativeScript::Variant expression;
195         QDeclarativeScript::Property *property;
196         QDeclarativeScript::Value *value;
197
198         int compiledIndex;
199
200         QString rewrittenExpression;
201         BindingContext bindingContext;
202
203         JSBindingReference *nextReference;
204     };
205
206     struct TrBindingReference : public QDeclarativePool::POD,
207                                 public BindingReference
208     {
209         QStringRef text;
210         QStringRef comment;
211         int n;
212     };
213
214     struct IdList : public QFieldList<QDeclarativeScript::Object, 
215                                       &QDeclarativeScript::Object::nextIdObject>
216     {
217         QDeclarativeScript::Object *value(const QString &id) const {
218             for (QDeclarativeScript::Object *o = first(); o; o = next(o)) {
219                 if (o->id == id)
220                     return o;
221             }
222             return 0;
223         }
224     };
225
226     struct DepthStack {
227         DepthStack() : _depth(0), _maxDepth(0) {}
228         DepthStack(const DepthStack &o) : _depth(o._depth), _maxDepth(o._maxDepth) {}
229         DepthStack &operator=(const DepthStack &o) { _depth = o._depth; _maxDepth = o._maxDepth; return *this; }
230
231         int depth() const { return _depth; }
232         int maxDepth() const { return _maxDepth; }
233
234         void push() { ++_depth; _maxDepth = qMax(_depth, _maxDepth); }
235         void pop() { --_depth; Q_ASSERT(_depth >= 0); Q_ASSERT(_maxDepth > _depth); }
236
237         void pushPop(int count) { _maxDepth = qMax(_depth + count, _maxDepth); }
238     private:
239         int _depth;
240         int _maxDepth;
241     };
242
243     // Contains all the incremental compiler state about a component.  As
244     // a single QML file can have multiple components defined, there may be
245     // more than one of these for each compile
246     struct ComponentCompileState : public QDeclarativePool::Class
247     {
248         ComponentCompileState() 
249         : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false), 
250           v8BindingProgramLine(-1), root(0) {}
251
252         IdList ids;
253         int parserStatusCount;
254         int totalBindingsCount;
255         int pushedProperties;
256         bool nested;
257
258         QByteArray compiledBindingData;
259         QString v8BindingProgram;
260         int v8BindingProgramLine;
261         int v8BindingProgramIndex;
262
263         DepthStack objectDepth;
264         DepthStack listDepth;
265
266         typedef QDeclarativeCompilerTypes::JSBindingReference B;
267         typedef QFieldList<B, &B::nextReference> JSBindingReferenceList;
268         JSBindingReferenceList bindings;
269         typedef QDeclarativeScript::Object O;
270         typedef QFieldList<O, &O::nextAliasingObject> AliasingObjectsList;
271         AliasingObjectsList aliasingObjects;
272         QDeclarativeScript::Object *root;
273     };
274 };
275
276 class QMetaObjectBuilder;
277 class Q_AUTOTEST_EXPORT QDeclarativeCompiler
278 {
279     Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
280 public:
281     QDeclarativeCompiler(QDeclarativePool *);
282
283     bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
284
285     bool isError() const;
286     QList<QDeclarativeError> errors() const;
287
288     static bool isAttachedPropertyName(const QString &);
289     static bool isSignalPropertyName(const QString &);
290     static bool isAttachedPropertyName(const QHashedStringRef &);
291     static bool isSignalPropertyName(const QHashedStringRef &);
292
293     int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
294     const QMetaObject *resolveType(const QString& name) const; // for QDeclarativeCustomParser::resolveType
295     int rewriteBinding(const QDeclarativeScript::Variant& value, const QString& name); // for QDeclarativeCustomParser::rewriteBinding
296     QString rewriteSignalHandler(const QString &handler, const QString &name);  // for QDeclarativeCustomParser::rewriteSignalHandler
297
298 private:
299     typedef QDeclarativeCompiledData::Instruction Instruction;
300
301     static void reset(QDeclarativeCompiledData *);
302
303     void compileTree(QDeclarativeScript::Object *tree);
304
305
306     bool buildObject(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
307     bool buildComponent(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
308     bool buildSubObject(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
309     bool buildSignal(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj, 
310                      const QDeclarativeCompilerTypes::BindingContext &);
311     bool buildProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj, 
312                        const QDeclarativeCompilerTypes::BindingContext &);
313     bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
314                                   QDeclarativeScript::Property *prop, 
315                                   QDeclarativeScript::Object *obj, 
316                                   const QDeclarativeCompilerTypes::BindingContext &);
317     bool buildIdProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
318     bool buildAttachedProperty(QDeclarativeScript::Property *prop, 
319                                QDeclarativeScript::Object *obj,
320                                const QDeclarativeCompilerTypes::BindingContext &ctxt);
321     bool buildGroupedProperty(QDeclarativeScript::Property *prop,
322                               QDeclarativeScript::Object *obj,
323                               const QDeclarativeCompilerTypes::BindingContext &ctxt);
324     bool buildValueTypeProperty(QObject *type, 
325                                 QDeclarativeScript::Object *obj, 
326                                 QDeclarativeScript::Object *baseObj,
327                                 const QDeclarativeCompilerTypes::BindingContext &ctxt);
328     bool buildListProperty(QDeclarativeScript::Property *prop,
329                            QDeclarativeScript::Object *obj,
330                            const QDeclarativeCompilerTypes::BindingContext &ctxt);
331     bool buildScriptStringProperty(QDeclarativeScript::Property *prop,
332                                    QDeclarativeScript::Object *obj,
333                                    const QDeclarativeCompilerTypes::BindingContext &ctxt);
334     bool buildPropertyAssignment(QDeclarativeScript::Property *prop,
335                                  QDeclarativeScript::Object *obj,
336                                  const QDeclarativeCompilerTypes::BindingContext &ctxt);
337     bool buildPropertyObjectAssignment(QDeclarativeScript::Property *prop,
338                                        QDeclarativeScript::Object *obj,
339                                        QDeclarativeScript::Value *value,
340                                        const QDeclarativeCompilerTypes::BindingContext &ctxt);
341     bool buildPropertyOnAssignment(QDeclarativeScript::Property *prop,
342                                    QDeclarativeScript::Object *obj,
343                                    QDeclarativeScript::Object *baseObj,
344                                    QDeclarativeScript::Value *value,
345                                    const QDeclarativeCompilerTypes::BindingContext &ctxt);
346     bool buildPropertyLiteralAssignment(QDeclarativeScript::Property *prop,
347                                         QDeclarativeScript::Object *obj,
348                                         QDeclarativeScript::Value *value,
349                                         const QDeclarativeCompilerTypes::BindingContext &ctxt);
350     bool doesPropertyExist(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
351     bool testLiteralAssignment(QDeclarativeScript::Property *prop,
352                                QDeclarativeScript::Value *value);
353     bool testQualifiedEnumAssignment(QDeclarativeScript::Property *prop,
354                                      QDeclarativeScript::Object *obj,
355                                      QDeclarativeScript::Value *value,
356                                      bool *isAssignment);
357     enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
358     bool mergeDynamicMetaProperties(QDeclarativeScript::Object *obj);
359     bool buildDynamicMeta(QDeclarativeScript::Object *obj, DynamicMetaMode mode);
360     bool checkDynamicMeta(QDeclarativeScript::Object *obj);
361     bool buildBinding(QDeclarativeScript::Value *, QDeclarativeScript::Property *prop,
362                       const QDeclarativeCompilerTypes::BindingContext &ctxt);
363     bool buildLiteralBinding(QDeclarativeScript::Value *, QDeclarativeScript::Property *prop,
364                              const QDeclarativeCompilerTypes::BindingContext &ctxt);
365     bool buildComponentFromRoot(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
366     bool compileAlias(QFastMetaBuilder &, 
367                       QByteArray &data,
368                       QDeclarativeScript::Object *obj, 
369                       int propIndex, int aliasIndex,
370                       QDeclarativeScript::Object::DynamicProperty &);
371     bool completeComponentBuild();
372     bool checkValidId(QDeclarativeScript::Value *, const QString &);
373
374
375     void genObject(QDeclarativeScript::Object *obj);
376     void genObjectBody(QDeclarativeScript::Object *obj);
377     void genValueTypeProperty(QDeclarativeScript::Object *obj,QDeclarativeScript::Property *);
378     void genComponent(QDeclarativeScript::Object *obj);
379     void genValueProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
380     void genListProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
381     void genPropertyAssignment(QDeclarativeScript::Property *prop, 
382                                QDeclarativeScript::Object *obj,
383                                QDeclarativeScript::Property *valueTypeProperty = 0);
384     void genLiteralAssignment(QDeclarativeScript::Property *prop,
385                               QDeclarativeScript::Value *value);
386     void genBindingAssignment(QDeclarativeScript::Value *binding, 
387                               QDeclarativeScript::Property *prop, 
388                               QDeclarativeScript::Object *obj,
389                               QDeclarativeScript::Property *valueTypeProperty = 0);
390     int genContextCache();
391
392     QDeclarativePropertyData genValueTypeData(QDeclarativeScript::Property *prop,
393                                               QDeclarativeScript::Property *valueTypeProp);
394
395     int componentTypeRef();
396     int translationContextIndex();
397
398     static QDeclarativeType *toQmlType(QDeclarativeScript::Object *from);
399     bool canCoerce(int to, QDeclarativeScript::Object *from);
400
401     QString elementName(QDeclarativeScript::Object *);
402
403     QStringList deferredProperties(QDeclarativeScript::Object *);
404
405     QDeclarativePropertyData *property(QDeclarativeScript::Object *, int);
406     QDeclarativePropertyData *property(QDeclarativeScript::Object *, const QHashedStringRef &,
407                                        bool *notInRevision = 0);
408     QDeclarativePropertyData *signal(QDeclarativeScript::Object *, const QHashedStringRef &,
409                                      bool *notInRevision = 0);
410     int indexOfProperty(QDeclarativeScript::Object *, const QHashedStringRef &, bool *notInRevision = 0);
411     int indexOfProperty(QDeclarativeScript::Object *, const QString &, bool *notInRevision = 0);
412     int indexOfSignal(QDeclarativeScript::Object *, const QString &, bool *notInRevision = 0);
413
414     void addId(const QString &, QDeclarativeScript::Object *);
415
416     void dumpStats();
417
418     void addBindingReference(QDeclarativeCompilerTypes::JSBindingReference *);
419
420     QDeclarativeCompilerTypes::ComponentCompileState *compileState;
421
422     QDeclarativePool *pool;
423
424     QDeclarativeCompilerTypes::ComponentCompileState *componentState(QDeclarativeScript::Object *);
425     void saveComponentState();
426
427     QList<QDeclarativeError> exceptions;
428     QDeclarativeCompiledData *output;
429     QDeclarativeEngine *engine;
430     QDeclarativeEnginePrivate *enginePrivate;
431     QDeclarativeScript::Object *unitRoot;
432     QDeclarativeTypeData *unit;
433     int cachedComponentTypeRef;
434     int cachedTranslationContextIndex;
435
436     // Compiler component statistics.  Only collected if QML_COMPILER_STATS=1
437     struct ComponentStat
438     {
439         ComponentStat() : ids(0), objects(0) {}
440
441         int lineNumber;
442
443         int ids;
444         QList<QDeclarativeScript::LocationSpan> scriptBindings;
445         QList<QDeclarativeScript::LocationSpan> optimizedBindings;
446         int objects;
447     };
448     struct ComponentStats : public QDeclarativePool::Class
449     {
450         ComponentStat componentStat;
451         QList<ComponentStat> savedComponentStats;
452     };
453     ComponentStats *componentStats;
454 };
455
456 QT_END_NAMESPACE
457
458 #endif // QDECLARATIVECOMPILER_P_H