From 4005c0e29cea1bbcb35c480866418ba01f019756 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 10 Jan 2014 14:51:00 +0100 Subject: [new compiler] Initial support for QQuick state changes This requires the use of the customer parser together with lazy binding compilation Change-Id: I45d8a206267d3e0c807771a79645168254be9c95 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compileddata_p.h | 2 +- src/qml/qml/qqmlcustomparser.cpp | 14 ++++++++ src/qml/qml/qqmlcustomparser_p.h | 1 + src/quick/util/qquickpropertychanges.cpp | 61 ++++++++++++++++++++++++++++++++ src/quick/util/qquickpropertychanges_p.h | 2 ++ 5 files changed, 79 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index c069111b91..3bffc5c8ef 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -264,7 +264,7 @@ struct Function // Qml data structures -struct Binding +struct Q_QML_EXPORT Binding { quint32 propertyNameIndex; diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index 0cc62fb988..3f8fc967f4 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -297,6 +297,20 @@ void QQmlCustomParser::error(const QV4::CompiledData::Binding *binding, const QS exceptions << error; } +/*! + Reports an error in parsing \a object, with the given \a description. + + An error is generated referring to the position of \a object in the source file. +*/ +void QQmlCustomParser::error(const QV4::CompiledData::Object *object, const QString &description) +{ + QQmlError error; + error.setLine(object->location.line); + error.setColumn(object->location.column); + error.setDescription(description); + exceptions << error; +} + /*! If \a script is a simple enumeration expression (eg. Text.AlignLeft), returns the integer equivalent (eg. 1), and sets \a ok to true. diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index 3004b0f50c..39afa2a28e 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -136,6 +136,7 @@ protected: void error(const QQmlCustomParserProperty&, const QString& description); void error(const QQmlCustomParserNode&, const QString& description); void error(const QV4::CompiledData::Binding *binding, const QString& description); + void error(const QV4::CompiledData::Object *object, const QString& description); int evaluateEnum(const QByteArray&, bool *ok) const; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 148c55bbcb..55ac85e64d 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -259,6 +259,29 @@ QQuickPropertyChangesParser::compileList(QList > &list, } } +void QQuickPropertyChangesParser::compileList(QList > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding) +{ + QString propName = pre + qmlUnit->header.stringAt(binding->propertyNameIndex); + + if (binding->type == QV4::CompiledData::Binding::Type_Object) { + error(qmlUnit->objectAt(binding->value.objectIndex), QQuickPropertyChanges::tr("PropertyChanges does not support creating state-specific objects.")); + return; + } + + if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty + || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + QString pre = propName + QLatin1Char('.'); + const QV4::CompiledData::Object *subObj = qmlUnit->objectAt(binding->value.objectIndex); + const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); + for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) { + compileList(list, pre, qmlUnit, subBinding); + } + return; + } + + list << qMakePair(propName, binding); +} + QByteArray QQuickPropertyChangesParser::compile(const QList &props) { @@ -303,6 +326,44 @@ QQuickPropertyChangesParser::compile(const QList &prop return rv; } +QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props) +{ + QList > data; + for (int ii = 0; ii < props.count(); ++ii) + compileList(data, QString(), qmlUnit, props.at(ii)); + + QByteArray rv; + QDataStream ds(&rv, QIODevice::WriteOnly); + + ds << data.count(); + for (int ii = 0; ii < data.count(); ++ii) { + const QV4::CompiledData::Binding *binding = data.at(ii).second; + QVariant var; + bool isScript = binding->type == QV4::CompiledData::Binding::Type_Script; + QQmlBinding::Identifier id = QQmlBinding::Invalid; + switch (binding->type) { + case QV4::CompiledData::Binding::Type_Script: + // ### pre-compile binding + case QV4::CompiledData::Binding::Type_String: + var = binding->valueAsString(&qmlUnit->header); + break; + case QV4::CompiledData::Binding::Type_Number: + var = binding->valueAsNumber(); + break; + case QV4::CompiledData::Binding::Type_Boolean: + var = binding->valueAsBoolean(); + break; + default: + break; + } + ds << data.at(ii).first << isScript << var; + if (isScript) + ds << id; + } + + return rv; +} + void QQuickPropertyChangesPrivate::decode() { Q_Q(QQuickPropertyChanges); diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h index 0236e4529b..081ea72862 100644 --- a/src/quick/util/qquickpropertychanges_p.h +++ b/src/quick/util/qquickpropertychanges_p.h @@ -93,8 +93,10 @@ public: : QQmlCustomParser(AcceptsAttachedProperties) {} void compileList(QList > &list, const QString &pre, const QQmlCustomParserProperty &prop); + void compileList(QList > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding); virtual QByteArray compile(const QList &); + virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props); virtual void setCustomData(QObject *, const QByteArray &); }; -- cgit v1.2.3