summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp2
-rw-r--r--src/declarative/qml/qmlcontext.cpp21
-rw-r--r--src/declarative/qml/qmlcontext_p.h6
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp2
-rw-r--r--src/declarative/qml/qmlengine.cpp2
-rw-r--r--src/declarative/qml/qmlexpression.cpp10
-rw-r--r--tests/auto/declarative/qmllanguage/data/alias.7.qml14
-rw-r--r--tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml5
-rw-r--r--tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml6
-rw-r--r--tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp57
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 {}");