aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-04-25 16:19:02 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-04 08:25:52 +0200
commit52e07d564b65ed6ce26955a676c7692ad67686c1 (patch)
tree04354cdf1d56776e9b52819f4329b70c57e235dc /tests/auto/qml
parent481447ae664fa2998cb03f93f0c066caa2782bf0 (diff)
Rework custom parser integration
The custom parser design used to be so that the custom parser operates on the "AST", creates its own binary representation of the data it needs, stores it in a QByteArray and gets that at object instantiation time. That meant serializing everything necessary. With the introduction of the "binary" QML data structure, that process of serialization becomes obsolete and would require extra work in the custom parsers for example for QQuickStates to store the translation parameters. The clean solution is to eliminate this unnecessary serialization process and instead let the custom parsers do a verification pass at type compile time and then simply operate directly on the QV4::CompiledData::Bindings at object instantiation time. That simplifies the code, and allows for support of translations throughout all list model properties. Additionally this speeds up the creation of state objects and reduces memory consumption. Previously a text: qsTr("foo") binding in states would result in an actual java script binding. After this patch it is merely stored as a string and translated at object instantiation time. Change-Id: I7550274513f54abb09a0ab4de51c4c0bcdb23cae Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp81
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h20
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp4
3 files changed, 37 insertions, 68 deletions
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 8ffa327cf2..1498fba9e2 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -40,6 +40,8 @@
****************************************************************************/
#include "testtypes.h"
+#include <private/qqmlcompiler_p.h>
+
void registerTypes()
{
qmlRegisterInterface<MyInterface>("MyInterface");
@@ -105,105 +107,70 @@ QVariant myCustomVariantTypeConverter(const QString &data)
}
-QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- QByteArray result;
- QDataStream ds(&result, QIODevice::WriteOnly);
-
- ds << bindings.count();
- for (int i = 0; i < bindings.count(); ++i) {
- const QV4::CompiledData::Binding *binding = bindings.at(i);
- ds << qmlUnit->header.stringAt(binding->propertyNameIndex);
-
- Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
- int bindingId = bindingIdentifier(binding);
- ds << bindingId;
-
- ds << binding->location.line;
- }
-
- return result;
-}
-
-void CustomBindingParser::setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData*)
+void CustomBindingParser::applyBindings(QObject *object, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings)
{
CustomBinding *customBinding = qobject_cast<CustomBinding*>(object);
Q_ASSERT(customBinding);
- customBinding->m_bindingData = data;
+ customBinding->cdata = cdata;
+ customBinding->bindings = bindings;
}
void CustomBinding::componentComplete()
{
Q_ASSERT(m_target);
- QDataStream ds(m_bindingData);
- int count;
- ds >> count;
- for (int i = 0; i < count; ++i) {
- QString name;
- ds >> name;
+ foreach (const QV4::CompiledData::Binding *binding, bindings) {
+ QString name = cdata->compilationUnit->data->stringAt(binding->propertyNameIndex);
- int bindingId;
- ds >> bindingId;
+ int bindingId = binding->value.compiledScriptIndex;
- int line;
- ds >> line;
+ QQmlContextData *context = QQmlContextData::get(qmlContext(this));
- QQmlBinding *binding = QQmlBinding::createBinding(QQmlBinding::Identifier(bindingId), m_target, qmlContext(this));
+ QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
+ QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId]));
+ QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context);
QQmlProperty property(m_target, name, qmlContext(this));
- binding->setTarget(property);
- QQmlPropertyPrivate::setBinding(property, binding);
+ qmlBinding->setTarget(property);
+ QQmlPropertyPrivate::setBinding(property, qmlBinding);
}
}
-QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
+void EnumSupportingCustomParser::verifyBindings(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
{
- Q_UNUSED(qmlUnit)
-
if (bindings.count() != 1) {
error(bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test"));
- return QByteArray();
+ return;
}
const QV4::CompiledData::Binding *binding = bindings.first();
if (qmlUnit->header.stringAt(binding->propertyNameIndex) != QStringLiteral("foo")) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property name"));
- return QByteArray();
+ return;
}
if (binding->type != QV4::CompiledData::Binding::Type_Script) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum"));
- return QByteArray();
+ return;
}
QByteArray script = qmlUnit->header.stringAt(binding->stringIndex).toUtf8();
bool ok;
int v = evaluateEnum(script, &ok);
if (!ok) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Script did not evaluate to enum"));
- return QByteArray();
+ return;
}
if (v != MyEnum1Class::A_13) {
error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Enum value is not the expected value."));
- return QByteArray();
+ return;
}
-
- return QByteArray();
-}
-
-
-QByteArray SimpleObjectCustomParser::compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &bindings)
-{
- return QByteArray::number(bindings.count());
}
-void SimpleObjectCustomParser::setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData*)
+void SimpleObjectCustomParser::applyBindings(QObject *object, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &bindings)
{
- SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
- Q_ASSERT(o);
- bool ok = false;
- o->setCustomBindingsCount(data.toInt(&ok));
- Q_ASSERT(ok);
+ SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
+ Q_ASSERT(o);
+ o->setCustomBindingsCount(bindings.count());
}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 1c13a2e21c..509cf40e47 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -54,7 +54,7 @@
#include <QtQml/qqmlpropertyvaluesource.h>
#include <QtQml/qqmlscriptstring.h>
#include <QtQml/qqmlproperty.h>
-
+#include <private/qqmlcompiler_p.h>
#include <private/qqmlcustomparser_p.h>
QVariant myCustomVariantTypeConverter(const QString &data);
@@ -739,15 +739,15 @@ class MyCustomParserType : public QObject
class MyCustomParserTypeParser : public QQmlCustomParser
{
public:
- QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) { return QByteArray(); }
- void setCustomData(QObject *, const QByteArray &, QQmlCompiledData*) {}
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class EnumSupportingCustomParser : public QQmlCustomParser
{
public:
- QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
- void setCustomData(QObject *, const QByteArray &, QQmlCompiledData*) {}
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &);
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {}
};
class MyParserStatus : public QObject, public QQmlParserStatus
@@ -1112,13 +1112,15 @@ public:
void setTarget(QObject *newTarget) { m_target = newTarget; }
QPointer<QObject> m_target;
+ QQmlRefPointer<QQmlCompiledData> cdata;
+ QList<const QV4::CompiledData::Binding*> bindings;
QByteArray m_bindingData;
};
class CustomBindingParser : public QQmlCustomParser
{
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
- virtual void setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData *);
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
};
class SimpleObjectWithCustomParser : public QObject
@@ -1144,8 +1146,8 @@ private:
class SimpleObjectCustomParser : public QQmlCustomParser
{
- virtual QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &bindings);
- virtual void setCustomData(QObject *object, const QByteArray &data, QQmlCompiledData *);
+ virtual void verifyBindings(const QV4::CompiledData::QmlUnit *, const QList<const QV4::CompiledData::Binding *> &) {}
+ virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &);
};
class RootObjectInCreationTester : public QObject
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 9b57eeffa9..22404aa862 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -352,12 +352,12 @@ void tst_qqmllistmodel::dynamic_i18n_data()
QTest::newRow("qsTr")
<< QString::fromUtf8("ListElement { foo: qsTr(\"test\") }")
<< QVariant(QString::fromUtf8("test"))
- << QString("ListElement: cannot use script for property value");
+ << QString();
QTest::newRow("qsTrId")
<< "ListElement { foo: qsTrId(\"qtn_test\") }"
<< QVariant(QString("qtn_test"))
- << QString("ListElement: cannot use script for property value");
+ << QString();
}
void tst_qqmllistmodel::dynamic_i18n()