aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlcompiler_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlcompiler_p.h')
-rw-r--r--src/qml/qml/qqmlcompiler_p.h467
1 files changed, 467 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
new file mode 100644
index 0000000000..3b6fdf1473
--- /dev/null
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLCOMPILER_P_H
+#define QQMLCOMPILER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qqml.h"
+#include "qqmlerror.h"
+#include <private/qv8_p.h>
+#include "qqmlinstruction_p.h"
+#include "qqmlscript_p.h"
+#include "qqmlengine_p.h"
+#include <private/qbitfield_p.h>
+#include "qqmlpropertycache_p.h"
+#include "qqmlintegercache_p.h"
+#include "qqmltypenamecache_p.h"
+#include "qqmltypeloader_p.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qset.h>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+class QQmlComponent;
+class QQmlContext;
+class QQmlContextData;
+
+class Q_AUTOTEST_EXPORT QQmlCompiledData : public QQmlRefCount,
+ public QQmlCleanup
+{
+public:
+ QQmlCompiledData(QQmlEngine *engine);
+ virtual ~QQmlCompiledData();
+
+ QQmlEngine *engine;
+
+ QString name;
+ QUrl url;
+ QQmlTypeNameCache *importCache;
+
+ struct TypeReference
+ {
+ TypeReference()
+ : type(0), typePropertyCache(0), component(0) {}
+
+ QString className;
+ QQmlType *type;
+ QQmlPropertyCache *typePropertyCache;
+ QQmlCompiledData *component;
+
+ const QMetaObject *metaObject() const;
+ QQmlPropertyCache *propertyCache() const;
+ QQmlPropertyCache *createPropertyCache(QQmlEngine *);
+ };
+ QList<TypeReference> types;
+
+ struct V8Program {
+ V8Program(const QByteArray &p, QQmlCompiledData *c)
+ : program(p), cdata(c) {}
+
+ QByteArray program;
+ v8::Persistent<v8::Array> bindings;
+ QQmlCompiledData *cdata;
+ };
+
+ QList<V8Program> programs;
+
+ const QMetaObject *root;
+ QAbstractDynamicMetaObject rootData;
+ QQmlPropertyCache *rootPropertyCache;
+ QList<QString> primitives;
+ QList<QByteArray> datas;
+ QByteArray bytecode;
+ QList<QQmlPropertyCache *> propertyCaches;
+ QList<QQmlIntegerCache *> contextCaches;
+ QList<QQmlScriptData *> scripts;
+ QList<QUrl> urls;
+
+ struct Instruction {
+#define QML_INSTR_DATA_TYPEDEF(I, FMT) typedef QQmlInstructionData<QQmlInstruction::I> I;
+ FOR_EACH_QML_INSTR(QML_INSTR_DATA_TYPEDEF)
+#undef QML_INSTR_DATA_TYPEDEF
+ private:
+ Instruction();
+ };
+
+ void dumpInstructions();
+
+ template <int Instr>
+ int addInstruction(const QQmlInstructionData<Instr> &data)
+ {
+ QQmlInstruction genericInstr;
+ QQmlInstructionMeta<Instr>::setData(genericInstr, data);
+ return addInstructionHelper(static_cast<QQmlInstruction::Type>(Instr), genericInstr);
+ }
+ int nextInstructionIndex();
+ QQmlInstruction *instruction(int index);
+ QQmlInstruction::Type instructionType(const QQmlInstruction *instr);
+
+ bool isInitialized() const { return hasEngine(); }
+ void initialize(QQmlEngine *);
+
+protected:
+ virtual void destroy(); // From QQmlRefCount
+ virtual void clear(); // From QQmlCleanup
+
+private:
+ friend class QQmlCompiler;
+
+ int addInstructionHelper(QQmlInstruction::Type type, QQmlInstruction &instr);
+ void dump(QQmlInstruction *, int idx = -1);
+ QQmlCompiledData(const QQmlCompiledData &other);
+ QQmlCompiledData &operator=(const QQmlCompiledData &other);
+ QByteArray packData;
+ int pack(const char *, size_t);
+
+ int indexForString(const QString &);
+ int indexForByteArray(const QByteArray &);
+ int indexForUrl(const QUrl &);
+};
+
+namespace QQmlCompilerTypes {
+ struct BindingContext
+ {
+ BindingContext()
+ : stack(0), owner(0), object(0) {}
+ BindingContext(QQmlScript::Object *o)
+ : stack(0), owner(0), object(o) {}
+ BindingContext incr() const {
+ BindingContext rv(object);
+ rv.stack = stack + 1;
+ return rv;
+ }
+ bool isSubContext() const { return stack != 0; }
+ int stack;
+ int owner;
+ QQmlScript::Object *object;
+ };
+
+ struct BindingReference
+ {
+ enum DataType { QtScript, V4, V8,
+ Tr, TrId };
+ DataType dataType;
+ };
+
+ struct JSBindingReference : public QQmlPool::Class,
+ public BindingReference
+ {
+ JSBindingReference() : nextReference(0) {}
+
+ QQmlScript::Variant expression;
+ QQmlScript::Property *property;
+ QQmlScript::Value *value;
+
+ int compiledIndex;
+
+ QString rewrittenExpression;
+ BindingContext bindingContext;
+
+ JSBindingReference *nextReference;
+ };
+
+ struct TrBindingReference : public QQmlPool::POD,
+ public BindingReference
+ {
+ QStringRef text;
+ QStringRef comment;
+ int n;
+ };
+
+ struct IdList : public QFieldList<QQmlScript::Object,
+ &QQmlScript::Object::nextIdObject>
+ {
+ QQmlScript::Object *value(const QString &id) const {
+ for (QQmlScript::Object *o = first(); o; o = next(o)) {
+ if (o->id == id)
+ return o;
+ }
+ return 0;
+ }
+ };
+
+ struct DepthStack {
+ DepthStack() : _depth(0), _maxDepth(0) {}
+ DepthStack(const DepthStack &o) : _depth(o._depth), _maxDepth(o._maxDepth) {}
+ DepthStack &operator=(const DepthStack &o) { _depth = o._depth; _maxDepth = o._maxDepth; return *this; }
+
+ int depth() const { return _depth; }
+ int maxDepth() const { return _maxDepth; }
+
+ void push() { ++_depth; _maxDepth = qMax(_depth, _maxDepth); }
+ void pop() { --_depth; Q_ASSERT(_depth >= 0); Q_ASSERT(_maxDepth > _depth); }
+
+ void pushPop(int count) { _maxDepth = qMax(_depth + count, _maxDepth); }
+ private:
+ int _depth;
+ int _maxDepth;
+ };
+
+ // Contains all the incremental compiler state about a component. As
+ // a single QML file can have multiple components defined, there may be
+ // more than one of these for each compile
+ struct ComponentCompileState : public QQmlPool::Class
+ {
+ ComponentCompileState()
+ : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false),
+ v8BindingProgramLine(-1), root(0) {}
+
+ IdList ids;
+ int parserStatusCount;
+ int totalBindingsCount;
+ int pushedProperties;
+ bool nested;
+
+ QByteArray compiledBindingData;
+ QByteArray v8BindingProgram;
+ int v8BindingProgramLine;
+
+ DepthStack objectDepth;
+ DepthStack listDepth;
+
+ typedef QQmlCompilerTypes::JSBindingReference B;
+ typedef QFieldList<B, &B::nextReference> JSBindingReferenceList;
+ JSBindingReferenceList bindings;
+ typedef QQmlScript::Object O;
+ typedef QFieldList<O, &O::nextAliasingObject> AliasingObjectsList;
+ AliasingObjectsList aliasingObjects;
+ QQmlScript::Object *root;
+ };
+};
+
+class QMetaObjectBuilder;
+class Q_AUTOTEST_EXPORT QQmlCompiler
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlCompiler)
+public:
+ QQmlCompiler(QQmlPool *);
+
+ bool compile(QQmlEngine *, QQmlTypeData *, QQmlCompiledData *);
+
+ bool isError() const;
+ QList<QQmlError> errors() const;
+
+ static bool isAttachedPropertyName(const QString &);
+ static bool isSignalPropertyName(const QString &);
+ static bool isAttachedPropertyName(const QHashedStringRef &);
+ static bool isSignalPropertyName(const QHashedStringRef &);
+
+ int evaluateEnum(const QByteArray& script) const; // for QQmlCustomParser::evaluateEnum
+ const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType
+ int rewriteBinding(const QQmlScript::Variant& value, const QString& name); // for QQmlCustomParser::rewriteBinding
+ QString rewriteSignalHandler(const QQmlScript::Variant& value, const QString &name); // for QQmlCustomParser::rewriteSignalHandler
+
+private:
+ typedef QQmlCompiledData::Instruction Instruction;
+
+ static void reset(QQmlCompiledData *);
+
+ void compileTree(QQmlScript::Object *tree);
+
+
+ bool buildObject(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
+ bool buildComponent(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
+ bool buildSubObject(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
+ bool buildSignal(QQmlScript::Property *prop, QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &);
+ bool buildProperty(QQmlScript::Property *prop, QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &);
+ bool buildPropertyInNamespace(QQmlImportedNamespace *ns,
+ QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &);
+ bool buildIdProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
+ bool buildAttachedProperty(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildGroupedProperty(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildValueTypeProperty(QObject *type,
+ QQmlScript::Object *obj,
+ QQmlScript::Object *baseObj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildListProperty(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildScriptStringProperty(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyObjectAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Value *value,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyOnAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Object *baseObj,
+ QQmlScript::Value *value,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyLiteralAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Value *value,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool doesPropertyExist(QQmlScript::Property *prop, QQmlScript::Object *obj);
+ bool testLiteralAssignment(QQmlScript::Property *prop,
+ QQmlScript::Value *value);
+ bool testQualifiedEnumAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Value *value,
+ bool *isAssignment);
+ enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
+ bool mergeDynamicMetaProperties(QQmlScript::Object *obj);
+ bool buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mode);
+ bool checkDynamicMeta(QQmlScript::Object *obj);
+ bool buildBinding(QQmlScript::Value *, QQmlScript::Property *prop,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildLiteralBinding(QQmlScript::Value *, QQmlScript::Property *prop,
+ const QQmlCompilerTypes::BindingContext &ctxt);
+ bool buildComponentFromRoot(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
+ bool compileAlias(QFastMetaBuilder &,
+ QByteArray &data,
+ QQmlScript::Object *obj,
+ int propIndex, int aliasIndex,
+ QQmlScript::Object::DynamicProperty &);
+ bool completeComponentBuild();
+ bool checkValidId(QQmlScript::Value *, const QString &);
+
+
+ void genObject(QQmlScript::Object *obj);
+ void genObjectBody(QQmlScript::Object *obj);
+ void genValueTypeProperty(QQmlScript::Object *obj,QQmlScript::Property *);
+ void genComponent(QQmlScript::Object *obj);
+ void genValueProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
+ void genListProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
+ void genPropertyAssignment(QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Property *valueTypeProperty = 0);
+ void genLiteralAssignment(QQmlScript::Property *prop,
+ QQmlScript::Value *value);
+ void genBindingAssignment(QQmlScript::Value *binding,
+ QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
+ QQmlScript::Property *valueTypeProperty = 0);
+ int genContextCache();
+
+ QQmlPropertyData genValueTypeData(QQmlScript::Property *prop,
+ QQmlScript::Property *valueTypeProp);
+
+ int componentTypeRef();
+ int translationContextIndex();
+
+ static QQmlType *toQmlType(QQmlScript::Object *from);
+ bool canCoerce(int to, QQmlScript::Object *from);
+
+ QString elementName(QQmlScript::Object *);
+
+ QStringList deferredProperties(QQmlScript::Object *);
+
+ QQmlPropertyData *property(QQmlScript::Object *, int);
+ QQmlPropertyData *property(QQmlScript::Object *, const QHashedStringRef &,
+ bool *notInRevision = 0);
+ QQmlPropertyData *signal(QQmlScript::Object *, const QHashedStringRef &,
+ bool *notInRevision = 0);
+ int indexOfProperty(QQmlScript::Object *, const QHashedStringRef &, bool *notInRevision = 0);
+ int indexOfProperty(QQmlScript::Object *, const QString &, bool *notInRevision = 0);
+ int indexOfSignal(QQmlScript::Object *, const QString &, bool *notInRevision = 0);
+
+ void addId(const QString &, QQmlScript::Object *);
+
+ void dumpStats();
+
+ void addBindingReference(QQmlCompilerTypes::JSBindingReference *);
+
+ QQmlCompilerTypes::ComponentCompileState *compileState;
+
+ QQmlPool *pool;
+
+ QQmlCompilerTypes::ComponentCompileState *componentState(QQmlScript::Object *);
+ void saveComponentState();
+
+ QList<QQmlError> exceptions;
+ QQmlCompiledData *output;
+ QQmlEngine *engine;
+ QQmlEnginePrivate *enginePrivate;
+ QQmlScript::Object *unitRoot;
+ QQmlTypeData *unit;
+ int cachedComponentTypeRef;
+ int cachedTranslationContextIndex;
+
+ // Compiler component statistics. Only collected if QML_COMPILER_STATS=1
+ struct ComponentStat
+ {
+ ComponentStat() : ids(0), objects(0) {}
+
+ int lineNumber;
+
+ int ids;
+ QList<QQmlScript::LocationSpan> scriptBindings;
+ QList<QQmlScript::LocationSpan> sharedBindings;
+ QList<QQmlScript::LocationSpan> optimizedBindings;
+ int objects;
+ };
+ struct ComponentStats : public QQmlPool::Class
+ {
+ ComponentStat componentStat;
+ QList<ComponentStat> savedComponentStats;
+ };
+ ComponentStats *componentStats;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLCOMPILER_P_H