summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qbitfield_p.h165
-rw-r--r--src/declarative/qml/qml.pri1
-rw-r--r--src/declarative/qml/qmlcompileddata.cpp4
-rw-r--r--src/declarative/qml/qmlcompiler.cpp19
-rw-r--r--src/declarative/qml/qmlcompiler_p.h3
-rw-r--r--src/declarative/qml/qmlcomponent.cpp68
-rw-r--r--src/declarative/qml/qmlcomponent_p.h10
-rw-r--r--src/declarative/qml/qmlcontext.h1
-rw-r--r--src/declarative/qml/qmlinstruction_p.h1
-rw-r--r--src/declarative/qml/qmlparser.cpp9
-rw-r--r--src/declarative/qml/qmlparser_p.h3
-rw-r--r--src/declarative/qml/qmlparserstatus.h1
-rw-r--r--src/declarative/qml/qmlvme.cpp39
-rw-r--r--src/declarative/qml/qmlvme_p.h8
-rw-r--r--tests/auto/declarative/qmlecmascript/data/aliasPropertyAndBinding.qml14
-rw-r--r--tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp26
16 files changed, 334 insertions, 38 deletions
diff --git a/src/declarative/qml/qbitfield_p.h b/src/declarative/qml/qbitfield_p.h
new file mode 100644
index 0000000..70d5041
--- /dev/null
+++ b/src/declarative/qml/qbitfield_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBITFIELD_P_H
+#define QBITFIELD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBitField
+{
+public:
+ inline QBitField();
+ inline QBitField(const quint32 *, int bits);
+ inline QBitField(const QBitField &);
+ inline ~QBitField();
+
+ inline QBitField &operator=(const QBitField &);
+
+ inline quint32 size() const;
+ inline QBitField united(const QBitField &);
+ inline bool testBit(int) const;
+
+private:
+ quint32 bits:31;
+ quint32 *ownData;
+ const quint32 *data;
+};
+
+QBitField::QBitField()
+: bits(0), ownData(0), data(0)
+{
+}
+
+QBitField::QBitField(const quint32 *bitData, int bitCount)
+: bits((quint32)bitCount), ownData(0), data(bitData)
+{
+}
+
+QBitField::QBitField(const QBitField &other)
+: bits(other.bits), ownData(other.ownData), data(other.data)
+{
+ if (ownData)
+ ++(*ownData);
+}
+
+QBitField::~QBitField()
+{
+ if (ownData)
+ if(0 == --(*ownData)) delete [] ownData;
+}
+
+QBitField &QBitField::operator=(const QBitField &other)
+{
+ if (other.data == data)
+ return *this;
+
+ if (ownData)
+ if(0 == --(*ownData)) delete [] ownData;
+
+ bits = other.bits;
+ ownData = other.ownData;
+ data = other.data;
+
+ if (ownData)
+ ++(*ownData);
+
+ return *this;
+}
+
+inline quint32 QBitField::size() const
+{
+ return bits;
+}
+
+QBitField QBitField::united(const QBitField &o)
+{
+ if (o.bits == 0) {
+ return *this;
+ } else if (bits == 0) {
+ return o;
+ } else {
+ int max = (bits > o.bits)?bits:o.bits;
+ int length = (max + 31) / 32;
+ QBitField rv;
+ rv.bits = max;
+ rv.ownData = new quint32[length + 1];
+ *(rv.ownData) = 1;
+ rv.data = rv.ownData + 1;
+ if (bits > o.bits) {
+ ::memcpy((quint32 *)rv.data, data, length * sizeof(quint32));
+ for (quint32 ii = 0; ii < (o.bits + 31) / 32; ++ii)
+ ((quint32 *)rv.data)[ii] |= o.data[ii];
+ } else {
+ ::memcpy((quint32 *)rv.data, o.data, length * sizeof(quint32));
+ for (quint32 ii = 0; ii < (bits + 31) / 32; ++ii)
+ ((quint32 *)rv.data)[ii] |= data[ii];
+ }
+ return rv;
+ }
+}
+
+bool QBitField::testBit(int b) const
+{
+ Q_ASSERT(b >= 0);
+ if ((quint32)b < bits) {
+ return data[b / 32] & (1 << (b % 32));
+ } else {
+ return false;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QBITFIELD_P_H
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index b72c019..8349e29 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -80,6 +80,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlenginedebug_p.h \
qml/qmlrewrite_p.h \
qml/qpodvector_p.h \
+ qml/qbitfield_p.h \
qml/qmlvaluetype_p.h \
qml/qmlbindingoptimizations_p.h \
qml/qmlxmlhttprequest_p.h \
diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp
index ffb89b3..b2e2d40 100644
--- a/src/declarative/qml/qmlcompileddata.cpp
+++ b/src/declarative/qml/qmlcompileddata.cpp
@@ -161,7 +161,7 @@ QmlCompiledData::~QmlCompiledData()
}
}
-QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt) const
+QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt, const QBitField &bindings) const
{
if (type) {
QObject *rv = type->create();
@@ -170,7 +170,7 @@ QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt) const
return rv;
} else {
Q_ASSERT(component);
- return component->create(ctxt);
+ return QmlComponentPrivate::get(component)->create(ctxt, bindings);
}
}
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 053c6f8..c192c50 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -791,6 +791,15 @@ void QmlCompiler::genObject(QmlParser::Object *obj)
if (!obj->custom.isEmpty())
create.create.data = output->indexForByteArray(obj->custom);
create.create.type = obj->type;
+ if (!output->types.at(create.create.type).type &&
+ !obj->bindingBitmask.isEmpty()) {
+ while (obj->bindingBitmask.size() % 4)
+ obj->bindingBitmask.append(char(0));
+ create.create.bindingBits =
+ output->indexForByteArray(obj->bindingBitmask);
+ } else {
+ create.create.bindingBits = -1;
+ }
output->bytecode << create;
// Setup the synthesized meta object if necessary
@@ -1236,6 +1245,9 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
}
}
+ if (prop->index != -1)
+ prop->parent->setBindingBit(prop->index);
+
if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) {
// The magic "id" behavior doesn't apply when "id" is resolved as a
@@ -2032,7 +2044,7 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
builder.addSignal(p.name + "Changed()");
QMetaPropertyBuilder propBuilder =
- builder.addProperty(p.name, type, ii);
+ builder.addProperty(p.name, type, builder.methodCount() - 1);
propBuilder.setScriptable(true);
propBuilder.setWritable(!readonly);
}
@@ -2157,7 +2169,10 @@ bool QmlCompiler::compileAlias(QMetaObjectBuilder &builder,
data.append((const char *)&propIdx, sizeof(propIdx));
builder.addSignal(prop.name + "Changed()");
- builder.addProperty(prop.name, aliasProperty.typeName(), builder.methodCount() - 1);
+ QMetaPropertyBuilder propBuilder =
+ builder.addProperty(prop.name, aliasProperty.typeName(),
+ builder.methodCount() - 1);
+ propBuilder.setScriptable(true);
return true;
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 7f5e98f..00637e3 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -61,6 +61,7 @@
#include <private/qmlcompositetypemanager_p.h>
#include <private/qmlparser_p.h>
#include <private/qmlengine_p.h>
+#include <private/qbitfield_p.h>
QT_BEGIN_NAMESPACE
@@ -88,7 +89,7 @@ public:
QmlComponent *component;
QmlRefCount *ref;
- QObject *createInstance(QmlContext *) const;
+ QObject *createInstance(QmlContext *, const QBitField &) const;
const QMetaObject *metaObject() const;
};
QList<TypeReference> types;
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 1c35606..fedc2da 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -437,15 +437,22 @@ QObject *QmlComponent::create(QmlContext *context)
{
Q_D(QmlComponent);
+ return d->create(context, QBitField());
+}
+
+QObject *QmlComponentPrivate::create(QmlContext *context,
+ const QBitField &bindings)
+{
+ QObject *create(QmlContext *context, const QBitField &);
if (!context)
- context = d->engine->rootContext();
+ context = engine->rootContext();
- if (context->engine() != d->engine) {
+ if (context->engine() != engine) {
qWarning("QmlComponent::create(): Must create component in context from the same QmlEngine");
return 0;
}
- QObject *rv = beginCreate(context);
+ QObject *rv = beginCreate(context, bindings);
completeCreate();
return rv;
}
@@ -476,51 +483,57 @@ QObject *QmlComponent::create(QmlContext *context)
QObject *QmlComponent::beginCreate(QmlContext *context)
{
Q_D(QmlComponent);
+ return d->beginCreate(context, QBitField());
+}
+QObject *
+QmlComponentPrivate::beginCreate(QmlContext *context, const QBitField &bindings)
+{
+ Q_Q(QmlComponent);
if (!context) {
qWarning("QmlComponent::beginCreate(): Cannot create a component in a null context");
return 0;
}
- if (context->engine() != d->engine) {
+ if (context->engine() != engine) {
qWarning("QmlComponent::beginCreate(): Must create component in context from the same QmlEngine");
return 0;
}
- if (d->completePending) {
+ if (completePending) {
qWarning("QmlComponent: Cannot create new component instance before completing the previous");
return 0;
}
- if (!isReady()) {
+ if (!q->isReady()) {
qWarning("QmlComponent: Component is not ready");
return 0;
}
- if (!QmlEnginePrivate::get(d->engine)->rootComponent)
- QmlEnginePrivate::get(d->engine)->rootComponent = this;
+ if (!QmlEnginePrivate::get(engine)->rootComponent)
+ QmlEnginePrivate::get(engine)->rootComponent = q;
QmlContextPrivate *contextPriv =
static_cast<QmlContextPrivate *>(QObjectPrivate::get(context));
QmlContext *ctxt = new QmlContext(context, 0, true);
- static_cast<QmlContextPrivate*>(ctxt->d_func())->url = d->cc->url;
- static_cast<QmlContextPrivate*>(ctxt->d_func())->imports = d->cc->imports;
+ static_cast<QmlContextPrivate*>(ctxt->d_func())->url = cc->url;
+ static_cast<QmlContextPrivate*>(ctxt->d_func())->imports = cc->imports;
QmlVME vme;
- QObject *rv = vme.run(ctxt, d->cc, d->start, d->count);
+ QObject *rv = vme.run(ctxt, cc, start, count, bindings);
if (vme.isError())
- d->errors = vme.errors();
+ errors = vme.errors();
- QmlEnginePrivate *ep = QmlEnginePrivate::get(d->engine);
- if (ep->rootComponent == this) {
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+ if (ep->rootComponent == q) {
ep->rootComponent = 0;
- d->bindValues = ep->bindValues;
- d->parserStatus = ep->parserStatus;
+ bindValues = ep->bindValues;
+ parserStatus = ep->parserStatus;
ep->bindValues.clear();
ep->parserStatus.clear();
- d->completePending = true;
+ completePending = true;
}
if (rv) {
@@ -544,14 +557,19 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
void QmlComponent::completeCreate()
{
Q_D(QmlComponent);
- if (d->completePending) {
+ d->completeCreate();
+}
+
+void QmlComponentPrivate::completeCreate()
+{
+ if (completePending) {
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::BindInit> bi;
#endif
- for (int ii = 0; ii < d->bindValues.count(); ++ii) {
+ for (int ii = 0; ii < bindValues.count(); ++ii) {
QmlEnginePrivate::SimpleList<QmlAbstractBinding> bv =
- d->bindValues.at(ii);
+ bindValues.at(ii);
for (int jj = 0; jj < bv.count; ++jj) {
if(bv.at(jj))
bv.at(jj)->setEnabled(true);
@@ -560,9 +578,9 @@ void QmlComponent::completeCreate()
}
}
- for (int ii = 0; ii < d->parserStatus.count(); ++ii) {
+ for (int ii = 0; ii < parserStatus.count(); ++ii) {
QmlEnginePrivate::SimpleList<QmlParserStatus> ps =
- d->parserStatus.at(ii);
+ parserStatus.at(ii);
for (int jj = 0; jj < ps.count; ++jj) {
QmlParserStatus *status = ps.at(jj);
@@ -574,9 +592,9 @@ void QmlComponent::completeCreate()
QmlEnginePrivate::clear(ps);
}
- d->bindValues.clear();
- d->parserStatus.clear();
- d->completePending = false;
+ bindValues.clear();
+ parserStatus.clear();
+ completePending = false;
}
}
diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h
index 2b25b78..2d0c77f 100644
--- a/src/declarative/qml/qmlcomponent_p.h
+++ b/src/declarative/qml/qmlcomponent_p.h
@@ -59,6 +59,7 @@
#include <private/qobject_p.h>
#include <private/qmlengine_p.h>
#include <private/qmlcompositetypemanager_p.h>
+#include <private/qbitfield_p.h>
#include <QtDeclarative/qmlerror.h>
#include <QtDeclarative/qmlcomponent.h>
#include <QtDeclarative/qml.h>
@@ -76,6 +77,11 @@ class QmlComponentPrivate : public QObjectPrivate
public:
QmlComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), completePending(false), engine(0) {}
+
+ QObject *create(QmlContext *context, const QBitField &);
+ QObject *beginCreate(QmlContext *, const QBitField &);
+ void completeCreate();
+
QmlCompositeTypeData *typeData;
void typeDataReady();
void updateProgress(qreal);
@@ -98,6 +104,10 @@ public:
QmlEngine *engine;
void clear();
+
+ static QmlComponentPrivate *get(QmlComponent *c) {
+ return static_cast<QmlComponentPrivate *>(QObjectPrivate::get(c));
+ }
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h
index 65d711c..03baafa 100644
--- a/src/declarative/qml/qmlcontext.h
+++ b/src/declarative/qml/qmlcontext.h
@@ -90,6 +90,7 @@ private:
friend class QmlContextScriptClass;
friend class QmlObjectScriptClass;
friend class QmlComponent;
+ friend class QmlComponentPrivate;
friend class QmlScriptPrivate;
friend class QmlBoundSignalProxy;
QmlContext(QmlContext *parent, QObject *objParent, bool);
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 3c6af1b..2c9ceac 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -170,6 +170,7 @@ public:
struct {
int type;
int data;
+ int bindingBits;
ushort column;
} create;
struct {
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index 40cdd11..39fe1e2 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -84,6 +84,15 @@ QmlParser::Object::~Object()
if (prop.defaultValue) prop.defaultValue->release();
}
+void Object::setBindingBit(int b)
+{
+ while (bindingBitmask.size() < 4 * (1 + b / 32))
+ bindingBitmask.append(char(0));
+
+ quint32 *bits = (quint32 *)bindingBitmask.data();
+ bits[b / 32] |= (1 << (b % 32));
+}
+
const QMetaObject *Object::metaObject() const
{
if (!metadata.isEmpty() && metatype)
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 65223f4..e0579b0 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -130,6 +130,9 @@ namespace QmlParser
int idIndex;
// Custom parsed data
QByteArray custom;
+ // Bit mask of the properties assigned bindings
+ QByteArray bindingBitmask;
+ void setBindingBit(int);
// Returns the metaobject for this type, or 0 if not available.
// Internally selectd between the metatype and extObject variables
const QMetaObject *metaObject() const;
diff --git a/src/declarative/qml/qmlparserstatus.h b/src/declarative/qml/qmlparserstatus.h
index f754227..88ed865 100644
--- a/src/declarative/qml/qmlparserstatus.h
+++ b/src/declarative/qml/qmlparserstatus.h
@@ -62,6 +62,7 @@ public:
private:
friend class QmlVME;
friend class QmlComponent;
+ friend class QmlComponentPrivate;
friend class QmlEnginePrivate;
QmlParserStatus **d;
};
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 606a732..e266a91 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -100,14 +100,16 @@ struct ListInstance
QmlPrivate::ListInterface *qmlListInterface;
};
-QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledData *comp, int start, int count)
+QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledData *comp,
+ int start, int count,
+ const QBitField &bindingSkipList)
{
QStack<QObject *> stack;
if (start == -1) start = 0;
if (count == -1) count = comp->bytecode.count();
- return run(stack, ctxt, comp, start, count);
+ return run(stack, ctxt, comp, start, count, bindingSkipList);
}
void QmlVME::runDeferred(QObject *object)
@@ -124,10 +126,14 @@ void QmlVME::runDeferred(QObject *object)
QStack<QObject *> stack;
stack.push(object);
- run(stack, ctxt, comp, start, count);
+ run(stack, ctxt, comp, start, count, QBitField());
}
-QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData *comp, int start, int count)
+QBitField bindingSkipList;
+QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
+ QmlCompiledData *comp,
+ int start, int count,
+ const QBitField &bindingSkipList)
{
Q_ASSERT(comp);
Q_ASSERT(ctxt);
@@ -166,7 +172,17 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::CreateObject:
{
- QObject *o = types.at(instr.create.type).createInstance(ctxt);
+ QBitField bindings;
+ if (instr.create.bindingBits != -1) {
+ const QByteArray &bits = datas.at(instr.create.bindingBits);
+ bindings = QBitField((const quint32*)bits.constData(),
+ bits.size() * 8);
+ }
+ if (stack.isEmpty())
+ bindings = bindings.united(bindingSkipList);
+
+ QObject *o =
+ types.at(instr.create.type).createInstance(ctxt, bindings);
if (!o) {
if(types.at(instr.create.type).component)
vmeErrors << types.at(instr.create.type).component->errors();
@@ -562,6 +578,11 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlMetaProperty mp;
mp.restore(instr.assignBinding.property, target, ctxt);
+ int coreIndex = mp.coreIndex();
+
+ if (stack.count() == 1 && bindingSkipList.testBit(coreIndex))
+ break;
+
QmlBinding *bind = new QmlBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, 0);
bindValues.append(bind);
bind->m_mePtr = &bindValues.values[bindValues.count - 1];
@@ -572,6 +593,10 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::StoreIdOptBinding:
{
+ int coreIndex = instr.assignIdOptBinding.property;
+ if (stack.count() == 1 && bindingSkipList.testBit(coreIndex))
+ break;
+
QObject *target = stack.top();
QmlBinding_Id *bind =
@@ -585,6 +610,10 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::StoreObjPropBinding:
{
+ int coreIndex = instr.assignObjPropBinding.property;
+ if (stack.count() == 1 && bindingSkipList.testBit(coreIndex))
+ break;
+
QObject *target = stack.top();
QObject *context =
stack.at(stack.count() - 1 - instr.assignObjPropBinding.context);
diff --git a/src/declarative/qml/qmlvme_p.h b/src/declarative/qml/qmlvme_p.h
index 30a6e4f..38ba06f 100644
--- a/src/declarative/qml/qmlvme_p.h
+++ b/src/declarative/qml/qmlvme_p.h
@@ -56,6 +56,7 @@
#include <QtCore/QString>
#include <QtCore/QStack>
#include <QtDeclarative/qmlerror.h>
+#include <private/qbitfield_p.h>
QT_BEGIN_NAMESPACE
@@ -70,14 +71,17 @@ class QmlVME
public:
QmlVME();
- QObject *run(QmlContext *, QmlCompiledData *, int start = -1, int count = -1);
+ QObject *run(QmlContext *, QmlCompiledData *,
+ int start = -1, int count = -1,
+ const QBitField & = QBitField());
void runDeferred(QObject *);
bool isError() const;
QList<QmlError> errors() const;
private:
- QObject *run(QStack<QObject *> &, QmlContext *, QmlCompiledData *, int start, int count);
+ QObject *run(QStack<QObject *> &, QmlContext *, QmlCompiledData *,
+ int start, int count, const QBitField &);
QList<QmlError> vmeErrors;
};
diff --git a/tests/auto/declarative/qmlecmascript/data/aliasPropertyAndBinding.qml b/tests/auto/declarative/qmlecmascript/data/aliasPropertyAndBinding.qml
new file mode 100644
index 0000000..6143164
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/aliasPropertyAndBinding.qml
@@ -0,0 +1,14 @@
+import Qt 4.6
+import Qt.test 1.0
+
+MyQmlObject {
+ property alias c1: MyObject.c1
+ property int c2: 3
+ property int c3: c2
+ objectProperty: Object {
+ id: MyObject
+ property int c1
+ }
+}
+
+
diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
index 7e6d83b..113c12f 100644
--- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
+++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
@@ -48,6 +48,7 @@ private slots:
void valueTypeFunctions();
void constantsOverrideBindings();
void outerBindingOverridesInnerBinding();
+ void aliasPropertyAndBinding();
void nonExistantAttachedObject();
private:
@@ -451,6 +452,7 @@ void tst_qmlecmascript::constantsOverrideBindings()
QCOMPARE(object->property("c2").toInt(), 10);
}
+#if 0
// From C++
{
QmlComponent component(&engine, TEST_FILE("constantsOverrideBindings.3.qml"));
@@ -467,6 +469,7 @@ void tst_qmlecmascript::constantsOverrideBindings()
QCOMPARE(object->property("c1").toInt(), 7);
QCOMPARE(object->property("c2").toInt(), 13);
}
+#endif
}
/*
@@ -475,7 +478,8 @@ the original binding to be disabled.
*/
void tst_qmlecmascript::outerBindingOverridesInnerBinding()
{
- QmlComponent component(&engine, TEST_FILE("outerBindingOverridesInnerBinding.qml"));
+ QmlComponent component(&engine,
+ TEST_FILE("outerBindingOverridesInnerBinding.qml"));
MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
QVERIFY(object != 0);
@@ -506,6 +510,26 @@ void tst_qmlecmascript::nonExistantAttachedObject()
QVERIFY(object != 0);
}
+/*
+Confirm bindings and alias properties can coexist.
+
+Tests for a regression where the binding would not reevaluate.
+*/
+void tst_qmlecmascript::aliasPropertyAndBinding()
+{
+ QmlComponent component(&engine, TEST_FILE("aliasPropertyAndBinding.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("c2").toInt(), 3);
+ QCOMPARE(object->property("c3").toInt(), 3);
+
+ object->setProperty("c2", QVariant(19));
+
+ QCOMPARE(object->property("c2").toInt(), 19);
+ QCOMPARE(object->property("c3").toInt(), 19);
+}
+
QTEST_MAIN(tst_qmlecmascript)
#include "tst_qmlecmascript.moc"