190class Q_QML_EXPORT QQmlPropertyCache final :
public QQmlRefCounted<QQmlPropertyCache>
193 using Ptr = QQmlRefPointer<QQmlPropertyCache>;
195 struct ConstPtr :
public QQmlRefPointer<
const QQmlPropertyCache>
197 using QQmlRefPointer<
const QQmlPropertyCache>::QQmlRefPointer;
199 ConstPtr(
const Ptr &ptr) : ConstPtr(ptr.data(), AddRef) {}
200 ConstPtr(Ptr &&ptr) : ConstPtr(ptr.take(), Adopt) {}
201 ConstPtr &operator=(
const Ptr &ptr) {
return operator=(ConstPtr(ptr)); }
202 ConstPtr &operator=(Ptr &&ptr) {
return operator=(ConstPtr(std::move(ptr))); }
205 static Ptr createStandalone(
206 const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero());
209 OverrideSemantics::HandlerRef handleOverride = OverrideSemantics::handleOverride)
210 : _handleOverride(handleOverride) { };
211 ~QQmlPropertyCache();
213 void update(
const QMetaObject *);
214 void invalidate(
const QMetaObject *);
216 QQmlPropertyCache::Ptr copy()
const;
218 QQmlPropertyCache::Ptr copyAndAppend(
219 const QMetaObject *, QTypeRevision typeVersion,
220 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
221 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
222 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags())
const;
224 QQmlPropertyCache::Ptr copyAndReserve(
225 int propertyCount,
int methodCount,
int signalCount,
int enumCount)
const;
227 const QMetaObject *metaObject()
const;
228 const QMetaObject *createMetaObject()
const;
229 const QMetaObject *firstCppMetaObject()
const;
232 const QQmlPropertyData *property(
const K &key, QObject *object,
233 const QQmlRefPointer<QQmlContextData> &context)
const
235 return findProperty(stringCache.find(key), object, context);
238 const QQmlPropertyData *property(
int)
const;
239 const QQmlPropertyData *maybeUnresolvedProperty(
int)
const;
240 const QQmlPropertyData *method(
int)
const;
241 const QQmlPropertyData *signal(
int index)
const;
242 QQmlEnumData *qmlEnum(
int)
const;
243 int methodIndexToSignalIndex(
int)
const;
245 QString defaultPropertyName()
const;
246 const QQmlPropertyData *defaultProperty()
const;
249 inline const QQmlPropertyCache::ConstPtr &parent()
const;
252 void setParent(QQmlPropertyCache::ConstPtr newParent);
254 inline const QQmlPropertyData *overrideData(
const QQmlPropertyData *)
const;
255 inline bool isAllowedInRevision(
const QQmlPropertyData *)
const;
257 static const QQmlPropertyData *property(
258 QObject *, QStringView,
const QQmlRefPointer<QQmlContextData> &,
260 static const QQmlPropertyData *property(QObject *,
const QLatin1String &,
const QQmlRefPointer<QQmlContextData> &,
262 static const QQmlPropertyData *property(QObject *,
const QV4::String *,
const QQmlRefPointer<QQmlContextData> &,
266 int originalClone(
int index)
const;
267 static int originalClone(
const QObject *,
int index);
269 QList<QByteArray> signalParameterNames(
int index)
const;
270 static QString signalParameterStringForJS(
271 const QList<QByteArray> ¶meterNameList, QString *errorString =
nullptr);
273 const char *className()
const;
275 inline int propertyCount()
const;
276 inline int ownPropertyCount()
const {
return int(propertyIndexCache.count()); }
277 inline int propertyOffset()
const;
278 inline int methodCount()
const;
279 inline int ownMethodCount()
const {
return int(methodIndexCache.count()); }
280 inline int methodOffset()
const;
281 inline int signalCount()
const;
282 inline int ownSignalCount()
const {
return int(signalHandlerIndexCache.count()); }
283 inline int signalOffset()
const;
284 inline int qmlEnumCount()
const;
286 void toMetaObjectBuilder(QMetaObjectBuilder &)
const;
288 inline bool callJSFactoryMethod(QObject *object,
void **args)
const;
290 static bool determineMetaObjectSizes(
const QMetaObject &mo,
int *fieldCount,
int *stringCount);
291 static bool addToHash(QCryptographicHash &hash,
const QMetaObject &mo);
293 QByteArray checksum(QHash<quintptr, QByteArray> *checksums,
bool *ok)
const;
295 QTypeRevision allowedRevision(
int index)
const {
return allowedRevisionCache[index]; }
296 void setAllowedRevision(
int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; }
299 friend class QQmlEnginePrivate;
300 friend class QQmlCompiler;
301 template <
typename T>
friend class QQmlPropertyCacheCreator;
302 template <
typename T>
friend class QQmlPropertyCacheAliasCreator;
303 template <
typename T>
friend class QQmlComponentAndAliasResolver;
304 friend class QQmlMetaObject;
305 friend class ::tst_qqmlpropertycache;
308 const QQmlMetaObjectPointer &metaObject,
309 OverrideSemantics::HandlerRef handleOverride = OverrideSemantics::handleOverride)
310 : _handleOverride(handleOverride), _metaObject(metaObject)
314 inline QQmlPropertyCache::Ptr copy(
const QQmlMetaObjectPointer &mo,
int reserve)
const;
316 void append(
const QMetaObject *, QTypeRevision typeVersion,
317 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
318 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
319 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
322 using Error = OverrideSemantics::Status;
323 using AppendResult = q23::expected<
void, Error>;
328 AppendResult appendPropertyAttr(
const QString &name, QQmlPropertyData &&data);
329 AppendResult appendAlias(
const QString &, QQmlPropertyData::Flags flags,
int coreIndex,
330 QMetaType propType, QTypeRevision version,
int notifyIndex,
331 int encodedTargetIndex,
int targetObjectId);
332 void appendSignal(
const QString &, QQmlPropertyData::Flags,
int coreIndex,
333 const QMetaType *types =
nullptr,
334 const QList<QByteArray> &names = QList<QByteArray>());
335 void appendMethod(
const QString &, QQmlPropertyData::Flags flags,
int coreIndex,
336 QMetaType returnType,
const QList<QByteArray> &names,
337 const QList<QMetaType> ¶meterTypes);
338 void appendEnum(
const QString &,
const QList<QQmlEnumValue> &);
340 QQmlPropertyCacheMethodArguments *createArgumentsObject(
int count,
341 const QList<QByteArray> &names);
343 typedef QList<QQmlPropertyData> IndexCache;
344 typedef QLinkedStringMultiHash<std::pair<
int, QQmlPropertyData *> > StringCache;
345 typedef QList<QTypeRevision> AllowedRevisionCache;
347 const QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *,
348 const QQmlRefPointer<QQmlContextData> &)
const;
349 const QQmlPropertyData *findProperty(StringCache::ConstIterator it,
const QQmlVMEMetaObject *,
350 const QQmlRefPointer<QQmlContextData> &)
const;
353 QQmlPropertyData *findNamedProperty(
const K &key)
const
355 StringCache::mapped_type *it = stringCache.value(key);
356 return it ? it->second : 0;
360 void setNamedProperty(
const K &key,
int index, QQmlPropertyData *data)
362 stringCache.insert(key, std::make_pair(index, data));
373 template <
typename String>
374 void maybeLog(OverrideSemantics::Status status,
const String &name)
const
377 case OverrideSemantics::Status::OverridingFinal: {
378 qCWarning(qqmlPropertyCacheAppend).noquote()
379 << QStringLiteral(
"Final member %1 is overridden in class %2. The "
380 "override won't be used.")
381 .arg(qPrintable(name), className());
384 case OverrideSemantics::Status::MissingBase: {
385 qCWarning(qqmlPropertyCacheAppend).noquote()
386 << QStringLiteral(
"Member %1 of the object %2 does not override anything."
387 " Consider removing \"override\". ")
388 .arg(qPrintable(name), className());
391 case OverrideSemantics::Status::OverridingNonVirtual: {
393 qCDebug(qqmlPropertyCacheAppend).noquote()
394 << QStringLiteral(
"Member %1 of the object %2 overrides a non-virtual member. "
395 "Consider renaming it or mark it virtual in the base object")
396 .arg(qPrintable(name), className());
399 case OverrideSemantics::Status::OverridingNonVirtualError: {
400 qCWarning(qqmlPropertyCacheAppend).noquote()
401 << QStringLiteral(
"Member %1 of the object %2 overrides a non-virtual member. "
402 "Consider renaming it or mark it virtual in the base object")
403 .arg(qPrintable(name), className());
406 case OverrideSemantics::Status::MissingOverrideOrFinalSpecifier: {
407 qCWarning(qqmlPropertyCacheAppend).noquote()
409 "Member %1 of the object %2 overrides a member of the base object. "
410 "Consider renaming it or adding final or override specifier")
411 .arg(qPrintable(name), className());
421 OverrideSemantics::HandlerRef _handleOverride;
423 int propertyIndexCacheStart = 0;
424 QQmlPropertyCache::ConstPtr _parent;
426 IndexCache propertyIndexCache;
427 IndexCache methodIndexCache;
428 IndexCache signalHandlerIndexCache;
429 StringCache stringCache;
430 AllowedRevisionCache allowedRevisionCache;
431 QList<QQmlEnumData> enumCache;
433 QQmlMetaObjectPointer _metaObject;
434 QByteArray _dynamicClassName;
435 QByteArray _dynamicStringData;
436 QByteArray _listPropertyAssignBehavior;
437 QString _defaultPropertyName;
438 QQmlPropertyCacheMethodArguments *argumentsCache =
nullptr;
439 int methodIndexCacheStart = 0;
440 int signalHandlerIndexCacheStart = 0;
441 int _jsFactoryMethodIndex = -1;