diff options
author | Martin Jones <martin.jones@nokia.com> | 2009-10-16 06:20:19 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2009-10-16 06:20:19 (GMT) |
commit | b49b85d4c0decce35e1ad4a0b08dc9c0c82b384e (patch) | |
tree | 3e947e7ba5d06a827707777c80491ac8d1f013d9 /src/declarative/qml | |
parent | dc66752f24442a0bb219a9a4810b47ba4ece3d5c (diff) | |
parent | c017a4dc6b5a81136b3654ca0ac75630cdf11675 (diff) | |
download | Qt-b49b85d4c0decce35e1ad4a0b08dc9c0c82b384e.zip Qt-b49b85d4c0decce35e1ad4a0b08dc9c0c82b384e.tar.gz Qt-b49b85d4c0decce35e1ad4a0b08dc9c0c82b384e.tar.bz2 |
Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative/qml')
-rw-r--r-- | src/declarative/qml/qmlbasicscript.cpp | 11 | ||||
-rw-r--r-- | src/declarative/qml/qmlbinding.cpp | 13 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontextscriptclass.cpp | 9 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.cpp | 41 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.cpp | 130 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.cpp | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlobjectscriptclass.cpp | 37 | ||||
-rw-r--r-- | src/declarative/qml/qmlobjectscriptclass_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlrewrite.cpp | 27 | ||||
-rw-r--r-- | src/declarative/qml/qmlrewrite_p.h | 2 |
14 files changed, 191 insertions, 101 deletions
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index a0d749f..b7aac54 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -181,19 +181,24 @@ static QVariant fetch_value(QObject *o, int idx, int type) break; default: { + // If the object is null, we extract the predicted type. While this isn't + // 100% reliable, in many cases it gives us better error messages if we + // assign this null-object to an incompatible property if (QmlMetaType::isObject(type)) { // NOTE: This assumes a cast to QObject does not alter the // object pointer QObject *val = 0; void *args[] = { &val, 0 }; QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args); - return QVariant::fromValue(val); + if (!val) return QVariant(type, &val); + else return QVariant::fromValue(val); } else { QVariant var = o->metaObject()->property(idx).read(o); if (QmlMetaType::isObject(var.userType())) { QObject *obj = 0; obj = *(QObject **)var.data(); - var = QVariant::fromValue(obj); + if (!obj) var = QVariant(var.userType(), &obj); + else var = QVariant::fromValue(obj); } return var; } @@ -665,7 +670,7 @@ QVariant QmlBasicScript::run(QmlContext *context, QObject *me) case ScriptInstruction::FetchConstant: { QVariant o = stack.pop(); - QObject *obj = qvariant_cast<QObject *>(o); + QObject *obj = *(QObject **)o.constData(); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); if (obj && instr.constant.notify != 0) diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index 6a70c1e..2b4e723 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -129,7 +129,18 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) } else { QVariant value = this->value(); - data->property.write(value, flags); + if (data->property.object() && !data->property.write(value, flags)) { + QString fileName = data->fileName; + int line = data->line; + if (fileName.isEmpty()) fileName = QLatin1String("<Unknown File>"); + + const char *valueType = 0; + if (value.userType() == QVariant::Invalid) valueType = "null"; + else valueType = QMetaType::typeName(value.userType()); + qWarning().nospace() << qPrintable(fileName) << ":" << line + << " Unable to assign " << valueType << " to " + << QMetaType::typeName(data->property.propertyType()); + } } data->updating = false; diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 43a4741..31d4e1f 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -469,7 +469,7 @@ QUrl QmlContext::resolvedUrl(const QUrl &src) } /*! - Explicitly sets the url resolveUrl() will use for relative references to \a baseUrl. + Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl. Calling this function will override the url of the containing component used by default. diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index 939d008..ae86fb1 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -144,7 +144,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje if (scopeObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(scopeObject, name, flags, 0); + ep->objectClass->queryProperty(scopeObject, name, flags, bindContext); if (rv) { lastScopeObject = scopeObject; lastContext = bindContext; @@ -154,7 +154,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje for (int ii = 0; ii < cp->defaultObjects.count(); ++ii) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, 0); + ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext); if (rv) { lastDefaultObject = ii; @@ -225,9 +225,10 @@ void QmlContextScriptClass::setProperty(Object *object, const Identifier &name, QmlContextPrivate *cp = QmlContextPrivate::get(bindContext); if (lastScopeObject) { - ep->objectClass->setProperty(lastScopeObject, name, value); + ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); } else { - ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value); + ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value, + bindContext); } } diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index d73d51a..356c3c6 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -338,20 +338,17 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope) rv = QVariant::fromValue(list); } } else if (svalue.isObject() && - !svalue.isNumber() && - !svalue.isString() && - !svalue.isDate() && - !svalue.isError() && - !svalue.isFunction() && - !svalue.isNull() && - !svalue.isQMetaObject() && - !svalue.isQObject() && - !svalue.isRegExp()) { - + ep->objectClass->scriptClass(svalue) == ep->objectClass) { QObject *o = svalue.toQObject(); - if (o) - return qVariantFromValue(o); + int type = QMetaType::QObjectStar; + // If the object is null, we extract the predicted type. While this isn't + // 100% reliable, in many cases it gives us better error messages if we + // assign this null-object to an incompatible property + if (!o) type = ep->objectClass->objectType(svalue); + + return QVariant(type, &o); } + if (rv.isNull()) rv = svalue.toVariant(); @@ -458,6 +455,26 @@ void QmlExpression::setTrackChange(bool trackChange) } /*! + Returns the source file URL for this expression. The source location must + have been previously set by calling setSourceLocation(). +*/ +QUrl QmlExpression::sourceFile() const +{ + Q_D(const QmlExpression); + return QUrl(d->data->fileName); +} + +/*! + Returns the source file line number for this expression. The source location + must have been previously set by calling setSourceLocation(). +*/ +int QmlExpression::lineNumber() const +{ + Q_D(const QmlExpression); + return d->data->line; +} + +/*! Set the location of this expression to \a line of \a fileName. This information is used by the script engine. */ diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index b85e0a7..73682f1 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -76,6 +76,8 @@ public: bool trackChange() const; void setTrackChange(bool); + QUrl sourceFile() const; + int lineNumber() const; void setSourceLocation(const QUrl &fileName, int line); QObject *scopeObject() const; diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 5635016..feedf13 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -768,13 +768,14 @@ bool QmlMetaPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int id return status; } -void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value, +bool QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value, QmlMetaProperty::WriteFlags flags) { // Remove any existing bindings on this property if (!(flags & QmlMetaProperty::DontRemoveBinding)) delete q->setBinding(0); + bool rv = false; uint type = q->type(); if (type & QmlMetaProperty::ValueTypeProperty) { QmlEnginePrivate *ep = @@ -792,20 +793,23 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value, QmlPropertyCache::Data data = core; data.coreIndex = valueTypeCoreIdx; data.propType = valueTypePropType; - write(writeBack, data, value, context, flags); + rv = write(writeBack, data, value, context, flags); writeBack->write(object, core.coreIndex, flags); if (!ep) delete writeBack; } else { - write(object, core, value, context, flags); + rv = write(object, core, value, context, flags); } + + return rv; } -void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property, - const QVariant &value, QmlContext *context, QmlMetaProperty::WriteFlags flags) +bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property, + const QVariant &value, QmlContext *context, + QmlMetaProperty::WriteFlags flags) { int coreIdx = property.coreIndex; int status = -1; //for dbus @@ -820,14 +824,16 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data if (qFuzzyCompare(fractional, (double)0.0)) v.convert(QVariant::Int); } - writeEnumProperty(prop, coreIdx, object, v, flags); - - return; + return writeEnumProperty(prop, coreIdx, object, v, flags); } int t = property.propType; int vt = value.userType(); + QmlEnginePrivate *enginePriv = 0; + if (context && context->engine()) + enginePriv = QmlEnginePrivate::get(context->engine()); + if (t == QVariant::Url) { QUrl u; @@ -843,13 +849,14 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data found = true; } - if (found) { - if (context && u.isRelative() && !u.isEmpty()) - u = context->baseUrl().resolved(u); - int status = -1; - void *argv[] = { &u, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); - } + if (!found) + return false; + + if (context && u.isRelative() && !u.isEmpty()) + u = context->baseUrl().resolved(u); + int status = -1; + void *argv[] = { &u, 0, &status, &flags }; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); } else if (vt == t) { @@ -863,29 +870,33 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data } else if (property.flags & QmlPropertyCache::Data::IsQObjectDerived) { - QObject *o = QmlMetaType::toQObject(value); - const QMetaObject *valMo = 0; + if (enginePriv) valMo = enginePriv->rawMetaObjectForType(value.userType()); + else valMo = QmlMetaType::rawMetaObjectForType(value.userType()); + + if (!valMo) + return false; - if (o) { + QObject *o = *(QObject **)value.constData(); + const QMetaObject *propMo = 0; + if (enginePriv) propMo = enginePriv->rawMetaObjectForType(t); + else propMo = QmlMetaType::rawMetaObjectForType(t); - valMo = o->metaObject(); - const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t); - - while (valMo) { - if (equal(valMo, propMo)) - break; - valMo = valMo->superClass(); - } - - } - - if (valMo || !o) { + if (o) valMo = o->metaObject(); + if (canConvert(valMo, propMo)) { void *args[] = { &o, 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args); - + } else if (!o && canConvert(propMo, valMo)) { + // In the case of a null QObject, we assign the null if there is + // any change that the null variant type could be up or down cast to + // the property type. + void *args[] = { &o, 0, &status, &flags }; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, + args); + } else { + return false; } } else if (property.flags & QmlPropertyCache::Data::IsQList) { @@ -932,10 +943,8 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data objMo = objMo->superClass(); } - if (!found) { - qWarning() << "Unable to assign object to list"; - return; - } + if (!found) + return false; // NOTE: This assumes a cast to QObject does not alter // the object pointer @@ -951,35 +960,36 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else if ((uint)t >= QVariant::UserType && vt == QVariant::String) { QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t); - if (con) { - QVariant v = con(value.toString()); - if (v.userType() == t) { - void *a[] = { (void *)v.constData(), 0, &status, &flags}; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); - } + if (!con) + return false; + + QVariant v = con(value.toString()); + if (v.userType() == t) { + void *a[] = { (void *)v.constData(), 0, &status, &flags}; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } + } else { + return false; } } + + return true; } /*! Set the property value to \a value. */ -void QmlMetaProperty::write(const QVariant &value) const +bool QmlMetaProperty::write(const QVariant &value) const { - write(value, 0); + return write(value, 0); } -void QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const +bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const { - if (!d->object) - return; - - if (type() & Property && d->core.isValid()) { - - d->writeValueProperty(value, flags); - - } + if (d->object && type() & Property && d->core.isValid()) + return d->writeValueProperty(value, flags); + else + return false; } /*! @@ -1217,5 +1227,21 @@ bool QmlMetaPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rh return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata); } +/*! + Returns true if from inherits to. +*/ +bool QmlMetaPropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to) +{ + if (from && to == &QObject::staticMetaObject) + return true; + + while (from) { + if (equal(from, to)) + return true; + from = from->superClass(); + } + + return false; +} QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index b0ae28c..fcc020e 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -87,10 +87,10 @@ public: QString name() const; QVariant read() const; - void write(const QVariant &) const; + bool write(const QVariant &) const; enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 }; Q_DECLARE_FLAGS(WriteFlags, WriteFlag) - void write(const QVariant &, QmlMetaProperty::WriteFlags) const; + bool write(const QVariant &, QmlMetaProperty::WriteFlags) const; bool hasChangedNotifier() const; bool needsChangedNotifier() const; diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h index 7288266..368ca30 100644 --- a/src/declarative/qml/qmlmetaproperty_p.h +++ b/src/declarative/qml/qmlmetaproperty_p.h @@ -97,9 +97,9 @@ public: QmlMetaProperty::PropertyCategory propertyCategory() const; QVariant readValueProperty(); - void writeValueProperty(const QVariant &, QmlMetaProperty::WriteFlags); + bool writeValueProperty(const QVariant &, QmlMetaProperty::WriteFlags); static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags); - static void write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *, + static bool write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *, QmlMetaProperty::WriteFlags flags = 0); static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *, QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding); @@ -108,6 +108,7 @@ public: static quint32 saveProperty(int); static bool equal(const QMetaObject *, const QMetaObject *); + static bool canConvert(const QMetaObject *from, const QMetaObject *to); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp index 5198f9f..1ab7aff 100644 --- a/src/declarative/qml/qmlmetatype.cpp +++ b/src/declarative/qml/qmlmetatype.cpp @@ -642,6 +642,9 @@ QVariant QmlMetaType::fromObject(QObject *obj, int typeId) const QMetaObject *QmlMetaType::rawMetaObjectForType(int id) { + if (id == QMetaType::QObjectStar) + return &QObject::staticMetaObject; + QReadLocker lock(metaTypeDataLock()); QmlMetaTypeData *data = metaTypeData(); diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 122db51..a6edd3b 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -52,8 +52,9 @@ QT_BEGIN_NAMESPACE struct ObjectData : public QScriptDeclarativeClass::Object { - ObjectData(QObject *o) : object(o) {} + ObjectData(QObject *o, int t) : object(o), type(t) {} QGuard<QObject> object; + int type; }; /* @@ -77,22 +78,22 @@ QmlObjectScriptClass::~QmlObjectScriptClass() { } -QScriptValue QmlObjectScriptClass::newQObject(QObject *object) +QScriptValue QmlObjectScriptClass::newQObject(QObject *object, int type) { QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); if (!object) - return newObject(scriptEngine, this, new ObjectData(object)); + return newObject(scriptEngine, this, new ObjectData(object, type)); QmlDeclarativeData *ddata = QmlDeclarativeData::get(object, true); if (!ddata->scriptValue.isValid()) { - ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object)); + ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type)); return ddata->scriptValue; } else if (ddata->scriptValue.engine() == QmlEnginePrivate::getScriptEngine(engine)) { return ddata->scriptValue; } else { - return newObject(scriptEngine, this, new ObjectData(object)); + return newObject(scriptEngine, this, new ObjectData(object, type)); } } @@ -101,6 +102,15 @@ QObject *QmlObjectScriptClass::toQObject(const QScriptValue &value) const return value.toQObject(); } +int QmlObjectScriptClass::objectType(const QScriptValue &value) const +{ + if (scriptClass(value) != this) + return QVariant::Invalid; + + Object *o = object(value); + return ((ObjectData*)(o))->type; +} + QScriptClass::QueryFlags QmlObjectScriptClass::queryProperty(Object *object, const Identifier &name, QScriptClass::QueryFlags flags) @@ -224,7 +234,8 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name QObject *rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); - return newQObject(rv); + + return newQObject(rv, lastData->propType); } else { QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj); return enginePriv->scriptValueFromVariant(var); @@ -242,7 +253,8 @@ void QmlObjectScriptClass::setProperty(Object *object, void QmlObjectScriptClass::setProperty(QObject *obj, const Identifier &name, - const QScriptValue &value) + const QScriptValue &value, + QmlContext *evalContext) { Q_UNUSED(name); @@ -251,10 +263,19 @@ void QmlObjectScriptClass::setProperty(QObject *obj, QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); + if (!evalContext && context()) { + // Global object, QScriptContext activation object, QmlContext object + QScriptValue scopeNode = scopeChainValue(context(), -3); + Q_ASSERT(scopeNode.isValid()); + Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass); + + evalContext = enginePriv->contextClass->contextFromValue(scopeNode); + } + // ### Can well known types be optimized? QVariant v = QmlScriptClass::toVariant(engine, value); delete QmlMetaPropertyPrivate::setBinding(obj, *lastData, 0); - QmlMetaPropertyPrivate::write(obj, *lastData, v, enginePriv->currentExpression->context()); + QmlMetaPropertyPrivate::write(obj, *lastData, v, evalContext); } QObject *QmlObjectScriptClass::toQObject(Object *object, bool *ok) diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h index 3fcf009..7fb727e 100644 --- a/src/declarative/qml/qmlobjectscriptclass_p.h +++ b/src/declarative/qml/qmlobjectscriptclass_p.h @@ -70,8 +70,9 @@ public: QmlObjectScriptClass(QmlEngine *); ~QmlObjectScriptClass(); - QScriptValue newQObject(QObject *); + QScriptValue newQObject(QObject *, int type = QMetaType::QObjectStar); QObject *toQObject(const QScriptValue &) const; + int objectType(const QScriptValue &) const; enum QueryMode { IncludeAttachedProperties, SkipAttachedProperties }; @@ -79,7 +80,8 @@ public: QScriptClass::QueryFlags flags, QmlContext *evalContext); QScriptValue property(QObject *, const Identifier &); - void setProperty(QObject *, const Identifier &name, const QScriptValue &); + void setProperty(QObject *, const Identifier &name, const QScriptValue &, + QmlContext *evalContext = 0); protected: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp index 19b88cc..43b2529 100644 --- a/src/declarative/qml/qmlrewrite.cpp +++ b/src/declarative/qml/qmlrewrite.cpp @@ -71,6 +71,7 @@ QString RewriteBinding::rewrite(QString code, unsigned position, TextWriter w; _writer = &w; _position = position; + _inLoop = 0; accept(node); @@ -111,7 +112,7 @@ bool RewriteBinding::visit(AST::Block *ast) bool RewriteBinding::visit(AST::ExpressionStatement *ast) { - if (_loopStack.isEmpty()) { + if (! _inLoop) { unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position; _writer->replace(startOfExpressionStatement, 0, QLatin1String("return ")); } @@ -121,68 +122,68 @@ bool RewriteBinding::visit(AST::ExpressionStatement *ast) bool RewriteBinding::visit(AST::DoWhileStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::DoWhileStatement *) { - _loopStack.removeLast(); + --_inLoop; } bool RewriteBinding::visit(AST::WhileStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::WhileStatement *) { - _loopStack.removeLast(); + --_inLoop; } bool RewriteBinding::visit(AST::ForStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::ForStatement *) { - _loopStack.removeLast(); + --_inLoop; } bool RewriteBinding::visit(AST::LocalForStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::LocalForStatement *) { - _loopStack.removeLast(); + --_inLoop; } bool RewriteBinding::visit(AST::ForEachStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::ForEachStatement *) { - _loopStack.removeLast(); + --_inLoop; } bool RewriteBinding::visit(AST::LocalForEachStatement *ast) { - _loopStack.append(ast); + ++_inLoop; return true; } void RewriteBinding::endVisit(AST::LocalForEachStatement *) { - _loopStack.removeLast(); + --_inLoop; } } // namespace QmlRewrite diff --git a/src/declarative/qml/qmlrewrite_p.h b/src/declarative/qml/qmlrewrite_p.h index 449b219..59057d5 100644 --- a/src/declarative/qml/qmlrewrite_p.h +++ b/src/declarative/qml/qmlrewrite_p.h @@ -99,7 +99,7 @@ protected: virtual void endVisit(AST::LocalForEachStatement *ast); private: - QList<AST::Statement *> _loopStack; + int _inLoop; }; } // namespace QmlRewrite |