From 1ea93870fce7ff032053775fb19d42e950dd5ccb Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 12 Oct 2009 13:58:42 +1000 Subject: Composite types should assign to object properties Fixes QT-956 --- src/declarative/qml/qmlcompileddata.cpp | 4 ++-- src/declarative/qml/qmlcompiler.cpp | 16 +++++++++++----- src/declarative/qml/qmlcompiler_p.h | 3 ++- src/declarative/qml/qmlengine.cpp | 6 +++--- src/declarative/qml/qmlmetaproperty.cpp | 13 +++++++++++-- src/declarative/qml/qmlmetaproperty_p.h | 2 ++ .../declarative/qmllanguage/data/CompositeType.qml | 4 ++++ .../declarative/qmllanguage/data/CompositeType2.qml | 5 +++++ .../declarative/qmllanguage/data/CompositeType3.qml | 5 +++++ .../declarative/qmllanguage/data/CompositeType4.qml | 6 ++++++ .../qmllanguage/data/assignCompositeToType.qml | 18 ++++++++++++++++++ tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp | 10 ++++++++++ 12 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 tests/auto/declarative/qmllanguage/data/CompositeType.qml create mode 100644 tests/auto/declarative/qmllanguage/data/CompositeType2.qml create mode 100644 tests/auto/declarative/qmllanguage/data/CompositeType3.qml create mode 100644 tests/auto/declarative/qmllanguage/data/CompositeType4.qml create mode 100644 tests/auto/declarative/qmllanguage/data/assignCompositeToType.qml diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp index 8c3c355..7032a3b 100644 --- a/src/declarative/qml/qmlcompileddata.cpp +++ b/src/declarative/qml/qmlcompileddata.cpp @@ -150,7 +150,7 @@ int QmlCompiledData::indexForLocation(const QmlParser::LocationSpan &l) } QmlCompiledData::QmlCompiledData() -: importCache(0) +: importCache(0), root(0) { } @@ -189,7 +189,7 @@ const QMetaObject *QmlCompiledData::TypeReference::metaObject() const return type->metaObject(); } else { Q_ASSERT(component); - return &static_cast(QObjectPrivate::get(component))->cc->root; + return static_cast(QObjectPrivate::get(component))->cc->root; } } diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 48d3360..6d1df6d 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -647,7 +647,13 @@ void QmlCompiler::compileTree(Object *tree) output->importCache = output->imports.cache(engine); Q_ASSERT(tree->metatype); - static_cast(output->root) = *tree->metaObject(); + + if (tree->metadata.isEmpty()) { + output->root = tree->metatype; + } else { + static_cast(output->rootData) = *tree->metaObject(); + output->root = &output->rootData; + } if (!tree->metadata.isEmpty()) QmlEnginePrivate::get(engine)->registerCompositeType(output); } @@ -1905,7 +1911,7 @@ bool QmlCompiler::buildPropertyObjectAssignment(QmlParser::Property *prop, if (propertyMetaObject) { const QMetaObject *c = v->object->metatype; while(c) { - isAssignable |= (c == propertyMetaObject); + isAssignable |= (QmlMetaPropertyPrivate::equal(c, propertyMetaObject)); c = c->superClass(); } } @@ -2101,7 +2107,7 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode) Q_ASSERT(tdata->status == QmlCompositeTypeData::Complete); QmlCompiledData *data = tdata->toCompiledComponent(engine); - customTypeName = data->root.className(); + customTypeName = data->root->className(); } else { customTypeName = qmltype->typeName(); } @@ -2473,7 +2479,7 @@ bool QmlCompiler::canCoerce(int to, QmlParser::Object *from) const QMetaObject *fromMo = from->metaObject(); while (fromMo) { - if (fromMo == toMo) + if (QmlMetaPropertyPrivate::equal(fromMo, toMo)) return true; fromMo = fromMo->superClass(); } @@ -2492,7 +2498,7 @@ bool QmlCompiler::canCoerce(int to, int from) QmlEnginePrivate::get(engine)->rawMetaObjectForType(from); while (fromMo) { - if (fromMo == toMo) + if (QmlMetaPropertyPrivate::equal(fromMo, toMo)) return true; fromMo = fromMo->superClass(); } diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 3a35d58..ecf3344 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -104,7 +104,8 @@ public: int type; }; - QAbstractDynamicMetaObject root; + const QMetaObject *root; + QAbstractDynamicMetaObject rootData; QList primitives; QList floatData; QList intData; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index c644ccc..245ddc0 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1379,7 +1379,7 @@ static void *voidptr_constructor(const void *v) void QmlEnginePrivate::registerCompositeType(QmlCompiledData *data) { - QByteArray name = data->root.className(); + QByteArray name = data->root->className(); QByteArray ptr = name + "*"; QByteArray lst = "QmlList<" + ptr + ">*"; @@ -1417,7 +1417,7 @@ const QMetaObject *QmlEnginePrivate::rawMetaObjectForType(int t) const { QHash::ConstIterator iter = m_compositeTypes.find(t); if (iter != m_compositeTypes.end()) { - return &(*iter)->root; + return (*iter)->root; } else { return QmlMetaType::rawMetaObjectForType(t); } @@ -1427,7 +1427,7 @@ const QMetaObject *QmlEnginePrivate::metaObjectForType(int t) const { QHash::ConstIterator iter = m_compositeTypes.find(t); if (iter != m_compositeTypes.end()) { - return &(*iter)->root; + return (*iter)->root; } else { return QmlMetaType::metaObjectForType(t); } diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index ce4836e..34c98bf 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -874,7 +874,7 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t); while (valMo) { - if (valMo == propMo) + if (equal(valMo, propMo)) break; valMo = valMo->superClass(); } @@ -928,7 +928,7 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data const QMetaObject *objMo = obj->metaObject(); bool found = false; while(!found && objMo) { - if (objMo == mo) + if (equal(objMo, mo)) found = true; else objMo = objMo->superClass(); @@ -1211,4 +1211,13 @@ QmlMetaProperty QmlMetaProperty::createProperty(QObject *obj, return prop; } +/*! + Returns true if lhs and rhs refer to the same metaobject data +*/ +bool QmlMetaPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rhs) +{ + return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata); +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h index b74aa2d..7288266 100644 --- a/src/declarative/qml/qmlmetaproperty_p.h +++ b/src/declarative/qml/qmlmetaproperty_p.h @@ -106,6 +106,8 @@ public: static quint32 saveValueType(int, int); static quint32 saveProperty(int); + + static bool equal(const QMetaObject *, const QMetaObject *); }; QT_END_NAMESPACE diff --git a/tests/auto/declarative/qmllanguage/data/CompositeType.qml b/tests/auto/declarative/qmllanguage/data/CompositeType.qml new file mode 100644 index 0000000..8c5094b --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/CompositeType.qml @@ -0,0 +1,4 @@ +import Qt 4.6 + +Object { +} diff --git a/tests/auto/declarative/qmllanguage/data/CompositeType2.qml b/tests/auto/declarative/qmllanguage/data/CompositeType2.qml new file mode 100644 index 0000000..86210e9 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/CompositeType2.qml @@ -0,0 +1,5 @@ +import Test 1.0 + +MyQmlObject { +} + diff --git a/tests/auto/declarative/qmllanguage/data/CompositeType3.qml b/tests/auto/declarative/qmllanguage/data/CompositeType3.qml new file mode 100644 index 0000000..bb5469a --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/CompositeType3.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +Object { + property int a +} diff --git a/tests/auto/declarative/qmllanguage/data/CompositeType4.qml b/tests/auto/declarative/qmllanguage/data/CompositeType4.qml new file mode 100644 index 0000000..a6a8168 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/CompositeType4.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +MyQmlObject { + property int a +} + diff --git a/tests/auto/declarative/qmllanguage/data/assignCompositeToType.qml b/tests/auto/declarative/qmllanguage/data/assignCompositeToType.qml new file mode 100644 index 0000000..ec2867d --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/assignCompositeToType.qml @@ -0,0 +1,18 @@ +import Qt 4.6 +import Test 1.0 + +Object { + property Object myProperty + property Object myProperty2 + property Object myProperty3 + property Object myProperty4 + property MyQmlObject myProperty5 + property MyQmlObject myProperty6 + + myProperty: CompositeType {} + myProperty2: CompositeType2 {} + myProperty3: CompositeType3 {} + myProperty4: CompositeType4 {} + myProperty5: CompositeType2 {} + myProperty6: CompositeType4 {} +} diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp index ff78e6d..94998c7 100644 --- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp +++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp @@ -39,6 +39,7 @@ private slots: void assignQmlComponent(); void assignBasicTypes(); void assignTypeExtremes(); + void assignCompositeToType(); void customParserTypes(); void rootAsQmlComponent(); void inlineQmlComponents(); @@ -323,6 +324,15 @@ void tst_qmllanguage::assignTypeExtremes() QCOMPARE(object->intProperty(), -0x77359400); } +// Test that a composite type can assign to a property of its base type +void tst_qmllanguage::assignCompositeToType() +{ + QmlComponent component(&engine, TEST_FILE("assignCompositeToType.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); +} + // Tests that custom parser types can be instantiated void tst_qmllanguage::customParserTypes() { -- cgit v0.12