1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #ifndef QDECLARATIVECOMPILER_P_H
43 #define QDECLARATIVECOMPILER_P_H
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.
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"
68 #include <QtCore/qbytearray.h>
69 #include <QtCore/qset.h>
70 #include <QtCore/QCoreApplication>
74 class QDeclarativeEngine;
75 class QDeclarativeComponent;
76 class QDeclarativeContext;
77 class QDeclarativeContextData;
79 class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount,
80 public QDeclarativeCleanup
83 QDeclarativeCompiledData(QDeclarativeEngine *engine);
84 virtual ~QDeclarativeCompiledData();
86 QDeclarativeEngine *engine;
90 QDeclarativeTypeNameCache *importCache;
95 : type(0), typePropertyCache(0), component(0) {}
98 QDeclarativeType *type;
99 QDeclarativePropertyCache *typePropertyCache;
100 QDeclarativeCompiledData *component;
102 const QMetaObject *metaObject() const;
103 QDeclarativePropertyCache *propertyCache() const;
104 QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
106 QList<TypeReference> types;
108 QList<v8::Persistent<v8::Array> > v8bindings;
110 const QMetaObject *root;
111 QAbstractDynamicMetaObject rootData;
112 QDeclarativePropertyCache *rootPropertyCache;
113 QList<QString> primitives;
114 QList<QByteArray> datas;
116 QList<QDeclarativePropertyCache *> propertyCaches;
117 QList<QDeclarativeIntegerCache *> contextCaches;
118 QList<QDeclarativeScriptData *> scripts;
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
129 void dumpInstructions();
132 int addInstruction(const QDeclarativeInstructionData<Instr> &data)
134 QDeclarativeInstruction genericInstr;
135 QDeclarativeInstructionMeta<Instr>::setData(genericInstr, data);
136 return addInstructionHelper(static_cast<QDeclarativeInstruction::Type>(Instr), genericInstr);
138 int nextInstructionIndex();
139 QDeclarativeInstruction *instruction(int index);
140 QDeclarativeInstruction::Type instructionType(const QDeclarativeInstruction *instr);
142 bool isInitialized() const { return hasEngine(); }
143 void initialize(QDeclarativeEngine *);
146 virtual void destroy(); // From QDeclarativeRefCount
147 virtual void clear(); // From QDeclarativeCleanup
150 friend class QDeclarativeCompiler;
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);
157 int pack(const char *, size_t);
159 int indexForString(const QString &);
160 int indexForByteArray(const QByteArray &);
161 int indexForUrl(const QUrl &);
164 namespace QDeclarativeCompilerTypes {
165 struct 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;
176 bool isSubContext() const { return stack != 0; }
179 QDeclarativeScript::Object *object;
182 struct BindingReference
184 enum DataType { QtScript, V4, V8,
189 struct JSBindingReference : public QDeclarativePool::Class,
190 public BindingReference
192 JSBindingReference() : nextReference(0) {}
194 QDeclarativeScript::Variant expression;
195 QDeclarativeScript::Property *property;
196 QDeclarativeScript::Value *value;
200 QString rewrittenExpression;
201 BindingContext bindingContext;
203 JSBindingReference *nextReference;
206 struct TrBindingReference : public QDeclarativePool::POD,
207 public BindingReference
214 struct IdList : public QFieldList<QDeclarativeScript::Object,
215 &QDeclarativeScript::Object::nextIdObject>
217 QDeclarativeScript::Object *value(const QString &id) const {
218 for (QDeclarativeScript::Object *o = first(); o; o = next(o)) {
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; }
231 int depth() const { return _depth; }
232 int maxDepth() const { return _maxDepth; }
234 void push() { ++_depth; _maxDepth = qMax(_depth, _maxDepth); }
235 void pop() { --_depth; Q_ASSERT(_depth >= 0); Q_ASSERT(_maxDepth > _depth); }
237 void pushPop(int count) { _maxDepth = qMax(_depth + count, _maxDepth); }
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
248 ComponentCompileState()
249 : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false),
250 v8BindingProgramLine(-1), root(0) {}
253 int parserStatusCount;
254 int totalBindingsCount;
255 int pushedProperties;
258 QByteArray compiledBindingData;
259 QString v8BindingProgram;
260 int v8BindingProgramLine;
261 int v8BindingProgramIndex;
263 DepthStack objectDepth;
264 DepthStack listDepth;
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;
276 class QMetaObjectBuilder;
277 class Q_AUTOTEST_EXPORT QDeclarativeCompiler
279 Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
281 QDeclarativeCompiler(QDeclarativePool *);
283 bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
285 bool isError() const;
286 QList<QDeclarativeError> errors() const;
288 static bool isAttachedPropertyName(const QString &);
289 static bool isSignalPropertyName(const QString &);
290 static bool isAttachedPropertyName(const QHashedStringRef &);
291 static bool isSignalPropertyName(const QHashedStringRef &);
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
299 typedef QDeclarativeCompiledData::Instruction Instruction;
301 static void reset(QDeclarativeCompiledData *);
303 void compileTree(QDeclarativeScript::Object *tree);
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,
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 &,
368 QDeclarativeScript::Object *obj,
369 int propIndex, int aliasIndex,
370 QDeclarativeScript::Object::DynamicProperty &);
371 bool completeComponentBuild();
372 bool checkValidId(QDeclarativeScript::Value *, const QString &);
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();
392 QDeclarativePropertyData genValueTypeData(QDeclarativeScript::Property *prop,
393 QDeclarativeScript::Property *valueTypeProp);
395 int componentTypeRef();
396 int translationContextIndex();
398 static QDeclarativeType *toQmlType(QDeclarativeScript::Object *from);
399 bool canCoerce(int to, QDeclarativeScript::Object *from);
401 QString elementName(QDeclarativeScript::Object *);
403 QStringList deferredProperties(QDeclarativeScript::Object *);
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);
414 void addId(const QString &, QDeclarativeScript::Object *);
418 void addBindingReference(QDeclarativeCompilerTypes::JSBindingReference *);
420 QDeclarativeCompilerTypes::ComponentCompileState *compileState;
422 QDeclarativePool *pool;
424 QDeclarativeCompilerTypes::ComponentCompileState *componentState(QDeclarativeScript::Object *);
425 void saveComponentState();
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;
436 // Compiler component statistics. Only collected if QML_COMPILER_STATS=1
439 ComponentStat() : ids(0), objects(0) {}
444 QList<QDeclarativeScript::LocationSpan> scriptBindings;
445 QList<QDeclarativeScript::LocationSpan> optimizedBindings;
448 struct ComponentStats : public QDeclarativePool::Class
450 ComponentStat componentStat;
451 QList<ComponentStat> savedComponentStats;
453 ComponentStats *componentStats;
458 #endif // QDECLARATIVECOMPILER_P_H