diff options
-rw-r--r-- | src/declarative/qml/qmlbasicscript.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.cpp | 21 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontextscriptclass.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.cpp | 10 | ||||
-rw-r--r-- | tests/auto/declarative/qmllanguage/data/alias.7.qml | 14 | ||||
-rw-r--r-- | tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml | 5 | ||||
-rw-r--r-- | tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml | 6 | ||||
-rw-r--r-- | tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp | 57 |
10 files changed, 93 insertions, 32 deletions
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index b7aac54..eba4307 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -658,7 +658,7 @@ QVariant QmlBasicScript::run(QmlContext *context, QObject *me) case ScriptInstruction::FetchRootConstant: { - QObject *obj = contextPrivate->defaultObjects.last(); + QObject *obj = contextPrivate->defaultObjects.at(0); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); if (obj && instr.constant.notify != 0) diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 7ba3544..2ebdf10 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -50,9 +50,6 @@ #include <private/qmlbindingoptimizations_p.h> #include <QtDeclarative/qmlinfo.h> -// 6-bits -#define MAXIMUM_DEFAULT_OBJECTS 63 - QT_BEGIN_NAMESPACE QmlContextPrivate::QmlContextPrivate() @@ -130,22 +127,6 @@ void QmlContextPrivate::init() parent->d_func()->childContexts.insert(q); } -void QmlContextPrivate::addDefaultObject(QObject *object, Priority priority) -{ - if (defaultObjects.count() >= (MAXIMUM_DEFAULT_OBJECTS - 1)) { - qWarning("QmlContext: Cannot have more than %d default objects on " - "one bind context.", MAXIMUM_DEFAULT_OBJECTS - 1); - return; - } - - if (priority == HighPriority) { - defaultObjects.insert(highPriorityCount++, object); - } else { - defaultObjects.append(object); - } -} - - /*! \class QmlContext \brief The QmlContext class defines a context within a QML engine. @@ -366,7 +347,7 @@ QmlContext *QmlContext::parentContext() const void QmlContext::addDefaultObject(QObject *defaultObject) { Q_D(QmlContext); - d->addDefaultObject(defaultObject, QmlContextPrivate::NormalPriority); + d->defaultObjects.prepend(defaultObject); } /*! diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index be7bf1d..6af5f64 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -104,12 +104,6 @@ public: void dump(); void dump(int depth); - enum Priority { - HighPriority, - NormalPriority - }; - void addDefaultObject(QObject *, Priority); - void invalidateEngines(); QSet<QmlContext *> childContexts; diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index 4df23f0..a978df2 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -155,7 +155,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje } } - for (int ii = 0; ii < cp->defaultObjects.count(); ++ii) { + for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) { QScriptClass::QueryFlags rv = ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index ab3c23a..0e239ce 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -476,6 +476,8 @@ QmlEngine *qmlEngine(const QObject *obj) QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) { QmlDeclarativeData *data = QmlDeclarativeData::get(object); + if (!data) + return 0; // Attached properties are only on objects created by QML QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0; if (rv || !create) diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 3b89a23..c62756b 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -293,8 +293,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); if (secondaryScope) - ctxtPriv->defaultObjects.insert(ctxtPriv->highPriorityCount, - secondaryScope); + ctxtPriv->defaultObjects.append(secondaryScope); QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); @@ -328,8 +327,11 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd return QVariant(); } - if (secondaryScope) - ctxtPriv->defaultObjects.removeAt(ctxtPriv->highPriorityCount); + if (secondaryScope) { + QObject *last = ctxtPriv->defaultObjects.takeLast(); + Q_ASSERT(last == secondaryScope); + Q_UNUSED(last); + } QVariant rv; diff --git a/tests/auto/declarative/qmllanguage/data/alias.7.qml b/tests/auto/declarative/qmllanguage/data/alias.7.qml new file mode 100644 index 0000000..d3cf5fe --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/alias.7.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Object { + property Object object + property alias aliasedObject: target.object + + object: Object { + id: target + + property Object object + object: Object {} + } +} + diff --git a/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml new file mode 100644 index 0000000..99a9746 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml @@ -0,0 +1,5 @@ +import Test 1.0 +import Qt 4.6 +Object { +} + diff --git a/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml new file mode 100644 index 0000000..8179dbd --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml @@ -0,0 +1,6 @@ +import Test 1.0 +import Qt 4.6 +Object { + MyQmlObject.value: 10 +} + diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp index 4bc02c0..2746e98 100644 --- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp +++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp @@ -74,6 +74,8 @@ private slots: void importsOrder_data(); void importsOrder(); + void qmlAttachedPropertiesObjectMethod(); + // regression tests for crashes void crash1(); @@ -693,6 +695,33 @@ void tst_qmllanguage::aliasProperties() QCOMPARE(object->property("a").toInt(), 1923); } + + // Ptr Alias Cleanup - check that aliases to ptr types return 0 + // if the object aliased to is removed + { + QmlComponent component(&engine, TEST_FILE("alias.7.qml")); + VERIFY_ERRORS(0); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QObject *object1 = qvariant_cast<QObject *>(object->property("object")); + QVERIFY(object1 != 0); + QObject *object2 = qvariant_cast<QObject *>(object1->property("object")); + QVERIFY(object2 != 0); + + QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject")); + QVERIFY(alias == object2); + + delete object1; + + QObject *alias2 = object; // "Random" start value + int status = -1; + void *a[] = { &alias2, 0, &status }; + QMetaObject::metacall(object, QMetaObject::ReadProperty, + object->metaObject()->indexOfProperty("aliasedObject"), a); + QVERIFY(alias2 == 0); + } } // Test that the root element in a composite type can be a Component @@ -1012,6 +1041,34 @@ void tst_qmllanguage::importsOrder() testType(qml,type); } +void tst_qmllanguage::qmlAttachedPropertiesObjectMethod() +{ + QObject object; + + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0); + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0); + + { + QmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0); + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0); + } + + { + QmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0); + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0); + } +} + void tst_qmllanguage::crash1() { QmlComponent component(&engine, "Component {}"); |