aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatypedata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlmetatypedata.cpp')
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp145
1 files changed, 66 insertions, 79 deletions
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 4be26acdc6..bc7e762e53 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qqmlmetatypedata_p.h"
@@ -51,9 +15,14 @@ QQmlMetaTypeData::QQmlMetaTypeData()
QQmlMetaTypeData::~QQmlMetaTypeData()
{
- for (auto it = propertyCaches.begin(), end = propertyCaches.end(); it != end; ++it)
- (*it)->release();
+ {
+ // Unregister all remaining composite types.
+ // Avoid deletion recursion (via QQmlTypePrivate dtor) by moving them out of the way first.
+ CompositeTypes emptyComposites;
+ emptyComposites.swap(compositeTypes);
+ }
+ propertyCaches.clear();
// Do this before the attached properties disappear.
types.clear();
undeletableTypes.clear();
@@ -63,7 +32,7 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
// This expects a "fresh" QQmlTypePrivate and adopts its reference.
void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
{
- for (int i = 0; i < types.count(); ++i) {
+ for (int i = 0; i < types.size(); ++i) {
if (!types.at(i).isValid()) {
types[i] = QQmlType(priv);
priv->index = i;
@@ -72,7 +41,7 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
}
}
types.append(QQmlType(priv));
- priv->index = types.count() - 1;
+ priv->index = types.size() - 1;
priv->release();
}
@@ -118,48 +87,53 @@ bool QQmlMetaTypeData::registerModuleTypes(const QString &uri)
return false;
}
-QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForVersion(int index, QTypeRevision version) const
+QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
+ int index, QTypeRevision version) const
{
- return (index < typePropertyCaches.length())
- ? typePropertyCaches.at(index).value(version).data()
- : nullptr;
+ return (index < typePropertyCaches.size())
+ ? typePropertyCaches.at(index).value(version)
+ : QQmlPropertyCache::ConstPtr();
}
void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version,
- QQmlPropertyCache *cache)
+ const QQmlPropertyCache::ConstPtr &cache)
{
- if (index >= typePropertyCaches.length())
+ if (index >= typePropertyCaches.size())
typePropertyCaches.resize(index + 1);
typePropertyCaches[index][version] = cache;
}
void QQmlMetaTypeData::clearPropertyCachesForVersion(int index)
{
- if (index < typePropertyCaches.length())
+ if (index < typePropertyCaches.size())
typePropertyCaches[index].clear();
}
-QQmlRefPointer<QQmlPropertyCache> QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, QTypeRevision version)
+QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache(
+ const QMetaObject *metaObject, QTypeRevision version)
{
- if (QQmlPropertyCache *rv = propertyCaches.value(metaObject))
+ if (QQmlPropertyCache::ConstPtr rv = propertyCaches.value(metaObject))
return rv;
- if (!metaObject->superClass()) {
- QQmlPropertyCache *rv = new QQmlPropertyCache(metaObject);
+ QQmlPropertyCache::ConstPtr rv;
+ if (const QMetaObject *superMeta = metaObject->superClass())
+ rv = propertyCache(superMeta, version)->copyAndAppend(metaObject, version);
+ else
+ rv = QQmlPropertyCache::createStandalone(metaObject);
+
+ const auto *mop = reinterpret_cast<const QMetaObjectPrivate *>(metaObject->d.data);
+ if (!(mop->flags & DynamicMetaObject))
propertyCaches.insert(metaObject, rv);
- return rv;
- }
- auto super = propertyCache(metaObject->superClass(), version);
- QQmlPropertyCache *rv = super->copyAndAppend(metaObject, version);
- propertyCaches.insert(metaObject, rv);
+
return rv;
}
-QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRevision version)
+QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache(
+ const QQmlType &type, QTypeRevision version)
{
Q_ASSERT(type.isValid());
- if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), version))
+ if (auto pc = propertyCacheForVersion(type.index(), version))
return pc;
QVector<QQmlType> types;
@@ -167,13 +141,14 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe
quint8 maxMinorVersion = 0;
const QMetaObject *metaObject = type.metaObject();
+ Q_ASSERT(metaObject);
const QTypeRevision combinedVersion = version.hasMajorVersion()
? version
: (version.hasMinorVersion()
? QTypeRevision::fromVersion(type.version().majorVersion(),
version.minorVersion())
- : type.version());
+ : QTypeRevision::fromMajorVersion(type.version().majorVersion()));
while (metaObject) {
QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), combinedVersion);
@@ -189,32 +164,28 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe
const QTypeRevision maxVersion = QTypeRevision::fromVersion(combinedVersion.majorVersion(),
maxMinorVersion);
- if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), maxVersion)) {
+ if (auto pc = propertyCacheForVersion(type.index(), maxVersion)) {
setPropertyCacheForVersion(type.index(), maxVersion, pc);
return pc;
}
- QQmlPropertyCache *raw = propertyCache(type.metaObject(), combinedVersion).data();
-
- bool hasCopied = false;
+ QQmlPropertyCache::ConstPtr raw = propertyCache(type.metaObject(), combinedVersion);
+ QQmlPropertyCache::Ptr copied;
- for (int ii = 0; ii < types.count(); ++ii) {
+ for (int ii = 0; ii < types.size(); ++ii) {
const QQmlType &currentType = types.at(ii);
if (!currentType.isValid())
continue;
QTypeRevision rev = currentType.metaObjectRevision();
- int moIndex = types.count() - 1 - ii;
+ int moIndex = types.size() - 1 - ii;
if (raw->allowedRevision(moIndex) != rev) {
- if (!hasCopied) {
- // TODO: The copy should be mutable, and the original should be const
- // Considering this, the setAllowedRevision() below does not violate
- // the immutability of already published property caches.
- raw = raw->copy();
- hasCopied = true;
+ if (copied.isNull()) {
+ copied = raw->copy();
+ raw = copied;
}
- raw->setAllowedRevision(moIndex, rev);
+ copied->setAllowedRevision(moIndex, rev);
}
}
@@ -240,12 +211,12 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe
!overloadError && iter != raw->stringCache.end();
++iter) {
- QQmlPropertyData *d = *iter;
+ const QQmlPropertyData *d = *iter;
if (raw->isAllowedInRevision(d))
continue; // Not excluded - no problems
// check that a regular "name" overload isn't happening
- QQmlPropertyData *current = d;
+ const QQmlPropertyData *current = d;
while (!overloadError && current) {
current = d->overrideData(current);
if (current && raw->isAllowedInRevision(current))
@@ -263,13 +234,29 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRe
setPropertyCacheForVersion(type.index(), version, raw);
- if (hasCopied)
- raw->release();
-
if (version != maxVersion)
setPropertyCacheForVersion(type.index(), maxVersion, raw);
return raw;
}
+static QQmlPropertyCache::ConstPtr propertyCacheForPotentialInlineComponentType(
+ QMetaType t, const QQmlMetaTypeData::CompositeTypes::const_iterator &iter) {
+ if (t != (*iter)->metaType()) {
+ // this is an inline component, and what we have in the iterator is currently the parent compilation unit
+ for (auto &&icDatum: (*iter)->inlineComponentData)
+ if (icDatum.qmlType.typeId() == t)
+ return (*iter)->propertyCaches.at(icDatum.objectIndex);
+ }
+ return (*iter)->rootPropertyCache();
+}
+
+QQmlPropertyCache::ConstPtr QQmlMetaTypeData::findPropertyCacheInCompositeTypes(QMetaType t) const
+{
+ auto iter = compositeTypes.constFind(t.iface());
+ return (iter == compositeTypes.constEnd())
+ ? QQmlPropertyCache::ConstPtr()
+ : propertyCacheForPotentialInlineComponentType(t, iter);
+}
+
QT_END_NAMESPACE