aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-09-14 21:23:32 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-09-21 19:59:27 +0000
commitb7738beda651c2927e1a9d58c592148b1dc99576 (patch)
tree55d62516410088f22885ff551d57fff5ae50a5bc /src
parentba7edffda3f360955825c3ef886ec232c0b2022b (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.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp10
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h1
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp2
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h6
-rw-r--r--src/qml/qml/qqmlmetatype.cpp30
-rw-r--r--src/qml/qml/qqmlmetatype_p.h8
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp2
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();