aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qml.pri6
-rw-r--r--src/qml/qml/qqmlabstractbinding_p.h5
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp6
-rw-r--r--src/qml/qml/qqmlcompiler_p.h12
-rw-r--r--src/qml/qml/qqmlcomponent.cpp26
-rw-r--r--src/qml/qml/qqmlcomponent_p.h16
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlengine_p.h1
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp686
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h97
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp79
-rw-r--r--src/qml/qml/qqmltypeloader_p.h6
13 files changed, 928 insertions, 19 deletions
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index dae76ede32..77b0334c7e 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -54,7 +54,8 @@ SOURCES += \
$$PWD/qqmllistwrapper.cpp \
$$PWD/qqmlcontextwrapper.cpp \
$$PWD/qqmlvaluetypewrapper.cpp \
- $$PWD/qqmltypewrapper.cpp
+ $$PWD/qqmltypewrapper.cpp \
+ $$PWD/qqmlobjectcreator.cpp
HEADERS += \
$$PWD/qqmlglobal_p.h \
@@ -130,7 +131,8 @@ HEADERS += \
$$PWD/qqmllistwrapper_p.h \
$$PWD/qqmlcontextwrapper_p.h \
$$PWD/qqmlvaluetypewrapper_p.h \
- $$PWD/qqmltypewrapper_p.h
+ $$PWD/qqmltypewrapper_p.h \
+ $$PWD/qqmlobjectcreator_p.h
include(ftw/ftw.pri)
include(v8/v8.pri)
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h
index 40d42d8284..8b04d823e2 100644
--- a/src/qml/qml/qqmlabstractbinding_p.h
+++ b/src/qml/qml/qqmlabstractbinding_p.h
@@ -60,6 +60,10 @@
QT_BEGIN_NAMESPACE
+namespace QtQml {
+class QmlObjectCreator;
+}
+
class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding
{
public:
@@ -150,6 +154,7 @@ private:
friend class QQmlVME;
friend class QtSharedPointer::ExternalRefCount<QQmlAbstractBinding>;
friend class QV4Bindings;
+ friend class QtQml::QmlObjectCreator;
typedef QSharedPointer<QQmlAbstractBinding> SharedPointer;
// To save memory, we also store the rarely used weakPointer() instance in here
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp
index abe278f570..a2e323a129 100644
--- a/src/qml/qml/qqmlcompileddata.cpp
+++ b/src/qml/qml/qqmlcompileddata.cpp
@@ -87,7 +87,7 @@ int QQmlCompiledData::indexForUrl(const QUrl &data)
QQmlCompiledData::QQmlCompiledData(QQmlEngine *engine)
: engine(engine), importCache(0), metaTypeId(-1), listMetaTypeId(-1), isRegisteredWithEngine(false),
- rootPropertyCache(0)
+ rootPropertyCache(0), compilationUnit(0), qmlUnit(0)
{
Q_ASSERT(engine);
@@ -127,6 +127,10 @@ QQmlCompiledData::~QQmlCompiledData()
if (rootPropertyCache)
rootPropertyCache->release();
+
+ if (compilationUnit)
+ compilationUnit->deref();
+ free(qmlUnit);
}
void QQmlCompiledData::clear()
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index bc013358f5..ca825a923d 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -70,6 +70,13 @@
QT_BEGIN_NAMESPACE
+namespace QV4 {
+namespace CompiledData {
+struct CompilationUnit;
+struct QmlUnit;
+}
+}
+
class QQmlEngine;
class QQmlComponent;
class QQmlContext;
@@ -125,6 +132,11 @@ public:
QList<QQmlScriptData *> scripts;
QList<QUrl> urls;
+ // --- new compiler
+ QV4::CompiledData::CompilationUnit *compilationUnit;
+ QV4::CompiledData::QmlUnit *qmlUnit;
+ // ---
+
struct Instruction {
#define QML_INSTR_DATA_TYPEDEF(I, FMT) typedef QQmlInstructionData<QQmlInstruction::I> I;
FOR_EACH_QML_INSTR(QML_INSTR_DATA_TYPEDEF)
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 5f3a2e971c..ff961c7822 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -893,8 +893,16 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
state.completePending = true;
enginePriv->referenceScarceResources();
- state.vme.init(context, cc, start, creationContext);
- QObject *rv = state.vme.execute(&state.errors);
+ QObject *rv = 0;
+ if (enginePriv->useNewCompiler) {
+ state.creator = new QtQml::QmlObjectCreator(engine, context, cc);
+ rv = state.creator->create();
+ if (!rv)
+ state.errors = state.creator->errors;
+ } else {
+ state.vme.init(context, cc, start, creationContext);
+ rv = state.vme.execute(&state.errors);
+ }
enginePriv->dereferenceScarceResources();
if (rv) {
@@ -934,14 +942,22 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
state->errors.clear();
state->completePending = true;
- state->vme.initDeferred(object);
- state->vme.execute(&state->errors);
+ if (enginePriv->useNewCompiler) {
+ // ###
+ } else {
+ state->vme.initDeferred(object);
+ state->vme.execute(&state->errors);
+ }
}
void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionState *state)
{
if (state->completePending) {
- state->vme.complete();
+ if (enginePriv->useNewCompiler) {
+ // ###
+ } else {
+ state->vme.complete();
+ }
state->completePending = false;
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 439f1fcdd9..3bd0a194df 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -62,6 +62,7 @@
#include "qqmlerror.h"
#include "qqml.h"
#include <private/qqmlprofilerservice_p.h>
+#include <private/qqmlobjectcreator_p.h>
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -105,9 +106,20 @@ public:
QQmlCompiledData *cc;
struct ConstructionState {
- ConstructionState() : completePending(false) {}
-
+ ConstructionState()
+ : creator(0)
+ , completePending(false)
+ {}
+ ~ConstructionState()
+ {
+ delete creator;
+ }
+
+ // --- new compiler
+ QtQml::QmlObjectCreator *creator;
+ // --- old compiler
QQmlVME vme;
+ // ---
QList<QQmlError> errors;
bool completePending;
};
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 39c3399917..971836f783 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -510,6 +510,7 @@ the same object as is returned from the Qt.include() call.
*/
// Qt.include() is implemented in qv4include.cpp
+DEFINE_BOOL_CONFIG_OPTION(qmlUseNewCompiler, QML_NEW_COMPILER)
QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
: propertyCapture(0), rootContext(0), isDebugging(false),
@@ -520,6 +521,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
{
+ useNewCompiler = qmlUseNewCompiler();
}
QQmlEnginePrivate::~QQmlEnginePrivate()
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index c57c70fa40..b57c84ceae 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -144,6 +144,7 @@ public:
QQmlContext *rootContext;
bool isDebugging;
+ bool useNewCompiler;
bool outputWarningsToStdErr;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
new file mode 100644
index 0000000000..8fdfe8e4f1
--- /dev/null
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -0,0 +1,686 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlobjectcreator_p.h"
+
+#include <private/qqmlengine_p.h>
+#include <private/qqmlabstractbinding_p.h>
+#include <private/qqmlvmemetaobject_p.h>
+#include <private/qv4function_p.h>
+#include <private/qv4functionobject_p.h>
+#include <private/qqmlcontextwrapper_p.h>
+#include <private/qqmlbinding_p.h>
+#include <private/qqmlstringconverters_p.h>
+
+QT_USE_NAMESPACE
+
+using namespace QtQml;
+
+static void removeBindingOnProperty(QObject *o, int index)
+{
+ int coreIndex = index & 0x0000FFFF;
+ int valueTypeIndex = (index & 0xFFFF0000 ? index >> 16 : -1);
+
+ QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, coreIndex, valueTypeIndex, 0);
+ if (binding) binding->destroy();
+}
+
+QmlObjectCreator::QmlObjectCreator(QQmlEngine *engine, QQmlContextData *contextData, QQmlCompiledData *runtimeData)
+ : engine(engine)
+ , unit(runtimeData->qmlUnit)
+ , jsUnit(runtimeData->compilationUnit)
+ , context(contextData)
+ , typeNameCache(0)
+ , runtimeData(runtimeData)
+ , imports(&QQmlEnginePrivate::get(engine)->typeLoader)
+ , _object(0)
+ , _ddata(0)
+ , _propertyCache(0)
+{
+ typeNameCache = new QQmlTypeNameCache;
+
+ QQmlImportDatabase *idb = &QQmlEnginePrivate::get(engine)->importDatabase;
+
+ for (uint i = 0; i < unit->nImports; ++i) {
+ const QV4::CompiledData::Import *import = unit->importAt(i);
+ if (import->type == QV4::CompiledData::Import::ImportLibrary) {
+ imports.addLibraryImport(idb, stringAt(import->uriIndex), stringAt(import->qualifierIndex),
+ import->majorVersion, import->minorVersion, /*qmldir identifier*/ QString(),
+ /*qmldir url*/ QString(), /*incomplete*/ false, &errors);
+ } else {
+ // ###
+ }
+ }
+
+ imports.populateCache(typeNameCache);
+ context->imports = typeNameCache;
+ context->imports->addref();
+
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ if (runtimeData->compilationUnit && !runtimeData->compilationUnit->engine)
+ runtimeData->compilationUnit->linkToEngine(v4);
+}
+
+QVector<QQmlAbstractBinding*> QmlObjectCreator::setupBindings(const QV4::CompiledData::Object *obj, QV4::Object *qmlGlobal)
+{
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+
+ QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor |
+ QQmlPropertyPrivate::RemoveBindingOnAliasWrite;
+ int propertyWriteStatus = -1;
+ QVariant fallbackVariantValue;
+
+ QVector<QQmlAbstractBinding*> createdDynamicBindings(obj->nBindings, 0);
+
+ const QV4::CompiledData::Binding *binding = obj->bindingTable();
+ for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
+ QString name = stringAt(binding->propertyNameIndex);
+
+ if (name.isEmpty() && binding->value.type == QV4::CompiledData::Value::Type_Object) {
+ create(binding->value.objectIndex, _object);
+ continue;
+ }
+
+ QQmlPropertyData *property = _propertyCache->property(name, _object, context);
+
+ if (_ddata->hasBindingBit(property->coreIndex))
+ removeBindingOnProperty(_object, property->coreIndex);
+
+ if (binding->value.type == QV4::CompiledData::Value::Type_Script) {
+ QV4::Function *runtimeFunction = jsUnit->runtimeFunctions[binding->value.compiledScriptIndex];
+ QV4::FunctionObject *function = new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, runtimeFunction, qmlGlobal);
+ QQmlBinding *binding = new QQmlBinding(QV4::Value::fromObject(function), _object, context,
+ QString(), 0, 0); // ###
+
+ binding->setTarget(_object, *property, context);
+ binding->addToObject();
+
+ createdDynamicBindings[i] = binding;
+ binding->m_mePtr = &createdDynamicBindings[i];
+ continue;
+ }
+
+ void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags };
+
+ // shortcuts
+#if 0
+ if (property->propType == QMetaType::Double && binding->value.type == QV4::CompiledData::Value::Type_Number) {
+ argv[0] = const_cast<double*>(&binding->value.d);
+ } else if (property->propType == QMetaType::Bool && binding->value.type == QV4::CompiledData::Value::Type_Boolean) {
+ argv[0] = const_cast<bool*>(&binding->value.b);
+ } else
+#endif
+ {
+ // fallback
+ fallbackVariantValue = variantForBinding(property->propType, binding);
+
+ if (property->propType == QMetaType::QVariant)
+ argv[0] = &fallbackVariantValue;
+ else
+ argv[0] = fallbackVariantValue.data();
+ }
+
+ QMetaObject::metacall(_object, QMetaObject::WriteProperty, property->coreIndex, argv);
+ }
+
+ return createdDynamicBindings;
+}
+
+void QmlObjectCreator::setupFunctions(const QV4::CompiledData::Object *obj, QV4::Object *qmlGlobal)
+{
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(_object);
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+
+ const quint32 *functionIdx = obj->functionOffsetTable();
+ for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIdx) {
+ QV4::Function *function = jsUnit->runtimeFunctions[*functionIdx];
+ const QString name = function->name->toQString();
+
+ QQmlPropertyData *property = _propertyCache->property(name, _object, context);
+ if (!property->isVMEFunction())
+ continue;
+
+ QV4::FunctionObject *v4Function = new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, function, qmlGlobal);
+ vme->setVmeMethod(property->coreIndex, QV4::Value::fromObject(v4Function));
+ }
+}
+
+QObject *QmlObjectCreator::create(int index, QObject *parent)
+{
+ const QV4::CompiledData::Object *obj = unit->objectAt(index);
+
+ QQmlTypeNameCache::Result res = typeNameCache->query(stringAt(obj->inheritedTypeNameIndex));
+ if (!res.isValid())
+ return 0;
+
+ QObject *result = res.type->create();
+ // ### use no-event variant
+ if (parent)
+ result->setParent(parent);
+
+ QQmlData *declarativeData = QQmlData::get(result, /*create*/true);
+
+ qSwap(_object, result);
+ qSwap(_ddata, declarativeData);
+
+ context->addObject(_object);
+
+ // ### avoid _object->metaObject
+ QQmlPropertyCache *baseTypeCache = QQmlEnginePrivate::get(engine)->cache(_object->metaObject());
+ baseTypeCache->addref();
+
+ QQmlPropertyCache *cache = 0;
+ QByteArray vmeMetaData;
+ bool needCustomMetaObject = createVMEMetaObjectAndPropertyCache(obj, baseTypeCache, &cache, &vmeMetaData);
+ cache->addref();
+
+ baseTypeCache->release();
+ baseTypeCache = 0;
+
+ qSwap(_propertyCache, cache);
+
+ if (needCustomMetaObject) {
+ runtimeData->datas.append(vmeMetaData);
+ // install on _object
+ (void)new QQmlVMEMetaObject(_object, _propertyCache, reinterpret_cast<const QQmlVMEMetaData*>(runtimeData->datas.last().constData()));
+ if (_ddata->propertyCache)
+ _ddata->propertyCache->release();
+ _ddata->propertyCache = _propertyCache;
+ _ddata->propertyCache->addref();
+ }
+
+ QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _object);
+
+ QVector<QQmlAbstractBinding*> dynamicBindings = setupBindings(obj, scopeObject.asObject());
+ setupFunctions(obj, scopeObject.asObject());
+
+ // ### do this later when requested
+ for (int i = 0; i < dynamicBindings.count(); ++i) {
+ QQmlAbstractBinding *b = dynamicBindings.at(i);
+ if (!b)
+ continue;
+ b->m_mePtr = 0;
+ QQmlData *data = QQmlData::get(b->object());
+ Q_ASSERT(data);
+ data->clearPendingBindingBit(b->propertyIndex());
+ b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
+ QQmlPropertyPrivate::DontRemoveBinding);
+ }
+
+ qSwap(_propertyCache, cache);
+ qSwap(_ddata, declarativeData);
+ qSwap(_object, result);
+
+ cache->release();
+
+ return result;
+}
+
+// ###
+#define COMPILE_EXCEPTION(token, desc) {}
+
+static QAtomicInt classIndexCounter(0);
+
+bool QmlObjectCreator::createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache, QQmlPropertyCache **outputCache, QByteArray *vmeMetaObjectData) const
+{
+ if (!obj->nProperties) {
+ *outputCache = baseTypeCache;
+ return false;
+ }
+
+ QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(engine, obj->nProperties, /*methodCount*/0, /*signalCount*/0);
+ *outputCache = cache;
+
+ vmeMetaObjectData->clear();
+
+ struct TypeData {
+ QV4::CompiledData::Property::Type dtype;
+ int metaType;
+ } builtinTypes[] = {
+ { QV4::CompiledData::Property::Var, QMetaType::QVariant },
+ { QV4::CompiledData::Property::Variant, QMetaType::QVariant },
+ { QV4::CompiledData::Property::Int, QMetaType::Int },
+ { QV4::CompiledData::Property::Bool, QMetaType::Bool },
+ { QV4::CompiledData::Property::Real, QMetaType::Double },
+ { QV4::CompiledData::Property::String, QMetaType::QString },
+ { QV4::CompiledData::Property::Url, QMetaType::QUrl },
+ { QV4::CompiledData::Property::Color, QMetaType::QColor },
+ { QV4::CompiledData::Property::Font, QMetaType::QFont },
+ { QV4::CompiledData::Property::Time, QMetaType::QTime },
+ { QV4::CompiledData::Property::Date, QMetaType::QDate },
+ { QV4::CompiledData::Property::DateTime, QMetaType::QDateTime },
+ { QV4::CompiledData::Property::Rect, QMetaType::QRectF },
+ { QV4::CompiledData::Property::Point, QMetaType::QPointF },
+ { QV4::CompiledData::Property::Size, QMetaType::QSizeF },
+ { QV4::CompiledData::Property::Vector2D, QMetaType::QVector2D },
+ { QV4::CompiledData::Property::Vector3D, QMetaType::QVector3D },
+ { QV4::CompiledData::Property::Vector4D, QMetaType::QVector4D },
+ { QV4::CompiledData::Property::Matrix4x4, QMetaType::QMatrix4x4 },
+ { QV4::CompiledData::Property::Quaternion, QMetaType::QQuaternion }
+ };
+ static const uint builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
+
+ QByteArray newClassName;
+
+ if (false /* ### compileState->root == obj && !compileState->nested*/) {
+#if 0 // ###
+ QString path = output->url.path();
+ int lastSlash = path.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash > -1) {
+ QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
+ if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
+ newClassName = nameBase.toUtf8() + "_QMLTYPE_" +
+ QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
+ }
+#endif
+ }
+ if (newClassName.isEmpty()) {
+ newClassName = QQmlMetaObject(baseTypeCache).className();
+ newClassName.append("_QML_");
+ newClassName.append(QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1)));
+ }
+
+ cache->_dynamicClassName = newClassName;
+
+ int aliasCount = 0;
+ int varPropCount = 0;
+
+ const QV4::CompiledData::Property *p = obj->propertyTable();
+ for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
+
+ if (p->type == QV4::CompiledData::Property::Alias)
+ aliasCount++;
+ else if (p->type == QV4::CompiledData::Property::Var)
+ varPropCount++;
+
+#if 0 // ### Do this elsewhere
+ // No point doing this for both the alias and non alias cases
+ QQmlPropertyData *d = property(obj, p->name);
+ if (d && d->isFinal())
+ COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
+#endif
+ }
+
+ typedef QQmlVMEMetaData VMD;
+
+ QByteArray &dynamicData = *vmeMetaObjectData = QByteArray(sizeof(QQmlVMEMetaData)
+ + obj->nProperties * sizeof(VMD::PropertyData)
+ + obj->nFunctions * sizeof(VMD::MethodData)
+ + aliasCount * sizeof(VMD::AliasData), 0);
+
+ int effectivePropertyIndex = cache->propertyIndexCacheStart;
+ int effectiveMethodIndex = cache->methodIndexCacheStart;
+
+ // For property change signal override detection.
+ // We prepopulate a set of signal names which already exist in the object,
+ // and throw an error if there is a signal/method defined as an override.
+ QSet<QString> seenSignals;
+ seenSignals << QStringLiteral("destroyed") << QStringLiteral("parentChanged") << QStringLiteral("objectNameChanged");
+ QQmlPropertyCache *parentCache = cache;
+ while ((parentCache = parentCache->parent())) {
+ if (int pSigCount = parentCache->signalCount()) {
+ int pSigOffset = parentCache->signalOffset();
+ for (int i = pSigOffset; i < pSigCount; ++i) {
+ QQmlPropertyData *currPSig = parentCache->signal(i);
+ // XXX TODO: find a better way to get signal name from the property data :-/
+ for (QQmlPropertyCache::StringCache::ConstIterator iter = parentCache->stringCache.begin();
+ iter != parentCache->stringCache.end(); ++iter) {
+ if (currPSig == (*iter).second) {
+ seenSignals.insert(iter.key());
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // First set up notify signals for properties - first normal, then var, then alias
+ enum { NSS_Normal = 0, NSS_Var = 1, NSS_Alias = 2 };
+ for (int ii = NSS_Normal; ii <= NSS_Alias; ++ii) { // 0 == normal, 1 == var, 2 == alias
+
+ if (ii == NSS_Var && varPropCount == 0) continue;
+ else if (ii == NSS_Alias && aliasCount == 0) continue;
+
+ const QV4::CompiledData::Property *p = obj->propertyTable();
+ for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
+ if ((ii == NSS_Normal && (p->type == QV4::CompiledData::Property::Alias ||
+ p->type == QV4::CompiledData::Property::Var)) ||
+ ((ii == NSS_Var) && (p->type != QV4::CompiledData::Property::Var)) ||
+ ((ii == NSS_Alias) && (p->type != QV4::CompiledData::Property::Alias)))
+ continue;
+
+ quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
+ QQmlPropertyData::IsVMESignal;
+
+ QString changedSigName = stringAt(p->nameIndex) + QLatin1String("Changed");
+ seenSignals.insert(changedSigName);
+
+ cache->appendSignal(changedSigName, flags, effectiveMethodIndex++);
+ }
+ }
+
+ // Dynamic signals
+ for (uint i = 0; i < obj->nSignals; ++i) {
+ const QV4::CompiledData::Signal *s = obj->signalAt(i);
+ const int paramCount = s->nParameters;
+
+ QList<QByteArray> names;
+ QVarLengthArray<int, 10> paramTypes(paramCount?(paramCount + 1):0);
+
+ if (paramCount) {
+ paramTypes[0] = paramCount;
+
+ for (int i = 0; i < paramCount; ++i) {
+ const QV4::CompiledData::Parameter *param = s->parameterAt(i);
+ names.append(stringAt(param->nameIndex).toUtf8());
+ if (param->type < builtinTypeCount) {
+ // built-in type
+ paramTypes[i + 1] = builtinTypes[param->type].metaType;
+ } else {
+ // lazily resolved type
+ Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
+ QQmlType *qmltype = 0;
+ if (!imports.resolveType(stringAt(param->customTypeNameIndex), &qmltype, 0, 0, 0))
+ COMPILE_EXCEPTION(s, tr("Invalid signal parameter type: %1").arg(s->parameterTypeNames.at(i).toString()));
+
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = QQmlEnginePrivate::get(engine)->typeLoader.getType(qmltype->sourceUrl());
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
+
+ QQmlCompiledData *data = tdata->compiledData();
+
+ paramTypes[i + 1] = data->metaTypeId;
+
+ tdata->release();
+ } else {
+ paramTypes[i + 1] = qmltype->typeId();
+ }
+ }
+ }
+ }
+
+ ((QQmlVMEMetaData *)dynamicData.data())->signalCount++;
+
+ quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
+ QQmlPropertyData::IsVMESignal;
+ if (paramCount)
+ flags |= QQmlPropertyData::HasArguments;
+
+ QString signalName = stringAt(s->nameIndex);
+ if (seenSignals.contains(signalName)) {
+#if 0 // ###
+ const QQmlScript::Object::DynamicSignal &currSig = *s;
+ COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name: invalid override of property change signal or superclass signal"));
+#endif
+ }
+ seenSignals.insert(signalName);
+
+ cache->appendSignal(signalName, flags, effectiveMethodIndex++,
+ paramCount?paramTypes.constData():0, names);
+ }
+
+
+ // Dynamic slots
+ const quint32 *functionIndex = obj->functionOffsetTable();
+ for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) {
+ const QV4::CompiledData::Function *s = unit->header.functionAt(*functionIndex);
+ int paramCount = s->nFormals;
+
+ quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction;
+
+ if (paramCount)
+ flags |= QQmlPropertyData::HasArguments;
+
+ QString slotName = stringAt(s->nameIndex);
+ if (seenSignals.contains(slotName)) {
+#if 0 // ###
+ const QQmlScript::Object::DynamicSlot &currSlot = *s;
+ COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name: invalid override of property change signal or superclass signal"));
+#endif
+ }
+ // Note: we don't append slotName to the seenSignals list, since we don't
+ // protect against overriding change signals or methods with properties.
+
+ const quint32 *formalsIndices = s->formalsTable();
+ QList<QByteArray> parameterNames;
+ parameterNames.reserve(paramCount);
+ for (int i = 0; i < paramCount; ++i)
+ parameterNames << stringAt(formalsIndices[i]).toUtf8();
+
+ cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames);
+ }
+
+
+ // Dynamic properties (except var and aliases)
+ int effectiveSignalIndex = cache->signalHandlerIndexCacheStart;
+ /* const QV4::CompiledData::Property* */ p = obj->propertyTable();
+ for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
+
+ if (p->type == QV4::CompiledData::Property::Alias ||
+ p->type == QV4::CompiledData::Property::Var)
+ continue;
+
+ int propertyType = 0;
+ int vmePropertyType = 0;
+ quint32 propertyFlags = 0;
+
+ if (p->type < builtinTypeCount) {
+ propertyType = builtinTypes[p->type].metaType;
+ vmePropertyType = propertyType;
+
+ if (p->type == QV4::CompiledData::Property::Variant)
+ propertyFlags |= QQmlPropertyData::IsQVariant;
+ } else {
+ Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
+ p->type == QV4::CompiledData::Property::Custom);
+
+ QQmlType *qmltype = 0;
+ if (!imports.resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0))
+ COMPILE_EXCEPTION(p, tr("Invalid property type"));
+
+ Q_ASSERT(qmltype);
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = QQmlEnginePrivate::get(engine)->typeLoader.getType(qmltype->sourceUrl());
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
+
+ QQmlCompiledData *data = tdata->compiledData();
+
+ if (p->type == QV4::CompiledData::Property::Custom) {
+ propertyType = data->metaTypeId;
+ vmePropertyType = QMetaType::QObjectStar;
+ } else {
+ propertyType = data->listMetaTypeId;
+ vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
+ }
+
+ tdata->release();
+ } else {
+ if (p->type == QV4::CompiledData::Property::Custom) {
+ propertyType = qmltype->typeId();
+ vmePropertyType = QMetaType::QObjectStar;
+ } else {
+ propertyType = qmltype->qListTypeId();
+ vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
+ }
+ }
+
+ if (p->type == QV4::CompiledData::Property::Custom)
+ propertyFlags |= QQmlPropertyData::IsQObjectDerived;
+ else
+ propertyFlags |= QQmlPropertyData::IsQList;
+ }
+
+ if ((!p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList)
+ propertyFlags |= QQmlPropertyData::IsWritable;
+
+
+ QString propertyName = stringAt(p->nameIndex);
+ if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
+ cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
+ propertyType, effectiveSignalIndex);
+
+ effectiveSignalIndex++;
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ (vmd->propertyData() + vmd->propertyCount)->propertyType = vmePropertyType;
+ vmd->propertyCount++;
+ }
+
+ // Now do var properties
+ /* const QV4::CompiledData::Property* */ p = obj->propertyTable();
+ for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
+
+ if (p->type != QV4::CompiledData::Property::Var)
+ continue;
+
+ quint32 propertyFlags = QQmlPropertyData::IsVarProperty;
+ if (!p->flags & QV4::CompiledData::Property::IsReadOnly)
+ propertyFlags |= QQmlPropertyData::IsWritable;
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ (vmd->propertyData() + vmd->propertyCount)->propertyType = QMetaType::QVariant;
+ vmd->propertyCount++;
+ ((QQmlVMEMetaData *)dynamicData.data())->varPropertyCount++;
+
+ QString propertyName = stringAt(p->nameIndex);
+ if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
+ cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
+ QMetaType::QVariant, effectiveSignalIndex);
+
+ effectiveSignalIndex++;
+ }
+
+ // Alias property count. Actual data is setup in buildDynamicMetaAliases
+ ((QQmlVMEMetaData *)dynamicData.data())->aliasCount = aliasCount;
+
+ // Dynamic slot data - comes after the property data
+ /*const quint32* */functionIndex = obj->functionOffsetTable();
+ for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) {
+ const QV4::CompiledData::Function *s = unit->header.functionAt(*functionIndex);
+
+ VMD::MethodData methodData = { int(s->nFormals),
+ /* body offset*/0,
+ /* body length*/0,
+ /* s->location.start.line */0 }; // ###
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ VMD::MethodData &md = *(vmd->methodData() + vmd->methodCount);
+ vmd->methodCount++;
+ md = methodData;
+ }
+
+ return true;
+}
+
+QVariant QmlObjectCreator::variantForBinding(int expectedMetaType, const QV4::CompiledData::Binding *binding) const
+{
+ QVariant result;
+
+ switch (expectedMetaType) {
+ case QMetaType::QString:
+ result = valueAsString(&binding->value);
+ break;
+ case QMetaType::Bool:
+ result = valueAsBoolean(&binding->value);
+ break;
+ case QMetaType::Double:
+ result = valueAsNumber(&binding->value);
+ break;
+ case QMetaType::Int:
+ result = (int)valueAsNumber(&binding->value);
+ break;
+ case QVariant::Color: {
+ bool ok = false;
+ result = QQmlStringConverters::colorFromString(valueAsString(&binding->value), &ok);
+ if (!ok) {
+ // ### compile error
+ }
+ break;
+ }
+ default:
+ QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(expectedMetaType);
+ if (converter) {
+ result = converter(valueAsString(&binding->value));
+ } else {
+ if (expectedMetaType == QMetaType::QVariant)
+ result = QVariant();
+ else
+ result = QVariant(expectedMetaType, (void*)0);
+ }
+ break;
+ }
+ return result;
+}
+
+QString QmlObjectCreator::valueAsString(const QV4::CompiledData::Value *value) const
+{
+ switch (value->type) {
+ case QV4::CompiledData::Value::Type_Script:
+ case QV4::CompiledData::Value::Type_String:
+ return stringAt(value->stringIndex);
+ case QV4::CompiledData::Value::Type_Boolean:
+ return value->b ? QStringLiteral("true") : QStringLiteral("false");
+ case QV4::CompiledData::Value::Type_Number:
+ return QString::number(value->d);
+ case QV4::CompiledData::Value::Type_Invalid:
+ return QString();
+ default:
+ break;
+ }
+ return QString();
+}
+
+double QmlObjectCreator::valueAsNumber(const QV4::CompiledData::Value *value)
+{
+ if (value->type == QV4::CompiledData::Value::Type_Number)
+ return value->d;
+ return 0.0;
+}
+
+bool QmlObjectCreator::valueAsBoolean(const QV4::CompiledData::Value *value)
+{
+ if (value->type == QV4::CompiledData::Value::Type_Boolean)
+ return value->b;
+ return false;
+}
+
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
new file mode 100644
index 0000000000..6a2b28c35d
--- /dev/null
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQMLOBJECTCREATOR_P_H
+#define QQMLOBJECTCREATOR_P_H
+
+#include <private/qqmlimport_p.h>
+#include <private/qqmltypenamecache_p.h>
+#include <private/qv4compileddata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlAbstractBinding;
+
+namespace QtQml {
+
+struct Q_QML_EXPORT QmlObjectCreator
+{
+ QmlObjectCreator(QQmlEngine *engine,
+ // extra data/output stored in these two
+ QQmlContextData *contextData,
+ QQmlCompiledData *runtimeData);
+
+ QObject *create(QObject *parent = 0)
+ { return create(unit->indexOfRootObject); }
+ QObject *create(int index, QObject *parent = 0);
+
+ QList<QQmlError> errors;
+
+ bool createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData) const;
+private:
+ QString stringAt(int idx) const { return unit->header.stringAt(idx); }
+
+ QVector<QQmlAbstractBinding *> setupBindings(const QV4::CompiledData::Object *obj, QV4::Object *qmlGlobal);
+ void setupFunctions(const QV4::CompiledData::Object *obj, QV4::Object *qmlGlobal);
+
+ QVariant variantForBinding(int expectedMetaType, const QV4::CompiledData::Binding *binding) const;
+
+ QString valueAsString(const QV4::CompiledData::Value *value) const;
+ static double valueAsNumber(const QV4::CompiledData::Value *value);
+ static bool valueAsBoolean(const QV4::CompiledData::Value *value);
+
+ QQmlEngine *engine;
+ const QV4::CompiledData::QmlUnit *unit;
+ const QV4::CompiledData::CompilationUnit *jsUnit;
+ QQmlContextData *context;
+ QQmlTypeNameCache *typeNameCache;
+ QQmlCompiledData *runtimeData;
+ QQmlImports imports;
+
+ QObject *_object;
+ QQmlData *_ddata;
+ QQmlPropertyCache *_propertyCache;
+};
+
+} // end namespace QtQml
+
+QT_END_NAMESPACE
+
+#endif // QQMLOBJECTCREATOR_P_H
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 21fee28b02..0fd9252754 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -66,6 +66,10 @@
QT_BEGIN_NAMESPACE
+namespace QtQml {
+struct QmlObjectCreator;
+}
+
class QV8Engine;
class QMetaProperty;
class QQmlEngine;
@@ -339,6 +343,7 @@ protected:
private:
friend class QQmlEnginePrivate;
friend class QQmlCompiler;
+ friend struct QtQml::QmlObjectCreator;
inline QQmlPropertyCache *copy(int reserve);
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 3531e89779..cd57704771 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1900,6 +1900,7 @@ QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager)
: QQmlTypeLoader::Blob(url, QmlFile, manager),
m_typesResolved(false), m_compiledData(0), m_implicitImport(0), m_implicitImportLoaded(false)
{
+ m_useNewCompiler = QQmlEnginePrivate::get(manager->engine())->useNewCompiler;
}
QQmlTypeData::~QQmlTypeData()
@@ -2031,9 +2032,17 @@ void QQmlTypeData::dataReceived(const Data &data)
if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse"));
- if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) {
- setError(scriptParser.errors());
- return;
+ if (m_useNewCompiler) {
+ QQmlCodeGenerator compiler;
+ if (!compiler.generateFromQml(code, finalUrl(), finalUrlString(), &parsedQML)) {
+ setError(compiler.errors);
+ return;
+ }
+ } else {
+ if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) {
+ setError(scriptParser.errors());
+ return;
+ }
}
m_imports.setBaseUrl(finalUrl(), finalUrlString());
@@ -2063,7 +2072,34 @@ void QQmlTypeData::dataReceived(const Data &data)
QList<QQmlError> errors;
- foreach (const QQmlScript::Import &import, scriptParser.imports()) {
+ // ### convert to use new data structure once old compiler is gone.
+ QList<QQmlScript::Import> imports;
+ if (m_useNewCompiler) {
+ imports.reserve(parsedQML.imports.size());
+ foreach (QV4::CompiledData::Import *i, parsedQML.imports) {
+ QQmlScript::Import import;
+ import.uri = parsedQML.stringAt(i->uriIndex);
+ import.qualifier = parsedQML.stringAt(i->qualifierIndex);
+ import.majorVersion = i->majorVersion;
+ import.minorVersion = i->minorVersion;
+ import.location.start.line = i->location.line;
+ import.location.start.column = i->location.column;
+
+ switch (i->type) {
+ case QV4::CompiledData::Import::ImportFile: import.type = QQmlScript::Import::File; break;
+ case QV4::CompiledData::Import::ImportLibrary: import.type = QQmlScript::Import::Library; break;
+ case QV4::CompiledData::Import::ImportScript: import.type = QQmlScript::Import::Script; break;
+ default: break;
+ }
+
+
+ imports << import;
+ }
+ } else {
+ imports = scriptParser.imports();
+ }
+
+ foreach (const QQmlScript::Import &import, imports) {
if (!addImport(import, &errors)) {
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
@@ -2124,11 +2160,36 @@ void QQmlTypeData::compile()
QQmlCompilingProfiler prof(m_compiledData->name);
- QQmlCompiler compiler(&scriptParser._pool);
- if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
- setError(compiler.errors());
- m_compiledData->release();
- m_compiledData = 0;
+ if (m_useNewCompiler) {
+ JSCodeGen jsCodeGen;
+ jsCodeGen.generateJSCodeForFunctionsAndBindings(finalUrlString(), &parsedQML);
+
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
+
+ QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(v4->executableAllocator, &parsedQML.jsModule, &parsedQML.jsGenerator));
+ isel->setUseFastLookups(false);
+ QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/false);
+
+ QmlUnitGenerator qmlGenerator;
+ QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(parsedQML);
+
+ if (jsUnit) {
+ Q_ASSERT(!jsUnit->data);
+ jsUnit->ownsData = false;
+ jsUnit->data = &qmlUnit->header;
+ }
+
+ m_compiledData->compilationUnit = jsUnit;
+ if (m_compiledData->compilationUnit)
+ m_compiledData->compilationUnit->ref();
+ m_compiledData->qmlUnit = qmlUnit; // ownership transferred to m_compiledData
+ } else {
+ QQmlCompiler compiler(&scriptParser._pool);
+ if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
+ setError(compiler.errors());
+ m_compiledData->release();
+ m_compiledData = 0;
+ }
}
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index abe545fc8f..9e71bab7b0 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -68,6 +68,7 @@
#include <private/qqmlbundle_p.h>
#include <private/qflagpointer_p.h>
#include <private/qqmlabstracturlinterceptor_p.h>
+#include <private/qqmlcodegenerator_p.h>
#include <private/qv4value_p.h>
#include <private/qv4script_p.h>
@@ -446,7 +447,11 @@ private:
virtual void scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &nameSpace);
+ // --- old compiler
QQmlScript::Parser scriptParser;
+ // --- new compiler
+ QtQml::ParsedQML parsedQML;
+ // ---
QList<ScriptReference> m_scripts;
@@ -454,6 +459,7 @@ private:
QList<TypeReference> m_types;
bool m_typesResolved:1;
+ bool m_useNewCompiler:1;
QQmlCompiledData *m_compiledData;