diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-09-14 21:23:32 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-09-21 19:59:27 +0000 |
commit | b7738beda651c2927e1a9d58c592148b1dc99576 (patch) | |
tree | 55d62516410088f22885ff551d57fff5ae50a5bc /src | |
parent | ba7edffda3f360955825c3ef886ec232c0b2022b (diff) |
Make QML composite types inherit enums
Problem: in Qt Quick Controls 2, enums declared in the abstract
C++ base types were not accessible with the concrete QML type name,
but had to be referenced using the base type name:
Slider {
snapMode: AbstractSlider.SnapOnRelease
}
Solution: this change resolves the C++ base type and creates the
missing link between the composite type and its base type's meta-
object. This allows referencing enums using the concrete/composite
QML type name:
Slider {
snapMode: Slider.SnapOnRelease
}
Change-Id: Icefdec91b012b12728367fd54b4d16796233ee12
Task-number: QTBUG-43582
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlcustomparser.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlcustomparser_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 30 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 2 |
9 files changed, 48 insertions, 15 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 4b1e3601dc..7b0d4240c4 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1590,7 +1590,7 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe if (member->name->constData()->isUpper()) { bool ok = false; - int value = type->enumValue(*member->name, &ok); + int value = type->enumValue(qmlEngine, *member->name, &ok); if (ok) { member->setEnumValue(value); resolver->clear(); diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 7f62446c22..e36ba76326 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1163,8 +1163,6 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, if (!type && typeName != QLatin1String("Qt")) return true; - if (type && type->isComposite()) //No enums on composite (or composite singleton) types - return true; int value = 0; bool ok = false; @@ -1182,7 +1180,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, } else { // Otherwise we have to search the whole type if (type) { - value = type->enumValue(QHashedStringRef(enumValue), &ok); + value = type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok); } else { QByteArray enumName = enumValue.toUtf8(); const QMetaObject *metaObject = StaticQtMetaObject::get(); @@ -1210,7 +1208,9 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e if (scope != QLatin1String("Qt")) { QQmlType *type = 0; imports->resolveType(scope, &type, 0, 0, 0); - return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; + if (!type) + return -1; + return type ? type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; } const QMetaObject *mo = StaticQtMetaObject::get(); @@ -1988,9 +1988,11 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD if (customParser && !customBindings.isEmpty()) { customParser->clearErrors(); customParser->validator = this; + customParser->engine = enginePrivate; customParser->imports = compiler->imports(); customParser->verifyBindings(qmlUnit, customBindings); customParser->validator = 0; + customParser->engine = 0; customParser->imports = (QQmlImports*)0; customParserBindingsPerObject->insert(objectIndex, customParserBindings); const QList<QQmlError> parserErrors = customParser->errors(); diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index cbc68280b7..09ef7aad67 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -273,6 +273,7 @@ public: bool validate(); const QQmlImports &imports() const; + QQmlEnginePrivate *engine() const { return enginePrivate; } private: bool validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty = false) const; diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index ec88ee015a..517f8d42ed 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -141,7 +141,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const type = result.type; } - return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; + return type ? type->enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; } const QMetaObject *mo = StaticQtMetaObject::get(); diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index dd461ba299..8bdc73fab1 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE class QQmlCompiledData; class QQmlPropertyValidator; +class QQmlEnginePrivate; class Q_QML_PRIVATE_EXPORT QQmlCustomParser { @@ -67,8 +68,8 @@ public: }; Q_DECLARE_FLAGS(Flags, Flag) - QQmlCustomParser() : validator(0), m_flags(NoFlag) {} - QQmlCustomParser(Flags f) : validator(0), m_flags(f) {} + QQmlCustomParser() : engine(0), validator(0), m_flags(NoFlag) {} + QQmlCustomParser(Flags f) : engine(0), validator(0), m_flags(f) {} virtual ~QQmlCustomParser() {} void clearErrors(); @@ -92,6 +93,7 @@ protected: private: QList<QQmlError> exceptions; + QQmlEnginePrivate *engine; const QQmlPropertyValidator *validator; Flags m_flags; QBiPointer<const QQmlImports, QQmlTypeNameCache> imports; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index f0debb8e59..b173bc8bec 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -38,6 +38,7 @@ #include <private/qqmlcustomparser_p.h> #include <private/qhashedstring_p.h> #include <private/qqmlimport_p.h> +#include <private/qqmlcompiler_p.h> #include <QtCore/qdebug.h> #include <QtCore/qstringlist.h> @@ -473,6 +474,23 @@ QQmlType *QQmlType::superType() const return d->superType; } +int QQmlType::resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + if (!engine) + return -1; + QQmlTypeData *td = engine->typeLoader.getType(sourceUrl()); + if (!td || !td->isComplete()) + return -1; + QQmlCompiledData *cd = td->compiledData(); + const QMetaObject *mo = cd->rootPropertyCache->firstCppMetaObject(); + QQmlType *type = QQmlMetaType::qmlType(mo); + if (!type) + return -1; + return type->enumValue(engine, name, ok); +} + static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd) { @@ -907,9 +925,11 @@ QUrl QQmlType::sourceUrl() const return QUrl(); } -int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const +int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const { Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeEnumValue(engine, name.toString(), ok); *ok = true; d->initEnums(); @@ -922,9 +942,11 @@ int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const return -1; } -int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const +int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name, bool *ok) const { Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeEnumValue(engine, name.toUtf16(), ok); *ok = true; d->initEnums(); @@ -937,9 +959,11 @@ int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const return -1; } -int QQmlType::enumValue(const QV4::String *name, bool *ok) const +int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const { Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeEnumValue(engine, name->toQString(), ok); *ok = true; d->initEnums(); diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 61a6567f1d..08f19bcf09 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE class QQmlType; class QQmlEngine; +class QQmlEnginePrivate; class QQmlCustomParser; class QQmlTypePrivate; class QQmlTypeModule; @@ -204,11 +205,12 @@ public: QUrl sourceUrl() const; - int enumValue(const QHashedStringRef &, bool *ok) const; - int enumValue(const QHashedCStringRef &, bool *ok) const; - int enumValue(const QV4::String *, bool *ok) const; + int enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &, bool *ok) const; + int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const; + int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; private: QQmlType *superType() const; + int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; friend class QQmlTypePrivate; friend struct QQmlMetaTypeData; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index f371a369a1..171fa048ce 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1101,6 +1101,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (customParser) { QHash<int, QBitArray>::ConstIterator customParserBindings = compiledData->customParserBindings.constFind(index); if (customParserBindings != compiledData->customParserBindings.constEnd()) { + customParser->engine = QQmlEnginePrivate::get(engine); customParser->imports = compiledData->importCache; QList<const QV4::CompiledData::Binding *> bindings; @@ -1110,6 +1111,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo bindings << obj->bindingTable() + i; customParser->applyBindings(instance, compiledData, bindings); + customParser->engine = 0; customParser->imports = (QQmlTypeNameCache*)0; bindingsToSkip = *customParserBindings; } diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 1d72b2da0d..1145f1b64f 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -182,7 +182,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope if (name->startsWithUpper()) { bool ok = false; - int value = type->enumValue(name, &ok); + int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); if (ok) return QV4::Primitive::fromInt32(value).asReturnedValue(); |