From 312d43f215e96397c14ecbb52beb593adbffb7e5 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Mon, 5 Sep 2011 13:35:16 +0200 Subject: [PATCH] QmlJS: Fix lookup for enums. * Also look for enums in prototypes. * Report back which QmlObjectValue had the enum. * Fix a bug where enum lookup was always skipped. Change-Id: I9c9fd8f8cf9bd8cc5f1bb5688fef5786267cd794 Reviewed-on: http://codereview.qt.nokia.com/4192 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com> --- src/libs/qmljs/qmljsinterpreter.cpp | 65 +++++++++++-------- src/libs/qmljs/qmljsinterpreter.h | 4 +- .../designercore/metainfo/nodemetainfo.cpp | 29 ++------- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 2f1d5334767..a8cfb6e9748 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -269,46 +269,42 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const return objectValue; } - const Value *value = valueOwner()->undefinedValue(); if (typeName == QLatin1String("QByteArray") || typeName == QLatin1String("string") || typeName == QLatin1String("QString")) { - value = valueOwner()->stringValue(); + return valueOwner()->stringValue(); } else if (typeName == QLatin1String("QUrl")) { - value = valueOwner()->urlValue(); + return valueOwner()->urlValue(); } else if (typeName == QLatin1String("bool")) { - value = valueOwner()->booleanValue(); + return valueOwner()->booleanValue(); } else if (typeName == QLatin1String("int") || typeName == QLatin1String("long")) { - value = valueOwner()->intValue(); + return valueOwner()->intValue(); } else if (typeName == QLatin1String("float") || typeName == QLatin1String("double") || typeName == QLatin1String("qreal")) { // ### Review: more types here? - value = valueOwner()->realValue(); + return valueOwner()->realValue(); } else if (typeName == QLatin1String("QFont")) { - value = valueOwner()->qmlFontObject(); + return valueOwner()->qmlFontObject(); } else if (typeName == QLatin1String("QPoint") || typeName == QLatin1String("QPointF") || typeName == QLatin1String("QVector2D")) { - value = valueOwner()->qmlPointObject(); + return valueOwner()->qmlPointObject(); } else if (typeName == QLatin1String("QSize") || typeName == QLatin1String("QSizeF")) { - value = valueOwner()->qmlSizeObject(); + return valueOwner()->qmlSizeObject(); } else if (typeName == QLatin1String("QRect") || typeName == QLatin1String("QRectF")) { - value = valueOwner()->qmlRectObject(); + return valueOwner()->qmlRectObject(); } else if (typeName == QLatin1String("QVector3D")) { - value = valueOwner()->qmlVector3DObject(); + return valueOwner()->qmlVector3DObject(); } else if (typeName == QLatin1String("QColor")) { - value = valueOwner()->colorValue(); + return valueOwner()->colorValue(); } else if (typeName == QLatin1String("QDeclarativeAnchorLine")) { - value = valueOwner()->anchorLineValue(); + return valueOwner()->anchorLineValue(); } - if (value) - return value; - // might be an enum const QmlObjectValue *base = this; const QStringList components = typeName.split(QLatin1String("::")); @@ -317,10 +313,11 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const typeName = components.last(); } if (base) { - value = base->getEnumValue(typeName); + if (const QmlEnumValue *value = base->getEnumValue(typeName)) + return value; } - return value; + return valueOwner()->undefinedValue(); } const QmlObjectValue *QmlObjectValue::prototype() const @@ -377,18 +374,34 @@ bool QmlObjectValue::isListProperty(const QString &propertyName) const return false; } -FakeMetaEnum QmlObjectValue::getEnum(const QString &typeName) const +FakeMetaEnum QmlObjectValue::getEnum(const QString &typeName, const QmlObjectValue **foundInScope) const { - const int index = _metaObject->enumeratorIndex(typeName); - if (index == -1) - return FakeMetaEnum(); - - return _metaObject->enumerator(index); + for (const QmlObjectValue *it = this; it; it = it->prototype()) { + FakeMetaObject::ConstPtr iter = it->_metaObject; + const int index = iter->enumeratorIndex(typeName); + if (index != -1) { + if (foundInScope) + *foundInScope = it; + return iter->enumerator(index); + } + } + if (foundInScope) + *foundInScope = 0; + return FakeMetaEnum(); } -const QmlEnumValue *QmlObjectValue::getEnumValue(const QString &typeName) const +const QmlEnumValue *QmlObjectValue::getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope) const { - return _enums.value(typeName, 0); + for (const QmlObjectValue *it = this; it; it = it->prototype()) { + if (const QmlEnumValue *e = it->_enums.value(typeName)) { + if (foundInScope) + *foundInScope = it; + return e; + } + } + if (foundInScope) + *foundInScope = 0; + return 0; } bool QmlObjectValue::isWritable(const QString &propertyName) const diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index ab9a53b6652..cc7999739b9 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -441,8 +441,8 @@ public: bool hasProperty(const QString &typeName) const; bool hasChildInPackage() const; - LanguageUtils::FakeMetaEnum getEnum(const QString &typeName) const; - const QmlEnumValue *getEnumValue(const QString &typeName) const; + LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; + const QmlEnumValue *getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; protected: const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method, QString *methodName) const; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 5f348bb2046..eabd0bb5c42 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -667,18 +667,8 @@ bool NodeMetaInfoPrivate::isPropertyEnum(const QString &propertyName) const return false; } - QList<const ObjectValue *> objects; - objects = PrototypeIterator(getNearestQmlObjectValue(), context()).all(); - - //We have to run the prototype chain - foreach (const ObjectValue *ov, objects) { - if (const QmlObjectValue * qmlValue = dynamic_cast<const QmlObjectValue *>(ov)) { - if (qmlValue->getEnum(propertyType(propertyName)).isValid()) - return true; - } - } - - return false; + const QmlObjectValue *qmlObjectValue = getNearestQmlObjectValue(); + return qmlObjectValue->getEnum(propertyType(propertyName)).isValid(); } QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) const @@ -703,16 +693,11 @@ QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) cons return QString(); } - QList<const ObjectValue *> objects; - objects = PrototypeIterator(getNearestQmlObjectValue(), context()).all(); - - //We have to run the prototype chain - foreach (const ObjectValue *ov, objects) { - if (const QmlObjectValue * qmlValue = dynamic_cast<const QmlObjectValue *>(ov)) { - if (qmlValue->getEnum(propertyType(propertyName)).isValid()) - return qmlValue->className(); - } - } + const QmlObjectValue *qmlObjectValue = getNearestQmlObjectValue(); + const QmlObjectValue *definedIn = 0; + qmlObjectValue->getEnum(propertyType(propertyName), &definedIn); + if (definedIn) + return definedIn->className(); return QString(); } -- GitLab