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>
This commit is contained in:
Christian Kamm
2011-09-05 13:35:16 +02:00
parent b8b8f167b1
commit 312d43f215
3 changed files with 48 additions and 50 deletions

View File

@@ -269,46 +269,42 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
return objectValue; return objectValue;
} }
const Value *value = valueOwner()->undefinedValue();
if (typeName == QLatin1String("QByteArray") if (typeName == QLatin1String("QByteArray")
|| typeName == QLatin1String("string") || typeName == QLatin1String("string")
|| typeName == QLatin1String("QString")) { || typeName == QLatin1String("QString")) {
value = valueOwner()->stringValue(); return valueOwner()->stringValue();
} else if (typeName == QLatin1String("QUrl")) { } else if (typeName == QLatin1String("QUrl")) {
value = valueOwner()->urlValue(); return valueOwner()->urlValue();
} else if (typeName == QLatin1String("bool")) { } else if (typeName == QLatin1String("bool")) {
value = valueOwner()->booleanValue(); return valueOwner()->booleanValue();
} else if (typeName == QLatin1String("int") } else if (typeName == QLatin1String("int")
|| typeName == QLatin1String("long")) { || typeName == QLatin1String("long")) {
value = valueOwner()->intValue(); return valueOwner()->intValue();
} else if (typeName == QLatin1String("float") } else if (typeName == QLatin1String("float")
|| typeName == QLatin1String("double") || typeName == QLatin1String("double")
|| typeName == QLatin1String("qreal")) { || typeName == QLatin1String("qreal")) {
// ### Review: more types here? // ### Review: more types here?
value = valueOwner()->realValue(); return valueOwner()->realValue();
} else if (typeName == QLatin1String("QFont")) { } else if (typeName == QLatin1String("QFont")) {
value = valueOwner()->qmlFontObject(); return valueOwner()->qmlFontObject();
} else if (typeName == QLatin1String("QPoint") } else if (typeName == QLatin1String("QPoint")
|| typeName == QLatin1String("QPointF") || typeName == QLatin1String("QPointF")
|| typeName == QLatin1String("QVector2D")) { || typeName == QLatin1String("QVector2D")) {
value = valueOwner()->qmlPointObject(); return valueOwner()->qmlPointObject();
} else if (typeName == QLatin1String("QSize") } else if (typeName == QLatin1String("QSize")
|| typeName == QLatin1String("QSizeF")) { || typeName == QLatin1String("QSizeF")) {
value = valueOwner()->qmlSizeObject(); return valueOwner()->qmlSizeObject();
} else if (typeName == QLatin1String("QRect") } else if (typeName == QLatin1String("QRect")
|| typeName == QLatin1String("QRectF")) { || typeName == QLatin1String("QRectF")) {
value = valueOwner()->qmlRectObject(); return valueOwner()->qmlRectObject();
} else if (typeName == QLatin1String("QVector3D")) { } else if (typeName == QLatin1String("QVector3D")) {
value = valueOwner()->qmlVector3DObject(); return valueOwner()->qmlVector3DObject();
} else if (typeName == QLatin1String("QColor")) { } else if (typeName == QLatin1String("QColor")) {
value = valueOwner()->colorValue(); return valueOwner()->colorValue();
} else if (typeName == QLatin1String("QDeclarativeAnchorLine")) { } else if (typeName == QLatin1String("QDeclarativeAnchorLine")) {
value = valueOwner()->anchorLineValue(); return valueOwner()->anchorLineValue();
} }
if (value)
return value;
// might be an enum // might be an enum
const QmlObjectValue *base = this; const QmlObjectValue *base = this;
const QStringList components = typeName.split(QLatin1String("::")); const QStringList components = typeName.split(QLatin1String("::"));
@@ -317,10 +313,11 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
typeName = components.last(); typeName = components.last();
} }
if (base) { 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 const QmlObjectValue *QmlObjectValue::prototype() const
@@ -377,18 +374,34 @@ bool QmlObjectValue::isListProperty(const QString &propertyName) const
return false; 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); for (const QmlObjectValue *it = this; it; it = it->prototype()) {
if (index == -1) FakeMetaObject::ConstPtr iter = it->_metaObject;
return FakeMetaEnum(); const int index = iter->enumeratorIndex(typeName);
if (index != -1) {
return _metaObject->enumerator(index); 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 bool QmlObjectValue::isWritable(const QString &propertyName) const

View File

@@ -441,8 +441,8 @@ public:
bool hasProperty(const QString &typeName) const; bool hasProperty(const QString &typeName) const;
bool hasChildInPackage() const; bool hasChildInPackage() const;
LanguageUtils::FakeMetaEnum getEnum(const QString &typeName) const; LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const QmlObjectValue **foundInScope = 0) const;
const QmlEnumValue *getEnumValue(const QString &typeName) const; const QmlEnumValue *getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope = 0) const;
protected: protected:
const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method, const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method,
QString *methodName) const; QString *methodName) const;

View File

@@ -667,18 +667,8 @@ bool NodeMetaInfoPrivate::isPropertyEnum(const QString &propertyName) const
return false; return false;
} }
QList<const ObjectValue *> objects; const QmlObjectValue *qmlObjectValue = getNearestQmlObjectValue();
objects = PrototypeIterator(getNearestQmlObjectValue(), context()).all(); return qmlObjectValue->getEnum(propertyType(propertyName)).isValid();
//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;
} }
QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) const QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) const
@@ -703,16 +693,11 @@ QString NodeMetaInfoPrivate::propertyEnumScope(const QString &propertyName) cons
return QString(); return QString();
} }
QList<const ObjectValue *> objects; const QmlObjectValue *qmlObjectValue = getNearestQmlObjectValue();
objects = PrototypeIterator(getNearestQmlObjectValue(), context()).all(); const QmlObjectValue *definedIn = 0;
qmlObjectValue->getEnum(propertyType(propertyName), &definedIn);
//We have to run the prototype chain if (definedIn)
foreach (const ObjectValue *ov, objects) { return definedIn->className();
if (const QmlObjectValue * qmlValue = dynamic_cast<const QmlObjectValue *>(ov)) {
if (qmlValue->getEnum(propertyType(propertyName)).isValid())
return qmlValue->className();
}
}
return QString(); return QString();
} }