Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlmetatypedata.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <private/qqmltype_p_p.h>
7#include <private/qqmltypemodule_p.h>
8#include <private/qqmlpropertycache_p.h>
9
11
15
17{
18 {
19 // Unregister all remaining composite types.
20 // Avoid deletion recursion (via QQmlTypePrivate dtor) by moving them out of the way first.
21 CompositeTypes emptyComposites;
22 emptyComposites.swap(compositeTypes);
23 }
24
26 // Do this before the attached properties disappear.
27 types.clear();
30}
31
32// This expects a "fresh" QQmlTypePrivate and adopts its reference.
34{
35 for (int i = 0; i < types.size(); ++i) {
36 if (!types.at(i).isValid()) {
37 types[i] = QQmlType(priv);
38 priv->index = i;
39 priv->release();
40 return;
41 }
42 }
43 types.append(QQmlType(priv));
44 priv->index = types.size() - 1;
45 priv->release();
46}
47
48QQmlMetaTypeData::VersionedUri::VersionedUri(const std::unique_ptr<QQmlTypeModule> &module)
49 : uri(module->module()), majorVersion(module->majorVersion())
50{
51}
52
54{
55 const auto qqtm = std::lower_bound(
56 uriToModule.begin(), uriToModule.end(), VersionedUri(module, version),
57 std::less<QQmlMetaTypeData::VersionedUri>());
58 if (qqtm == uriToModule.end())
59 return nullptr;
60
61 QQmlTypeModule *candidate = qqtm->get();
62 return (candidate->module() == module && candidate->majorVersion() == version.majorVersion())
63 ? candidate
64 : nullptr;
65}
66
67QQmlTypeModule *QQmlMetaTypeData::addTypeModule(std::unique_ptr<QQmlTypeModule> module)
68{
69 QQmlTypeModule *ret = module.get();
70 uriToModule.emplace_back(std::move(module));
71 std::sort(uriToModule.begin(), uriToModule.end(),
72 [](const std::unique_ptr<QQmlTypeModule> &a,
73 const std::unique_ptr<QQmlTypeModule> &b) {
74 const int diff = a->module().compare(b->module());
75 return diff < 0 || (diff == 0 && a->majorVersion() < b->majorVersion());
76 });
77 return ret;
78}
79
81{
82 auto function = moduleTypeRegistrationFunctions.constFind(uri);
83 if (function != moduleTypeRegistrationFunctions.constEnd()) {
84 (*function)();
85 return true;
86 }
87 return false;
88}
89
97
105
111
113 const QMetaObject *metaObject, QTypeRevision version)
114{
116 return rv;
117
119 if (const QMetaObject *superMeta = metaObject->superClass())
120 rv = propertyCache(superMeta, version)->copyAndAppend(metaObject, version);
121 else
123
124 const auto *mop = reinterpret_cast<const QMetaObjectPrivate *>(metaObject->d.data);
125 if (!(mop->flags & DynamicMetaObject))
127
128 return rv;
129}
130
132 const QQmlType &type, QTypeRevision version)
133{
134 Q_ASSERT(type.isValid());
135
136 if (auto pc = propertyCacheForVersion(type.index(), version))
137 return pc;
138
139 QVector<QQmlType> types;
140
141 quint8 maxMinorVersion = 0;
142
143 const QMetaObject *metaObject = type.metaObject();
145
146 const QTypeRevision combinedVersion = version.hasMajorVersion()
147 ? version
148 : (version.hasMinorVersion()
149 ? QTypeRevision::fromVersion(type.version().majorVersion(),
150 version.minorVersion())
151 : QTypeRevision::fromMajorVersion(type.version().majorVersion()));
152
153 while (metaObject) {
154 QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), combinedVersion);
155 if (t.isValid()) {
156 maxMinorVersion = qMax(maxMinorVersion, t.version().minorVersion());
157 types << t;
158 } else {
159 types << QQmlType();
160 }
161
162 metaObject = metaObject->superClass();
163 }
164
165 const QTypeRevision maxVersion = QTypeRevision::fromVersion(combinedVersion.majorVersion(),
166 maxMinorVersion);
167 if (auto pc = propertyCacheForVersion(type.index(), maxVersion)) {
168 setPropertyCacheForVersion(type.index(), maxVersion, pc);
169 return pc;
170 }
171
172 QQmlPropertyCache::ConstPtr raw = propertyCache(type.metaObject(), combinedVersion);
174
175 for (int ii = 0; ii < types.size(); ++ii) {
176 const QQmlType &currentType = types.at(ii);
177 if (!currentType.isValid())
178 continue;
179
180 QTypeRevision rev = currentType.metaObjectRevision();
181 int moIndex = types.size() - 1 - ii;
182
183 if (raw->allowedRevision(moIndex) != rev) {
184 if (copied.isNull()) {
185 copied = raw->copy();
186 raw = copied;
187 }
188 copied->setAllowedRevision(moIndex, rev);
189 }
190 }
191
192 // Test revision compatibility - the basic rule is:
193 // * Anything that is excluded, cannot overload something that is not excluded *
194
195 // Signals override:
196 // * other signals and methods of the same name.
197 // * properties named on<Signal Name>
198 // * automatic <property name>Changed notify signals
199
200 // Methods override:
201 // * other methods of the same name
202
203 // Properties override:
204 // * other elements of the same name
205
206#if 0
207 bool overloadError = false;
208 QString overloadName;
209
210 for (QQmlPropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
211 !overloadError && iter != raw->stringCache.end();
212 ++iter) {
213
214 const QQmlPropertyData *d = *iter;
215 if (raw->isAllowedInRevision(d))
216 continue; // Not excluded - no problems
217
218 // check that a regular "name" overload isn't happening
219 const QQmlPropertyData *current = d;
220 while (!overloadError && current) {
221 current = d->overrideData(current);
222 if (current && raw->isAllowedInRevision(current))
223 overloadError = true;
224 }
225 }
226
227 if (overloadError) {
228 if (hasCopied) raw->release();
229
230 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."));
231 return 0;
232 }
233#endif
234
235 setPropertyCacheForVersion(type.index(), version, raw);
236
237 if (version != maxVersion)
238 setPropertyCacheForVersion(type.index(), maxVersion, raw);
239
240 return raw;
241}
242
245 if (t != (*iter)->metaType()) {
246 // this is an inline component, and what we have in the iterator is currently the parent compilation unit
247 for (auto &&icDatum: (*iter)->inlineComponentData)
248 if (icDatum.qmlType.typeId() == t)
249 return (*iter)->propertyCaches.at(icDatum.objectIndex);
250 }
251 return (*iter)->rootPropertyCache();
252}
253
261
const_iterator constFind(const Key &key) const noexcept
Definition qhash.h:1299
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
Definition qhash.h:1219
T value(const Key &key) const noexcept
Definition qhash.h:1054
void swap(QHash &other) noexcept
Definition qhash.h:900
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:951
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
typename QLinkedStringHash< QPair< int, QQmlPropertyData * > >::ConstIterator ConstIterator
\inmodule QtCore
Definition qmetatype.h:341
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version)
Returns the type (if any) of URI-qualified named qualifiedName and version specified by version_major...
static Ptr createStandalone(const QMetaObject *, QTypeRevision metaObjectRevision=QTypeRevision::zero())
Creates a standalone QQmlPropertyCache of metaObject.
quint8 majorVersion() const
QString module() const
bool isValid() const
Definition qqmltype_p.h:54
QTypeRevision metaObjectRevision() const
Definition qqmltype.cpp:704
void clear()
Definition qset.h:61
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
static constexpr QTypeRevision fromMajorVersion(Major majorVersion)
Produces a QTypeRevision from the given majorVersion with an invalid minor version.
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given majorVersion and minorVersion, both of which need to be a val...
constexpr bool hasMinorVersion() const
Returns true if the minor version is known, otherwise false.
constexpr bool hasMajorVersion() const
Returns true if the major version is known, otherwise false.
constexpr quint8 minorVersion() const
Returns the minor version encoded in the revision.
constexpr quint8 majorVersion() const
Returns the major version encoded in the revision.
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
DBusConnection const char DBusError * error
return ret
static const QMetaObjectPrivate * priv(const uint *data)
@ DynamicMetaObject
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLsizei GLenum GLenum * types
GLenum type
GLdouble GLdouble t
Definition qopenglext.h:243
static QQmlPropertyCache::ConstPtr propertyCacheForPotentialInlineComponentType(QMetaType t, const QQmlMetaTypeData::CompositeTypes::const_iterator &iter)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
unsigned char quint8
Definition qtypes.h:46
obj metaObject() -> className()
\inmodule QtCore \reentrant
Definition qchar.h:18
\inmodule QtCore
const QMetaObject * superClass() const
Returns the meta-object of the superclass, or \nullptr if there is no such object.
QQmlTypeModule * addTypeModule(std::unique_ptr< QQmlTypeModule > module)
bool registerModuleTypes(const QString &uri)
QQmlTypeModule * findTypeModule(const QString &module, QTypeRevision version)
QHash< int, QQmlValueType * > metaTypeToValueType
QQmlPropertyCache::ConstPtr propertyCache(const QMetaObject *metaObject, QTypeRevision version)
QHash< const QMetaObject *, QQmlPropertyCache::ConstPtr > propertyCaches
void registerType(QQmlTypePrivate *priv)
QVector< QHash< QTypeRevision, QQmlPropertyCache::ConstPtr > > typePropertyCaches
QHash< QString, void(*)()> moduleTypeRegistrationFunctions
CompositeTypes compositeTypes
QList< QQmlType > types
QSet< QQmlType > undeletableTypes
QQmlPropertyCache::ConstPtr findPropertyCacheInCompositeTypes(QMetaType t) const
QQmlPropertyCache::ConstPtr propertyCacheForVersion(int index, QTypeRevision version) const
void clearPropertyCachesForVersion(int index)
void setPropertyCacheForVersion(int index, QTypeRevision version, const QQmlPropertyCache::ConstPtr &cache)