aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-08-16 14:56:31 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2017-08-18 11:46:11 +0200
commit43a615e309e70978711f5c2c56a9881876b96349 (patch)
treea8d0899cbc1e7775f52056fc56db58b2fcf305de
parent6034d89bdd907d4795c19e8ac752f4eb51c82a94 (diff)
parent3513995d8fde7f002977275463fcea1b86f4a693 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/qml/compiler/qqmltypecompiler.cpp src/qml/jsruntime/qv4qmlcontext.cpp src/qml/jsruntime/qv4qobjectwrapper.cpp src/qml/qml/qqmlcustomparser.cpp src/qml/qml/qqmlimport.cpp src/qml/qml/qqmlimport_p.h src/qml/qml/qqmlmetatype.cpp src/qml/qml/qqmlmetatype_p.h src/qml/qml/qqmltypenamecache.cpp src/qml/qml/qqmltypenamecache_p.h src/qml/qml/qqmltypewrapper.cpp src/qml/qml/qqmltypewrapper_p.h src/qml/qml/qqmlvmemetaobject.cpp src/qml/util/qqmladaptormodel.cpp Change-Id: Ic959d03e6f9c328fb02710d9abbb0f27cddde131
-rw-r--r--examples/quick/demos/maroon/content/SoundEffect.qml2
-rw-r--r--examples/quick/scenegraph/sgengine/window.cpp2
-rw-r--r--src/imports/testlib/main.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp5
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp53
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h34
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp22
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp57
-rw-r--r--src/qml/compiler/qv4compileddata.cpp35
-rw-r--r--src/qml/compiler/qv4compileddata_p.h5
-rw-r--r--src/qml/compiler/qv4jsir_p.h15
-rw-r--r--src/qml/jsapi/qjsengine.cpp19
-rw-r--r--src/qml/jsapi/qjsengine_p.h17
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qml/jsruntime/qv4function.cpp7
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp5
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp14
-rw-r--r--src/qml/qml/qqmlengine.cpp177
-rw-r--r--src/qml/qml/qqmlengine_p.h19
-rw-r--r--src/qml/qml/qqmlimport.cpp63
-rw-r--r--src/qml/qml/qqmlimport_p.h12
-rw-r--r--src/qml/qml/qqmllist.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp1045
-rw-r--r--src/qml/qml/qqmlmetatype_p.h111
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp36
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp2
-rw-r--r--src/qml/qml/qqmlproperty.cpp23
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp54
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h21
-rw-r--r--src/qml/qml/qqmltypeloader.cpp89
-rw-r--r--src/qml/qml/qqmltypeloader_p.h8
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp40
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h79
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp94
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h15
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp85
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h3
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp6
-rw-r--r--src/qml/util/qqmladaptormodel.cpp9
-rw-r--r--src/qml/util/qqmladaptormodel_p.h5
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp2
-rw-r--r--src/quick/designer/qquickdesignersupportitems.cpp41
-rw-r--r--src/quick/designer/qquickdesignersupportmetainfo.cpp4
-rw-r--r--src/quick/doc/src/qtquick.qdoc8
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquickitemview_p_p.h1
-rw-r--r--src/quick/items/qquicklistview.cpp12
-rw-r--r--src/quick/items/qquicktextinput.cpp5
m---------tests/auto/qml/ecmascripttests/test2620
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp6
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp104
-rw-r--r--tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp18
-rw-r--r--tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp24
-rw-r--r--tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml31
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp24
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp75
-rw-r--r--tests/auto/quick/qquickwindow/data/windowattached.qml1
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp102
-rw-r--r--tests/benchmarks/qml/creation/tst_creation.cpp4
-rw-r--r--tools/qmlplugindump/main.cpp124
62 files changed, 1665 insertions, 1231 deletions
diff --git a/examples/quick/demos/maroon/content/SoundEffect.qml b/examples/quick/demos/maroon/content/SoundEffect.qml
index 136b33aa9b..4b723170a0 100644
--- a/examples/quick/demos/maroon/content/SoundEffect.qml
+++ b/examples/quick/demos/maroon/content/SoundEffect.qml
@@ -42,7 +42,7 @@ import QtQuick 2.0
//Proxies a SoundEffect if QtMultimedia is installed
Item {
id: container
- property QtObject effect: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{ source: '" + container.source + "'; muted: !Qt.application.active }", container);
+ property QtObject effect: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{ source: '" + container.source + "'; muted: Qt.application.state != Qt.ApplicationActive }", container);
property url source: ""
onSourceChanged: if (effect != null) effect.source = source;
function play() {
diff --git a/examples/quick/scenegraph/sgengine/window.cpp b/examples/quick/scenegraph/sgengine/window.cpp
index 759bbf1fcd..a73d9bf755 100644
--- a/examples/quick/scenegraph/sgengine/window.cpp
+++ b/examples/quick/scenegraph/sgengine/window.cpp
@@ -173,7 +173,7 @@ void Window::addItems()
QSGTexture *tex = textures[i%2];
QPointF fromPos(-tex->textureSize().width(), qrand() / float(RAND_MAX) * (height() - tex->textureSize().height()));
QPointF toPos(width(), qrand() / float(RAND_MAX) * height() * 1.5 - height() * 0.25);
- m_items.append(QSharedPointer<Item>(new Item(m_sgRootNode.data(), tex, fromPos, toPos)));
+ m_items.append(QSharedPointer<Item>::create(m_sgRootNode.data(), tex, fromPos, toPos));
}
update();
}
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 3c28000e35..fc013d5afc 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -91,14 +91,14 @@ public Q_SLOTS:
{
QString name(v.typeName());
if (v.canConvert<QObject*>()) {
- QQmlType *type = 0;
+ QQmlType type;
const QMetaObject *mo = v.value<QObject*>()->metaObject();
- while (!type && mo) {
+ while (!type.isValid() && mo) {
type = QQmlMetaType::qmlType(mo);
mo = mo->superClass();
}
- if (type) {
- name = type->qmlTypeName();
+ if (type.isValid()) {
+ name = type.qmlTypeName();
}
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index f0bb4de016..3d08c4c809 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -695,8 +695,9 @@ bool QQmlEngineDebugServiceImpl::resetBinding(int objectId, const QString &prope
property.reset();
} else {
// overwrite with default value
- if (QQmlType *objType = QQmlMetaType::qmlType(object->metaObject())) {
- if (QObject *emptyObject = objType->create()) {
+ QQmlType objType = QQmlMetaType::qmlType(object->metaObject());
+ if (objType.isValid()) {
+ if (QObject *emptyObject = objType.create()) {
if (emptyObject->property(parentProperty).isValid()) {
QVariant defaultValue = QQmlProperty(emptyObject, propertyName).read();
if (defaultValue.isValid()) {
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index e05c38e14a..b58920d812 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1777,7 +1777,7 @@ enum MetaObjectResolverFlags {
};
static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject);
-static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlType *qmlType, int index);
+static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index);
static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
const QV4::IR::MemberExpressionResolver *resolver,
@@ -1785,16 +1785,16 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
{
QV4::IR::Type result = QV4::IR::VarType;
- QQmlType *type = static_cast<QQmlType*>(resolver->data);
+ QQmlType type = resolver->qmlType;
if (member->name->constData()->isUpper()) {
bool ok = false;
- int value = type->enumValue(qmlEngine, *member->name, &ok);
+ int value = type.enumValue(qmlEngine, *member->name, &ok);
if (ok) {
member->setEnumValue(value);
return QV4::IR::SInt32Type;
} else {
- int index = type->scopedEnumIndex(qmlEngine, *member->name, &ok);
+ int index = type.scopedEnumIndex(qmlEngine, *member->name, &ok);
if (ok) {
auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
newResolver->owner = resolver->owner;
@@ -1804,8 +1804,8 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
}
}
- if (type->isCompositeSingleton()) {
- QQmlRefPointer<QQmlTypeData> tdata = qmlEngine->typeLoader.getType(type->singletonInstanceInfo()->url);
+ if (type.isCompositeSingleton()) {
+ QQmlRefPointer<QQmlTypeData> tdata = qmlEngine->typeLoader.getType(type.singletonInstanceInfo()->url);
Q_ASSERT(tdata);
tdata->release(); // Decrease the reference count added from QQmlTypeLoader::getType()
// When a singleton tries to reference itself, it may not be complete yet.
@@ -1816,8 +1816,8 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
newResolver->flags |= AllPropertiesAreFinal;
return newResolver->resolveMember(qmlEngine, newResolver, member);
}
- } else if (type->isSingleton()) {
- const QMetaObject *singletonMeta = type->singletonInstanceInfo()->instanceMetaObject;
+ } else if (type.isSingleton()) {
+ const QMetaObject *singletonMeta = type.singletonInstanceInfo()->instanceMetaObject;
if (singletonMeta) { // QJSValue-based singletons cannot be accelerated
auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
newResolver->owner = resolver->owner;
@@ -1842,13 +1842,13 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
return result;
}
-static void initQmlTypeResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlType *qmlType)
+static void initQmlTypeResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType)
{
Q_ASSERT(resolver);
resolver->resolveMember = &resolveQmlType;
- resolver->data = qmlType;
- resolver->extraData = 0;
+ resolver->qmlType = qmlType;
+ resolver->typenameCache = 0;
resolver->flags = 0;
}
@@ -1857,8 +1857,8 @@ static QV4::IR::DiscoveredType resolveImportNamespace(
QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
- QQmlTypeNameCache *typeNamespace = static_cast<QQmlTypeNameCache*>(resolver->extraData);
- void *importNamespace = resolver->data;
+ QQmlTypeNameCache *typeNamespace = resolver->typenameCache;
+ const QQmlImportRef *importNamespace = resolver->import;
QQmlTypeNameCache::Result r = typeNamespace->query(*member->name, importNamespace);
if (r.isValid()) {
@@ -1866,11 +1866,11 @@ static QV4::IR::DiscoveredType resolveImportNamespace(
if (r.scriptIndex != -1) {
// TODO: remember the index and replace with subscript later.
result = QV4::IR::VarType;
- } else if (r.type) {
+ } else if (r.type.isValid()) {
// TODO: Propagate singleton information, so that it is loaded
// through the singleton getter in the run-time. Until then we
// can't accelerate access :(
- if (!r.type->isSingleton()) {
+ if (!r.type.isSingleton()) {
auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
newResolver->owner = resolver->owner;
initQmlTypeResolver(newResolver, r.type);
@@ -1885,11 +1885,11 @@ static QV4::IR::DiscoveredType resolveImportNamespace(
}
static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver,
- QQmlTypeNameCache *imports, const void *importNamespace)
+ QQmlTypeNameCache *imports, const QQmlImportRef *importNamespace)
{
resolver->resolveMember = &resolveImportNamespace;
- resolver->data = const_cast<void*>(importNamespace);
- resolver->extraData = imports;
+ resolver->import = importNamespace;
+ resolver->typenameCache = imports;
resolver->flags = 0;
}
@@ -1898,7 +1898,7 @@ static QV4::IR::DiscoveredType resolveMetaObjectProperty(
QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
- QQmlPropertyCache *metaObject = static_cast<QQmlPropertyCache*>(resolver->data);
+ QQmlPropertyCache *metaObject = resolver->propertyCache;
if (member->name->constData()->isUpper() && (resolver->flags & LookupsIncludeEnums)) {
const QMetaObject *mo = metaObject->createMetaObject();
@@ -1980,7 +1980,7 @@ static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver,
Q_ASSERT(resolver);
resolver->resolveMember = &resolveMetaObjectProperty;
- resolver->data = metaObject;
+ resolver->propertyCache = metaObject;
resolver->flags = 0;
}
@@ -1991,24 +1991,23 @@ static QV4::IR::DiscoveredType resolveScopedEnum(QQmlEnginePrivate *qmlEngine,
if (!member->name->constData()->isUpper())
return QV4::IR::VarType;
- QQmlType *type = static_cast<QQmlType*>(resolver->data);
+ QQmlType type = resolver->qmlType;
int index = resolver->flags;
bool ok = false;
- int value = type->scopedEnumValue(qmlEngine, index, *member->name, &ok);
+ int value = type.scopedEnumValue(qmlEngine, index, *member->name, &ok);
if (!ok)
return QV4::IR::VarType;
member->setEnumValue(value);
return QV4::IR::SInt32Type;
}
-static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlType *qmlType, int index)
+static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index)
{
Q_ASSERT(resolver);
resolver->resolveMember = &resolveScopedEnum;
- resolver->data = qmlType;
- resolver->extraData = 0;
+ resolver->qmlType = qmlType;
resolver->flags = index;
}
@@ -2077,10 +2076,10 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (r.scriptIndex != -1) {
return _block->SUBSCRIPT(_block->TEMP(_importedScriptsTemp),
_block->CONST(QV4::IR::SInt32Type, r.scriptIndex));
- } else if (r.type) {
+ } else if (r.type.isValid()) {
QV4::IR::Name *typeName = _block->NAME(name, line, col);
// Make sure the run-time loads this through the more efficient singleton getter.
- typeName->qmlSingleton = r.type->isCompositeSingleton();
+ typeName->qmlSingleton = r.type.isCompositeSingleton();
typeName->freeOfSideEffects = true;
QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
_block->MOVE(result, typeName);
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 5901e4e13e..b33deac045 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -211,12 +211,12 @@ inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCac
} else if (context.instantiatingBinding && context.instantiatingBinding->isAttachedProperty()) {
auto *typeRef = objectContainer->resolvedTypes.value(context.instantiatingBinding->propertyNameIndex);
Q_ASSERT(typeRef);
- QQmlType *qmltype = typeRef->type;
- if (!qmltype) {
+ QQmlType qmltype = typeRef->type;
+ if (!qmltype.isValid()) {
QString propertyName = stringAt(context.instantiatingBinding->propertyNameIndex);
if (imports->resolveType(propertyName, &qmltype, 0, 0, 0)) {
- if (qmltype->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
+ if (qmltype.isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -228,7 +228,7 @@ inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCac
}
}
- const QMetaObject *attachedMo = qmltype ? qmltype->attachedPropertiesType(enginePrivate) : 0;
+ const QMetaObject *attachedMo = qmltype.attachedPropertiesType(enginePrivate);
if (!attachedMo) {
*error = QQmlCompileError(context.instantiatingBinding->location, QQmlPropertyCacheCreatorBase::tr("Non-existent attached object"));
return nullptr;
@@ -410,12 +410,12 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
// lazily resolved type
Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
const QString customTypeName = stringAt(param->customTypeNameIndex);
- QQmlType *qmltype = 0;
+ QQmlType qmltype;
if (!imports->resolveType(customTypeName, &qmltype, 0, 0, 0))
return QQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Invalid signal parameter type: %1").arg(customTypeName));
- if (qmltype->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
+ if (qmltype.isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -425,7 +425,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
tdata->release();
} else {
- paramTypes[i + 1] = qmltype->typeId();
+ paramTypes[i + 1] = qmltype.typeId();
}
}
}
@@ -490,14 +490,14 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
p->type == QV4::CompiledData::Property::Custom);
- QQmlType *qmltype = 0;
+ QQmlType qmltype;
if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0)) {
return QQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
- Q_ASSERT(qmltype);
- if (qmltype->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
+ Q_ASSERT(qmltype.isValid());
+ if (qmltype.isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -512,9 +512,9 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
tdata->release();
} else {
if (p->type == QV4::CompiledData::Property::Custom) {
- propertyType = qmltype->typeId();
+ propertyType = qmltype.typeId();
} else {
- propertyType = qmltype->qListTypeId();
+ propertyType = qmltype.qListTypeId();
}
}
@@ -690,8 +690,8 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
auto *typeRef = objectContainer->resolvedTypes.value(targetObject.inheritedTypeNameIndex);
Q_ASSERT(typeRef);
- if (typeRef->type)
- *type = typeRef->type->typeId();
+ if (typeRef->type.isValid())
+ *type = typeRef->type.typeId();
else
*type = typeRef->compilationUnit->metaTypeId;
diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp
index 383c20239f..4ac7aad553 100644
--- a/src/qml/compiler/qqmlpropertyvalidator.cpp
+++ b/src/qml/compiler/qqmlpropertyvalidator.cpp
@@ -106,8 +106,8 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
QQmlCustomParser *customParser = 0;
if (auto typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (typeRef->type)
- customParser = typeRef->type->customParser();
+ if (typeRef->type.isValid())
+ customParser = typeRef->type.customParser();
}
QList<const QV4::CompiledData::Binding*> customBindings;
@@ -178,8 +178,8 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
if (notInRevision) {
QString typeName = stringAt(obj->inheritedTypeNameIndex);
auto *objectType = resolvedTypes.value(obj->inheritedTypeNameIndex);
- if (objectType && objectType->type) {
- return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type->module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
+ if (objectType && objectType->type.isValid()) {
+ return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type.module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
} else {
return recordError(binding->location, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name));
}
@@ -197,7 +197,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
collectedBindingPropertyData[i] = pd;
if (name.constData()->isUpper() && !binding->isAttachedProperty()) {
- QQmlType *type = 0;
+ QQmlType type;
QQmlImportNamespace *typeNamespace = 0;
imports.resolveType(stringAt(binding->propertyNameIndex), &type, 0, 0, &typeNamespace);
if (typeNamespace)
@@ -628,21 +628,19 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
bool isValueSource = false;
bool isPropertyInterceptor = false;
- QQmlType *qmlType = 0;
const QV4::CompiledData::Object *targetObject = qmlUnit->objectAt(binding->value.objectIndex);
if (auto *typeRef = resolvedTypes.value(targetObject->inheritedTypeNameIndex)) {
QQmlPropertyCache *cache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
const QMetaObject *mo = cache->firstCppMetaObject();
- while (mo && !qmlType) {
+ QQmlType qmlType;
+ while (mo && !qmlType.isValid()) {
qmlType = QQmlMetaType::qmlType(mo);
mo = mo->superClass();
}
- Q_ASSERT(qmlType);
- }
+ Q_ASSERT(qmlType.isValid());
- if (qmlType) {
- isValueSource = qmlType->propertyValueSourceCast() != -1;
- isPropertyInterceptor = qmlType->propertyValueInterceptorCast() != -1;
+ isValueSource = qmlType.propertyValueSourceCast() != -1;
+ isPropertyInterceptor = qmlType.propertyValueInterceptorCast() != -1;
}
if (!isValueSource && !isPropertyInterceptor) {
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index c09fde86f1..9058a6c78f 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -75,7 +75,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
for (auto it = resolvedTypes.constBegin(), end = resolvedTypes.constEnd();
it != end; ++it) {
- QQmlCustomParser *customParser = (*it)->type ? (*it)->type->customParser() : 0;
+ QQmlCustomParser *customParser = (*it)->type.customParser();
if (customParser)
customParsers.insert(it.key(), customParser);
}
@@ -171,7 +171,6 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
compilationUnit->propertyCaches = std::move(m_propertyCaches);
Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects));
-
if (errors.isEmpty())
return compilationUnit;
else
@@ -345,11 +344,11 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex);
auto *typeRef = resolvedTypes.value(binding->propertyNameIndex);
- QQmlType *type = typeRef ? typeRef->type : 0;
- if (!type) {
+ QQmlType type = typeRef ? typeRef->type : QQmlType();
+ if (!type.isValid()) {
if (imports->resolveType(propertyName, &type, 0, 0, 0)) {
- if (type->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(type->sourceUrl());
+ if (type.isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(type.sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -361,7 +360,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
}
}
- const QMetaObject *attachedType = type ? type->attachedPropertiesType(enginePrivate) : 0;
+ const QMetaObject *attachedType = type.attachedPropertiesType(enginePrivate);
if (!attachedType)
COMPILE_EXCEPTION(binding, tr("Non-existent attached object"));
QQmlPropertyCache *cache = compiler->enginePrivate()->cache(attachedType);
@@ -418,9 +417,9 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
- const QQmlType *type = typeRef ? typeRef->type : 0;
- if (type) {
- COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type->module()).arg(type->majorVersion()).arg(type->minorVersion()));
+ const QQmlType type = typeRef->type;
+ if (type.isValid()) {
+ COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type.module()).arg(type.majorVersion()).arg(type.minorVersion()));
} else {
COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName));
}
@@ -623,17 +622,17 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
}
return true;
}
- QQmlType *type = 0;
+ QQmlType type;
imports->resolveType(typeName, &type, 0, 0, 0);
- if (!type && !isQtObject)
+ if (!type.isValid() && !isQtObject)
return true;
int value = 0;
bool ok = false;
auto *tr = resolvedTypes->value(obj->inheritedTypeNameIndex);
- if (type && tr && tr->type == type) {
+ if (type.isValid() && tr && tr->type == type) {
// When these two match, we can short cut the search
QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex());
QMetaEnum menum = mprop.enumerator();
@@ -648,11 +647,11 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
}
} else {
// Otherwise we have to search the whole type
- if (type) {
+ if (type.isValid()) {
if (!scopedEnumName.isEmpty())
- value = type->scopedEnumValue(compiler->enginePrivate(), scopedEnumName, enumValue, &ok);
+ value = type.scopedEnumValue(compiler->enginePrivate(), scopedEnumName, enumValue, &ok);
else
- value = type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
+ value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
} else {
QByteArray enumName = enumValue.toUtf8();
const QMetaObject *metaObject = StaticQtMetaObject::get();
@@ -675,13 +674,13 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &e
*ok = false;
if (scope != QLatin1String("Qt")) {
- QQmlType *type = 0;
+ QQmlType type;
imports->resolveType(scope, &type, 0, 0, 0);
- if (!type)
+ if (!type.isValid())
return -1;
if (!enumName.isEmpty())
- return type->scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
- return type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
+ return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
}
const QMetaObject *mo = StaticQtMetaObject::get();
@@ -820,8 +819,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
const QmlIR::Object *targetObject = qmlObjects->at(binding->value.objectIndex);
auto *tr = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
Q_ASSERT(tr);
- if (QQmlType *targetType = tr->type) {
- if (targetType->metaObject() == &QQmlComponent::staticMetaObject)
+ if (tr->type.isValid()) {
+ if (tr->type.metaObject() == &QQmlComponent::staticMetaObject)
continue;
} else if (tr->compilationUnit) {
if (tr->compilationUnit->rootPropertyCache()->firstCppMetaObject() == &QQmlComponent::staticMetaObject)
@@ -850,22 +849,22 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
continue;
// emulate "import Qml 2.0 as QmlInternals" and then wrap the component in "QmlInternals.Component {}"
- QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
- Q_ASSERT(componentType);
+ QQmlType componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
+ Q_ASSERT(componentType.isValid());
const QString qualifier = QStringLiteral("QmlInternals");
- compiler->addImport(componentType->module(), qualifier, componentType->majorVersion(), componentType->minorVersion());
+ compiler->addImport(componentType.module(), qualifier, componentType.majorVersion(), componentType.minorVersion());
QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>();
- syntheticComponent->init(pool, compiler->registerString(qualifier + QLatin1Char('.') + componentType->elementName()), compiler->registerString(QString()));
+ syntheticComponent->init(pool, compiler->registerString(qualifier + QLatin1Char('.') + componentType.elementName()), compiler->registerString(QString()));
syntheticComponent->location = binding->valueLocation;
syntheticComponent->flags |= QV4::CompiledData::Object::IsComponent;
if (!resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
auto typeRef = new QV4::CompiledData::ResolvedTypeReference;
typeRef->type = componentType;
- typeRef->majorVersion = componentType->majorVersion();
- typeRef->minorVersion = componentType->minorVersion();
+ typeRef->majorVersion = componentType.majorVersion();
+ typeRef->minorVersion = componentType.minorVersion();
resolvedTypes->insert(syntheticComponent->inheritedTypeNameIndex, typeRef);
}
@@ -906,7 +905,7 @@ bool QQmlComponentAndAliasResolver::resolve()
if (obj->inheritedTypeNameIndex) {
auto *tref = resolvedTypes->value(obj->inheritedTypeNameIndex);
Q_ASSERT(tref);
- if (tref->type && tref->type->metaObject() == &QQmlComponent::staticMetaObject)
+ if (tref->type.metaObject() == &QQmlComponent::staticMetaObject)
isExplicitComponent = true;
}
if (!isExplicitComponent) {
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index be7429df41..96b76d8cfd 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -57,6 +57,7 @@
#include <QScopedValueRollback>
#include <QStandardPaths>
#include <QDir>
+#include <private/qv4identifiertable_p.h>
#endif
#include <private/qqmlirbuilder_p.h>
#include <QCoreApplication>
@@ -127,7 +128,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
// memset the strings to 0 in case a GC run happens while we're within the loop below
memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::Heap::String*));
for (uint i = 0; i < data->stringTableSize; ++i)
- runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
+ runtimeStrings[i] = engine->newString(data->stringAt(i));
runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
// memset the regexps to 0 in case a GC run happens while we're within the loop below
@@ -179,7 +180,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
QV4::InternalClass *klass = engine->internalClasses[QV4::ExecutionEngine::Class_Object];
for (int j = 0; j < memberCount; ++j, ++member)
- klass = klass->addMember(runtimeStrings[member->nameOffset]->identifier, member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
+ klass = klass->addMember(engine->identifierTable->identifier(runtimeStrings[member->nameOffset]), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
runtimeClasses[i] = klass;
}
@@ -210,8 +211,9 @@ void CompilationUnit::unlink()
if (isRegisteredWithEngine) {
Q_ASSERT(data && quint32(propertyCaches.count()) > data->indexOfRootObject && propertyCaches.at(data->indexOfRootObject));
- QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(propertyCaches.at(data->indexOfRootObject)->engine);
- qmlEngine->unregisterInternalCompositeType(this);
+ if (engine)
+ QQmlEnginePrivate::get(engine)->unregisterInternalCompositeType(this);
+ QQmlMetaType::unregisterInternalCompositeType(this);
isRegisteredWithEngine = false;
}
@@ -284,9 +286,10 @@ IdentifierHash<int> CompilationUnit::namedObjectsPerComponent(int componentObjec
void CompilationUnit::finalize(QQmlEnginePrivate *engine)
{
// Add to type registry of composites
- if (propertyCaches.needsVMEMetaObject(data->indexOfRootObject))
+ if (propertyCaches.needsVMEMetaObject(data->indexOfRootObject)) {
+ QQmlMetaType::registerInternalCompositeType(this);
engine->registerInternalCompositeType(this);
- else {
+ } else {
const QV4::CompiledData::Object *obj = objectAt(data->indexOfRootObject);
auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
@@ -294,8 +297,8 @@ void CompilationUnit::finalize(QQmlEnginePrivate *engine)
metaTypeId = typeRef->compilationUnit->metaTypeId;
listMetaTypeId = typeRef->compilationUnit->listMetaTypeId;
} else {
- metaTypeId = typeRef->type->typeId();
- listMetaTypeId = typeRef->type->qListTypeId();
+ metaTypeId = typeRef->type.typeId();
+ listMetaTypeId = typeRef->type.qListTypeId();
}
}
@@ -307,8 +310,8 @@ void CompilationUnit::finalize(QQmlEnginePrivate *engine)
const QV4::CompiledData::Object *obj = data->objectAt(i);
bindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (QQmlType *qmlType = typeRef->type) {
- if (qmlType->parserStatusCast() != -1)
+ if (typeRef->type.isValid()) {
+ if (typeRef->type.parserStatusCast() != -1)
++parserStatusCount;
}
++objectCount;
@@ -672,7 +675,7 @@ Returns the property cache, if one alread exists. The cache is not referenced.
*/
QQmlPropertyCache *ResolvedTypeReference::propertyCache() const
{
- if (type)
+ if (type.isValid())
return typePropertyCache;
else
return compilationUnit->rootPropertyCache();
@@ -685,8 +688,8 @@ QQmlPropertyCache *ResolvedTypeReference::createPropertyCache(QQmlEngine *engine
{
if (typePropertyCache) {
return typePropertyCache;
- } else if (type) {
- typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type->metaObject());
+ } else if (type.isValid()) {
+ typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject());
return typePropertyCache;
} else {
return compilationUnit->rootPropertyCache();
@@ -695,7 +698,7 @@ QQmlPropertyCache *ResolvedTypeReference::createPropertyCache(QQmlEngine *engine
bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine)
{
- if (type) {
+ if (type.isValid()) {
bool ok = false;
hash->addData(createPropertyCache(engine)->checksum(&ok));
return ok;
@@ -719,8 +722,8 @@ void ResolvedTypeReference::doDynamicTypeCheck()
const QMetaObject *mo = 0;
if (typePropertyCache)
mo = typePropertyCache->firstCppMetaObject();
- else if (type)
- mo = type->metaObject();
+ else if (type.isValid())
+ mo = type.metaObject();
else if (compilationUnit)
mo = compilationUnit->rootPropertyCache()->firstCppMetaObject();
isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo);
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index b28f77e6e6..6ad53fca4f 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -967,13 +967,12 @@ protected:
struct ResolvedTypeReference
{
ResolvedTypeReference()
- : type(0)
- , majorVersion(0)
+ : majorVersion(0)
, minorVersion(0)
, isFullyDynamicType(false)
{}
- QQmlType *type;
+ QQmlType type;
QQmlRefPointer<QQmlPropertyCache> typePropertyCache;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 190fb1bd5b..fb65eb4d8c 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -54,6 +54,9 @@
#include <private/qqmljsmemorypool_p.h>
#include <private/qqmljsastfwd_p.h>
#include <private/qflagpointer_p.h>
+#ifndef V4_BOOTSTRAP
+#include <private/qqmlmetatype_p.h>
+#endif
#include <QtCore/private/qnumeric_p.h>
#include <QtCore/QVector>
@@ -77,6 +80,8 @@ class QQmlType;
class QQmlPropertyData;
class QQmlPropertyCache;
class QQmlEnginePrivate;
+struct QQmlImportRef;
+class QQmlTypeNameCache;
namespace QV4 {
@@ -248,14 +253,18 @@ struct MemberExpressionResolver
Member *member);
MemberExpressionResolver()
- : resolveMember(0), data(0), extraData(0), owner(nullptr), flags(0) {}
+ : resolveMember(0), import(nullptr), propertyCache(nullptr), typenameCache(nullptr), owner(nullptr), flags(0) {}
bool isValid() const { return !!resolveMember; }
void clear() { *this = MemberExpressionResolver(); }
ResolveFunction resolveMember;
- void *data; // Could be pointer to meta object, importNameSpace, etc. - depends on resolveMember implementation
- void *extraData; // Could be QQmlTypeNameCache
+#ifndef V4_BOOTSTRAP
+ QQmlType qmlType;
+#endif
+ const QQmlImportRef *import;
+ QQmlPropertyCache *propertyCache;
+ QQmlTypeNameCache *typenameCache;
Function *owner;
unsigned int flags;
};
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index c678f8037a..d5b8b295a7 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -730,10 +730,7 @@ QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
QJSEnginePrivate::~QJSEnginePrivate()
{
- typedef QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator PropertyCacheIt;
-
- for (PropertyCacheIt iter = propertyCache.begin(), end = propertyCache.end(); iter != end; ++iter)
- (*iter)->release();
+ QQmlMetaType::freeUnusedTypesAndCaches();
}
void QJSEnginePrivate::addToDebugServer(QJSEngine *q)
@@ -756,20 +753,6 @@ void QJSEnginePrivate::removeFromDebugServer(QJSEngine *q)
server->removeEngine(q);
}
-QQmlPropertyCache *QJSEnginePrivate::createCache(const QMetaObject *mo)
-{
- if (!mo->superClass()) {
- QQmlPropertyCache *rv = new QQmlPropertyCache(QV8Engine::getV4(q_func()), mo);
- propertyCache.insert(mo, rv);
- return rv;
- } else {
- QQmlPropertyCache *super = cache(mo->superClass());
- QQmlPropertyCache *rv = super->copyAndAppend(mo);
- propertyCache.insert(mo, rv);
- return rv;
- }
-}
-
/*!
\since 5.5
\relates QJSEngine
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
index 2b462451ed..cbfe0f14a3 100644
--- a/src/qml/jsapi/qjsengine_p.h
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -55,6 +55,7 @@
#include <QtCore/qmutex.h>
#include "qjsengine.h"
#include "private/qtqmlglobal_p.h"
+#include <private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -110,14 +111,6 @@ public:
// These methods may be called from the QML loader thread
inline QQmlPropertyCache *cache(QObject *obj);
inline QQmlPropertyCache *cache(const QMetaObject *);
-
-private:
- // Must be called locked
- QQmlPropertyCache *createCache(const QMetaObject *);
-
- // These members must be protected by a QJSEnginePrivate::Locker as they are required by
- // the threaded loader. Only access them through their respective accessor methods.
- QHash<const QMetaObject *, QQmlPropertyCache *> propertyCache;
};
QJSEnginePrivate::Locker::Locker(const QJSEngine *e)
@@ -174,9 +167,7 @@ QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj)
Locker locker(this);
const QMetaObject *mo = obj->metaObject();
- QQmlPropertyCache *rv = propertyCache.value(mo);
- if (!rv) rv = createCache(mo);
- return rv;
+ return QQmlMetaType::propertyCache(mo);
}
/*!
@@ -193,9 +184,7 @@ QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject)
Q_ASSERT(metaObject);
Locker locker(this);
- QQmlPropertyCache *rv = propertyCache.value(metaObject);
- if (!rv) rv = createCache(metaObject);
- return rv;
+ return QQmlMetaType::propertyCache(metaObject);
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 019936767a..caa6e8b7ac 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -813,10 +813,10 @@ ReturnedValue ExecutionEngine::qmlSingletonWrapper(String *name)
QQmlTypeNameCache::Result r = ctx->imports->query(name);
Q_ASSERT(r.isValid());
- Q_ASSERT(r.type);
- Q_ASSERT(r.type->isSingleton());
+ Q_ASSERT(r.type.isValid());
+ Q_ASSERT(r.type.isSingleton());
- QQmlType::SingletonInstanceInfo *siinfo = r.type->singletonInstanceInfo();
+ QQmlType::SingletonInstanceInfo *siinfo = r.type.singletonInstanceInfo();
QQmlEngine *e = qmlEngine();
siinfo->init(e);
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index d1bdab1b3c..4b88d85e68 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -44,6 +44,7 @@
#include "qv4engine_p.h"
#include "qv4lookup_p.h"
#include <private/qv4mm_p.h>
+#include <private/qv4identifiertable_p.h>
QT_BEGIN_NAMESPACE
@@ -57,8 +58,6 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
, codeData(0)
, hasQmlDependencies(function->hasQmlDependencies())
{
- Q_UNUSED(engine);
-
internalClass = engine->internalClasses[EngineBase::Class_Empty];
const quint32_le *formalsIndices = compiledFunction->formalsTable();
// iterate backwards, so we get the right ordering for duplicate names
@@ -81,7 +80,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
const quint32_le *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
- internalClass = internalClass->addMember(compilationUnit->runtimeStrings[localsIndices[i]]->identifier, Attr_NotConfigurable);
+ internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
canUseSimpleCall = compiledFunction->flags & CompiledData::Function::CanUseSimpleCall;
}
@@ -113,7 +112,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
const quint32_le *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
- internalClass = internalClass->addMember(compilationUnit->runtimeStrings[localsIndices[i]]->identifier, Attr_NotConfigurable);
+ internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
canUseSimpleCall = false;
}
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index d943ae1340..afadf59bd5 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -40,6 +40,7 @@
#include "qv4functionobject_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4string_p.h"
+#include <private/qv4identifiertable_p.h>
QT_BEGIN_NAMESPACE
@@ -49,7 +50,7 @@ using namespace QV4;
ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttributes *attrs)
{
ExecutionEngine *engine = o->engine();
- Identifier *name = engine->current->compilationUnit->runtimeStrings[nameIndex]->identifier;
+ Identifier *name = engine->identifierTable->identifier(engine->current->compilationUnit->runtimeStrings[nameIndex]);
int i = 0;
Heap::Object *obj = o->d();
while (i < Size && obj) {
@@ -85,7 +86,7 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs
{
Heap::Object *obj = thisObject->d();
ExecutionEngine *engine = thisObject->engine();
- Identifier *name = engine->current->compilationUnit->runtimeStrings[nameIndex]->identifier;
+ Identifier *name = engine->identifierTable->identifier(engine->current->compilationUnit->runtimeStrings[nameIndex]);
int i = 0;
while (i < Size && obj) {
classList[i] = obj->internalClass;
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 89770d269a..c483fdb7e7 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -142,7 +142,7 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
if (r.scriptIndex != -1) {
QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
return scripts->getIndexed(r.scriptIndex);
- } else if (r.type) {
+ } else if (r.type.isValid()) {
return QQmlTypeWrapper::create(v4, scopeObject, r.type);
} else if (r.importNamespace) {
return QQmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 91650f16e2..72ad0ce7b7 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -296,7 +296,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
if (r.isValid()) {
if (r.scriptIndex != -1) {
return QV4::Encode::undefined();
- } else if (r.type) {
+ } else if (r.type.isValid()) {
return QQmlTypeWrapper::create(v4, d()->object(),
r.type, Heap::QQmlTypeWrapper::ExcludeEnums);
} else if (r.importNamespace) {
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 6ad641b8b1..cc6e75a39c 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -135,7 +135,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
if (scope != QLatin1String("Qt")) {
if (imports.isNull())
return -1;
- QQmlType *type = 0;
+ QQmlType type;
if (imports.isT1()) {
imports.asT1()->resolveType(scope, &type, 0, 0, 0);
@@ -145,7 +145,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
type = result.type;
}
- if (!type)
+ if (!type.isValid())
return -1;
int dot2 = script.indexOf('.', dot+1);
@@ -153,9 +153,9 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray());
if (!scopedEnumName.isEmpty())
- return type->scopedEnumValue(engine, scopedEnumName, enumValue, ok);
+ return type.scopedEnumValue(engine, scopedEnumName, enumValue, ok);
else
- return type->enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
}
QByteArray enumValue = script.mid(dot + 1);
@@ -177,12 +177,10 @@ const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const
{
if (!imports.isT1())
return nullptr;
- QQmlType *qmltype = 0;
+ QQmlType qmltype;
if (!imports.asT1()->resolveType(name, &qmltype, 0, 0, 0))
return nullptr;
- if (!qmltype)
- return nullptr;
- return qmltype->metaObject();
+ return qmltype.metaObject();
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 38a2978712..eb2fbcdd73 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -683,8 +683,6 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
QQmlEnginePrivate::~QQmlEnginePrivate()
{
- typedef QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::const_iterator TypePropertyCacheIt;
-
if (inProgressCreations)
qWarning() << QQmlEngine::tr("There are still \"%1\" items in the process of being created at engine destruction.").arg(inProgressCreations);
@@ -702,8 +700,8 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
if (incubationController) incubationController->d = 0;
incubationController = 0;
- for (TypePropertyCacheIt iter = typePropertyCache.cbegin(), end = typePropertyCache.cend(); iter != end; ++iter)
- (*iter)->release();
+ QQmlMetaType::freeUnusedTypesAndCaches();
+
for (auto iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter) {
iter.value()->isRegisteredWithEngine = false;
@@ -1028,9 +1026,9 @@ QQmlEngine::~QQmlEngine()
// we do this here and not in the private dtor since otherwise a crash can
// occur (if we are the QObject parent of the QObject singleton instance)
// XXX TODO: performance -- store list of singleton types separately?
- const QList<QQmlType*> singletonTypes = QQmlMetaType::qmlSingletonTypes();
- for (QQmlType *currType : singletonTypes)
- currType->singletonInstanceInfo()->destroy(this);
+ QList<QQmlType> singletonTypes = QQmlMetaType::qmlSingletonTypes();
+ for (const QQmlType &currType : singletonTypes)
+ currType.singletonInstanceInfo()->destroy(this);
delete d->rootContext;
d->rootContext = 0;
@@ -2224,108 +2222,6 @@ QString QQmlEnginePrivate::offlineStorageDatabaseDirectory() const
return q->offlineStoragePath() + QDir::separator() + QLatin1String("Databases") + QDir::separator();
}
-QQmlPropertyCache *QQmlEnginePrivate::createCache(QQmlType *type, int minorVersion)
-{
- QList<QQmlType *> types;
-
- int maxMinorVersion = 0;
-
- const QMetaObject *metaObject = type->metaObject();
-
- while (metaObject) {
- QQmlType *t = QQmlMetaType::qmlType(metaObject, type->module(),
- type->majorVersion(), minorVersion);
- if (t) {
- maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
- types << t;
- } else {
- types << 0;
- }
-
- metaObject = metaObject->superClass();
- }
-
- if (QQmlPropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
- c->addref();
- typePropertyCache.insert(qMakePair(type, minorVersion), c);
- return c;
- }
-
- QQmlPropertyCache *raw = cache(type->metaObject());
-
- bool hasCopied = false;
-
- for (int ii = 0; ii < types.count(); ++ii) {
- QQmlType *currentType = types.at(ii);
- if (!currentType)
- continue;
-
- int rev = currentType->metaObjectRevision();
- int moIndex = types.count() - 1 - ii;
-
- if (raw->allowedRevisionCache[moIndex] != rev) {
- if (!hasCopied) {
- raw = raw->copy();
- hasCopied = true;
- }
- raw->allowedRevisionCache[moIndex] = rev;
- }
- }
-
- // Test revision compatibility - the basic rule is:
- // * Anything that is excluded, cannot overload something that is not excluded *
-
- // Signals override:
- // * other signals and methods of the same name.
- // * properties named on<Signal Name>
- // * automatic <property name>Changed notify signals
-
- // Methods override:
- // * other methods of the same name
-
- // Properties override:
- // * other elements of the same name
-
-#if 0
- bool overloadError = false;
- QString overloadName;
-
- for (QQmlPropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
- !overloadError && iter != raw->stringCache.end();
- ++iter) {
-
- QQmlPropertyData *d = *iter;
- if (raw->isAllowedInRevision(d))
- continue; // Not excluded - no problems
-
- // check that a regular "name" overload isn't happening
- QQmlPropertyData *current = d;
- while (!overloadError && current) {
- current = d->overrideData(current);
- if (current && raw->isAllowedInRevision(current))
- overloadError = true;
- }
- }
-
- if (overloadError) {
- if (hasCopied) raw->release();
-
- error.setDescription(QLatin1String("Type ") + type->qmlTypeName() + QLatin1Char(' ') + QString::number(type->majorVersion()) + QLatin1Char('.') + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation."));
- return 0;
- }
-#endif
-
- if (!hasCopied) raw->addref();
- typePropertyCache.insert(qMakePair(type, minorVersion), raw);
-
- if (minorVersion != maxMinorVersion) {
- raw->addref();
- typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
- }
-
- return raw;
-}
-
bool QQmlEnginePrivate::isQObject(int t)
{
Locker locker(this);
@@ -2349,26 +2245,17 @@ QQmlMetaType::TypeCategory QQmlEnginePrivate::typeCategory(int t) const
Locker locker(this);
if (m_compositeTypes.contains(t))
return QQmlMetaType::Object;
- else if (m_qmlLists.contains(t))
- return QQmlMetaType::List;
- else
- return QQmlMetaType::typeCategory(t);
+ return QQmlMetaType::typeCategory(t);
}
bool QQmlEnginePrivate::isList(int t) const
{
- Locker locker(this);
- return m_qmlLists.contains(t) || QQmlMetaType::isList(t);
+ return QQmlMetaType::isList(t);
}
int QQmlEnginePrivate::listType(int t) const
{
- Locker locker(this);
- QHash<int, int>::ConstIterator iter = m_qmlLists.constFind(t);
- if (iter != m_qmlLists.cend())
- return *iter;
- else
- return QQmlMetaType::listType(t);
+ return QQmlMetaType::listType(t);
}
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
@@ -2378,8 +2265,8 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
if (iter != m_compositeTypes.cend()) {
return QQmlMetaObject((*iter)->rootPropertyCache());
} else {
- QQmlType *type = QQmlMetaType::qmlType(t);
- return QQmlMetaObject(type?type->baseMetaObject():0);
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return QQmlMetaObject(type.baseMetaObject());
}
}
@@ -2390,8 +2277,8 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
if (iter != m_compositeTypes.cend()) {
return QQmlMetaObject((*iter)->rootPropertyCache());
} else {
- QQmlType *type = QQmlMetaType::qmlType(t);
- return QQmlMetaObject(type?type->metaObject():0);
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return QQmlMetaObject(type.metaObject());
}
}
@@ -2402,9 +2289,9 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
if (iter != m_compositeTypes.cend()) {
return (*iter)->rootPropertyCache();
} else {
- QQmlType *type = QQmlMetaType::qmlType(t);
+ QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type?cache(type->metaObject()):0;
+ return type.isValid() ? cache(type.metaObject()) : 0;
}
}
@@ -2415,54 +2302,28 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
if (iter != m_compositeTypes.cend()) {
return (*iter)->rootPropertyCache();
} else {
- QQmlType *type = QQmlMetaType::qmlType(t);
+ QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type?cache(type->baseMetaObject()):0;
+ return type.isValid() ? cache(type.baseMetaObject()) : 0;
}
}
void QQmlEnginePrivate::registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit)
{
- QByteArray name = compilationUnit->rootPropertyCache()->className();
-
- QByteArray ptr = name + '*';
- QByteArray lst = "QQmlListProperty<" + name + '>';
-
- int ptr_type = QMetaType::registerNormalizedType(ptr,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Construct,
- sizeof(QObject*),
- static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
- 0);
- int lst_type = QMetaType::registerNormalizedType(lst,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Construct,
- sizeof(QQmlListProperty<QObject>),
- static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
- static_cast<QMetaObject*>(0));
-
- compilationUnit->metaTypeId = ptr_type;
- compilationUnit->listMetaTypeId = lst_type;
compilationUnit->isRegisteredWithEngine = true;
Locker locker(this);
- m_qmlLists.insert(lst_type, ptr_type);
// The QQmlCompiledData is not referenced here, but it is removed from this
// hash in the QQmlCompiledData destructor
- m_compositeTypes.insert(ptr_type, compilationUnit);
+ m_compositeTypes.insert(compilationUnit->metaTypeId, compilationUnit);
}
void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit)
{
- int ptr_type = compilationUnit->metaTypeId;
- int lst_type = compilationUnit->listMetaTypeId;
+ compilationUnit->isRegisteredWithEngine = false;
Locker locker(this);
- m_qmlLists.remove(lst_type);
- m_compositeTypes.remove(ptr_type);
-
- QMetaType::unregisterType(ptr_type);
- QMetaType::unregisterType(lst_type);
+ m_compositeTypes.remove(compilationUnit->metaTypeId);
}
bool QQmlEnginePrivate::isTypeLoaded(const QUrl &url) const
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 1bdeacd524..da8ea24ea0 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -208,7 +208,7 @@ public:
QString offlineStorageDatabaseDirectory() const;
// These methods may be called from the loader thread
- inline QQmlPropertyCache *cache(QQmlType *, int);
+ inline QQmlPropertyCache *cache(const QQmlType &, int);
using QJSEnginePrivate::cache;
// These methods may be called from the loader thread
@@ -259,13 +259,8 @@ public:
mutable QMutex networkAccessManagerMutex;
private:
- // Must be called locked
- QQmlPropertyCache *createCache(QQmlType *, int);
-
// These members must be protected by a QQmlEnginePrivate::Locker as they are required by
// the threaded loader. Only access them through their respective accessor methods.
- QHash<QPair<QQmlType *, int>, QQmlPropertyCache *> typePropertyCache;
- QHash<int, int> m_qmlLists;
QHash<int, QV4::CompiledData::CompilationUnit *> m_compositeTypes;
static bool s_designerMode;
@@ -375,17 +370,15 @@ Returns a QQmlPropertyCache for \a type with \a minorVersion.
The returned cache is not referenced, so if it is to be stored, call addref().
*/
-QQmlPropertyCache *QQmlEnginePrivate::cache(QQmlType *type, int minorVersion)
+QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersion)
{
- Q_ASSERT(type);
+ Q_ASSERT(type.isValid());
- if (minorVersion == -1 || !type->containsRevisionedAttributes())
- return cache(type->metaObject());
+ if (minorVersion == -1 || !type.containsRevisionedAttributes())
+ return cache(type.metaObject());
Locker locker(this);
- QQmlPropertyCache *rv = typePropertyCache.value(qMakePair(type, minorVersion));
- if (!rv) rv = createCache(type, minorVersion);
- return rv;
+ return QQmlMetaType::propertyCache(type, minorVersion);
}
QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e)
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index fc8e60e3f2..7c9dcb1826 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -142,13 +142,13 @@ bool isPathAbsolute(const QString &path)
Errors (if there are any) are placed into \a errors, if it is nonzero. Note
that errors are treated as fatal if \a errors is not set.
*/
-QQmlType *fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRef& typeName,
+QQmlType fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRef& typeName,
bool isCompositeSingleton, QList<QQmlError> *errors,
int majorVersion=-1, int minorVersion=-1)
{
QUrl url(urlString); // ### unfortunate (costly) conversion
- QQmlType *ret = QQmlMetaType::qmlType(url);
- if (ret)
+ QQmlType ret = QQmlMetaType::qmlType(url);
+ if (ret.isValid())
return ret;
int dot = typeName.indexOf(QLatin1Char('.'));
@@ -183,7 +183,7 @@ QQmlType *fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringR
minorVersion,
buf.constData()
};
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &reg));
+ ret = QQmlMetaType::registerCompositeSingletonType(reg);
} else {
QQmlPrivate::RegisterCompositeType reg = {
url,
@@ -192,13 +192,13 @@ QQmlType *fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringR
minorVersion,
buf.constData()
};
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
+ ret = QQmlMetaType::registerCompositeType(reg);
}
// This means that the type couldn't be found by URL, but could not be
// registered either, meaning we most likely were passed some kind of bad
// data.
- if (!ret) {
+ if (!ret.isValid()) {
if (!errors) // Cannot list errors properly, just quit
qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData());
QQmlError error;
@@ -295,7 +295,7 @@ public:
QList<QQmlError> *errors);
bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
- QQmlType** type_return, QList<QQmlError> *errors,
+ QQmlType* type_return, QList<QQmlError> *errors,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion);
QUrl baseUrl;
@@ -421,13 +421,14 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
const QQmlImportNamespace &set = *ns;
// positioning is important; we must create the namespace even if there is no module.
- QQmlTypeNameCache::Import &typeimport = cache->m_namedImports[set.prefix];
+ QQmlImportRef &typeimport = cache->m_namedImports[set.prefix];
typeimport.m_qualifier = set.prefix;
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion);
if (module) {
+ QQmlImportRef &typeimport = cache->m_namedImports[set.prefix];
typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion));
}
}
@@ -620,7 +621,7 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version)
\sa addFileImport(), addLibraryImport
*/
bool QQmlImports::resolveType(const QHashedStringRef &type,
- QQmlType** type_return, int *vmaj, int *vmin,
+ QQmlType* type_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors,
QQmlImport::RecursionRestriction recursionRestriction) const
{
@@ -631,17 +632,19 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
return true;
}
if (type_return) {
- if (d->resolveType(type,vmaj,vmin,type_return, errors, recursionRestriction)) {
+ if (d->resolveType(type, vmaj, vmin, type_return, errors, recursionRestriction)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
<< ')' << "::resolveType: " << type.toString() << " => "
- if (type_return && *type_return && (*type_return)->isCompositeSingleton())
- RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << (*type_return)->sourceUrl() << " TYPE/URL-SINGLETON";
- else if (type_return && *type_return && (*type_return)->isComposite())
- RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << (*type_return)->sourceUrl() << " TYPE/URL";
- else if (type_return && *type_return)
- RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << " TYPE";
+ if (type_return && type_return->isValid()) {
+ if (type_return->isCompositeSingleton())
+ RESOLVE_TYPE_DEBUG << type_return->typeName() << ' ' << type_return->sourceUrl() << " TYPE/URL-SINGLETON";
+ else if (type_return->isComposite())
+ RESOLVE_TYPE_DEBUG << type_return->typeName() << ' ' << type_return->sourceUrl() << " TYPE/URL";
+ else
+ RESOLVE_TYPE_DEBUG << type_return->typeName() << " TYPE";
+ }
#undef RESOLVE_TYPE_DEBUG
}
return true;
@@ -706,20 +709,20 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml
If the return pointer is 0, the corresponding search is not done.
*/
-bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QHashedStringRef &type,
- QQmlType** type_return, int *vmaj, int *vmin) const
+bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type,
+ QQmlType *type_return, int *vmaj, int *vmin) const
{
- return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return);
+ return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return);
}
bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader,
const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QString *base, bool *typeRecursionDetected,
+ QQmlType* type_return, QString *base, bool *typeRecursionDetected,
QQmlImport::RecursionRestriction recursionRestriction) const
{
if (majversion >= 0 && minversion >= 0) {
- QQmlType *t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
- if (t) {
+ QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
+ if (t.isValid()) {
if (vmajor) *vmajor = majversion;
if (vminor) *vminor = minversion;
if (type_return)
@@ -769,11 +772,11 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader,
componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName);
int major = vmajor ? *vmajor : -1;
int minor = vminor ? *vminor : -1;
- QQmlType *returnType = fetchOrCreateTypeForUrl(componentUrl, type, isCompositeSingleton, 0,
+ QQmlType returnType = fetchOrCreateTypeForUrl(componentUrl, type, isCompositeSingleton, 0,
major, minor);
if (type_return)
*type_return = returnType;
- return returnType != 0;
+ return returnType.isValid();
}
} else if (!isLibrary) {
QString qmlUrl;
@@ -797,10 +800,10 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader,
if (typeRecursionDetected)
*typeRecursionDetected = true;
} else {
- QQmlType *returnType = fetchOrCreateTypeForUrl(qmlUrl, type, false, 0);
+ QQmlType returnType = fetchOrCreateTypeForUrl(qmlUrl, type, false, 0);
if (type_return)
*type_return = returnType;
- return returnType != 0;
+ return returnType.isValid();
}
}
}
@@ -809,7 +812,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader,
}
bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QList<QQmlError> *errors,
+ QQmlType* type_return, QList<QQmlError> *errors,
QQmlImport::RecursionRestriction recursionRestriction)
{
QQmlImportNamespace *s = 0;
@@ -839,12 +842,12 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
}
QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
if (s) {
- if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return, &base, errors, recursionRestriction))
+ if (s->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors, recursionRestriction))
return true;
if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
// qualified, and only 1 url
*type_return = fetchOrCreateTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, false, errors);
- return (*type_return != 0);
+ return type_return->isValid();
}
}
@@ -861,7 +864,7 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const
}
bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor, QQmlType** type_return,
+ int *vmajor, int *vminor, QQmlType* type_return,
QString *base, QList<QQmlError> *errors,
QQmlImport::RecursionRestriction recursionRestriction)
{
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 1a50d5c16a..0b4a0e6f80 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -90,7 +90,7 @@ struct QQmlImportInstance
static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor, QQmlType** type_return,
+ int *vmajor, int *vminor, QQmlType* type_return,
QString *base = 0, bool *typeRecursionDetected = 0,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
};
@@ -106,7 +106,7 @@ public:
QQmlImportInstance *findImport(const QString &uri) const;
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor, QQmlType** type_return,
+ int *vmajor, int *vminor, QQmlType* type_return,
QString *base = 0, QList<QQmlError> *errors = 0,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion);
@@ -131,14 +131,14 @@ public:
QUrl baseUrl() const;
bool resolveType(const QHashedStringRef &type,
- QQmlType** type_return,
+ QQmlType *type_return,
int *version_major, int *version_minor,
- QQmlImportNamespace** ns_return,
+ QQmlImportNamespace **ns_return,
QList<QQmlError> *errors = 0,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
- bool resolveType(QQmlImportNamespace*,
+ bool resolveType(QQmlImportNamespace *,
const QHashedStringRef& type,
- QQmlType** type_return, int *version_major, int *version_minor) const;
+ QQmlType *type_return, int *version_major, int *version_minor) const;
bool addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors);
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index 2c71293363..71be2e82a3 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -148,7 +148,7 @@ QQmlListReference::QQmlListReference(QObject *object, const char *property, QQml
d = new QQmlListReferencePrivate;
d->object = object;
- d->elementType = p?p->rawMetaObjectForType(listType):QQmlMetaType::qmlType(listType)->baseMetaObject();
+ d->elementType = p ? p->rawMetaObjectForType(listType) : QQmlMetaType::qmlType(listType).baseMetaObject();
d->propertyType = data->propType();
void *args[] = { &d->property, 0 };
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index b75508e1e5..9bc35b3b52 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -69,18 +69,20 @@ struct QQmlMetaTypeData
{
QQmlMetaTypeData();
~QQmlMetaTypeData();
- QList<QQmlType *> types;
- typedef QHash<int, QQmlType *> Ids;
+ void registerType(QQmlTypePrivate *priv);
+ QList<QQmlType> types;
+ QSet<QQmlType> undeletableTypes;
+ typedef QHash<int, QQmlTypePrivate *> Ids;
Ids idToType;
- typedef QHash<QHashedStringRef,QQmlType *> Names;
+ typedef QHash<QHashedStringRef, QQmlTypePrivate *> Names;
Names nameToType;
- typedef QHash<QUrl, QQmlType *> Files; //For file imported composite types only
+ typedef QHash<QUrl, QQmlTypePrivate *> Files; //For file imported composite types only
Files urlToType;
Files urlToNonFileImportType; // For non-file imported composite and composite
// singleton types. This way we can locate any
// of them by url, even if it was registered as
// a module via QQmlPrivate::RegisterCompositeType
- typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
+ typedef QHash<const QMetaObject *, QQmlTypePrivate *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
@@ -110,6 +112,12 @@ struct QQmlMetaTypeData
QString typeRegistrationNamespace;
QStringList typeRegistrationFailures;
+
+ QHash<int, int> qmlLists;
+
+ QHash<const QMetaObject *, QQmlPropertyCache *> propertyCaches;
+ QQmlPropertyCache *propertyCache(const QMetaObject *metaObject);
+ QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
};
class QQmlTypeModulePrivate
@@ -126,10 +134,11 @@ public:
int maxMinorVersion;
bool locked;
- void add(QQmlType *);
+ void add(QQmlTypePrivate *);
+ void remove(const QQmlTypePrivate *type);
- QStringHash<QList<QQmlType *> > typeHash;
- QList<QQmlType *> types;
+ typedef QStringHash<QList<QQmlTypePrivate *> > TypeHash;
+ TypeHash typeHash;
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
@@ -146,15 +155,16 @@ QQmlMetaTypeData::QQmlMetaTypeData()
QQmlMetaTypeData::~QQmlMetaTypeData()
{
- for (int i = 0; i < types.count(); ++i)
- delete types.at(i);
-
for (TypeModules::const_iterator i = uriToModule.constBegin(), cend = uriToModule.constEnd(); i != cend; ++i)
delete *i;
+ for (QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = propertyCaches.begin(), end = propertyCaches.end();
+ it != end; ++it)
+ (*it)->release();
}
class QQmlTypePrivate
{
+ Q_DISABLE_COPY(QQmlTypePrivate)
public:
QQmlTypePrivate(QQmlType::RegistrationType type);
~QQmlTypePrivate();
@@ -164,6 +174,7 @@ public:
void insertEnums(const QMetaObject *metaObject) const;
void insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const;
+ QAtomicInt refCount;
QQmlType::RegistrationType regType;
struct QQmlCppTypeData
@@ -208,7 +219,7 @@ public:
int listId;
int revision;
mutable bool containsRevisionedAttributes;
- mutable QQmlType *superType;
+ mutable QQmlType superType;
const QMetaObject *baseMetaObject;
int index;
@@ -221,8 +232,32 @@ public:
mutable QList<QStringHash<int>*> scopedEnums;
static QHash<const QMetaObject *, int> attachedPropertyIds;
+
+ struct PropertyCacheByMinorVersion
+ {
+ PropertyCacheByMinorVersion() : cache(Q_NULLPTR), minorVersion(-1) {}
+ explicit PropertyCacheByMinorVersion(QQmlPropertyCache *pc, int ver) : cache(pc), minorVersion(ver) {}
+ QQmlPropertyCachePtr cache;
+ int minorVersion;
+ };
+ QVector<PropertyCacheByMinorVersion> propertyCaches;
+ QQmlPropertyCache *propertyCacheForMinorVersion(int minorVersion) const;
+ void setPropertyCacheForMinorVersion(int minorVersion, QQmlPropertyCache *cache);
};
+void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
+{
+ for (int i = 0; i < types.count(); ++i) {
+ if (!types.at(i).isValid()) {
+ types[i] = QQmlType(priv);
+ priv->index = i;
+ return;
+ }
+ }
+ types.append(QQmlType(priv));
+ priv->index = types.count() - 1;
+}
+
void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(e->handle());
@@ -281,8 +316,8 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const
QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds;
QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
-: regType(type), iid(0), typeId(0), listId(0), revision(0),
- containsRevisionedAttributes(false), superType(0), baseMetaObject(0),
+: refCount(1), regType(type), iid(0), typeId(0), listId(0), revision(0),
+ containsRevisionedAttributes(false), baseMetaObject(0),
index(-1), isSetup(false), isEnumSetup(false), haveSuperType(false)
{
switch (type) {
@@ -335,21 +370,23 @@ QQmlTypePrivate::~QQmlTypePrivate()
}
}
-QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
-: d(new QQmlTypePrivate(InterfaceType))
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &interface)
+ : d(new QQmlTypePrivate(InterfaceType))
{
d->iid = interface.iid;
d->typeId = interface.typeId;
d->listId = interface.listId;
- d->index = index;
d->isSetup = true;
d->version_maj = 0;
d->version_min = 0;
+ data->registerType(d);
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
-: d(new QQmlTypePrivate(SingletonType))
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
+ : d(new QQmlTypePrivate(SingletonType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -365,8 +402,6 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
d->revision = type.revision;
}
- d->index = index;
-
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
@@ -375,25 +410,27 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
= (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
- : d(new QQmlTypePrivate(CompositeSingletonType))
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
+ : d(new QQmlTypePrivate(CompositeSingletonType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
d->version_maj = type.versionMajor;
d->version_min = type.versionMinor;
- d->index = index;
-
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->url = type.url;
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type)
-: d(new QQmlTypePrivate(CppType))
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterType &type)
+ : d(new QQmlTypePrivate(CppType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -412,7 +449,7 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
if (d->extraData.cd->attachedPropertiesType) {
QHash<const QMetaObject *, int>::Iterator iter = d->attachedPropertyIds.find(d->baseMetaObject);
if (iter == d->attachedPropertyIds.end())
- iter = d->attachedPropertyIds.insert(d->baseMetaObject, index);
+ iter = d->attachedPropertyIds.insert(d->baseMetaObject, d->index);
d->extraData.cd->attachedPropertiesId = *iter;
} else {
d->extraData.cd->attachedPropertiesId = -1;
@@ -422,16 +459,16 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
d->extraData.cd->extFunc = type.extensionObjectCreate;
d->extraData.cd->customParser = type.customParser;
- d->index = index;
if (type.extensionMetaObject)
d->extraData.cd->extMetaObject = type.extensionMetaObject;
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
-: d(new QQmlTypePrivate(CompositeType))
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
+ : d(new QQmlTypePrivate(CompositeType))
{
- d->index = index;
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -441,44 +478,88 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
d->extraData.fd->url = type.url;
}
+QQmlType::QQmlType()
+ : d(0)
+{
+}
+
+QQmlType::QQmlType(const QQmlType &other)
+ : d(other.d)
+{
+ if (d)
+ d->refCount.ref();
+}
+
+QQmlType &QQmlType::operator =(const QQmlType &other)
+{
+ if (d != other.d) {
+ if (d && !d->refCount.deref())
+ delete d;
+ d = other.d;
+ if (d)
+ d->refCount.ref();
+ }
+ return *this;
+}
+
+QQmlType::QQmlType(QQmlTypePrivate *priv)
+ : d(priv)
+{
+ if (d)
+ d->refCount.ref();
+}
+
QQmlType::~QQmlType()
{
- delete d;
+ if (d && !d->refCount.deref())
+ delete d;
}
-const QHashedString &QQmlType::module() const
+QHashedString QQmlType::module() const
{
+ if (!d)
+ return QHashedString();
return d->module;
}
int QQmlType::majorVersion() const
{
+ if (!d)
+ return -1;
return d->version_maj;
}
int QQmlType::minorVersion() const
{
+ if (!d)
+ return -1;
return d->version_min;
}
bool QQmlType::availableInVersion(int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
+ if (!d)
+ return false;
return vmajor == d->version_maj && vminor >= d->version_min;
}
bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
+ if (!d)
+ return false;
return module == d->module && vmajor == d->version_maj && vminor >= d->version_min;
}
// returns the nearest _registered_ super class
-QQmlType *QQmlType::superType() const
+QQmlType QQmlType::superType() const
{
+ if (!d)
+ return QQmlType();
if (!d->haveSuperType && d->baseMetaObject) {
const QMetaObject *mo = d->baseMetaObject->superClass();
- while (mo && !d->superType) {
+ while (mo && !d->superType.isValid()) {
d->superType = QQmlMetaType::qmlType(mo, d->module, d->version_maj, d->version_min);
mo = mo->superClass();
}
@@ -488,14 +569,14 @@ QQmlType *QQmlType::superType() const
return d->superType;
}
-QQmlType *QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
+QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
{
Q_ASSERT(isComposite());
- if (!engine)
- return 0;
+ if (!engine || !d)
+ return QQmlType();
QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt);
if (td.isNull() || !td->isComplete())
- return 0;
+ return QQmlType();
QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
const QMetaObject *mo = compilationUnit->rootPropertyCache()->firstCppMetaObject();
return QQmlMetaType::qmlType(mo);
@@ -631,18 +712,18 @@ void QQmlTypePrivate::init() const
mo = mo->d.superdata;
while(mo) {
- QQmlType *t = metaTypeData()->metaObjectToType.value(mo);
+ QQmlTypePrivate *t = metaTypeData()->metaObjectToType.value(mo);
if (t) {
- if (t->d->regType == QQmlType::CppType) {
- if (t->d->extraData.cd->extFunc) {
+ if (t->regType == QQmlType::CppType) {
+ if (t->extraData.cd->extFunc) {
QMetaObjectBuilder builder;
- clone(builder, t->d->extraData.cd->extMetaObject, t->d->baseMetaObject, baseMetaObject);
+ clone(builder, t->extraData.cd->extMetaObject, t->baseMetaObject, baseMetaObject);
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
QMetaObject *mmo = builder.toMetaObject();
mmo->d.superdata = baseMetaObject;
if (!metaObjects.isEmpty())
metaObjects.constLast().metaObject->d.superdata = mmo;
- QQmlProxyMetaObject::ProxyData data = { mmo, t->d->extraData.cd->extFunc, 0, 0 };
+ QQmlProxyMetaObject::ProxyData data = { mmo, t->extraData.cd->extFunc, 0, 0 };
metaObjects << data;
}
}
@@ -754,23 +835,47 @@ void QQmlTypePrivate::insertEnumsFromPropertyCache(const QQmlPropertyCache *cach
}
+QQmlPropertyCache *QQmlTypePrivate::propertyCacheForMinorVersion(int minorVersion) const
+{
+ for (int i = 0; i < propertyCaches.count(); ++i)
+ if (propertyCaches.at(i).minorVersion == minorVersion)
+ return propertyCaches.at(i).cache;
+ return Q_NULLPTR;
+}
+
+void QQmlTypePrivate::setPropertyCacheForMinorVersion(int minorVersion, QQmlPropertyCache *cache)
+{
+ for (int i = 0; i < propertyCaches.count(); ++i) {
+ if (propertyCaches.at(i).minorVersion == minorVersion) {
+ propertyCaches[i].cache = cache;
+ return;
+ }
+ }
+ propertyCaches.append(PropertyCacheByMinorVersion(cache, minorVersion));
+}
+
QByteArray QQmlType::typeName() const
{
- if (d->regType == SingletonType || d->regType == CompositeSingletonType)
- return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8();
- else if (d->baseMetaObject)
- return d->baseMetaObject->className();
- else
- return QByteArray();
+ if (d) {
+ if (d->regType == SingletonType || d->regType == CompositeSingletonType)
+ return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8();
+ else if (d->baseMetaObject)
+ return d->baseMetaObject->className();
+ }
+ return QByteArray();
}
-const QString &QQmlType::elementName() const
+QString QQmlType::elementName() const
{
+ if (!d)
+ return QString();
return d->elementName;
}
-const QString &QQmlType::qmlTypeName() const
+QString QQmlType::qmlTypeName() const
{
+ if (!d)
+ return QString();
if (d->name.isEmpty()) {
if (!d->module.isEmpty())
d->name = static_cast<QString>(d->module) + QLatin1Char('/') + d->elementName;
@@ -783,7 +888,7 @@ const QString &QQmlType::qmlTypeName() const
QObject *QQmlType::create() const
{
- if (!isCreatable())
+ if (!d || !isCreatable())
return 0;
d->init();
@@ -799,7 +904,7 @@ QObject *QQmlType::create() const
void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) const
{
- if (!isCreatable())
+ if (!d || !isCreatable())
return;
d->init();
@@ -816,6 +921,8 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con
QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
{
+ if (!d)
+ return 0;
if (d->regType != SingletonType && d->regType != CompositeSingletonType)
return 0;
return d->extraData.sd->singletonInstanceInfo;
@@ -823,6 +930,8 @@ QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
QQmlCustomParser *QQmlType::customParser() const
{
+ if (!d)
+ return 0;
if (d->regType != CppType)
return 0;
return d->extraData.cd->customParser;
@@ -830,32 +939,34 @@ QQmlCustomParser *QQmlType::customParser() const
QQmlType::CreateFunc QQmlType::createFunction() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return 0;
return d->extraData.cd->newFunc;
}
QString QQmlType::noCreationReason() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return QString();
return d->extraData.cd->noCreationReason;
}
int QQmlType::createSize() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return 0;
return d->extraData.cd->allocationSize;
}
bool QQmlType::isCreatable() const
{
- return d->regType == CppType && d->extraData.cd->newFunc;
+ return d && d->regType == CppType && d->extraData.cd->newFunc;
}
bool QQmlType::isExtendedType() const
{
+ if (!d)
+ return false;
d->init();
return !d->metaObjects.isEmpty();
@@ -863,36 +974,38 @@ bool QQmlType::isExtendedType() const
bool QQmlType::isSingleton() const
{
- return d->regType == SingletonType || d->regType == CompositeSingletonType;
+ return d && (d->regType == SingletonType || d->regType == CompositeSingletonType);
}
bool QQmlType::isInterface() const
{
- return d->regType == InterfaceType;
+ return d && d->regType == InterfaceType;
}
bool QQmlType::isComposite() const
{
- return d->regType == CompositeType || d->regType == CompositeSingletonType;
+ return d && (d->regType == CompositeType || d->regType == CompositeSingletonType);
}
bool QQmlType::isCompositeSingleton() const
{
- return d->regType == CompositeSingletonType;
+ return d && d->regType == CompositeSingletonType;
}
int QQmlType::typeId() const
{
- return d->typeId;
+ return d ? d->typeId : -1;
}
int QQmlType::qListTypeId() const
{
- return d->listId;
+ return d ? d->listId : -1;
}
const QMetaObject *QQmlType::metaObject() const
{
+ if (!d)
+ return 0;
d->init();
if (d->metaObjects.isEmpty())
@@ -904,11 +1017,13 @@ const QMetaObject *QQmlType::metaObject() const
const QMetaObject *QQmlType::baseMetaObject() const
{
- return d->baseMetaObject;
+ return d ? d->baseMetaObject : 0;
}
bool QQmlType::containsRevisionedAttributes() const
{
+ if (!d)
+ return false;
d->init();
return d->containsRevisionedAttributes;
@@ -916,29 +1031,33 @@ bool QQmlType::containsRevisionedAttributes() const
int QQmlType::metaObjectRevision() const
{
- return d->revision;
+ return d ? d->revision : -1;
}
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
{
+ if (!d)
+ return 0;
if (d->regType == CppType)
return d->extraData.cd->attachedPropertiesFunc;
- QQmlType *base = 0;
+ QQmlType base;
if (d->regType == CompositeType)
base = resolveCompositeBaseType(engine);
- return base ? base->attachedPropertiesFunction(engine) : 0;
+ return base.attachedPropertiesFunction(engine);
}
const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) const
{
+ if (!d)
+ return 0;
if (d->regType == CppType)
return d->extraData.cd->attachedPropertiesType;
- QQmlType *base = 0;
+ QQmlType base;
if (d->regType == CompositeType)
base = resolveCompositeBaseType(engine);
- return base ? base->attachedPropertiesType(engine) : 0;
+ return base.attachedPropertiesType(engine);
}
/*
@@ -948,70 +1067,75 @@ Qt 4.7 and QtQuick 1.0).
*/
int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const
{
+ if (!d)
+ return -1;
if (d->regType == CppType)
return d->extraData.cd->attachedPropertiesId;
- QQmlType *base = 0;
+ QQmlType base;
if (d->regType == CompositeType)
base = resolveCompositeBaseType(engine);
- return base ? base->attachedPropertiesId(engine) : 0;
+ return base.attachedPropertiesId(engine);
}
int QQmlType::parserStatusCast() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return -1;
return d->extraData.cd->parserStatusCast;
}
int QQmlType::propertyValueSourceCast() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return -1;
return d->extraData.cd->propertyValueSourceCast;
}
int QQmlType::propertyValueInterceptorCast() const
{
- if (d->regType != CppType)
+ if (!d || d->regType != CppType)
return -1;
return d->extraData.cd->propertyValueInterceptorCast;
}
const char *QQmlType::interfaceIId() const
{
- if (d->regType != InterfaceType)
+ if (!d || d->regType != InterfaceType)
return 0;
return d->iid;
}
int QQmlType::index() const
{
- return d->index;
+ return d ? d->index : -1;
}
QUrl QQmlType::sourceUrl() const
{
- if (d->regType == CompositeType)
- return d->extraData.fd->url;
- else if (d->regType == CompositeSingletonType)
- return d->extraData.sd->singletonInstanceInfo->url;
- else
- return QUrl();
+ if (d) {
+ if (d->regType == CompositeType)
+ return d->extraData.fd->url;
+ else if (d->regType == CompositeSingletonType)
+ return d->extraData.sd->singletonInstanceInfo->url;
+ }
+ return QUrl();
}
int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
+ *ok = true;
- d->initEnums(cache);
+ d->initEnums(cache);
- int *rv = d->enums.value(name);
- if (rv)
- return *rv;
+ int *rv = d->enums.value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1020,15 +1144,17 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name,
int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
+ *ok = true;
- d->initEnums(cache);
+ d->initEnums(cache);
- int *rv = d->enums.value(name);
- if (rv)
- return *rv;
+ int *rv = d->enums.value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1037,14 +1163,16 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name
int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
- d->initEnums(cache);
+ d->initEnums(cache);
- int *rv = d->enums.value(name);
- if (rv)
- return *rv;
+ int *rv = d->enums.value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1053,14 +1181,16 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool
int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
- d->initEnums(cache);
+ d->initEnums(cache);
- int *rv = d->scopedEnumIndex.value(name);
- if (rv)
- return *rv;
+ int *rv = d->scopedEnumIndex.value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1069,14 +1199,16 @@ int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name
int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
- d->initEnums(cache);
+ d->initEnums(cache);
- int *rv = d->scopedEnumIndex.value(name);
- if (rv)
- return *rv;
+ int *rv = d->scopedEnumIndex.value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1088,10 +1220,12 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::S
Q_ASSERT(ok);
*ok = true;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- int *rv = d->scopedEnums.at(index)->value(name);
- if (rv)
- return *rv;
+ if (d) {
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ int *rv = d->scopedEnums.at(index)->value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1103,10 +1237,12 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QStrin
Q_ASSERT(ok);
*ok = true;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- int *rv = d->scopedEnums.at(index)->value(name);
- if (rv)
- return *rv;
+ if (d) {
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ int *rv = d->scopedEnums.at(index)->value(name);
+ if (rv)
+ return *rv;
+ }
*ok = false;
return -1;
@@ -1115,18 +1251,20 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QStrin
int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scopedEnumName, const QByteArray &name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
-
- d->initEnums(cache);
-
- int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length()));
- if (rv) {
- int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length()));
- if (rv)
- return *rv;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length()));
+ if (rv) {
+ int index = *rv;
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length()));
+ if (rv)
+ return *rv;
+ }
}
*ok = false;
@@ -1136,24 +1274,59 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scope
int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scopedEnumName, const QStringRef &name, bool *ok) const
{
Q_ASSERT(ok);
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
- *ok = true;
-
- d->initEnums(cache);
-
- int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName));
- if (rv) {
- int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- rv = d->scopedEnums.at(index)->value(QHashedStringRef(name));
- if (rv)
- return *rv;
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName));
+ if (rv) {
+ int index = *rv;
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ rv = d->scopedEnums.at(index)->value(QHashedStringRef(name));
+ if (rv)
+ return *rv;
+ }
}
*ok = false;
return -1;
}
+void QQmlType::refHandle(QQmlTypePrivate *priv)
+{
+ if (priv)
+ priv->refCount.ref();
+}
+
+void QQmlType::derefHandle(QQmlTypePrivate *priv)
+{
+ if (priv && !priv->refCount.deref())
+ delete priv;
+}
+
+namespace {
+template <typename QQmlTypeContainer>
+void removeQQmlTypePrivate(QQmlTypeContainer &container, const QQmlTypePrivate *reference)
+{
+ for (typename QQmlTypeContainer::iterator it = container.begin(); it != container.end();) {
+ if (*it == reference)
+ it = container.erase(it);
+ else
+ ++it;
+ }
+}
+
+struct IsQQmlTypePrivate
+{
+ const QQmlTypePrivate *reference;
+ explicit IsQQmlTypePrivate(const QQmlTypePrivate *ref) : reference(ref) {}
+
+ bool operator()(const QQmlTypePrivate *priv) const { return reference == priv; }
+};
+}
+
QQmlTypeModule::QQmlTypeModule()
: d(new QQmlTypeModulePrivate)
{
@@ -1184,14 +1357,16 @@ int QQmlTypeModule::maximumMinorVersion() const
return d->maxMinorVersion;
}
-void QQmlTypeModulePrivate::add(QQmlType *type)
+void QQmlTypeModulePrivate::add(QQmlTypePrivate *type)
{
- minMinorVersion = qMin(minMinorVersion, type->minorVersion());
- maxMinorVersion = qMax(maxMinorVersion, type->minorVersion());
+ int minVersion = type->version_min;
+ minMinorVersion = qMin(minMinorVersion, minVersion);
+ maxMinorVersion = qMax(maxMinorVersion, minVersion);
- QList<QQmlType *> &list = typeHash[type->elementName()];
+ QList<QQmlTypePrivate *> &list = typeHash[type->elementName];
for (int ii = 0; ii < list.count(); ++ii) {
- if (list.at(ii)->minorVersion() < type->minorVersion()) {
+ Q_ASSERT(list.at(ii));
+ if (list.at(ii)->version_min < minVersion) {
list.insert(ii, type);
return;
}
@@ -1199,46 +1374,50 @@ void QQmlTypeModulePrivate::add(QQmlType *type)
list.append(type);
}
-QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor) const
+void QQmlTypeModulePrivate::remove(const QQmlTypePrivate *type)
{
- QMutexLocker lock(metaTypeDataLock());
+ for (TypeHash::ConstIterator elementIt = typeHash.begin(); elementIt != typeHash.end();) {
+ QList<QQmlTypePrivate *> &list = typeHash[elementIt.key()];
- QList<QQmlType *> *types = d->typeHash.value(name);
- if (!types) return 0;
+ removeQQmlTypePrivate(list, type);
- for (int ii = 0; ii < types->count(); ++ii)
- if (types->at(ii)->minorVersion() <= minor)
- return types->at(ii);
-
- return 0;
+#if 0
+ if (list.isEmpty())
+ elementIt = typeHash.erase(elementIt);
+ else
+ ++elementIt;
+#else
+ ++elementIt;
+#endif
+ }
}
-QQmlType *QQmlTypeModule::type(const QV4::String *name, int minor) const
+QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const
{
QMutexLocker lock(metaTypeDataLock());
- QList<QQmlType *> *types = d->typeHash.value(name);
- if (!types) return 0;
-
- for (int ii = 0; ii < types->count(); ++ii)
- if (types->at(ii)->minorVersion() <= minor)
- return types->at(ii);
+ QList<QQmlTypePrivate *> *types = d->typeHash.value(name);
+ if (types) {
+ for (int ii = 0; ii < types->count(); ++ii)
+ if (types->at(ii)->version_min <= minor)
+ return QQmlType(types->at(ii));
+ }
- return 0;
+ return QQmlType();
}
-QList<QQmlType*> QQmlTypeModule::singletonTypes(int minor) const
+QQmlType QQmlTypeModule::type(const QV4::String *name, int minor) const
{
QMutexLocker lock(metaTypeDataLock());
- QList<QQmlType *> retn;
- for (int ii = 0; ii < d->types.count(); ++ii) {
- QQmlType *curr = d->types.at(ii);
- if (curr->isSingleton() && curr->minorVersion() <= minor)
- retn.append(curr);
+ QList<QQmlTypePrivate *> *types = d->typeHash.value(name);
+ if (types) {
+ for (int ii = 0; ii < types->count(); ++ii)
+ if (types->at(ii)->version_min <= minor)
+ return QQmlType(types->at(ii));
}
- return retn;
+ return QQmlType();
}
QQmlTypeModuleVersion::QQmlTypeModuleVersion()
@@ -1275,16 +1454,18 @@ int QQmlTypeModuleVersion::minorVersion() const
return m_minor;
}
-QQmlType *QQmlTypeModuleVersion::type(const QHashedStringRef &name) const
+QQmlType QQmlTypeModuleVersion::type(const QHashedStringRef &name) const
{
- if (m_module) return m_module->type(name, m_minor);
- else return 0;
+ if (!m_module)
+ return QQmlType();
+ return m_module->type(name, m_minor);
}
-QQmlType *QQmlTypeModuleVersion::type(const QV4::String *name) const
+QQmlType QQmlTypeModuleVersion::type(const QV4::String *name) const
{
- if (m_module) return m_module->type(name, m_minor);
- else return 0;
+ if (!m_module)
+ return QQmlType();
+ return m_module->type(name, m_minor);
}
void qmlClearTypeRegistrations() // Declared in qqml.h
@@ -1293,9 +1474,6 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- for (int i = 0; i < data->types.count(); ++i)
- delete data->types.at(i);
-
for (QQmlMetaTypeData::TypeModules::const_iterator i = data->uriToModule.constBegin(), cend = data->uriToModule.constEnd(); i != cend; ++i)
delete *i;
@@ -1313,7 +1491,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
#endif
}
-int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
+static int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
@@ -1323,7 +1501,7 @@ int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
return data->parentFunctions.count() - 1;
}
-int registerInterface(const QQmlPrivate::RegisterInterface &interface)
+QQmlType registerInterface(const QQmlPrivate::RegisterInterface &interface)
{
if (interface.version > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
@@ -1331,16 +1509,15 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- int index = data->types.count();
+ QQmlType type(data, interface);
+ QQmlTypePrivate *priv = type.priv();
+ Q_ASSERT(priv);
- QQmlType *type = new QQmlType(index, interface);
-
- data->types.append(type);
- data->idToType.insert(type->typeId(), type);
- data->idToType.insert(type->qListTypeId(), type);
+ data->idToType.insert(priv->typeId, priv);
+ data->idToType.insert(priv->listId, priv);
// XXX No insertMulti, so no multi-version interfaces?
- if (!type->elementName().isEmpty())
- data->nameToType.insert(type->elementName(), type);
+ if (!priv->elementName.isEmpty())
+ data->nameToType.insert(priv->elementName, priv);
if (data->interfaces.size() <= interface.typeId)
data->interfaces.resize(interface.typeId + 16);
@@ -1349,7 +1526,7 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
data->interfaces.setBit(interface.typeId, true);
data->lists.setBit(interface.listId, true);
- return index;
+ return type;
}
QString registrationTypeString(QQmlType::RegistrationType typeType)
@@ -1431,76 +1608,72 @@ QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMe
}
// NOTE: caller must hold a QMutexLocker on "data"
-void addTypeToData(QQmlType* type, QQmlMetaTypeData *data)
+void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
{
- if (!type->elementName().isEmpty())
- data->nameToType.insertMulti(type->elementName(), type);
+ Q_ASSERT(type);
+
+ if (!type->elementName.isEmpty())
+ data->nameToType.insertMulti(type->elementName, type);
- if (type->baseMetaObject())
- data->metaObjectToType.insertMulti(type->baseMetaObject(), type);
+ if (type->baseMetaObject)
+ data->metaObjectToType.insertMulti(type->baseMetaObject, type);
- if (type->typeId()) {
- data->idToType.insert(type->typeId(), type);
- if (data->objects.size() <= type->typeId())
- data->objects.resize(type->typeId() + 16);
- data->objects.setBit(type->typeId(), true);
+ if (type->typeId) {
+ data->idToType.insert(type->typeId, type);
+ if (data->objects.size() <= type->typeId)
+ data->objects.resize(type->typeId + 16);
+ data->objects.setBit(type->typeId, true);
}
- if (type->qListTypeId()) {
- if (data->lists.size() <= type->qListTypeId())
- data->lists.resize(type->qListTypeId() + 16);
- data->lists.setBit(type->qListTypeId(), true);
- data->idToType.insert(type->qListTypeId(), type);
+ if (type->listId) {
+ if (data->lists.size() <= type->listId)
+ data->lists.resize(type->listId + 16);
+ data->lists.setBit(type->listId, true);
+ data->idToType.insert(type->listId, type);
}
- if (!type->module().isEmpty()) {
- const QHashedString &mod = type->module();
+ if (!type->module.isEmpty()) {
+ const QHashedString &mod = type->module;
- QQmlTypeModule *module = getTypeModule(mod, type->majorVersion(), data);
+ QQmlTypeModule *module = getTypeModule(mod, type->version_maj, data);
Q_ASSERT(module);
module->d->add(type);
}
}
-int registerType(const QQmlPrivate::RegisterType &type)
+QQmlType registerType(const QQmlPrivate::RegisterType &type)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString elementName = QString::fromUtf8(type.elementName);
if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType *dtype = new QQmlType(index, elementName, type);
+ QQmlType dtype(data, elementName, type);
- data->types.append(dtype);
- addTypeToData(dtype, data);
+ addTypeToData(dtype.priv(), data);
if (!type.typeId)
- data->idToType.insert(dtype->typeId(), dtype);
+ data->idToType.insert(dtype.typeId(), dtype.priv());
- return index;
+ return dtype;
}
-int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
+QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType *dtype = new QQmlType(index, typeName, type);
+ QQmlType dtype(data, typeName, type);
- data->types.append(dtype);
- addTypeToData(dtype, data);
+ addTypeToData(dtype.priv(), data);
- return index;
+ return dtype;
}
-int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
+QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QMutexLocker lock(metaTypeDataLock());
@@ -1510,22 +1683,19 @@ int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingleton
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? 0 : type.uri, typeName))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType *dtype = new QQmlType(index, typeName, type);
+ QQmlType dtype(data, typeName, type);
- data->types.append(dtype);
- addTypeToData(dtype, data);
+ addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype);
+ files->insertMulti(type.url, dtype.priv());
- return index;
+ return dtype;
}
-int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
+QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QMutexLocker lock(metaTypeDataLock());
@@ -1535,18 +1705,56 @@ int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType *dtype = new QQmlType(index, typeName, type);
- data->types.append(dtype);
- addTypeToData(dtype, data);
+ QQmlType dtype(data, typeName, type);
+ addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype);
+ files->insertMulti(type.url, dtype.priv());
- return index;
+ return dtype;
+}
+
+void QQmlMetaType::registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit)
+{
+ QByteArray name = compilationUnit->rootPropertyCache()->className();
+
+ QByteArray ptr = name + '*';
+ QByteArray lst = "QQmlListProperty<" + name + '>';
+
+ int ptr_type = QMetaType::registerNormalizedType(ptr,
+ QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Destruct,
+ QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Construct,
+ sizeof(QObject*),
+ static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
+ 0);
+ int lst_type = QMetaType::registerNormalizedType(lst,
+ QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Destruct,
+ QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Construct,
+ sizeof(QQmlListProperty<QObject>),
+ static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
+ static_cast<QMetaObject*>(0));
+
+ compilationUnit->metaTypeId = ptr_type;
+ compilationUnit->listMetaTypeId = lst_type;
+
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *d = metaTypeData();
+ d->qmlLists.insert(lst_type, ptr_type);
+}
+
+void QQmlMetaType::unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit)
+{
+ int ptr_type = compilationUnit->metaTypeId;
+ int lst_type = compilationUnit->listMetaTypeId;
+
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *d = metaTypeData();
+ d->qmlLists.remove(lst_type);
+
+ QMetaType::unregisterType(ptr_type);
+ QMetaType::unregisterType(lst_type);
}
int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
@@ -1565,22 +1773,30 @@ the future without adding exported symbols.
*/
int QQmlPrivate::qmlregister(RegistrationType type, void *data)
{
- if (type == TypeRegistration) {
- return registerType(*reinterpret_cast<RegisterType *>(data));
- } else if (type == InterfaceRegistration) {
- return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
- } else if (type == AutoParentRegistration) {
+ if (type == AutoParentRegistration)
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
- } else if (type == SingletonRegistration) {
- return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
- } else if (type == CompositeRegistration) {
- return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
- } else if (type == CompositeSingletonRegistration) {
- return registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
- } else if (type == QmlUnitCacheHookRegistration) {
+ else if (type == QmlUnitCacheHookRegistration)
return registerQmlUnitCacheHook(*reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
- }
- return -1;
+
+ QQmlType dtype;
+ if (type == TypeRegistration)
+ dtype = registerType(*reinterpret_cast<RegisterType *>(data));
+ else if (type == InterfaceRegistration)
+ dtype = registerInterface(*reinterpret_cast<RegisterInterface *>(data));
+ else if (type == SingletonRegistration)
+ dtype = registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
+ else if (type == CompositeRegistration)
+ dtype = QQmlMetaType::registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
+ else if (type == CompositeSingletonRegistration)
+ dtype = QQmlMetaType::registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
+ else
+ return -1;
+
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *typeData = metaTypeData();
+ typeData->undeletableTypes.insert(dtype);
+
+ return dtype.index();
}
//From qqml.h
@@ -1620,8 +1836,8 @@ bool QQmlMetaType::namespaceContainsRegistrations(const QString &uri, int majorV
// Has any type previously been installed to this namespace?
QHashedString nameSpace(uri);
- for (const QQmlType *type : data->types)
- if (type->module() == nameSpace && type->majorVersion() == majorVersion)
+ for (const QQmlType &type : data->types)
+ if (type.module() == nameSpace && type.majorVersion() == majorVersion)
return true;
return false;
@@ -1753,9 +1969,12 @@ int QQmlMetaType::listType(int id)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlType *type = data->idToType.value(id);
- if (type && type->qListTypeId() == id)
- return type->typeId();
+ QHash<int, int>::ConstIterator iter = data->qmlLists.constFind(id);
+ if (iter != data->qmlLists.cend())
+ return *iter;
+ QQmlTypePrivate *type = data->idToType.value(id);
+ if (type && type->listId == id)
+ return type->typeId;
else
return 0;
}
@@ -1765,9 +1984,9 @@ int QQmlMetaType::attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMet
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlType *type = data->metaObjectToType.value(mo);
- if (type && type->attachedPropertiesFunction(engine))
- return type->attachedPropertiesId(engine);
+ QQmlType type(data->metaObjectToType.value(mo));
+ if (type.attachedPropertiesFunction(engine))
+ return type.attachedPropertiesId(engine);
else
return -1;
}
@@ -1778,7 +1997,7 @@ QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(QQmlEnginePr
return 0;
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- return data->types.at(id)->attachedPropertiesFunction(engine);
+ return data->types.at(id).attachedPropertiesFunction(engine);
}
QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject)
@@ -1842,7 +2061,9 @@ QQmlMetaType::TypeCategory QQmlMetaType::typeCategory(int userType)
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- if (userType < data->objects.size() && data->objects.testBit(userType))
+ if (data->qmlLists.contains(userType))
+ return List;
+ else if (userType < data->objects.size() && data->objects.testBit(userType))
return Object;
else if (userType < data->lists.size() && data->lists.testBit(userType))
return List;
@@ -1861,10 +2082,10 @@ const char *QQmlMetaType::interfaceIId(int userType)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlType *type = data->idToType.value(userType);
+ QQmlType type(data->idToType.value(userType));
lock.unlock();
- if (type && type->isInterface() && type->typeId() == userType)
- return type->interfaceIId();
+ if (type.isInterface() && type.typeId() == userType)
+ return type.interfaceIId();
else
return 0;
}
@@ -1873,6 +2094,8 @@ bool QQmlMetaType::isList(int userType)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
+ if (data->qmlLists.contains(userType))
+ return true;
return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
}
@@ -1917,11 +2140,11 @@ QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type)
Returns the type (if any) of URI-qualified named \a qualifiedName and version specified
by \a version_major and \a version_minor.
*/
-QQmlType *QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor)
{
int slash = qualifiedName.indexOf(QLatin1Char('/'));
if (slash <= 0)
- return 0;
+ return QQmlType();
QHashedStringRef module(qualifiedName.constData(), slash);
QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
@@ -1933,7 +2156,7 @@ QQmlType *QQmlMetaType::qmlType(const QString &qualifiedName, int version_major,
Returns the type (if any) of \a name in \a module and version specified
by \a version_major and \a version_minor.
*/
-QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QMutexLocker lock(metaTypeDataLock());
@@ -1941,25 +2164,26 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
while (it != data->nameToType.cend() && it.key() == name) {
+ QQmlType t(*it);
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
- if (version_major < 0 || module.isEmpty() || (*it)->availableInVersion(module, version_major,version_minor))
- return (*it);
+ if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor))
+ return t;
++it;
}
- return 0;
+ return QQmlType();
}
/*!
Returns the type (if any) that corresponds to the \a metaObject. Returns null if no
type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject)
+QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- return data->metaObjectToType.value(metaObject);
+ return QQmlType(data->metaObjectToType.value(metaObject));
}
/*!
@@ -1967,7 +2191,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject)
by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QMutexLocker lock(metaTypeDataLock());
@@ -1975,29 +2199,29 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
while (it != data->metaObjectToType.cend() && it.key() == metaObject) {
- QQmlType *t = *it;
- if (version_major < 0 || module.isEmpty() || t->availableInVersion(module, version_major,version_minor))
+ QQmlType t(*it);
+ if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor))
return t;
++it;
}
- return 0;
+ return QQmlType();
}
/*!
Returns the type (if any) that corresponds to the QVariant::Type \a userType.
Returns null if no type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(int userType)
+QQmlType QQmlMetaType::qmlType(int userType)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlType *type = data->idToType.value(userType);
- if (type && type->typeId() == userType)
- return type;
+ QQmlTypePrivate *type = data->idToType.value(userType);
+ if (type && type->typeId == userType)
+ return QQmlType(type);
else
- return 0;
+ return QQmlType();
}
/*!
@@ -2006,34 +2230,209 @@ QQmlType *QQmlMetaType::qmlType(int userType)
Returns null if no such type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
+QQmlType QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlType *type = data->urlToType.value(url);
- if (!type && includeNonFileImports)
- type = data->urlToNonFileImportType.value(url);
+ QQmlType type(data->urlToType.value(url));
+ if (!type.isValid() && includeNonFileImports)
+ type = QQmlType(data->urlToNonFileImportType.value(url));
- if (type && type->sourceUrl() == url)
+ if (type.sourceUrl() == url)
return type;
else
+ return QQmlType();
+}
+
+QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject)
+{
+ if (QQmlPropertyCache *rv = propertyCaches.value(metaObject))
+ return rv;
+
+ if (!metaObject->superClass()) {
+ QQmlPropertyCache *rv = new QQmlPropertyCache(metaObject);
+ propertyCaches.insert(metaObject, rv);
+ return rv;
+ }
+ QQmlPropertyCache *super = propertyCache(metaObject->superClass());
+ QQmlPropertyCache *rv = super->copyAndAppend(metaObject);
+ propertyCaches.insert(metaObject, rv);
+ return rv;
+}
+
+QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject)
+{
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ return data->propertyCache(metaObject);
+}
+
+QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int minorVersion)
+{
+ Q_ASSERT(type.isValid());
+
+ if (QQmlPropertyCache *pc = type.key()->propertyCacheForMinorVersion(minorVersion))
+ return pc;
+
+ QVector<QQmlType> types;
+
+ int maxMinorVersion = 0;
+
+ const QMetaObject *metaObject = type.metaObject();
+
+ while (metaObject) {
+ QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), type.majorVersion(), minorVersion);
+ if (t.isValid()) {
+ maxMinorVersion = qMax(maxMinorVersion, t.minorVersion());
+ types << t;
+ } else {
+ types << QQmlType();
+ }
+
+ metaObject = metaObject->superClass();
+ }
+
+ if (QQmlPropertyCache *pc = type.key()->propertyCacheForMinorVersion(maxMinorVersion)) {
+ const_cast<QQmlTypePrivate*>(type.key())->setPropertyCacheForMinorVersion(minorVersion, pc);
+ return pc;
+ }
+
+ QQmlPropertyCache *raw = propertyCache(type.metaObject());
+
+ bool hasCopied = false;
+
+ for (int ii = 0; ii < types.count(); ++ii) {
+ QQmlType currentType = types.at(ii);
+ if (!currentType.isValid())
+ continue;
+
+ int rev = currentType.metaObjectRevision();
+ int moIndex = types.count() - 1 - ii;
+
+ if (raw->allowedRevisionCache[moIndex] != rev) {
+ if (!hasCopied) {
+ raw = raw->copy();
+ hasCopied = true;
+ }
+ raw->allowedRevisionCache[moIndex] = rev;
+ }
+ }
+
+ // Test revision compatibility - the basic rule is:
+ // * Anything that is excluded, cannot overload something that is not excluded *
+
+ // Signals override:
+ // * other signals and methods of the same name.
+ // * properties named on<Signal Name>
+ // * automatic <property name>Changed notify signals
+
+ // Methods override:
+ // * other methods of the same name
+
+ // Properties override:
+ // * other elements of the same name
+
+#if 0
+ bool overloadError = false;
+ QString overloadName;
+
+ for (QQmlPropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
+ !overloadError && iter != raw->stringCache.end();
+ ++iter) {
+
+ QQmlPropertyData *d = *iter;
+ if (raw->isAllowedInRevision(d))
+ continue; // Not excluded - no problems
+
+ // check that a regular "name" overload isn't happening
+ QQmlPropertyData *current = d;
+ while (!overloadError && current) {
+ current = d->overrideData(current);
+ if (current && raw->isAllowedInRevision(current))
+ overloadError = true;
+ }
+ }
+
+ if (overloadError) {
+ if (hasCopied) raw->release();
+
+ error.setDescription(QLatin1String("Type ") + type.qmlTypeName() + QLatin1Char(' ') + QString::number(type.majorVersion()) + QLatin1Char('.') + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation."));
return 0;
+ }
+#endif
+
+ const_cast<QQmlTypePrivate*>(type.key())->setPropertyCacheForMinorVersion(minorVersion, raw);
+
+ if (hasCopied)
+ raw->release();
+
+ if (minorVersion != maxMinorVersion)
+ const_cast<QQmlTypePrivate*>(type.key())->setPropertyCacheForMinorVersion(maxMinorVersion, raw);
+
+ return raw;
}
-/*!
- Returns the type (if any) with the given \a index in the global type store.
- This is for use when you just got the index back from a qmlRegister function.
- Returns null if the index is out of bounds.
-*/
-QQmlType *QQmlMetaType::qmlTypeFromIndex(int idx)
+QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVersion)
+{
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ return data->propertyCache(type, minorVersion);
+}
+
+void QQmlMetaType::freeUnusedTypesAndCaches()
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- if (idx < 0 || idx >= data->types.count())
- return 0;
- return data->types.at(idx);
+ {
+ bool deletedAtLeastOneType;
+ do {
+ deletedAtLeastOneType = false;
+ QList<QQmlType>::Iterator it = data->types.begin();
+ while (it != data->types.end()) {
+ const QQmlTypePrivate *d = (*it).priv();
+ if (d && d->refCount == 1) {
+ deletedAtLeastOneType = true;
+
+ removeQQmlTypePrivate(data->idToType, d);
+ removeQQmlTypePrivate(data->nameToType, d);
+ removeQQmlTypePrivate(data->urlToType, d);
+ removeQQmlTypePrivate(data->urlToNonFileImportType, d);
+ removeQQmlTypePrivate(data->metaObjectToType, d);
+
+ for (QQmlMetaTypeData::TypeModules::Iterator module = data->uriToModule.begin(); module != data->uriToModule.end(); ++module) {
+ QQmlTypeModulePrivate *modulePrivate = (*module)->priv();
+ modulePrivate->remove(d);
+ }
+
+ *it = QQmlType();
+ } else {
+ ++it;
+ }
+ }
+ } while (deletedAtLeastOneType);
+ }
+
+ {
+ bool deletedAtLeastOneCache;
+ do {
+ deletedAtLeastOneCache = false;
+ QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = data->propertyCaches.begin();
+ while (it != data->propertyCaches.end()) {
+
+ if ((*it)->count() == 1) {
+ QQmlPropertyCache *pc = Q_NULLPTR;
+ qSwap(pc, *it);
+ it = data->propertyCaches.erase(it);
+ pc->release();
+ deletedAtLeastOneCache = true;
+ } else {
+ ++it;
+ }
+ }
+ } while (deletedAtLeastOneCache);
+ }
}
/*!
@@ -2048,7 +2447,8 @@ QList<QString> QQmlMetaType::qmlTypeNames()
names.reserve(data->nameToType.count());
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
while (it != data->nameToType.cend()) {
- names += (*it)->qmlTypeName();
+ QQmlType t(*it);
+ names += t.qmlTypeName();
++it;
}
@@ -2058,18 +2458,22 @@ QList<QString> QQmlMetaType::qmlTypeNames()
/*!
Returns the list of registered QML types.
*/
-QList<QQmlType*> QQmlMetaType::qmlTypes()
+QList<QQmlType> QQmlMetaType::qmlTypes()
{
QMutexLocker lock(metaTypeDataLock());
- QQmlMetaTypeData *data = metaTypeData();
+ const QQmlMetaTypeData *data = metaTypeData();
+
+ QList<QQmlType> types;
+ for (QQmlTypePrivate *t : data->nameToType)
+ types.append(QQmlType(t));
- return data->nameToType.values();
+ return types;
}
/*!
Returns the list of all registered types.
*/
-QList<QQmlType*> QQmlMetaType::qmlAllTypes()
+QList<QQmlType> QQmlMetaType::qmlAllTypes()
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
@@ -2080,14 +2484,15 @@ QList<QQmlType*> QQmlMetaType::qmlAllTypes()
/*!
Returns the list of registered QML singleton types.
*/
-QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
+QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QList<QQmlType*> retn;
- for (const auto type : qAsConst(data->nameToType)) {
- if (type->isSingleton())
+ QList<QQmlType> retn;
+ for (const auto t : qAsConst(data->nameToType)) {
+ QQmlType type(t);
+ if (type.isSingleton())
retn.append(type);
}
return retn;
@@ -2115,9 +2520,9 @@ QString QQmlMetaType::prettyTypeName(const QObject *object)
if (!object)
return typeName;
- const QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
- if (type) {
- typeName = type->qmlTypeName();
+ QQmlType type = QQmlMetaType::qmlType(object->metaObject());
+ if (type.isValid()) {
+ typeName = type.qmlTypeName();
const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
typeName = typeName.mid(lastSlash + 1);
@@ -2133,8 +2538,8 @@ QString QQmlMetaType::prettyTypeName(const QObject *object)
if (marker != -1) {
typeName = typeName.leftRef(marker) + QLatin1Char('*');
type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
- if (type) {
- QString qmlTypeName = type->qmlTypeName();
+ if (type.isValid()) {
+ QString qmlTypeName = type.qmlTypeName();
const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
qmlTypeName = qmlTypeName.mid(lastSlash + 1);
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index ead4f130ec..8eb91f321a 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -70,24 +70,36 @@ class QQmlTypeModule;
class QHashedString;
class QHashedStringRef;
class QMutex;
+class QQmlPropertyCache;
+class QQmlCompiledData;
namespace QV4 { struct String; }
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
public:
+ static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type);
+ static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type);
+
+ static void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
+ static void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
+
static QList<QString> qmlTypeNames();
- static QList<QQmlType*> qmlTypes();
- static QList<QQmlType*> qmlSingletonTypes();
- static QList<QQmlType*> qmlAllTypes();
-
- static QQmlType *qmlType(const QString &qualifiedName, int, int);
- static QQmlType *qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int);
- static QQmlType *qmlType(const QMetaObject *);
- static QQmlType *qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
- static QQmlType *qmlType(int);
- static QQmlType *qmlType(const QUrl &url, bool includeNonFileImports = false);
- static QQmlType *qmlTypeFromIndex(int);
+ static QList<QQmlType> qmlTypes();
+ static QList<QQmlType> qmlSingletonTypes();
+ static QList<QQmlType> qmlAllTypes();
+
+ static QQmlType qmlType(const QString &qualifiedName, int, int);
+ static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int);
+ static QQmlType qmlType(const QMetaObject *);
+ static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
+ static QQmlType qmlType(int);
+ static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false);
+
+ static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject);
+ static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
+
+ static void freeUnusedTypesAndCaches();
static QMetaProperty defaultProperty(const QMetaObject *);
static QMetaProperty defaultProperty(QObject *);
@@ -139,11 +151,24 @@ class QQmlPropertyCache;
class Q_QML_PRIVATE_EXPORT QQmlType
{
public:
+ QQmlType();
+ QQmlType(const QQmlType &other);
+ QQmlType &operator =(const QQmlType &other);
+ explicit QQmlType(QQmlTypePrivate *priv);
+ ~QQmlType();
+
+ bool operator ==(const QQmlType &other) const {
+ return d == other.d;
+ }
+
+ bool isValid() const { return d != 0; }
+ const QQmlTypePrivate *key() const { return d; }
+
QByteArray typeName() const;
- const QString &qmlTypeName() const;
- const QString &elementName() const;
+ QString qmlTypeName() const;
+ QString elementName() const;
- const QHashedString &module() const;
+ QHashedString module() const;
int majorVersion() const;
int minorVersion() const;
@@ -225,12 +250,9 @@ public:
int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &, const QStringRef &, bool *ok) const;
-private:
- QQmlType *superType() const;
- QQmlType *resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
- QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const;
- friend class QQmlTypePrivate;
- friend struct QQmlMetaTypeData;
+ QQmlTypePrivate *priv() const { return d; }
+ static void refHandle(QQmlTypePrivate *priv);
+ static void derefHandle(QQmlTypePrivate *priv);
enum RegistrationType {
CppType = 0,
@@ -239,25 +261,39 @@ private:
CompositeType = 3,
CompositeSingletonType = 4
};
+
+private:
+ QQmlType superType() const;
+ QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
+ int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const;
+ QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const;
+ friend class QQmlTypePrivate;
+
friend QString registrationTypeString(RegistrationType);
friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &, int);
- friend int registerType(const QQmlPrivate::RegisterType &);
- friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
- friend int registerInterface(const QQmlPrivate::RegisterInterface &);
- friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
- friend int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &);
+ friend QQmlType registerType(const QQmlPrivate::RegisterType &);
+ friend QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
+ friend QQmlType registerInterface(const QQmlPrivate::RegisterInterface &);
friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &);
+ friend uint qHash(const QQmlType &t, uint seed);
friend Q_QML_EXPORT void qmlClearTypeRegistrations();
- QQmlType(int, const QQmlPrivate::RegisterInterface &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &);
- ~QQmlType();
+ friend class QQmlMetaType;
+
+ QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterSingletonType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &);
QQmlTypePrivate *d;
};
+Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE);
+
+
+inline uint qHash(const QQmlType &t, uint seed = 0) { return qHash(reinterpret_cast<quintptr>(t.d), seed); }
+
+
class QQmlTypeModulePrivate;
class QQmlTypeModule
{
@@ -268,15 +304,14 @@ public:
int minimumMinorVersion() const;
int maximumMinorVersion() const;
- QQmlType *type(const QHashedStringRef &, int) const;
- QQmlType *type(const QV4::String *, int) const;
-
- QList<QQmlType*> singletonTypes(int) const;
+ QQmlType type(const QHashedStringRef &, int) const;
+ QQmlType type(const QV4::String *, int) const;
+ QQmlTypeModulePrivate *priv() { return d; }
private:
//Used by register functions and creates the QQmlTypeModule for them
friend QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data);
- friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data);
+ friend void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data);
friend struct QQmlMetaTypeData;
friend Q_QML_EXPORT void qmlClearTypeRegistrations();
friend class QQmlTypeModulePrivate;
@@ -297,8 +332,8 @@ public:
QQmlTypeModule *module() const;
int minorVersion() const;
- QQmlType *type(const QHashedStringRef &) const;
- QQmlType *type(const QV4::String *) const;
+ QQmlType type(const QHashedStringRef &) const;
+ QQmlType type(const QV4::String *) const;
private:
QQmlTypeModule *m_module;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 9206395c8f..cc9cc889d0 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -613,11 +613,11 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
}
-static QQmlType *qmlTypeForObject(QObject *object)
+static QQmlType qmlTypeForObject(QObject *object)
{
- QQmlType *type = 0;
+ QQmlType type;
const QMetaObject *mo = object->metaObject();
- while (mo && !type) {
+ while (mo && !type.isValid()) {
type = QQmlMetaType::qmlType(mo);
mo = mo->superClass();
}
@@ -654,7 +654,7 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
} else if (binding) {
QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding);
- if (qmlTypeForObject(_bindingTarget)) {
+ if (qmlTypeForObject(_bindingTarget).isValid()) {
quint32 bindingSkipList = 0;
QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultPropertyOrAlias != -1 ? _propertyCache->parent()->defaultProperty() : _propertyCache->defaultProperty();
@@ -712,15 +712,15 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
Q_ASSERT(stringAt(qmlUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
QV4::CompiledData::ResolvedTypeReference *tr = resolvedTypes.value(binding->propertyNameIndex);
Q_ASSERT(tr);
- QQmlType *attachedType = tr->type;
- if (!attachedType) {
+ QQmlType attachedType = tr->type;
+ if (!attachedType.isValid()) {
QQmlTypeNameCache::Result res = context->imports->query(stringAt(binding->propertyNameIndex));
if (res.isValid())
attachedType = res.type;
else
return false;
}
- const int id = attachedType->attachedPropertiesId(QQmlEnginePrivate::get(engine));
+ const int id = attachedType.attachedPropertiesId(QQmlEnginePrivate::get(engine));
QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject);
if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/0))
return false;
@@ -851,10 +851,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
if (binding->type == QV4::CompiledData::Binding::Type_Object) {
if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) {
// ### determine value source and interceptor casts ahead of time.
- QQmlType *type = qmlTypeForObject(createdSubObject);
- Q_ASSERT(type);
+ QQmlType type = qmlTypeForObject(createdSubObject);
+ Q_ASSERT(type.isValid());
- int valueSourceCast = type->propertyValueSourceCast();
+ int valueSourceCast = type.propertyValueSourceCast();
if (valueSourceCast != -1) {
QQmlPropertyValueSource *vs = reinterpret_cast<QQmlPropertyValueSource *>(reinterpret_cast<char *>(createdSubObject) + valueSourceCast);
QObject *target = createdSubObject->parent();
@@ -866,7 +866,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
vs->setTarget(prop);
return true;
}
- int valueInterceptorCast = type->propertyValueInterceptorCast();
+ int valueInterceptorCast = type.propertyValueInterceptorCast();
if (valueInterceptorCast != -1) {
QQmlPropertyValueInterceptor *vi = reinterpret_cast<QQmlPropertyValueInterceptor *>(reinterpret_cast<char *>(createdSubObject) + valueInterceptorCast);
QObject *target = createdSubObject->parent();
@@ -1061,13 +1061,13 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QV4::CompiledData::ResolvedTypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
installPropertyCache = !typeRef->isFullyDynamicType;
- QQmlType *type = typeRef->type;
- if (type) {
+ QQmlType type = typeRef->type;
+ if (type.isValid()) {
Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
- compilationUnit, obj, type->qmlTypeName(), context->url()));
+ compilationUnit, obj, type.qmlTypeName(), context->url()));
void *ddataMemory = 0;
- type->create(&instance, &ddataMemory, sizeof(QQmlData));
+ type.create(&instance, &ddataMemory, sizeof(QQmlData));
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
return 0;
@@ -1081,11 +1081,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
p->declarativeData = ddata;
}
- const int parserStatusCast = type->parserStatusCast();
+ const int parserStatusCast = type.parserStatusCast();
if (parserStatusCast != -1)
parserStatus = reinterpret_cast<QQmlParserStatus*>(reinterpret_cast<char *>(instance) + parserStatusCast);
- customParser = type->customParser();
+ customParser = type.customParser();
if (sharedState->rootContext && sharedState->rootContext->isRootObjectInCreation) {
QQmlData *ddata = QQmlData::get(instance, /*create*/true);
@@ -1326,7 +1326,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) {
Q_ASSERT(!cache.isNull());
// install on _object
- vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, compilationUnit, _compiledObjectIndex);
+ vmeMetaObject = new QQmlVMEMetaObject(v4, _qobject, cache, compilationUnit, _compiledObjectIndex);
if (_ddata->propertyCache)
_ddata->propertyCache->release();
_ddata->propertyCache = cache;
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index 49f02476a2..fc85030b3d 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -376,7 +376,7 @@ void QQmlOpenMetaObject::setCached(bool c)
QQmlData *qmldata = QQmlData::get(d->object, true);
if (d->cacheProperties) {
if (!d->type->d->cache)
- d->type->d->cache = new QQmlPropertyCache(QV8Engine::getV4(d->type->d->engine), this);
+ d->type->d->cache = new QQmlPropertyCache(this);
qmldata->propertyCache = d->type->d->cache;
d->type->d->cache->addref();
} else {
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 9b5f7b0a06..21bbcadb1c 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -253,24 +253,24 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (typeNameCache) {
QQmlTypeNameCache::Result r = typeNameCache->query(pathName);
if (r.isValid()) {
- if (r.type) {
+ if (r.type.isValid()) {
QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlAttachedPropertiesFunc func = r.type->attachedPropertiesFunction(enginePrivate);
+ QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
if (!func) return; // Not an attachable type
- currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(enginePrivate), currentObject);
+ currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
if (!currentObject) return; // Something is broken with the attachable type
} else if (r.importNamespace) {
if ((ii + 1) == path.count()) return; // No type following the namespace
++ii; r = typeNameCache->query(path.at(ii), r.importNamespace);
- if (!r.type) return; // Invalid type in namespace
+ if (!r.type.isValid()) return; // Invalid type in namespace
QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlAttachedPropertiesFunc func = r.type->attachedPropertiesFunction(enginePrivate);
+ QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
if (!func) return; // Not an attachable type
- currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(enginePrivate), currentObject);
+ currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
if (!currentObject) return; // Something is broken with the attachable type
} else if (r.scriptIndex != -1) {
@@ -1275,10 +1275,10 @@ bool QQmlPropertyPrivate::write(QObject *object,
if (enginePriv) {
listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType()));
} else {
- QQmlType *type = QQmlMetaType::qmlType(QQmlMetaType::listType(property.propType()));
- if (!type)
+ QQmlType type = QQmlMetaType::qmlType(QQmlMetaType::listType(property.propType()));
+ if (!type.isValid())
return false;
- listType = type->baseMetaObject();
+ listType = type.baseMetaObject();
}
if (listType.isNull())
return false;
@@ -1393,8 +1393,9 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi
return metaType.metaObject();
if (engine)
return engine->rawMetaObjectForType(userType);
- if (QQmlType *type = QQmlMetaType::qmlType(userType))
- return QQmlMetaObject(type->baseMetaObject());
+ QQmlType type = QQmlMetaType::qmlType(userType);
+ if (type.isValid())
+ return QQmlMetaObject(type.baseMetaObject());
return QQmlMetaObject();
}
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 15b9fe8312..7178dffa8b 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -99,7 +99,7 @@ static QQmlPropertyData::Flags fastFlagsForProperty(const QMetaProperty &p)
// Flags that do depend on the property's QMetaProperty::userType() and thus are slow to
// load
-static void flagsForPropertyType(int propType, QQmlEngine *engine, QQmlPropertyData::Flags &flags)
+static void flagsForPropertyType(int propType, QQmlPropertyData::Flags &flags)
{
Q_ASSERT(propType != -1);
@@ -116,9 +116,7 @@ static void flagsForPropertyType(int propType, QQmlEngine *engine, QQmlPropertyD
} else if (propType == qMetaTypeId<QQmlV4Handle>()) {
flags.type = QQmlPropertyData::Flags::V4HandleType;
} else {
- QQmlMetaType::TypeCategory cat =
- engine ? QQmlEnginePrivate::get(engine)->typeCategory(propType)
- : QQmlMetaType::typeCategory(propType);
+ QQmlMetaType::TypeCategory cat = QQmlMetaType::typeCategory(propType);
if (cat == QQmlMetaType::Object || QMetaType::typeFlags(propType) & QMetaType::PointerToQObject)
flags.type = QQmlPropertyData::Flags::QObjectDerivedType;
@@ -136,10 +134,10 @@ static int metaObjectSignalCount(const QMetaObject *metaObject)
}
QQmlPropertyData::Flags
-QQmlPropertyData::flagsForProperty(const QMetaProperty &p, QQmlEngine *engine)
+QQmlPropertyData::flagsForProperty(const QMetaProperty &p)
{
auto flags = fastFlagsForProperty(p);
- flagsForPropertyType(p.userType(), engine, flags);
+ flagsForPropertyType(p.userType(), flags);
return flags;
}
@@ -166,13 +164,13 @@ void QQmlPropertyData::lazyLoad(const QMetaProperty &p)
}
}
-void QQmlPropertyData::load(const QMetaProperty &p, QQmlEngine *engine)
+void QQmlPropertyData::load(const QMetaProperty &p)
{
setPropType(p.userType());
setCoreIndex(p.propertyIndex());
setNotifyIndex(QMetaObjectPrivate::signalIndex(p.notifySignal()));
setFlags(fastFlagsForProperty(p));
- flagsForPropertyType(propType(), engine, _flags);
+ flagsForPropertyType(propType(), _flags);
Q_ASSERT(p.revision() <= Q_INT16_MAX);
setRevision(p.revision());
}
@@ -244,19 +242,18 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m)
/*!
Creates a new empty QQmlPropertyCache.
*/
-QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e)
- : engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
+QQmlPropertyCache::QQmlPropertyCache()
+ : _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
_metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
{
- Q_ASSERT(engine);
}
/*!
Creates a new QQmlPropertyCache of \a metaObject.
*/
-QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e, const QMetaObject *metaObject)
- : QQmlPropertyCache(e)
+QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject)
+ : QQmlPropertyCache()
{
Q_ASSERT(metaObject);
@@ -265,8 +262,6 @@ QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e, const QMetaObject
QQmlPropertyCache::~QQmlPropertyCache()
{
- clear();
-
QQmlPropertyCacheMethodArguments *args = argumentsCache;
while (args) {
QQmlPropertyCacheMethodArguments *next = args->next;
@@ -284,24 +279,11 @@ QQmlPropertyCache::~QQmlPropertyCache()
if (_ownMetaObject) free(const_cast<QMetaObject *>(_metaObject));
_metaObject = 0;
_parent = 0;
- engine = 0;
-}
-
-void QQmlPropertyCache::destroy()
-{
- delete this;
-}
-
-// This is inherited from QQmlCleanup, so it should only clear the things
-// that are tied to the specific QQmlEngine.
-void QQmlPropertyCache::clear()
-{
- engine = 0;
}
QQmlPropertyCache *QQmlPropertyCache::copy(int reserve)
{
- QQmlPropertyCache *cache = new QQmlPropertyCache(engine);
+ QQmlPropertyCache *cache = new QQmlPropertyCache();
cache->_parent = this;
cache->_parent->addref();
cache->propertyIndexCacheStart = propertyIndexCache.count() + propertyIndexCacheStart;
@@ -720,7 +702,7 @@ void QQmlPropertyCache::resolve(QQmlPropertyData *data) const
data->setPropType(registerResult == -1 ? QMetaType::UnknownType : registerResult);
}
}
- flagsForPropertyType(data->propType(), engine->qmlEngine(), data->_flags);
+ flagsForPropertyType(data->propType(), data->_flags);
}
}
@@ -791,7 +773,11 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, QObject *object, QQmlContextData *context) const
{
QQmlData *data = (object ? QQmlData::get(object) : 0);
- const QQmlVMEMetaObject *vmemo = (data && data->hasVMEMetaObject ? static_cast<const QQmlVMEMetaObject *>(object->metaObject()) : 0);
+ const QQmlVMEMetaObject *vmemo = 0;
+ if (data && data->hasVMEMetaObject) {
+ QObjectPrivate *op = QObjectPrivate::get(object);
+ vmemo = static_cast<const QQmlVMEMetaObject *>(op->metaObject);
+ }
return findProperty(it, vmemo, context);
}
@@ -835,9 +821,9 @@ QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it,
}
if (vmemo) {
- const int methodCount = vmemo->methodCount();
- const int signalCount = vmemo->signalCount();
- const int propertyCount = vmemo->propertyCount();
+ const int methodCount = vmemo->cache->methodCount();
+ const int signalCount = vmemo->cache->signalCount();
+ const int propertyCount = vmemo->cache->propertyCount();
// Ensure that the property we resolve to is accessible from this meta-object
do {
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 392768c1b1..6cdb82bd46 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -288,8 +288,8 @@ public:
inline bool operator==(const QQmlPropertyRawData &);
- static Flags flagsForProperty(const QMetaProperty &, QQmlEngine *engine = 0);
- void load(const QMetaProperty &, QQmlEngine *engine = 0);
+ static Flags flagsForProperty(const QMetaProperty &);
+ void load(const QMetaProperty &);
void load(const QMetaMethod &);
QString name(QObject *) const;
QString name(const QMetaObject *) const;
@@ -364,11 +364,11 @@ struct QQmlEnumData
};
class QQmlPropertyCacheMethodArguments;
-class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount, public QQmlCleanup
+class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount
{
public:
- QQmlPropertyCache(QV4::ExecutionEngine *);
- QQmlPropertyCache(QV4::ExecutionEngine *, const QMetaObject *);
+ QQmlPropertyCache();
+ QQmlPropertyCache(const QMetaObject *);
virtual ~QQmlPropertyCache();
void update(const QMetaObject *);
@@ -462,11 +462,6 @@ public:
static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo);
QByteArray checksum(bool *ok);
-
-protected:
- void destroy() override;
- void clear() override;
-
private:
friend class QQmlEnginePrivate;
friend class QQmlCompiler;
@@ -474,6 +469,7 @@ private:
template <typename T> friend class QQmlPropertyCacheAliasCreator;
friend class QQmlComponentAndAliasResolver;
friend class QQmlMetaObject;
+ friend struct QQmlMetaTypeData;
inline QQmlPropertyCache *copy(int reserve);
@@ -510,9 +506,6 @@ private:
_hasPropertyOverrides |= isOverride;
}
-public:
- QV4::ExecutionEngine *engine;
-
private:
QQmlPropertyCache *_parent;
int propertyIndexCacheStart;
@@ -537,6 +530,8 @@ private:
QByteArray _checksum;
};
+typedef QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCachePtr;
+
// QQmlMetaObject serves as a wrapper around either QMetaObject or QQmlPropertyCache.
// This is necessary as we delay creation of QMetaObject for synthesized QObjects, but
// we don't want to needlessly generate QQmlPropertyCaches every time we encounter a
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 151a7cd883..8721ec507a 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1778,23 +1778,21 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
#endif
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- QStringRef dirPath(&path, 0, lastSlash);
+ QString dirPath(path.left(lastSlash));
- StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
- if (!fileSet) {
- QHashedString dirPathString(dirPath.toString());
- bool exists = QDir(dirPathString).exists();
- QStringHash<bool> *files = exists ? new QStringHash<bool> : 0;
- m_importDirCache.insert(dirPathString, files);
- fileSet = m_importDirCache.value(dirPathString);
+ if (!m_importDirCache.contains(dirPath)) {
+ bool exists = QDir(dirPath).exists();
+ QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : 0;
+ m_importDirCache.insert(dirPath, entry);
}
- if (!(*fileSet))
+ QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
+ if (!fileSet)
return QString();
QString absoluteFilePath;
- QHashedStringRef fileName(path.constData()+lastSlash+1, path.length()-lastSlash-1);
+ QString fileName(path.mid(lastSlash+1, path.length()-lastSlash-1));
- bool *value = (*fileSet)->value(fileName);
+ bool *value = fileSet->object(fileName);
if (value) {
if (*value)
absoluteFilePath = path;
@@ -1808,7 +1806,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
#else
exists = QFile::exists(path);
#endif
- (*fileSet)->insert(fileName.toString(), exists);
+ fileSet->insert(fileName, new bool(exists));
if (exists)
absoluteFilePath = path;
}
@@ -1843,18 +1841,16 @@ bool QQmlTypeLoader::directoryExists(const QString &path)
int length = path.length();
if (path.endsWith(QLatin1Char('/')))
--length;
- QStringRef dirPath(&path, 0, length);
+ QString dirPath(path.left(length));
- StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
- if (!fileSet) {
- QHashedString dirPathString(dirPath.toString());
- bool exists = QDir(dirPathString).exists();
- QStringHash<bool> *files = exists ? new QStringHash<bool> : 0;
- m_importDirCache.insert(dirPathString, files);
- fileSet = m_importDirCache.value(dirPathString);
+ if (!m_importDirCache.contains(dirPath)) {
+ bool exists = QDir(dirPath).exists();
+ QCache<QString, bool> *files = exists ? new QCache<QString, bool> : 0;
+ m_importDirCache.insert(dirPath, files);
}
- return (*fileSet);
+ QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
+ return fileSet != 0;
}
@@ -1938,7 +1934,7 @@ void QQmlTypeLoader::clearCache()
(*iter)->release();
for (QmldirCache::Iterator iter = m_qmldirCache.begin(), end = m_qmldirCache.end(); iter != end; ++iter)
(*iter)->release();
- qDeleteAll(m_importDirCache);
+
qDeleteAll(m_importQmlDirCache);
m_typeCache.clear();
@@ -1947,6 +1943,7 @@ void QQmlTypeLoader::clearCache()
m_qmldirCache.clear();
m_importDirCache.clear();
m_importQmlDirCache.clear();
+ QQmlMetaType::freeUnusedTypesAndCaches();
}
void QQmlTypeLoader::updateTypeCacheTrimThreshold()
@@ -1988,6 +1985,8 @@ void QQmlTypeLoader::trimCache()
updateTypeCacheTrimThreshold();
+ QQmlMetaType::freeUnusedTypesAndCaches();
+
// TODO: release any scripts which are no longer referenced by any types
}
@@ -2013,7 +2012,7 @@ QString QQmlTypeData::TypeReference::qualifiedName() const
if (!prefix.isEmpty()) {
result = prefix + QLatin1Char('.');
}
- result.append(type->qmlTypeName());
+ result.append(type.qmlTypeName());
return result;
}
@@ -2168,8 +2167,8 @@ static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeRefere
if (typeRef.typeData) {
const auto unit = typeRef.typeData->compilationUnit();
hash->addData(unit->data->md5Checksum, sizeof(unit->data->md5Checksum));
- } else if (typeRef.type) {
- const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type->metaObject());
+ } else if (typeRef.type.isValid()) {
+ const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type.metaObject());
bool ok = false;
hash->addData(propertyCache->checksum(&ok));
if (!ok)
@@ -2233,7 +2232,7 @@ void QQmlTypeData::done()
const TypeReference &type = m_compositeSingletons.at(ii);
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
if (type.typeData && type.typeData->isError()) {
- QString typeName = type.type->qmlTypeName();
+ QString typeName = type.type.qmlTypeName();
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
@@ -2300,24 +2299,24 @@ void QQmlTypeData::done()
}
{
- QQmlType *type = QQmlMetaType::qmlType(finalUrl(), true);
+ QQmlType type = QQmlMetaType::qmlType(finalUrl(), true);
if (m_compiledData && m_compiledData->data->flags & QV4::CompiledData::Unit::IsSingleton) {
- if (!type) {
+ if (!type.isValid()) {
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("No matching type found, pragma Singleton files cannot be used by QQmlComponent."));
setError(error);
return;
- } else if (!type->isCompositeSingleton()) {
+ } else if (!type.isCompositeSingleton()) {
QQmlError error;
- error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(type->qmlTypeName()));
+ error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(type.qmlTypeName()));
setError(error);
return;
}
} else {
// If the type is CompositeSingleton but there was no pragma Singleton in the
// QML file, lets report an error.
- if (type && type->isCompositeSingleton()) {
- QString typeName = type->qmlTypeName();
+ if (type.isValid() && type.isCompositeSingleton()) {
+ QString typeName = type.qmlTypeName();
setError(QQmlTypeLoader::tr("qmldir defines type as singleton, but no pragma Singleton found in type %1.").arg(typeName));
return;
}
@@ -2609,8 +2608,8 @@ void QQmlTypeData::resolveTypes()
if (!resolveType(typeName, majorVersion, minorVersion, ref))
return;
- if (ref.type->isCompositeSingleton()) {
- ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
+ if (ref.type.isCompositeSingleton()) {
+ ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
addDependency(ref.typeData);
ref.prefix = csRef.prefix;
@@ -2637,8 +2636,8 @@ void QQmlTypeData::resolveTypes()
if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors) && reportErrors)
return;
- if (ref.type && ref.type->isComposite()) {
- ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
+ if (ref.type.isComposite()) {
+ ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
addDependency(ref.typeData);
}
ref.majorVersion = majorVersion;
@@ -2669,7 +2668,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
// Add any Composite Singletons that were used to the import cache
for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons)
- (*typeNameCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix);
+ (*typeNameCache)->add(singleton.type.qmlTypeName(), singleton.type.sourceUrl(), singleton.prefix);
m_importCache.populateCache(*typeNameCache);
@@ -2677,24 +2676,24 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
for (auto resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); resolvedType != end; ++resolvedType) {
QScopedPointer<QV4::CompiledData::ResolvedTypeReference> ref(new QV4::CompiledData::ResolvedTypeReference);
- QQmlType *qmlType = resolvedType->type;
+ QQmlType qmlType = resolvedType->type;
if (resolvedType->typeData) {
- if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) {
- return QQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName()));
+ if (resolvedType->needsCreation && qmlType.isCompositeSingleton()) {
+ return QQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType.qmlTypeName()));
}
ref->compilationUnit = resolvedType->typeData->compilationUnit();
- } else if (qmlType) {
+ } else if (qmlType.isValid()) {
ref->type = qmlType;
- Q_ASSERT(ref->type);
+ Q_ASSERT(ref->type.isValid());
- if (resolvedType->needsCreation && !ref->type->isCreatable()) {
- QString reason = ref->type->noCreationReason();
+ if (resolvedType->needsCreation && !ref->type.isCreatable()) {
+ QString reason = ref->type.noCreationReason();
if (reason.isEmpty())
reason = tr("Element is not creatable.");
return QQmlCompileError(resolvedType->location, reason);
}
- if (ref->type->containsRevisionedAttributes()) {
+ if (ref->type.containsRevisionedAttributes()) {
ref->typePropertyCache = engine->cache(ref->type,
resolvedType->minorVersion);
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index f367fa6f58..05923f77e8 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -55,6 +55,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qatomic.h>
#include <QtCore/qfileinfo.h>
+#include <QtCore/qcache.h>
#if QT_CONFIG(qml_network)
#include <QtNetwork/qnetworkreply.h>
#endif
@@ -362,8 +363,7 @@ private:
typedef QHash<QUrl, QQmlTypeData *> TypeCache;
typedef QHash<QUrl, QQmlScriptBlob *> ScriptCache;
typedef QHash<QUrl, QQmlQmldirData *> QmldirCache;
- typedef QStringHash<bool> StringSet;
- typedef QStringHash<StringSet*> ImportDirCache;
+ typedef QCache<QString, QCache<QString, bool> > ImportDirCache;
typedef QStringHash<QQmlTypeLoaderQmldirContent *> ImportQmlDirCache;
QQmlEngine *m_engine;
@@ -393,10 +393,10 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob
public:
struct TypeReference
{
- TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {}
+ TypeReference() : majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {}
QV4::CompiledData::Location location;
- QQmlType *type;
+ QQmlType type;
int majorVersion;
int minorVersion;
QQmlTypeData *typeData;
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index 35ef8ada57..136614d332 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -55,7 +55,7 @@ QQmlTypeNameCache::~QQmlTypeNameCache()
void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QHashedString &nameSpace)
{
if (nameSpace.length() != 0) {
- Import *i = m_namedImports.value(nameSpace);
+ QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != 0);
i->compositeSingletons.insert(name, url);
return;
@@ -69,12 +69,12 @@ void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QH
void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex, const QHashedString &nameSpace)
{
- Import import;
+ QQmlImportRef import;
import.scriptIndex = importedScriptIndex;
import.m_qualifier = name;
if (nameSpace.length() != 0) {
- Import *i = m_namedImports.value(nameSpace);
+ QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != 0);
m_namespacedImports[i].insert(name, import);
return;
@@ -100,7 +100,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
// Look up anonymous types from the imports of this document
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- QQmlType *t = 0;
+ QQmlType t;
bool typeFound = m_imports.resolveType(name, &t, 0, 0, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
@@ -112,25 +112,23 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
}
QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
- const void *importNamespace) const
+ const QQmlImportRef *importNamespace) const
{
- Q_ASSERT(importNamespace);
- const Import *i = static_cast<const Import *>(importNamespace);
- Q_ASSERT(i->scriptIndex == -1);
+ Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1);
- Result result = typeSearch(i->modules, name);
+ Result result = typeSearch(importNamespace->modules, name);
if (!result.isValid())
- result = query(i->compositeSingletons, name);
+ result = query(importNamespace->compositeSingletons, name);
if (!result.isValid()) {
// Look up types from the imports of this document
// ### it would be nice if QQmlImports allowed us to resolve a namespace
// first, and then types on it.
- QString qualifiedTypeName = i->m_qualifier + QLatin1Char('.') + name.toString();
+ QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name.toString();
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- QQmlType *t = 0;
+ QQmlType t;
bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
@@ -155,7 +153,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml
QString typeName = name->toQStringNoThrow();
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- QQmlType *t = 0;
+ QQmlType t;
bool typeFound = m_imports.resolveType(typeName, &t, 0, 0, &typeNamespace, &errors, recursionRestriction);
if (typeFound) {
return Result(t);
@@ -166,32 +164,30 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml
return result;
}
-QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, const void *importNamespace) const
+QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, const QQmlImportRef *importNamespace) const
{
- Q_ASSERT(importNamespace);
- const Import *i = static_cast<const Import *>(importNamespace);
- Q_ASSERT(i->scriptIndex == -1);
+ Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1);
- QMap<const Import *, QStringHash<Import> >::const_iterator it = m_namespacedImports.constFind(i);
+ QMap<const QQmlImportRef *, QStringHash<QQmlImportRef> >::const_iterator it = m_namespacedImports.constFind(importNamespace);
if (it != m_namespacedImports.constEnd()) {
Result r = query(*it, name);
if (r.isValid())
return r;
}
- Result r = typeSearch(i->modules, name);
+ Result r = typeSearch(importNamespace->modules, name);
if (!r.isValid())
- r = query(i->compositeSingletons, name);
+ r = query(importNamespace->compositeSingletons, name);
if (!r.isValid()) {
// Look up types from the imports of this document
// ### it would be nice if QQmlImports allowed us to resolve a namespace
// first, and then types on it.
- QString qualifiedTypeName = i->m_qualifier + QLatin1Char('.') + name->toQStringNoThrow();
+ QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name->toQStringNoThrow();
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- QQmlType *t = 0;
+ QQmlType t;
bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h
index f7ba2a91b7..6e5cd0fb54 100644
--- a/src/qml/qml/qqmltypenamecache_p.h
+++ b/src/qml/qml/qqmltypenamecache_p.h
@@ -62,6 +62,23 @@
QT_BEGIN_NAMESPACE
+struct QQmlImportRef {
+ inline QQmlImportRef()
+ : scriptIndex(-1)
+ {}
+ // Imported module
+ QVector<QQmlTypeModuleVersion> modules;
+
+ // Or, imported script
+ int scriptIndex;
+
+ // Or, imported compositeSingletons
+ QStringHash<QUrl> compositeSingletons;
+
+ // The qualifier of this import
+ QString m_qualifier;
+};
+
class QQmlType;
class QQmlEngine;
class QQmlTypeNameCache : public QQmlRefCount
@@ -77,50 +94,35 @@ public:
struct Result {
inline Result();
- inline Result(const void *importNamespace);
- inline Result(QQmlType *type);
+ inline Result(const QQmlImportRef *importNamespace);
+ inline Result(const QQmlType &type);
inline Result(int scriptIndex);
inline Result(const Result &);
inline bool isValid() const;
- QQmlType *type;
- const void *importNamespace;
+ QQmlType type;
+ const QQmlImportRef *importNamespace;
int scriptIndex;
};
Result query(const QHashedStringRef &) const;
- Result query(const QHashedStringRef &, const void *importNamespace) const;
+ Result query(const QHashedStringRef &, const QQmlImportRef *importNamespace) const;
Result query(const QV4::String *, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
- Result query(const QV4::String *, const void *importNamespace) const;
+ Result query(const QV4::String *, const QQmlImportRef *importNamespace) const;
private:
friend class QQmlImports;
- struct Import {
- inline Import();
- // Imported module
- QVector<QQmlTypeModuleVersion> modules;
-
- // Or, imported script
- int scriptIndex;
-
- // Or, imported compositeSingletons
- QStringHash<QUrl> compositeSingletons;
-
- // The qualifier of this import
- QString m_qualifier;
- };
-
template<typename Key>
- Result query(const QStringHash<Import> &imports, Key key) const
+ Result query(const QStringHash<QQmlImportRef> &imports, Key key) const
{
- Import *i = imports.value(key);
+ QQmlImportRef *i = imports.value(key);
if (i) {
Q_ASSERT(!i->m_qualifier.isEmpty());
if (i->scriptIndex != -1) {
return Result(i->scriptIndex);
} else {
- return Result(static_cast<const void *>(i));
+ return Result(i);
}
}
@@ -132,9 +134,8 @@ private:
{
QUrl *url = urls.value(key);
if (url) {
- QQmlType *type = QQmlMetaType::qmlType(*url);
- if (type)
- return Result(type);
+ QQmlType type = QQmlMetaType::qmlType(*url);
+ return Result(type);
}
return Result();
@@ -145,37 +146,38 @@ private:
{
QVector<QQmlTypeModuleVersion>::const_iterator end = modules.constEnd();
for (QVector<QQmlTypeModuleVersion>::const_iterator it = modules.constBegin(); it != end; ++it) {
- if (QQmlType *type = it->type(key))
+ QQmlType type = it->type(key);
+ if (type.isValid())
return Result(type);
}
return Result();
}
- QStringHash<Import> m_namedImports;
- QMap<const Import *, QStringHash<Import> > m_namespacedImports;
+ QStringHash<QQmlImportRef> m_namedImports;
+ QMap<const QQmlImportRef *, QStringHash<QQmlImportRef> > m_namespacedImports;
QVector<QQmlTypeModuleVersion> m_anonymousImports;
QStringHash<QUrl> m_anonymousCompositeSingletons;
QQmlImports m_imports;
};
QQmlTypeNameCache::Result::Result()
-: type(0), importNamespace(0), scriptIndex(-1)
+: importNamespace(0), scriptIndex(-1)
{
}
-QQmlTypeNameCache::Result::Result(const void *importNamespace)
-: type(0), importNamespace(importNamespace), scriptIndex(-1)
+QQmlTypeNameCache::Result::Result(const QQmlImportRef *importNamespace)
+: importNamespace(importNamespace), scriptIndex(-1)
{
}
-QQmlTypeNameCache::Result::Result(QQmlType *type)
+QQmlTypeNameCache::Result::Result(const QQmlType &type)
: type(type), importNamespace(0), scriptIndex(-1)
{
}
QQmlTypeNameCache::Result::Result(int scriptIndex)
-: type(0), importNamespace(0), scriptIndex(scriptIndex)
+: importNamespace(0), scriptIndex(scriptIndex)
{
}
@@ -186,12 +188,7 @@ QQmlTypeNameCache::Result::Result(const Result &o)
bool QQmlTypeNameCache::Result::isValid() const
{
- return type || importNamespace || scriptIndex != -1;
-}
-
-QQmlTypeNameCache::Import::Import()
-: scriptIndex(-1)
-{
+ return type.isValid() || importNamespace || scriptIndex != -1;
}
bool QQmlTypeNameCache::isEmpty() const
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 7a06077c11..404bc0612e 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -64,15 +64,22 @@ void Heap::QQmlTypeWrapper::init()
void Heap::QQmlTypeWrapper::destroy()
{
+ QQmlType::derefHandle(typePrivate);
+ typePrivate = nullptr;
if (typeNamespace)
typeNamespace->release();
object.destroy();
Object::destroy();
}
+QQmlType Heap::QQmlTypeWrapper::type() const
+{
+ return QQmlType(typePrivate);
+}
+
bool QQmlTypeWrapper::isSingleton() const
{
- return d()->type && d()->type->isSingleton();
+ return d()->type().isSingleton();
}
QObject* QQmlTypeWrapper::singletonObject() const
@@ -81,22 +88,16 @@ QObject* QQmlTypeWrapper::singletonObject() const
return 0;
QQmlEngine *e = engine()->qmlEngine();
- QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo();
+ QQmlType::SingletonInstanceInfo *siinfo = d()->type().singletonInstanceInfo();
siinfo->init(e);
return siinfo->qobjectApi(e);
}
QVariant QQmlTypeWrapper::toVariant() const
{
- if (d()->type && d()->type->isSingleton()) {
- QQmlEngine *e = engine()->qmlEngine();
- QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo();
- siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required.
- QObject *qobjectSingleton = siinfo->qobjectApi(e);
- if (qobjectSingleton) {
- return QVariant::fromValue<QObject*>(qobjectSingleton);
- }
- }
+ QObject *qobjectSingleton = singletonObject();
+ if (qobjectSingleton)
+ return QVariant::fromValue<QObject*>(qobjectSingleton);
// only QObject Singleton Type can be converted to a variant.
return QVariant();
@@ -104,20 +105,22 @@ QVariant QQmlTypeWrapper::toVariant() const
// Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
-ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlType *t,
+ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, const QQmlType &t,
Heap::QQmlTypeWrapper::TypeNameMode mode)
{
- Q_ASSERT(t);
+ Q_ASSERT(t.isValid());
Scope scope(engine);
Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>());
- w->d()->mode = mode; w->d()->object = o; w->d()->type = t;
+ w->d()->mode = mode; w->d()->object = o;
+ w->d()->typePrivate = t.priv();
+ QQmlType::refHandle(w->d()->typePrivate);
return w.asReturnedValue();
}
// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
// namespace.
-ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const void *importNamespace,
+ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const QQmlImportRef *importNamespace,
Heap::QQmlTypeWrapper::TypeNameMode mode)
{
Q_ASSERT(t);
@@ -131,10 +134,10 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o,
}
static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qobjectSingleton,
- QQmlType *type)
+ const QQmlType &type)
{
bool ok;
- int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
+ int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
if (ok)
return value;
@@ -150,11 +153,11 @@ static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qob
return -1;
}
-static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *name, QQmlType *type)
+static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *name, const QQmlType &type)
{
const QString message =
QStringLiteral("Cannot access enum value '%1' of '%2', enum values need to start with an uppercase letter.")
- .arg(name->toQString()).arg(QLatin1String(type->typeName()));
+ .arg(name->toQString()).arg(QLatin1String(type.typeName()));
return v4->throwTypeError(message);
}
@@ -173,14 +176,14 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
QQmlContextData *context = v4->callingQmlContext();
QObject *object = w->d()->object;
- QQmlType *type = w->d()->type;
+ QQmlType type = w->d()->type();
- if (type) {
+ if (type.isValid()) {
// singleton types are handled differently to other types.
- if (type->isSingleton()) {
+ if (type.isSingleton()) {
QQmlEngine *e = v4->qmlEngine();
- QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
+ QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo();
siinfo->init(e);
QObject *qobjectSingleton = siinfo->qobjectApi(e);
@@ -221,14 +224,15 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
if (name->startsWithUpper()) {
bool ok = false;
- int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
+ int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
if (ok)
return QV4::Primitive::fromInt32(value).asReturnedValue();
- value = type->scopedEnumIndex(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
+ value = type.scopedEnumIndex(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
if (ok) {
Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, v4->memoryManager->allocObject<QQmlScopedEnumWrapper>());
- enumWrapper->d()->type = type;
+ enumWrapper->d()->typePrivate = type.priv();
+ QQmlType::refHandle(enumWrapper->d()->typePrivate);
enumWrapper->d()->scopeEnumIndex = value;
return enumWrapper.asReturnedValue();
}
@@ -236,7 +240,7 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
// Fall through to base implementation
} else if (w->d()->object) {
- QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(QQmlEnginePrivate::get(v4->qmlEngine())), object);
+ QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(v4->qmlEngine())), object);
if (ao)
return QV4::QObjectWrapper::getQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);
@@ -253,7 +257,7 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
QQmlTypeNameCache::Result r = w->d()->typeNamespace->query(name, w->d()->importNamespace);
if (r.isValid()) {
- if (r.type) {
+ if (r.type.isValid()) {
return create(scope.engine, object, r.type, w->d()->mode);
} else if (r.scriptIndex != -1) {
QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
@@ -278,9 +282,9 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
*hasProperty = ok;
// Warn when attempting to access a lowercased enum value, non-singleton case
- if (!ok && type && !type->isSingleton() && !name->startsWithUpper()) {
+ if (!ok && type.isValid() && !type.isSingleton() && !name->startsWithUpper()) {
bool enumOk = false;
- type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &enumOk);
+ type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &enumOk);
if (enumOk)
return throwLowercaseEnumError(v4, name, type);
}
@@ -300,17 +304,17 @@ bool QQmlTypeWrapper::put(Managed *m, String *name, const Value &value)
QV4::Scope scope(v4);
QQmlContextData *context = v4->callingQmlContext();
- QQmlType *type = w->d()->type;
- if (type && !type->isSingleton() && w->d()->object) {
+ QQmlType type = w->d()->type();
+ if (type.isValid() && !type.isSingleton() && w->d()->object) {
QObject *object = w->d()->object;
QQmlEngine *e = scope.engine->qmlEngine();
- QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(QQmlEnginePrivate::get(e)), object);
+ QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(e)), object);
if (ao)
return QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
return false;
- } else if (type && type->isSingleton()) {
+ } else if (type.isSingleton()) {
QQmlEngine *e = scope.engine->qmlEngine();
- QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
+ QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo();
siinfo->init(e);
QObject *qobjectSingleton = siinfo->qobjectApi(e);
@@ -368,7 +372,7 @@ ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value
if (!wrapperObject)
return engine->throwTypeError();
- const int myTypeId = typeWrapper->d()->type->typeId();
+ const int myTypeId = typeWrapper->d()->type().typeId();
QQmlMetaObject myQmlType;
if (myTypeId == 0) {
// we're a composite type; a composite type cannot be equal to a
@@ -379,7 +383,7 @@ ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value
if (!theirDData->compilationUnit)
return Encode(false);
- QQmlTypeData *td = qenginepriv->typeLoader.getType(typeWrapper->d()->type->sourceUrl());
+ QQmlTypeData *td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
CompiledData::CompilationUnit *cu = td->compilationUnit();
myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
} else {
@@ -391,6 +395,18 @@ ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value
return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType));
}
+void Heap::QQmlScopedEnumWrapper::destroy()
+{
+ QQmlType::derefHandle(typePrivate);
+ typePrivate = nullptr;
+ Object::destroy();
+}
+
+QQmlType Heap::QQmlScopedEnumWrapper::type() const
+{
+ return QQmlType(typePrivate);
+}
+
ReturnedValue QQmlScopedEnumWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QQmlScopedEnumWrapper>());
@@ -398,11 +414,11 @@ ReturnedValue QQmlScopedEnumWrapper::get(const Managed *m, String *name, bool *h
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
- QQmlType *type = resource->d()->type;
+ QQmlType type = resource->d()->type();
int index = resource->d()->scopeEnumIndex;
bool ok = false;
- int value = type->scopedEnumValue(QQmlEnginePrivate::get(v4->qmlEngine()), index, name, &ok);
+ int value = type.scopedEnumValue(QQmlEnginePrivate::get(v4->qmlEngine()), index, name, &ok);
if (hasProperty)
*hasProperty = ok;
if (ok)
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index 730bfd6d12..bb65093163 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -76,16 +76,19 @@ struct QQmlTypeWrapper : Object {
TypeNameMode mode;
QQmlQPointer<QObject> object;
- QQmlType *type;
+ QQmlType type() const;
+
+ QQmlTypePrivate *typePrivate;
QQmlTypeNameCache *typeNamespace;
- const void *importNamespace;
+ const QQmlImportRef *importNamespace;
};
struct QQmlScopedEnumWrapper : Object {
void init() { Object::init(); }
- void destroy() { Object::destroy(); }
+ void destroy();
int scopeEnumIndex;
- QQmlType *type;
+ QQmlTypePrivate *typePrivate;
+ QQmlType type() const;
};
}
@@ -100,9 +103,9 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object
QVariant toVariant() const;
- static ReturnedValue create(ExecutionEngine *, QObject *, QQmlType *,
+ static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlType &,
Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums);
- static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const void *,
+ static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const QQmlImportRef *,
Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index a2ab9bdfed..67f8ec840e 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -313,24 +313,25 @@ QAbstractDynamicMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObje
return this;
}
-QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj,
+QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine,
+ QObject *obj,
QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId)
: QQmlInterceptorMetaObject(obj, cache),
+ engine(engine),
ctxt(QQmlData::get(obj, true)->outerContext),
aliasEndpoints(0), compilationUnit(qmlCompilationUnit), compiledObject(0)
{
+ Q_ASSERT(engine);
QQmlData::get(obj)->hasVMEMetaObject = true;
if (compilationUnit && qmlObjectId >= 0) {
compiledObject = compilationUnit->data->objectAt(qmlObjectId);
if (compiledObject->nProperties || compiledObject->nFunctions) {
- Q_ASSERT(cache && cache->engine);
- QV4::ExecutionEngine *v4 = cache->engine;
uint size = compiledObject->nProperties + compiledObject->nFunctions;
if (size) {
- QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, size);
- propertyAndMethodStorage.set(v4, data);
+ QV4::Heap::MemberData *data = QV4::MemberData::allocate(engine, size);
+ propertyAndMethodStorage.set(engine, data);
std::fill(data->values.values, data->values.values + data->values.size, QV4::Encode::undefined());
}
@@ -366,77 +367,77 @@ void QQmlVMEMetaObject::writeProperty(int id, int v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, QV4::Primitive::fromInt32(v));
+ md->set(engine, id, QV4::Primitive::fromInt32(v));
}
void QQmlVMEMetaObject::writeProperty(int id, bool v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, QV4::Primitive::fromBoolean(v));
+ md->set(engine, id, QV4::Primitive::fromBoolean(v));
}
void QQmlVMEMetaObject::writeProperty(int id, double v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, QV4::Primitive::fromDouble(v));
+ md->set(engine, id, QV4::Primitive::fromDouble(v));
}
void QQmlVMEMetaObject::writeProperty(int id, const QString& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newString(v));
+ md->set(engine, id, engine->newString(v));
}
void QQmlVMEMetaObject::writeProperty(int id, const QUrl& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDate& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDateTime& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QPointF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QSizeF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QRectF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant::fromValue(v)));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, QObject* v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- md->set(cache->engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(cache->engine, v)));
+ md->set(engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, v)));
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
if (v && !guard) {
@@ -453,7 +454,7 @@ int QQmlVMEMetaObject::readPropertyAsInt(int id) const
if (!md)
return 0;
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
if (!sv->isInt32())
return 0;
@@ -466,7 +467,7 @@ bool QQmlVMEMetaObject::readPropertyAsBool(int id) const
if (!md)
return false;
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
if (!sv->isBoolean())
return false;
@@ -479,7 +480,7 @@ double QQmlVMEMetaObject::readPropertyAsDouble(int id) const
if (!md)
return 0.0;
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
if (!sv->isDouble())
return 0.0;
@@ -492,7 +493,7 @@ QString QQmlVMEMetaObject::readPropertyAsString(int id) const
if (!md)
return QString();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
if (QV4::String *s = sv->stringValue())
return s->toQString();
@@ -505,7 +506,7 @@ QUrl QQmlVMEMetaObject::readPropertyAsUrl(int id) const
if (!md)
return QUrl();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::Url)
@@ -519,7 +520,7 @@ QDate QQmlVMEMetaObject::readPropertyAsDate(int id) const
if (!md)
return QDate();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::Date)
@@ -533,7 +534,7 @@ QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id)
if (!md)
return QDateTime();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::DateTime)
@@ -547,7 +548,7 @@ QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) const
if (!md)
return QSizeF();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::SizeF)
@@ -561,7 +562,7 @@ QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) const
if (!md)
return QPointF();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::PointF)
@@ -575,7 +576,7 @@ QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) const
if (!md)
return 0;
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::QObjectWrapper *wrapper = sv->as<QV4::QObjectWrapper>();
if (!wrapper)
@@ -589,12 +590,12 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
if (!md)
return 0;
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::Scoped<QV4::VariantObject> v(scope, *(md->data() + id));
if (!v || (int)v->d()->data().userType() != qMetaTypeId<QList<QObject *> >()) {
QVariant variant(qVariantFromValue(QList<QObject*>()));
- v = cache->engine->newVariantObject(variant);
- md->set(cache->engine, id, v);
+ v = engine->newVariantObject(variant);
+ md->set(engine, id, v);
}
return static_cast<QList<QObject *> *>(v->d()->data().data());
}
@@ -605,7 +606,7 @@ QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const
if (!md)
return QRectF();
- QV4::Scope scope(cache->engine);
+ QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
if (!v || v->d()->data().type() != QVariant::RectF)
@@ -819,7 +820,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
if (!v) {
- md->set(cache->engine, id, cache->engine->newVariantObject(QVariant()));
+ md->set(engine, id, engine->newVariantObject(QVariant()));
v = (md->data() + id)->as<QV4::VariantObject>();
QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data());
}
@@ -1015,7 +1016,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) const
const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
if (v)
return v->d()->data();
- return cache->engine->toVariant(*(md->data() + id), -1);
+ return engine->toVariant(*(md->data() + id), -1);
}
return QVariant();
}
@@ -1056,7 +1057,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
guard->setGuardedValue(valueObject, this, id);
// Write the value and emit change signal as appropriate.
- md->set(cache->engine, id, value);
+ md->set(engine, id, value);
activate(object, methodOffset() + id, 0);
}
@@ -1075,15 +1076,15 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
// And, if the new value is a scarce resource, we need to ensure that it does not get
// automatically released by the engine until no other references to it exist.
- QV4::Scope scope(cache->engine);
- QV4::ScopedValue newv(scope, cache->engine->fromVariant(value));
+ QV4::Scope scope(engine);
+ QV4::ScopedValue newv(scope, engine->fromVariant(value));
QV4::Scoped<QV4::VariantObject> v(scope, newv);
if (!!v)
v->addVmePropertyReference();
// Write the value and emit change signal as appropriate.
QVariant currentValue = readPropertyAsVariant(id);
- md->set(cache->engine, id, newv);
+ md->set(engine, id, newv);
if ((currentValue.userType() != value.userType() || currentValue != value))
activate(object, methodOffset() + id, 0);
} else {
@@ -1101,7 +1102,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
v->d()->data() != value);
if (v)
v->removeVmePropertyReference();
- md->set(cache->engine, id, cache->engine->newVariantObject(value));
+ md->set(engine, id, engine->newVariantObject(value));
v = static_cast<const QV4::VariantObject *>(md->data() + id);
v->addVmePropertyReference();
}
@@ -1141,7 +1142,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, const QV4::Value &function)
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
return;
- md->set(cache->engine, methodIndex + compiledObject->nProperties, function);
+ md->set(engine, methodIndex + compiledObject->nProperties, function);
}
QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index) const
@@ -1165,15 +1166,13 @@ void QQmlVMEMetaObject::setVMEProperty(int index, const QV4::Value &v)
void QQmlVMEMetaObject::ensureQObjectWrapper()
{
- Q_ASSERT(cache && cache->engine);
- QV4::ExecutionEngine *v4 = cache->engine;
- QV4::QObjectWrapper::wrap(v4, object);
+ Q_ASSERT(cache);
+ QV4::QObjectWrapper::wrap(engine, object);
}
void QQmlVMEMetaObject::mark(QV4::MarkStack *markStack)
{
- QV4::ExecutionEngine *v4 = cache ? cache->engine : 0;
- if (v4 != markStack->engine)
+ if (engine != markStack->engine)
return;
propertyAndMethodStorage.markOnce(markStack);
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 031a9a9ddd..ea5e9c0904 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -144,7 +144,7 @@ class QQmlVMEMetaObjectEndpoint;
class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject
{
public:
- QQmlVMEMetaObject(QObject *obj, QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId);
+ QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId);
~QQmlVMEMetaObject();
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
@@ -164,6 +164,7 @@ protected:
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) Q_DECL_OVERRIDE;
public:
+ QV4::ExecutionEngine *engine;
QQmlGuardedContextData ctxt;
inline int propOffset() const;
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 9620df6af9..d54bdeede6 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -941,7 +941,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
if (!cacheItem) {
- cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), it.modelIndex());
+ cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex());
if (!cacheItem)
return 0;
@@ -1623,7 +1623,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
if (!m_context || !m_context->isValid())
return false;
- QQmlDelegateModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), -1);
+ QQmlDelegateModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, -1);
if (!cacheItem)
return false;
if (!object.isObject())
@@ -2450,7 +2450,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
if (!cacheItem) {
cacheItem = model->m_adaptorModel.createItem(
- model->m_cacheMetaType, model->m_context->engine(), it.modelIndex());
+ model->m_cacheMetaType, it.modelIndex());
if (!cacheItem)
return QQmlV4Handle(QV4::Encode::undefined());
cacheItem->groups = it->flags;
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index b9f6ea461a..11fed281b7 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -515,16 +515,15 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- QQmlEngine *engine,
int index) const override
{
VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
if (!metaObject)
- dataType->initializeMetaType(model, engine);
+ dataType->initializeMetaType(model);
return new QQmlDMAbstractItemModelData(metaType, dataType, index);
}
- void initializeMetaType(QQmlAdaptorModel &model, QQmlEngine *engine)
+ void initializeMetaType(QQmlAdaptorModel &model)
{
QMetaObjectBuilder builder;
setModelDataType<QQmlDMAbstractItemModelData>(&builder, this);
@@ -549,7 +548,7 @@ public:
metaObject = builder.toMetaObject();
*static_cast<QMetaObject *>(this) = *metaObject;
- propertyCache = new QQmlPropertyCache(QV8Engine::getV4(engine), metaObject);
+ propertyCache = new QQmlPropertyCache(metaObject);
}
};
@@ -661,7 +660,6 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- QQmlEngine *,
int index) const override
{
return new QQmlDMListAccessorData(
@@ -746,7 +744,6 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- QQmlEngine *,
int index) const override
{
VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this);
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
index 78d964236e..7bbddcff07 100644
--- a/src/qml/util/qqmladaptormodel_p.h
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -82,7 +82,6 @@ public:
virtual QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &,
QQmlDelegateModelItemMetaType *,
- QQmlEngine *,
int) const { return 0; }
virtual bool notify(
@@ -122,8 +121,8 @@ public:
inline int count() const { return qMax(0, accessors->count(*this)); }
inline QVariant value(int index, const QString &role) const {
return accessors->value(*this, index, role); }
- inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, QQmlEngine *engine, int index) {
- return accessors->createItem(*this, metaType, engine, index); }
+ inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, int index) {
+ return accessors->createItem(*this, metaType, index); }
inline bool hasProxyObject() const {
return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; }
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index 5e897218c5..33ea442b76 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -127,7 +127,7 @@ void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine)
}
QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine)
- : QQmlVMEMetaObject(object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1),
+ : QQmlVMEMetaObject(QQmlEnginePrivate::getV4Engine(engine), object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1),
m_context(engine->contextForObject(object)),
m_data(new MetaPropertyData)
{
diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp
index 874faed0af..38ba46e702 100644
--- a/src/quick/designer/qquickdesignersupportitems.cpp
+++ b/src/quick/designer/qquickdesignersupportitems.cpp
@@ -175,29 +175,24 @@ static bool isWindow(QObject *object) {
return false;
}
-static QQmlType *getQmlType(const QString &typeName, int majorNumber, int minorNumber)
+static bool isCrashingType(const QQmlType &type)
{
- return QQmlMetaType::qmlType(typeName, majorNumber, minorNumber);
-}
+ QString name = type.qmlTypeName();
-static bool isCrashingType(QQmlType *type)
-{
- if (type) {
- if (type->qmlTypeName() == QLatin1String("QtMultimedia/MediaPlayer"))
- return true;
+ if (type.qmlTypeName() == QLatin1String("QtMultimedia/MediaPlayer"))
+ return true;
- if (type->qmlTypeName() == QLatin1String("QtMultimedia/Audio"))
- return true;
+ if (type.qmlTypeName() == QLatin1String("QtMultimedia/Audio"))
+ return true;
- if (type->qmlTypeName() == QLatin1String("QtQuick.Controls/MenuItem"))
- return true;
+ if (type.qmlTypeName() == QLatin1String("QtQuick.Controls/MenuItem"))
+ return true;
- if (type->qmlTypeName() == QLatin1String("QtQuick.Controls/Menu"))
- return true;
+ if (type.qmlTypeName() == QLatin1String("QtQuick.Controls/Menu"))
+ return true;
- if (type->qmlTypeName() == QLatin1String("QtQuick/Timer"))
- return true;
- }
+ if (type.qmlTypeName() == QLatin1String("QtQuick/Timer"))
+ return true;
return false;
}
@@ -209,19 +204,19 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in
Q_UNUSED(disableComponentComplete)
QObject *object = 0;
- QQmlType *type = getQmlType(typeName, majorNumber, minorNumber);
+ QQmlType type = QQmlMetaType::qmlType(typeName, majorNumber, minorNumber);
if (isCrashingType(type)) {
object = new QObject;
- } else if (type) {
- if ( type->isComposite()) {
- object = createComponent(type->sourceUrl(), context);
+ } else if (type.isValid()) {
+ if ( type.isComposite()) {
+ object = createComponent(type.sourceUrl(), context);
} else
{
- if (type->typeName() == "QQmlComponent") {
+ if (type.typeName() == "QQmlComponent") {
object = new QQmlComponent(context->engine(), 0);
} else {
- object = type->create();
+ object = type.create();
}
}
diff --git a/src/quick/designer/qquickdesignersupportmetainfo.cpp b/src/quick/designer/qquickdesignersupportmetainfo.cpp
index 332ae26bd4..b398bae55d 100644
--- a/src/quick/designer/qquickdesignersupportmetainfo.cpp
+++ b/src/quick/designer/qquickdesignersupportmetainfo.cpp
@@ -53,8 +53,8 @@ bool QQuickDesignerSupportMetaInfo::isSubclassOf(QObject *object, const QByteArr
const QMetaObject *metaObject = object->metaObject();
while (metaObject) {
- QQmlType *qmlType = QQmlMetaType::qmlType(metaObject);
- if (qmlType && qmlType->qmlTypeName() == QLatin1String(superTypeName)) // ignore version numbers
+ QQmlType qmlType = QQmlMetaType::qmlType(metaObject);
+ if (qmlType.qmlTypeName() == QLatin1String(superTypeName)) // ignore version numbers
return true;
if (metaObject->className() == superTypeName)
diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc
index 4bdd02241d..ede1eb19ac 100644
--- a/src/quick/doc/src/qtquick.qdoc
+++ b/src/quick/doc/src/qtquick.qdoc
@@ -86,6 +86,14 @@ To find out more about using the QML language, see the \l{Qt QML} module documen
\endlist
\endlist
+\section1 Licenses and Attributions
+
+Qt Quick is available under commercial licenses from \l{The Qt Company}.
+In addition, it is available under the
+\l{GNU Lesser General Public License, version 3}, or
+the \l{GNU General Public License, version 2}.
+See \l{Qt Licensing} for further details.
+
\section1 Reference Documentation
Additional Qt Quick information:
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 084b1f197a..1d0d042839 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1921,7 +1921,7 @@ void QQuickItemViewPrivate::layout()
markExtentsDirty();
updateHighlight();
- if (!q->isMoving() && !q->isFlicking()) {
+ if (!q->isMoving() && !q->isFlicking() && !movingFromHighlight()) {
fixupPosition();
refill();
}
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index b6353246e8..2c04022cde 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -363,6 +363,7 @@ protected:
virtual void createHighlight() = 0;
virtual void updateHighlight() = 0;
virtual void resetHighlightPosition() = 0;
+ virtual bool movingFromHighlight() { return false; }
virtual void setPosition(qreal pos) = 0;
virtual void fixupPosition() = 0;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 979a3557a1..edfa970035 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -101,6 +101,7 @@ public:
void createHighlight() override;
void updateHighlight() override;
void resetHighlightPosition() override;
+ bool movingFromHighlight() override;
void setPosition(qreal pos) override;
void layoutVisibleItems(int fromModelIndex = 0) override;
@@ -945,6 +946,17 @@ void QQuickListViewPrivate::resetHighlightPosition()
static_cast<FxListItemSG*>(highlight)->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
}
+bool QQuickListViewPrivate::movingFromHighlight()
+{
+ if (!haveHighlightRange || highlightRange != QQuickListView::StrictlyEnforceRange)
+ return false;
+
+ return (highlightPosAnimator && highlightPosAnimator->isRunning()) ||
+ (highlightHeightAnimator && highlightHeightAnimator->isRunning()) ||
+ (highlightWidthAnimator && highlightWidthAnimator->isRunning());
+}
+
+
QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
{
Q_Q(QQuickListView);
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 318a2fd9a3..06ad0a9dbf 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -3558,18 +3558,23 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
#endif
if (m_maskData) {
+ m_validInput = true;
if (m_text.length() != m_maxLength) {
+ m_validInput = false;
m_acceptableInput = false;
} else {
for (int i = 0; i < m_maxLength; ++i) {
if (m_maskData[i].separator) {
if (m_text.at(i) != m_maskData[i].maskChar) {
+ m_validInput = false;
m_acceptableInput = false;
break;
}
} else {
if (!isValidInput(m_text.at(i), m_maskData[i].maskChar)) {
m_acceptableInput = false;
+ if (m_text.at(i) != m_blank)
+ m_validInput = false;
break;
}
}
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
-Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
+Subproject fe58b18c13d1ea5d42951e5b698efc3bfab6dc8
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 3402aeebc1..6ab84774f2 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -283,9 +283,9 @@ void tst_qmldiskcache::registerImportForImplicitComponent()
QCOMPARE(quint32(testUnit->nImports), quint32(2));
QCOMPARE(testUnit->stringAt(testUnit->importAt(0)->uriIndex), QStringLiteral("QtQuick"));
- QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
+ QQmlType componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
- QCOMPARE(testUnit->stringAt(testUnit->importAt(1)->uriIndex), QString(componentType->module()));
+ QCOMPARE(testUnit->stringAt(testUnit->importAt(1)->uriIndex), QString(componentType.module()));
QCOMPARE(testUnit->stringAt(testUnit->importAt(1)->qualifierIndex), QStringLiteral("QmlInternals"));
QCOMPARE(quint32(testUnit->nObjects), quint32(3));
@@ -295,7 +295,7 @@ void tst_qmldiskcache::registerImportForImplicitComponent()
QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Object));
const QV4::CompiledData::Object *implicitComponent = testUnit->objectAt(obj->bindingTable()->value.objectIndex);
- QCOMPARE(testUnit->stringAt(implicitComponent->inheritedTypeNameIndex), QStringLiteral("QmlInternals.") + componentType->elementName());
+ QCOMPARE(testUnit->stringAt(implicitComponent->inheritedTypeNameIndex), QStringLiteral("QmlInternals.") + componentType.elementName());
}
}
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index 30e517c8f9..798e3fd386 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -148,14 +148,14 @@ void tst_qqmlmetatype::initTestCase()
void tst_qqmlmetatype::qmlParserStatusCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int));
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->parserStatusCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>())->parserStatusCast(), -1);
-
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()) != 0);
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>())->parserStatusCast();
+ QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).parserStatusCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).parserStatusCast(), -1);
+
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).parserStatusCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -168,14 +168,14 @@ void tst_qqmlmetatype::qmlParserStatusCast()
void tst_qqmlmetatype::qmlPropertyValueSourceCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int));
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->propertyValueSourceCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>())->propertyValueSourceCast(), -1);
-
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()) != 0);
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>())->propertyValueSourceCast();
+ QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueSourceCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueSourceCast(), -1);
+
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).propertyValueSourceCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -188,14 +188,14 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast()
void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int));
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->propertyValueInterceptorCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()) != 0);
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>())->propertyValueInterceptorCast(), -1);
-
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()) != 0);
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>())->propertyValueInterceptorCast();
+ QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueInterceptorCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueInterceptorCast(), -1);
+
+ QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).propertyValueInterceptorCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -208,17 +208,17 @@ void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
void tst_qqmlmetatype::qmlType()
{
- QQmlType *type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), 1, 0);
- QVERIFY(type);
- QVERIFY(type->module() == QLatin1String("Test"));
- QVERIFY(type->elementName() == QLatin1String("ParserStatusTestType"));
- QCOMPARE(type->qmlTypeName(), QLatin1String("Test/ParserStatusTestType"));
+ QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), 1, 0);
+ QVERIFY(type.isValid());
+ QVERIFY(type.module() == QLatin1String("Test"));
+ QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType"));
+ QCOMPARE(type.qmlTypeName(), QLatin1String("Test/ParserStatusTestType"));
type = QQmlMetaType::qmlType("Test/ParserStatusTestType", 1, 0);
- QVERIFY(type);
- QVERIFY(type->module() == QLatin1String("Test"));
- QVERIFY(type->elementName() == QLatin1String("ParserStatusTestType"));
- QCOMPARE(type->qmlTypeName(), QLatin1String("Test/ParserStatusTestType"));
+ QVERIFY(type.isValid());
+ QVERIFY(type.module() == QLatin1String("Test"));
+ QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType"));
+ QCOMPARE(type.qmlTypeName(), QLatin1String("Test/ParserStatusTestType"));
}
void tst_qqmlmetatype::invalidQmlTypeName()
@@ -277,23 +277,23 @@ void tst_qqmlmetatype::defaultObject()
void tst_qqmlmetatype::registrationType()
{
- QQmlType *type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), 1, 0);
- QVERIFY(type);
- QVERIFY(!type->isInterface());
- QVERIFY(!type->isSingleton());
- QVERIFY(!type->isComposite());
+ QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), 1, 0);
+ QVERIFY(type.isValid());
+ QVERIFY(!type.isInterface());
+ QVERIFY(!type.isSingleton());
+ QVERIFY(!type.isComposite());
type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), 1, 0);
- QVERIFY(type);
- QVERIFY(!type->isInterface());
- QVERIFY(type->isSingleton());
- QVERIFY(!type->isComposite());
+ QVERIFY(type.isValid());
+ QVERIFY(!type.isInterface());
+ QVERIFY(type.isSingleton());
+ QVERIFY(!type.isComposite());
type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), 1, 0);
- QVERIFY(type);
- QVERIFY(!type->isInterface());
- QVERIFY(!type->isSingleton());
- QVERIFY(type->isComposite());
+ QVERIFY(type.isValid());
+ QVERIFY(!type.isInterface());
+ QVERIFY(!type.isSingleton());
+ QVERIFY(type.isComposite());
}
void tst_qqmlmetatype::compositeType()
@@ -305,12 +305,12 @@ void tst_qqmlmetatype::compositeType()
QObject* obj = c.create();
QVERIFY(obj);
- QQmlType *type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0);
- QVERIFY(type);
- QVERIFY(type->module().isEmpty());
- QCOMPARE(type->elementName(), QLatin1String("ImplicitType"));
- QCOMPARE(type->qmlTypeName(), QLatin1String("ImplicitType"));
- QCOMPARE(type->sourceUrl(), testFileUrl("ImplicitType.qml"));
+ QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0);
+ QVERIFY(type.isValid());
+ QVERIFY(type.module().isEmpty());
+ QCOMPARE(type.elementName(), QLatin1String("ImplicitType"));
+ QCOMPARE(type.qmlTypeName(), QLatin1String("ImplicitType"));
+ QCOMPARE(type.sourceUrl(), testFileUrl("ImplicitType.qml"));
}
void tst_qqmlmetatype::externalEnums()
diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
index 824fe445c0..ac1b76b9d2 100644
--- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
+++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
@@ -103,11 +103,10 @@ QQmlPropertyData *cacheProperty(QQmlPropertyCache *cache, const char *name)
void tst_qqmlpropertycache::properties()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
+ QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject));
QQmlPropertyData *data;
QVERIFY((data = cacheProperty(cache, "propertyA")));
@@ -126,11 +125,10 @@ void tst_qqmlpropertycache::properties()
void tst_qqmlpropertycache::propertiesDerived()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject));
+ QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject));
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
@@ -150,11 +148,10 @@ void tst_qqmlpropertycache::propertiesDerived()
void tst_qqmlpropertycache::methods()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
+ QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject));
QQmlPropertyData *data;
QVERIFY((data = cacheProperty(cache, "slotA")));
@@ -185,11 +182,10 @@ void tst_qqmlpropertycache::methods()
void tst_qqmlpropertycache::methodsDerived()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject));
+ QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject));
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
@@ -221,11 +217,10 @@ void tst_qqmlpropertycache::methodsDerived()
void tst_qqmlpropertycache::signalHandlers()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject));
+ QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject));
QQmlPropertyData *data;
QVERIFY((data = cacheProperty(cache, "onSignalA")));
@@ -250,11 +245,10 @@ void tst_qqmlpropertycache::signalHandlers()
void tst_qqmlpropertycache::signalHandlersDerived()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
DerivedObject object;
const QMetaObject *metaObject = object.metaObject();
- QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject));
+ QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject));
QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()));
QQmlPropertyData *data;
diff --git a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
index fedca98205..071a7b3607 100644
--- a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
+++ b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
@@ -185,14 +185,17 @@ void tst_QQuickDropArea::containsDrag_external()
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
+ const qreal dpr = window.devicePixelRatio();
+ const QPoint nativePos1 = QPoint(50, 50) * dpr;
+ const QPoint nativePos2 = QPoint(150, 50) * dpr;
+ QWindowSystemInterface::handleDrag(&window, &data, nativePos1, Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
- QWindowSystemInterface::handleDrag(&alternateWindow, &data, QPoint(50, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&alternateWindow, &data, nativePos1, Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
@@ -200,13 +203,13 @@ void tst_QQuickDropArea::containsDrag_external()
evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(150, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&window, &data, nativePos2, Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&window, &data, nativePos1, Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
@@ -214,13 +217,13 @@ void tst_QQuickDropArea::containsDrag_external()
evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(150, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&window, &data, nativePos2, Qt::CopyAction);
QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
- QWindowSystemInterface::handleDrop(&window, &data, QPoint(150, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrop(&window, &data, nativePos2, Qt::CopyAction);
}
void tst_QQuickDropArea::keys_internal()
@@ -583,7 +586,8 @@ void tst_QQuickDropArea::position_external()
QMimeData data;
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction);
+ const qreal dpr = window.devicePixelRatio();
+ QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50) * dpr, Qt::CopyAction);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50));
@@ -594,7 +598,7 @@ void tst_QQuickDropArea::position_external()
QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(40, 50), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&window, &data, QPoint(40, 50) * dpr, Qt::CopyAction);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40));
@@ -605,7 +609,7 @@ void tst_QQuickDropArea::position_external()
QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
- QWindowSystemInterface::handleDrag(&window, &data, QPoint(75, 25), Qt::CopyAction);
+ QWindowSystemInterface::handleDrag(&window, &data, QPoint(75, 25) * dpr, Qt::CopyAction);
QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75));
@@ -615,7 +619,7 @@ void tst_QQuickDropArea::position_external()
QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75));
QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25));
- QWindowSystemInterface::handleDrop(&window, &data, QPoint(75, 25), Qt::CopyAction);
+ QWindowSystemInterface::handleDrop(&window, &data, QPoint(75, 25) * dpr, Qt::CopyAction);
}
void tst_QQuickDropArea::drop_internal()
diff --git a/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml b/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml
new file mode 100644
index 0000000000..338af38475
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.0
+
+ListView {
+ width: 400
+ height: 400
+ focus: true
+
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ highlightMoveVelocity: 200
+ preferredHighlightBegin: 150
+ preferredHighlightEnd: 150
+
+ property bool completed
+ Component.onCompleted: completed = true
+
+ model: 10
+ delegate: Item {
+ width: parent.width
+ height: ListView.isCurrentItem ? 100 : 50
+
+ Text {
+ anchors.centerIn: parent
+ text: index
+ }
+
+ Behavior on height {
+ enabled: completed
+ SmoothedAnimation { velocity: 200 }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 98c628068d..2eb87b9431 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -182,6 +182,7 @@ private slots:
void snapOneItemCurrentIndexRemoveAnimation();
void QTBUG_9791();
+ void QTBUG_33568();
void QTBUG_11105();
void QTBUG_21742();
@@ -3470,6 +3471,29 @@ void tst_QQuickListView::QTBUG_9791()
QTRY_COMPARE(listview->contentX(), 590.0);
}
+void tst_QQuickListView::QTBUG_33568()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("strictlyenforcerange-resize.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject());
+ QVERIFY(listview != 0);
+
+ // we want to verify that the change animates smoothly, rather than jumping into place
+ QSignalSpy spy(listview, SIGNAL(contentYChanged()));
+
+ listview->incrementCurrentIndex();
+ QTRY_COMPARE(listview->contentY(), -100.0);
+ QVERIFY(spy.count() > 1);
+
+ spy.clear();
+ listview->incrementCurrentIndex();
+ QTRY_COMPARE(listview->contentY(), -50.0);
+ QVERIFY(spy.count() > 1);
+}
+
void tst_QQuickListView::manualHighlight()
{
QQuickView *window = new QQuickView(0);
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 2e20275193..9b526f80c5 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -216,6 +216,8 @@ private slots:
void keypress_inputMask_data();
void keypress_inputMask();
void keypress_inputMethod_inputMask();
+ void keypress_inputMask_withValidator_data();
+ void keypress_inputMask_withValidator();
void hasAcceptableInputMask_data();
void hasAcceptableInputMask();
void maskCharacter_data();
@@ -6112,6 +6114,79 @@ void tst_qquicktextinput::negativeDimensions()
QCOMPARE(input->height(), qreal(-1));
}
+void tst_qquicktextinput::keypress_inputMask_withValidator_data()
+{
+ QTest::addColumn<QString>("mask");
+ QTest::addColumn<qreal>("validatorMinimum");
+ QTest::addColumn<qreal>("validatorMaximum");
+ QTest::addColumn<int>("decimals");
+ QTest::addColumn<QString>("validatorRegExp");
+ QTest::addColumn<KeyList>("keys");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<QString>("expectedDisplayText");
+
+ {
+ KeyList keys;
+ // inserting '1212' then two backspaces
+ keys << Qt::Key_Home << "1212" << Qt::Key_Backspace << Qt::Key_Backspace;
+ QTest::newRow("backspaceWithInt") << QString("9999;_") << 1.0 << 9999.00 << 0 << QString()
+ << keys << QString("12") << QString("12__");
+ }
+ {
+ KeyList keys;
+ // inserting '12.12' then two backspaces
+ keys << Qt::Key_Home << "12.12" << Qt::Key_Backspace << Qt::Key_Backspace;
+ QTest::newRow("backspaceWithDouble") << QString("99.99;_") << 1.0 << 99.99 << 2 << QString()
+ << keys << QString("12.") << QString("12.__");
+ }
+ {
+ KeyList keys;
+ // inserting '1111.11' then two backspaces
+ keys << Qt::Key_Home << "1111.11" << Qt::Key_Backspace << Qt::Key_Backspace;
+ QTest::newRow("backspaceWithRegExp") << QString("9999.99;_") << 0.0 << 0.0 << 0
+ << QString("/^[-]?((\\.\\d+)|(\\d+(\\.\\d+)?))$/")
+ << keys << QString("1111.") << QString("1111.__");
+ }
+}
+
+void tst_qquicktextinput::keypress_inputMask_withValidator()
+{
+ QFETCH(QString, mask);
+ QFETCH(qreal, validatorMinimum);
+ QFETCH(qreal, validatorMaximum);
+ QFETCH(int, decimals);
+ QFETCH(QString, validatorRegExp);
+ QFETCH(KeyList, keys);
+ QFETCH(QString, expectedText);
+ QFETCH(QString, expectedDisplayText);
+
+ QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; inputMask: \"" + mask + "\"\n";
+ if (!validatorRegExp.isEmpty())
+ componentStr += "validator: RegExpValidator { regExp: " + validatorRegExp + " }\n}";
+ else if (decimals > 0)
+ componentStr += QString("validator: DoubleValidator { bottom: %1; decimals: %2; top: %3 }\n}").
+ arg(validatorMinimum).arg(decimals).arg(validatorMaximum);
+ else
+ componentStr += QString("validator: IntValidator { bottom: %1; top: %2 }\n}").
+ arg((int)validatorMinimum).arg((int)validatorMaximum);
+
+ QQmlComponent textInputComponent(&engine);
+ textInputComponent.setData(componentStr.toLatin1(), QUrl());
+ QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+ QVERIFY(textInput != 0);
+
+ QQuickWindow window;
+ textInput->setParentItem(window.contentItem());
+ window.show();
+ window.requestActivate();
+ QTest::qWaitForWindowActive(&window);
+ QVERIFY(textInput->hasActiveFocus());
+
+ simulateKeys(&window, keys);
+
+ QCOMPARE(textInput->text(), expectedText);
+ QCOMPARE(textInput->displayText(), expectedDisplayText);
+}
void tst_qquicktextinput::setInputMask_data()
{
diff --git a/tests/auto/quick/qquickwindow/data/windowattached.qml b/tests/auto/quick/qquickwindow/data/windowattached.qml
index 9d61a02452..66083db428 100644
--- a/tests/auto/quick/qquickwindow/data/windowattached.qml
+++ b/tests/auto/quick/qquickwindow/data/windowattached.qml
@@ -19,7 +19,6 @@ Rectangle {
property Window extraWindow: Window {
objectName: "extraWindow"
title: "extra window"
- visible: true
Text {
objectName: "extraWindowText"
anchors.centerIn: parent
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 2133b4d2d3..adcdca4c3c 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -886,23 +886,29 @@ void tst_qquickwindow::touchEvent_velocity()
item->setPosition(QPointF(50, 50));
item->setSize(QSizeF(150, 150));
- QList<QWindowSystemInterface::TouchPoint> points;
- QWindowSystemInterface::TouchPoint tp;
- tp.id = 1;
- tp.state = Qt::TouchPointPressed;
- QPoint pos = window->mapToGlobal(item->mapToScene(QPointF(10, 10)).toPoint());
- tp.area = QRectF(pos, QSizeF(4, 4));
+ QList<QTouchEvent::TouchPoint> points;
+ QTouchEvent::TouchPoint tp;
+ tp.setId(1);
+ tp.setState(Qt::TouchPointPressed);
+ const QPointF localPos = item->mapToScene(QPointF(10, 10));
+ const QPointF screenPos = window->mapToGlobal(localPos.toPoint());
+ tp.setPos(localPos);
+ tp.setScreenPos(screenPos);
+ tp.setEllipseDiameters(QSizeF(4, 4));
points << tp;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
QCOMPARE(item->touchEventCount, 1);
- points[0].state = Qt::TouchPointMoved;
- points[0].area.adjust(5, 5, 5, 5);
+ points[0].setState(Qt::TouchPointMoved);
+ points[0].setPos(localPos + QPointF(5, 5));
+ points[0].setScreenPos(screenPos + QPointF(5, 5));
QVector2D velocity(1.5, 2.5);
- points[0].velocity = velocity;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setVelocity(velocity);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
QCOMPARE(item->touchEventCount, 2);
@@ -914,17 +920,20 @@ void tst_qquickwindow::touchEvent_velocity()
QMatrix4x4 transformMatrix;
transformMatrix.rotate(-90, 0, 0, 1); // counterclockwise
QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D();
- points[0].area.adjust(5, 5, 5, 5);
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setPos(points[0].pos() + QPointF(5, 5));
+ points[0].setScreenPos(points[0].screenPos() + QPointF(5, 5));
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
QCOMPARE(item->lastVelocity, transformedVelocity);
- QPoint itemLocalPos = item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint();
+ QPoint itemLocalPos = item->mapFromScene(points[0].pos()).toPoint();
QPoint itemLocalPosFromEvent = item->lastEvent.touchPoints[0].pos().toPoint();
QCOMPARE(itemLocalPos, itemLocalPosFromEvent);
- points[0].state = Qt::TouchPointReleased;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setState(Qt::TouchPointReleased);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
delete item;
@@ -1012,25 +1021,32 @@ void tst_qquickwindow::mouseFromTouch_basic()
item->setSize(QSizeF(150, 150));
item->acceptTouchEvents = false;
- QList<QWindowSystemInterface::TouchPoint> points;
- QWindowSystemInterface::TouchPoint tp;
- tp.id = 1;
- tp.state = Qt::TouchPointPressed;
- QPoint pos = window->mapToGlobal(item->mapToScene(QPointF(10, 10)).toPoint());
- tp.area = QRectF(pos, QSizeF(4, 4));
+ QList<QTouchEvent::TouchPoint> points;
+ QTouchEvent::TouchPoint tp;
+ tp.setId(1);
+ tp.setState(Qt::TouchPointPressed);
+ const QPointF localPos = item->mapToScene(QPointF(10, 10));
+ const QPointF screenPos = window->mapToGlobal(localPos.toPoint());
+ tp.setPos(localPos);
+ tp.setScreenPos(screenPos);
+ tp.setEllipseDiameters(QSizeF(4, 4));
points << tp;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].state = Qt::TouchPointMoved;
- points[0].area.adjust(5, 5, 5, 5);
+ points[0].setState(Qt::TouchPointMoved);
+ points[0].setPos(localPos + QPointF(5, 5));
+ points[0].setScreenPos(screenPos + QPointF(5, 5));
QVector2D velocity(1.5, 2.5);
- points[0].velocity = velocity;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setVelocity(velocity);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].state = Qt::TouchPointReleased;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setState(Qt::TouchPointReleased);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
@@ -1038,7 +1054,7 @@ void tst_qquickwindow::mouseFromTouch_basic()
QCOMPARE(item->mousePressNum, 1);
QCOMPARE(item->mouseMoveNum, 1);
QCOMPARE(item->mouseReleaseNum, 1);
- QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint());
+ QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(points[0].pos()).toPoint());
QCOMPARE(item->lastVelocityFromMouseMove, velocity);
QVERIFY((item->lastMouseCapabilityFlags & QTouchDevice::Velocity) != 0);
@@ -1047,22 +1063,27 @@ void tst_qquickwindow::mouseFromTouch_basic()
QMatrix4x4 transformMatrix;
transformMatrix.rotate(-90, 0, 0, 1); // counterclockwise
QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D();
- points[0].state = Qt::TouchPointPressed;
- points[0].velocity = velocity;
- points[0].area = QRectF(pos, QSizeF(4, 4));
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setState(Qt::TouchPointPressed);
+ points[0].setVelocity(velocity);
+ tp.setPos(localPos);
+ tp.setScreenPos(screenPos);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].state = Qt::TouchPointMoved;
- points[0].area.adjust(5, 5, 5, 5);
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setState(Qt::TouchPointMoved);
+ points[0].setPos(localPos + QPointF(5, 5));
+ points[0].setScreenPos(screenPos + QPointF(5, 5));
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint());
+ QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(points[0].pos()).toPoint());
QCOMPARE(item->lastVelocityFromMouseMove, transformedVelocity);
- points[0].state = Qt::TouchPointReleased;
- QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+ points[0].setState(Qt::TouchPointReleased);
+ QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QCoreApplication::processEvents();
QQuickTouchUtils::flush(window);
delete item;
@@ -2225,6 +2246,7 @@ void tst_qquickwindow::attachedProperty()
QQuickWindow *innerWindow = view.rootObject()->findChild<QQuickWindow*>("extraWindow");
QVERIFY(innerWindow);
+ innerWindow->show();
innerWindow->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(innerWindow));
diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp
index c0907b5dd1..91f907ab5e 100644
--- a/tests/benchmarks/qml/creation/tst_creation.cpp
+++ b/tests/benchmarks/qml/creation/tst_creation.cpp
@@ -196,10 +196,10 @@ void tst_creation::qobject_10tree_cpp()
void tst_creation::qobject_qmltype()
{
- QQmlType *t = QQmlMetaType::qmlType("QtQuick/QtObject", 2, 0);
+ QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", 2, 0);
QBENCHMARK {
- QObject *obj = t->create();
+ QObject *obj = t.create();
delete obj;
}
}
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 7b8dccec40..2b919909ac 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -144,11 +144,11 @@ void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *met
}
}
-void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType *ty, QSet<const QMetaObject *> *metas)
+void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, QSet<const QMetaObject *> *metas)
{
- collectReachableMetaObjects(ty->metaObject(), metas, ty->isExtendedType());
- if (ty->attachedPropertiesType(engine))
- collectReachableMetaObjects(ty->attachedPropertiesType(engine), metas);
+ collectReachableMetaObjects(ty.metaObject(), metas, ty.isExtendedType());
+ if (ty.attachedPropertiesType(engine))
+ collectReachableMetaObjects(ty.attachedPropertiesType(engine), metas);
}
/* We want to add the MetaObject for 'Qt' to the list, this is a
@@ -164,11 +164,11 @@ public:
To do this, we need to find the QQmlTypes associated with this
QMetaObject.
*/
-static QHash<QByteArray, QSet<const QQmlType *> > qmlTypesByCppName;
+static QHash<QByteArray, QSet<QQmlType> > qmlTypesByCppName;
/* A composite type is completely specified by name, major version and minor version.
*/
-static QMap<QString, QSet<const QQmlType *> > qmlTypesByCompositeName;
+static QMap<QString, QSet<QQmlType> > qmlTypesByCompositeName;
static QHash<QByteArray, QByteArray> cppToId;
@@ -213,12 +213,12 @@ QByteArray convertToId(const QMetaObject *mo)
// Collect all metaobjects for types registered with qmlRegisterType() without parameters
void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<const QMetaObject *>& metas ) {
const auto qmlAllTypes = QQmlMetaType::qmlAllTypes();
- for (const QQmlType *ty : qmlAllTypes) {
- if ( ! metas.contains(ty->metaObject()) ) {
- if (!ty->isComposite()) {
+ for (const QQmlType &ty : qmlAllTypes) {
+ if ( ! metas.contains(ty.metaObject()) ) {
+ if (!ty.isComposite()) {
collectReachableMetaObjects(engine, ty, &metas);
} else {
- qmlTypesByCompositeName[ty->elementName()].insert(ty);
+ qmlTypesByCompositeName[ty.elementName()].insert(ty);
}
}
}
@@ -227,25 +227,25 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<c
QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
QSet<const QMetaObject *> &noncreatables,
QSet<const QMetaObject *> &singletons,
- const QList<QQmlType *> &skip = QList<QQmlType *>())
+ const QList<QQmlType> &skip = QList<QQmlType>())
{
QSet<const QMetaObject *> metas;
metas.insert(FriendlyQObject::qtMeta());
QHash<QByteArray, QSet<QByteArray> > extensions;
const auto qmlTypes = QQmlMetaType::qmlTypes();
- for (const QQmlType *ty : qmlTypes) {
- if (!ty->isCreatable())
- noncreatables.insert(ty->metaObject());
- if (ty->isSingleton())
- singletons.insert(ty->metaObject());
- if (!ty->isComposite()) {
- qmlTypesByCppName[ty->metaObject()->className()].insert(ty);
- if (ty->isExtendedType())
- extensions[ty->typeName()].insert(ty->metaObject()->className());
+ for (const QQmlType &ty : qmlTypes) {
+ if (!ty.isCreatable())
+ noncreatables.insert(ty.metaObject());
+ if (ty.isSingleton())
+ singletons.insert(ty.metaObject());
+ if (!ty.isComposite()) {
+ qmlTypesByCppName[ty.metaObject()->className()].insert(ty);
+ if (ty.isExtendedType())
+ extensions[ty.typeName()].insert(ty.metaObject()->className());
collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas);
} else {
- qmlTypesByCompositeName[ty->elementName()].insert(ty);
+ qmlTypesByCompositeName[ty.elementName()].insert(ty);
}
}
@@ -254,21 +254,21 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
// Example: QDeclarativeGraphicsWidget overrides the QtQuick/QGraphicsWidget export
// of QGraphicsWidget.
for (auto it = extensions.cbegin(), end = extensions.cend(); it != end; ++it) {
- QSet<const QQmlType *> baseExports = qmlTypesByCppName.value(it.key());
+ QSet<QQmlType> baseExports = qmlTypesByCppName.value(it.key());
const QSet<QByteArray> extensionCppNames = it.value();
for (const QByteArray &extensionCppName : extensionCppNames) {
- const QSet<const QQmlType *> extensionExports = qmlTypesByCppName.value(extensionCppName);
+ const QSet<QQmlType> extensionExports = qmlTypesByCppName.value(extensionCppName);
// remove extension exports from base imports
// unfortunately the QQmlType pointers don't match, so can't use QSet::subtract
- QSet<const QQmlType *> newBaseExports;
- for (const QQmlType *baseExport : qAsConst(baseExports)) {
+ QSet<QQmlType> newBaseExports;
+ for (const QQmlType &baseExport : qAsConst(baseExports)) {
bool match = false;
- for (const QQmlType *extensionExport : extensionExports) {
- if (baseExport->qmlTypeName() == extensionExport->qmlTypeName()
- && baseExport->majorVersion() == extensionExport->majorVersion()
- && baseExport->minorVersion() == extensionExport->minorVersion()) {
+ for (const QQmlType &extensionExport : extensionExports) {
+ if (baseExport.qmlTypeName() == extensionExport.qmlTypeName()
+ && baseExport.majorVersion() == extensionExport.majorVersion()
+ && baseExport.minorVersion() == extensionExport.minorVersion()) {
match = true;
break;
}
@@ -284,17 +284,17 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
if (creatable) {
// find even more QMetaObjects by instantiating QML types and running
// over the instances
- for (QQmlType *ty : qmlTypes) {
+ for (const QQmlType &ty : qmlTypes) {
if (skip.contains(ty))
continue;
- if (ty->isExtendedType())
+ if (ty.isExtendedType())
continue;
- if (!ty->isCreatable())
+ if (!ty.isCreatable())
continue;
- if (ty->typeName() == "QQmlComponent")
+ if (ty.typeName() == "QQmlComponent")
continue;
- QString tyName = ty->qmlTypeName();
+ QString tyName = ty.qmlTypeName();
tyName = tyName.mid(tyName.lastIndexOf(QLatin1Char('/')) + 1);
if (tyName.isEmpty())
continue;
@@ -302,11 +302,11 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
inObjectInstantiation = tyName;
QObject *object = 0;
- if (ty->isSingleton()) {
- QQmlType::SingletonInstanceInfo *siinfo = ty->singletonInstanceInfo();
+ if (ty.isSingleton()) {
+ QQmlType::SingletonInstanceInfo *siinfo = ty.singletonInstanceInfo();
if (!siinfo) {
std::cerr << "Internal error, " << qPrintable(tyName)
- << "(" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")"
+ << "(" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")"
<< " is singleton, but has no singletonInstanceInfo" << std::endl;
continue;
}
@@ -324,8 +324,8 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
} else {
if (verbose)
std::cerr << "Trying to create object " << qPrintable( tyName )
- << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl;
- object = ty->create();
+ << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl;
+ object = ty.create();
}
inObjectInstantiation.clear();
@@ -333,7 +333,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
if (object) {
if (verbose)
std::cerr << "Got " << qPrintable( tyName )
- << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl;
+ << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl;
collectReachableMetaObjects(object, &metas);
object->deleteLater();
} else {
@@ -476,17 +476,17 @@ public:
return prototypeName;
}
- void dumpComposite(QQmlEngine *engine, const QSet<const QQmlType *> &compositeType, QSet<QByteArray> &defaultReachableNames)
+ void dumpComposite(QQmlEngine *engine, const QSet<QQmlType> &compositeType, QSet<QByteArray> &defaultReachableNames)
{
- for (const QQmlType *type : compositeType)
+ for (const QQmlType &type : compositeType)
dumpCompositeItem(engine, type, defaultReachableNames);
}
- void dumpCompositeItem(QQmlEngine *engine, const QQmlType *compositeType, QSet<QByteArray> &defaultReachableNames)
+ void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet<QByteArray> &defaultReachableNames)
{
- QQmlComponent e(engine, compositeType->sourceUrl());
+ QQmlComponent e(engine, compositeType.sourceUrl());
if (!e.isReady()) {
- std::cerr << "WARNING: skipping module " << compositeType->elementName().toStdString()
+ std::cerr << "WARNING: skipping module " << compositeType.elementName().toStdString()
<< std::endl << e.errorString().toStdString() << std::endl;
return;
}
@@ -507,14 +507,14 @@ public:
&objectsToMerge);
qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
- QString qmlTyName = compositeType->qmlTypeName();
- const QString exportString = getExportString(qmlTyName, compositeType->majorVersion(), compositeType->minorVersion());
+ QString qmlTyName = compositeType.qmlTypeName();
+ const QString exportString = getExportString(qmlTyName, compositeType.majorVersion(), compositeType.minorVersion());
qml->writeScriptBinding(QLatin1String("name"), exportString);
qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString);
- qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType->minorVersion()));
+ qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion()));
qml->writeBooleanBinding(QLatin1String("isComposite"), true);
- if (compositeType->isSingleton()) {
+ if (compositeType.isSingleton()) {
qml->writeBooleanBinding(QLatin1String("isCreatable"), false);
qml->writeBooleanBinding(QLatin1String("isSingleton"), true);
}
@@ -551,12 +551,12 @@ public:
if (meta->superClass())
qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass())));
- const QSet<const QQmlType *> qmlTypes = qmlTypesByCppName.value(meta->className());
+ const QSet<QQmlType> qmlTypes = qmlTypesByCppName.value(meta->className());
if (!qmlTypes.isEmpty()) {
- QHash<QString, const QQmlType *> exports;
+ QHash<QString, QQmlType> exports;
- for (const QQmlType *qmlTy : qmlTypes) {
- const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion());
+ for (const QQmlType &qmlTy : qmlTypes) {
+ const QString exportString = getExportString(qmlTy.qmlTypeName(), qmlTy.majorVersion(), qmlTy.minorVersion());
exports.insert(exportString, qmlTy);
}
@@ -574,12 +574,12 @@ public:
// write meta object revisions
QStringList metaObjectRevisions;
for (const QString &exportString : qAsConst(exportStrings)) {
- int metaObjectRevision = exports[exportString]->metaObjectRevision();
+ int metaObjectRevision = exports[exportString].metaObjectRevision();
metaObjectRevisions += QString::number(metaObjectRevision);
}
qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), metaObjectRevisions);
- if (const QMetaObject *attachedType = (*qmlTypes.begin())->attachedPropertiesType(engine)) {
+ if (const QMetaObject *attachedType = (*qmlTypes.begin()).attachedPropertiesType(engine)) {
// Can happen when a type is registered that returns itself as attachedPropertiesType()
// because there is no creatable type to attach to.
if (attachedType != meta) {
@@ -1186,7 +1186,7 @@ int main(int argc, char *argv[])
QSet<const QMetaObject *> uncreatableMetas;
QSet<const QMetaObject *> singletonMetas;
QSet<const QMetaObject *> defaultReachable = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas);
- QList<QQmlType *> defaultTypes = QQmlMetaType::qmlTypes();
+ QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes();
// add some otherwise unreachable QMetaObjects
defaultReachable.insert(&QQuickMouseEvent::staticMetaObject);
@@ -1227,16 +1227,16 @@ int main(int argc, char *argv[])
} else {
// find a valid QtQuick import
QByteArray importCode;
- QQmlType *qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject);
- if (!qtObjectType) {
+ QQmlType qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject);
+ if (!qtObjectType.isValid()) {
std::cerr << "Could not find QtObject type" << std::endl;
importCode = qtQmlImportString.toUtf8();
} else {
- QString module = qtObjectType->qmlTypeName();
+ QString module = qtObjectType.qmlTypeName();
module = module.mid(0, module.lastIndexOf(QLatin1Char('/')));
importCode = QString("import %1 %2.%3").arg(module,
- QString::number(qtObjectType->majorVersion()),
- QString::number(qtObjectType->minorVersion())).toUtf8();
+ QString::number(qtObjectType.majorVersion()),
+ QString::number(qtObjectType.minorVersion())).toUtf8();
}
// avoid importing dependencies?
for (const QString &moduleToImport : qAsConst(dependencies)) {
@@ -1325,7 +1325,7 @@ int main(int argc, char *argv[])
dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta));
}
- QMap<QString, QSet<const QQmlType *> >::const_iterator iter = qmlTypesByCompositeName.constBegin();
+ QMap<QString, QSet<QQmlType> >::const_iterator iter = qmlTypesByCompositeName.constBegin();
for (; iter != qmlTypesByCompositeName.constEnd(); ++iter)
dumper.dumpComposite(&engine, iter.value(), defaultReachableNames);