From e514c8c498bee83af9e2c688193fe7701e461617 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 3 Jul 2009 13:00:50 +1000 Subject: Warn annoyingly on non-notifyable properties --- src/declarative/fx/qfxtext.h | 2 +- src/declarative/qml/qmlbasicscript.cpp | 32 ++++++++++++++++++++++---------- src/declarative/qml/qmlengine.cpp | 6 +++--- src/declarative/qml/qmlengine_p.h | 5 +++-- src/declarative/qml/qmlexpression.cpp | 28 ++++++++++++++++++++++++---- src/declarative/qml/qmlmetaproperty.cpp | 3 ++- 6 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/declarative/fx/qfxtext.h b/src/declarative/fx/qfxtext.h index 104d18c..ee38a94 100644 --- a/src/declarative/fx/qfxtext.h +++ b/src/declarative/fx/qfxtext.h @@ -60,7 +60,7 @@ class Q_DECLARATIVE_EXPORT QFxText : public QFxItem Q_ENUMS(TextStyle) Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) - Q_PROPERTY(QmlFont *font READ font) + Q_PROPERTY(QmlFont *font READ font CONSTANT) Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(TextStyle style READ style WRITE setStyle) Q_PROPERTY(QColor styleColor READ styleColor WRITE setStyleColor) diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index 0cfb587..478491f 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -603,7 +603,10 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node, instr.type = ScriptInstruction::FetchD0Constant; instr.constant.idx = d0Idx; QMetaProperty prop = context->metaObject()->property(d0Idx); - instr.constant.notify = prop.notifySignalIndex(); + if (prop.isConstant()) + instr.constant.notify = 0; + else + instr.constant.notify = prop.notifySignalIndex(); instr.constant.type = prop.userType(); } else if (d1Idx != -1) { @@ -611,7 +614,10 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node, instr.type = ScriptInstruction::FetchD1Constant; instr.constant.idx = d1Idx; QMetaProperty prop = component->metaObject()->property(d1Idx); - instr.constant.notify = prop.notifySignalIndex(); + if (prop.isConstant()) + instr.constant.notify = 0; + else + instr.constant.notify = prop.notifySignalIndex(); instr.constant.type = prop.userType(); } else { @@ -635,7 +641,10 @@ bool QmlBasicScriptCompiler::parseName(AST::Node *node, instr.type = ScriptInstruction::FetchConstant; instr.constant.idx = idx; QMetaProperty prop = loadedType->metaObject()->property(idx); - instr.constant.notify = prop.notifySignalIndex(); + if (prop.isConstant()) + instr.constant.notify = 0; + else + instr.constant.notify = prop.notifySignalIndex(); instr.constant.type = prop.userType(); } else { int nref = data.count(); @@ -804,7 +813,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c { stack.push(contextPrivate->propertyValues.at(instr.fetch.idx)); enginePrivate->capturedProperties << - QmlEnginePrivate::CapturedProperty(context, contextPrivate->notifyIndex + instr.fetch.idx); + QmlEnginePrivate::CapturedProperty(context, -1, contextPrivate->notifyIndex + instr.fetch.idx); state = Reset; } break; @@ -814,8 +823,9 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c QObject *obj = contextPrivate->defaultObjects.at(0); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); - enginePrivate->capturedProperties << - QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + if (instr.constant.notify != 0) + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify); state = Reset; } break; @@ -825,8 +835,9 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c QObject *obj = contextPrivate->defaultObjects.at(1); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); - enginePrivate->capturedProperties << - QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + if (instr.constant.notify != 0) + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify); state = Reset; } break; @@ -837,8 +848,9 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c QObject *obj = qvariant_cast(o); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); - enginePrivate->capturedProperties << - QmlEnginePrivate::CapturedProperty(obj, instr.constant.notify); + if (instr.constant.notify != 0) + enginePrivate->capturedProperties << + QmlEnginePrivate::CapturedProperty(obj, instr.constant.idx, instr.constant.notify); state = Reset; } break; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index f26e389..9eb169e 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -208,7 +208,7 @@ QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c) } QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p) -: object(p.object()), notifyIndex(p.property().notifySignalIndex()) +: object(p.object()), coreIndex(p.coreIndex()), notifyIndex(p.property().notifySignalIndex()) { } @@ -357,7 +357,7 @@ bool QmlEnginePrivate::loadCache(QmlBasicScriptNodeCache &cache, const QString & cache.type = QmlBasicScriptNodeCache::Variant; cache.context = context; cache.contextIndex = *iter; - capturedProperties << CapturedProperty(context->q_ptr, *iter + context->notifyIndex); + capturedProperties << CapturedProperty(context->q_ptr, -1, *iter + context->notifyIndex); return true; } @@ -1008,7 +1008,7 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object, } else { rv = scriptEngine->newVariant(value); } - engine->d_func()->capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, index + bindContext->d_func()->notifyIndex); + engine->d_func()->capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, -1, index + bindContext->d_func()->notifyIndex); return rv; } default: diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index e91c4ee..25f6edf 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -103,11 +103,12 @@ public: QScriptValue propertyObject(const QScriptString &propName, QObject *, uint id = 0); struct CapturedProperty { - CapturedProperty(QObject *o, int n) - : object(o), notifyIndex(n) {} + CapturedProperty(QObject *o, int c, int n) + : object(o), coreIndex(c), notifyIndex(n) {} CapturedProperty(const QmlMetaProperty &); QObject *object; + int coreIndex; int notifyIndex; }; QPODVector capturedProperties; diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 1e7b149..84352b8 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -357,21 +357,41 @@ QVariant QmlExpression::value() QMetaObject::connect(prop.object, prop.notifyIndex, d->proxy, changedIndex); } else { - // ### FIXME - //QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object->metaObject()->className()) + QLatin1String("].") + prop.name; - //log.addWarning(warn); + const QMetaObject *metaObj = prop.object->metaObject(); + QMetaProperty metaProp = + metaObj->property(prop.coreIndex); + + QString warn = QLatin1String("Expression depends on non-NOTIFYable property: ") + + QLatin1String(metaObj->className()) + + QLatin1String("::") + + QLatin1String(metaProp.name()); + log.addWarning(warn); } } d->addLog(log); } else { + bool outputWarningHeader = false; for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) { const QmlEnginePrivate::CapturedProperty &prop = ep->capturedProperties.at(ii); - if (prop.notifyIndex != -1) + if (prop.notifyIndex != -1) { QMetaObject::connect(prop.object, prop.notifyIndex, d->proxy, changedIndex); + } else { + if (!outputWarningHeader) { + outputWarningHeader = true; + qWarning() << "QmlExpression: Expression" << expression() << "depends on non-NOTIFYable properties:"; + } + + const QMetaObject *metaObj = prop.object->metaObject(); + QMetaProperty metaProp = + metaObj->property(prop.coreIndex); + + qWarning().nospace() << " " << metaObj->className() + << "::" << metaProp.name(); + } } } } else { diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 90acd72..ee24074 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -882,7 +882,8 @@ bool QmlMetaProperty::hasChangedNotifier() const */ bool QmlMetaProperty::needsChangedNotifier() const { - return type() & Property && !(type() & Attached); + return type() & Property && !(type() & Attached) && + !property().isConstant(); } /*! -- cgit v0.12