From 49a3883e86b61d8facfeea9c43037d484cb50b92 Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Mon, 4 Jun 2012 14:43:38 +1000 Subject: Use V4 binding for non-final properties where possible When a property referenced in a binding is not marked as final, do not automatically abort optimization. Instead generate both V4 and V8 binidngs, and only fall back to the V8 binding if necessary at run time. Change-Id: I1bcc7e2b495935c5d519a9a223f640c1972cdb4e Reviewed-by: Michael Brasser --- .../auto/qml/qqmlecmascript/data/BaseComponent.qml | 6 ++ .../qml/qqmlecmascript/data/fallbackBindings.1.qml | 11 +++ .../qml/qqmlecmascript/data/fallbackBindings.2.qml | 12 +++ .../qml/qqmlecmascript/data/fallbackBindings.3.qml | 9 ++ .../qml/qqmlecmascript/data/fallbackBindings.4.qml | 9 ++ .../qml/qqmlecmascript/data/fallbackBindings.5.qml | 9 ++ .../qml/qqmlecmascript/data/fallbackBindings.6.qml | 9 ++ tests/auto/qml/qqmlecmascript/testtypes.cpp | 22 +++++ tests/auto/qml/qqmlecmascript/testtypes.h | 98 ++++++++++++++++++++++ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 25 ++++++ 10 files changed, 210 insertions(+) create mode 100644 tests/auto/qml/qqmlecmascript/data/BaseComponent.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.1.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.2.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.3.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.4.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.5.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/fallbackBindings.6.qml (limited to 'tests/auto/qml') diff --git a/tests/auto/qml/qqmlecmascript/data/BaseComponent.qml b/tests/auto/qml/qqmlecmascript/data/BaseComponent.qml new file mode 100644 index 0000000000..bad4bf8975 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/BaseComponent.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + property Item baz: Item { width: 100 } + property string bar: baz.width +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.1.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.1.qml new file mode 100644 index 0000000000..8de6607999 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.1.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + BaseComponent { + id: foo + } + + Component.onCompleted: success = (foo.bar == '100') +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.2.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.2.qml new file mode 100644 index 0000000000..c33c8959f0 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.2.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + BaseComponent { + id: foo + property Text baz: Text { width: 200 } + } + + Component.onCompleted: success = (foo.bar == '200') +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.3.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.3.qml new file mode 100644 index 0000000000..4080b8dcdf --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.3.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test.fallbackBindingsObject 1.0 as ModuleAPI + +Item { + property bool success: false + property string foo: ModuleAPI.test + + Component.onCompleted: success = (foo == '100') +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.4.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.4.qml new file mode 100644 index 0000000000..b7bd294c9f --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.4.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test.fallbackBindingsDerived 1.0 as ModuleAPI + +Item { + property bool success: false + property string foo: ModuleAPI.test + + Component.onCompleted: success = (foo == 'hello') +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.5.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.5.qml new file mode 100644 index 0000000000..3e869c17d9 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.5.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test.fallbackBindingsObject 1.0 + +Item { + property bool success: false + property string foo: FallbackBindingsType.test + + Component.onCompleted: success = (foo == '100') +} diff --git a/tests/auto/qml/qqmlecmascript/data/fallbackBindings.6.qml b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.6.qml new file mode 100644 index 0000000000..138216127b --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/fallbackBindings.6.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test.fallbackBindingsDerived 1.0 + +Item { + property bool success: false + property string foo: FallbackBindingsType.test + + Component.onCompleted: success = (foo == 'hello') +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index f488c6a14e..b02e9963ab 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -157,6 +157,22 @@ static QObject *qobject_api_engine_parent(QQmlEngine *engine, QJSEngine *scriptE return o; } +static QObject *fallback_bindings_object(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + + return new FallbackBindingsObject(); +} + +static QObject *fallback_bindings_derived(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + + return new FallbackBindingsDerived(); +} + class MyWorkerObjectThread : public QThread { public: @@ -231,6 +247,12 @@ void registerTypes() qmlRegisterType("Qt.test", 1, 0, "MySequenceConversionObject"); qmlRegisterType("Qt.test", 1, 0, "MyUnregisteredEnumTypeObject"); + + qmlRegisterModuleApi("Qt.test.fallbackBindingsObject", 1, 0, fallback_bindings_object); + qmlRegisterModuleApi("Qt.test.fallbackBindingsDerived", 1, 0, fallback_bindings_derived); + + qmlRegisterType("Qt.test.fallbackBindingsObject", 1, 0, "FallbackBindingsType"); + qmlRegisterType("Qt.test.fallbackBindingsDerived", 1, 0, "FallbackBindingsType"); } #include "testtypes.moc" diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 06e54ea552..d857b64d80 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1496,6 +1496,104 @@ private: MyEnum m_ev; }; +class FallbackBindingsObject : public QObject +{ + Q_OBJECT + Q_PROPERTY (int test READ test NOTIFY testChanged) +public: + FallbackBindingsObject(QObject* parent = 0) + : QObject(parent), m_test(100) + { + } + + int test() const { return m_test; } + +Q_SIGNALS: + void testChanged(); + +private: + int m_test; +}; + +class FallbackBindingsDerived : public FallbackBindingsObject +{ + Q_OBJECT + Q_PROPERTY (QString test READ test NOTIFY testChanged) +public: + FallbackBindingsDerived(QObject* parent = 0) + : FallbackBindingsObject(parent), m_test("hello") + { + } + + QString test() const { return m_test; } + +Q_SIGNALS: + void testChanged(); + +private: + QString m_test; +}; + +class FallbackBindingsAttachedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY (int test READ test NOTIFY testChanged) +public: + FallbackBindingsAttachedObject(QObject *parent) : QObject(parent), m_test(100) {} + + int test() const { return m_test; } + +Q_SIGNALS: + void testChanged(); + +private: + int m_test; +}; + +class FallbackBindingsAttachedDerived : public FallbackBindingsAttachedObject +{ + Q_OBJECT + Q_PROPERTY (QString test READ test NOTIFY testChanged) +public: + FallbackBindingsAttachedDerived(QObject* parent = 0) + : FallbackBindingsAttachedObject(parent), m_test("hello") + { + } + + QString test() const { return m_test; } + +Q_SIGNALS: + void testChanged(); + +private: + QString m_test; +}; + +class FallbackBindingsTypeObject : public QObject +{ + Q_OBJECT +public: + FallbackBindingsTypeObject() : QObject() {} + + static FallbackBindingsAttachedObject *qmlAttachedProperties(QObject *o) { + return new FallbackBindingsAttachedObject(o); + } +}; + +class FallbackBindingsTypeDerived : public QObject +{ + Q_OBJECT +public: + FallbackBindingsTypeDerived() : QObject() {} + + static FallbackBindingsAttachedObject *qmlAttachedProperties(QObject *o) { + return new FallbackBindingsAttachedDerived(o); + } +}; + +QML_DECLARE_TYPEINFO(FallbackBindingsTypeObject, QML_HAS_ATTACHED_PROPERTIES) +QML_DECLARE_TYPEINFO(FallbackBindingsTypeDerived, QML_HAS_ATTACHED_PROPERTIES) + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index e2f818c1ee..39174f089e 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -272,6 +272,8 @@ private slots: void secondAlias(); void varAlias(); void overrideDataAssert(); + void fallbackBindings_data(); + void fallbackBindings(); private: static void propertyVarWeakRefCallback(v8::Persistent object, void* parameter); @@ -6996,6 +6998,29 @@ void tst_qqmlecmascript::overrideDataAssert() delete object; } +void tst_qqmlecmascript::fallbackBindings_data() +{ + QTest::addColumn("source"); + + QTest::newRow("Property without fallback") << "fallbackBindings.1.qml"; + QTest::newRow("Property fallback") << "fallbackBindings.2.qml"; + QTest::newRow("ModuleAPI without fallback") << "fallbackBindings.3.qml"; + QTest::newRow("ModuleAPI fallback") << "fallbackBindings.4.qml"; + QTest::newRow("Attached without fallback") << "fallbackBindings.5.qml"; + QTest::newRow("Attached fallback") << "fallbackBindings.6.qml"; +} + +void tst_qqmlecmascript::fallbackBindings() +{ + QFETCH(QString, source); + + QQmlComponent component(&engine, testFileUrl(source)); + QScopedPointer object(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->property("success").toBool(), true); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" -- cgit v1.2.3