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;
217 QQmlPropertyCache::Ptr rebased(
const QQmlPropertyCache::ConstPtr &parent)
const;
219 QQmlPropertyCache::Ptr copyAndAppend(
220 const QMetaObject *, QTypeRevision typeVersion,
221 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
222 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
223 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags())
const;
225 QQmlPropertyCache::Ptr copyAndReserve(
226 int propertyCount,
int methodCount,
int signalCount,
int enumCount)
const;
228 const QMetaObject *metaObject()
const;
229 const QMetaObject *createMetaObject()
const;
230 const QMetaObject *firstCppMetaObject()
const;
233 const QQmlPropertyData *property(
const K &key, QObject *object,
234 const QQmlRefPointer<QQmlContextData> &context)
const
236 return findProperty(stringCache.find(key), object, context);
239 const QQmlPropertyData *property(
int)
const;
240 const QQmlPropertyData *maybeUnresolvedProperty(
int)
const;
241 const QQmlPropertyData *method(
int)
const;
242 const QQmlPropertyData *signal(
int index)
const;
243 QQmlEnumData *qmlEnum(
int)
const;
244 int methodIndexToSignalIndex(
int)
const;
246 QString defaultPropertyName()
const;
247 const QQmlPropertyData *defaultProperty()
const;
250 inline const QQmlPropertyCache::ConstPtr &parent()
const;
253 void setParent(QQmlPropertyCache::ConstPtr newParent);
255 inline const QQmlPropertyData *overrideData(
const QQmlPropertyData *)
const;
256 inline bool isAllowedInRevision(
const QQmlPropertyData *)
const;
258 static const QQmlPropertyData *property(
259 QObject *, QStringView,
const QQmlRefPointer<QQmlContextData> &,
261 static const QQmlPropertyData *property(QObject *,
const QLatin1String &,
const QQmlRefPointer<QQmlContextData> &,
263 static const QQmlPropertyData *property(QObject *,
const QV4::String *,
const QQmlRefPointer<QQmlContextData> &,
267 int originalClone(
int index)
const;
268 static int originalClone(
const QObject *,
int index);
270 QList<QByteArray> signalParameterNames(
int index)
const;
271 static QString signalParameterStringForJS(
272 const QList<QByteArray> ¶meterNameList, QString *errorString =
nullptr);
274 const char *className()
const;
276 inline int propertyCount()
const;
277 inline int ownPropertyCount()
const {
return int(propertyIndexCache.count()); }
278 inline int propertyOffset()
const;
279 inline int methodCount()
const;
280 inline int ownMethodCount()
const {
return int(methodIndexCache.count()); }
281 inline int methodOffset()
const;
282 inline int signalCount()
const;
283 inline int ownSignalCount()
const {
return int(signalHandlerIndexCache.count()); }
284 inline int signalOffset()
const;
285 inline int ownEnumCount()
const;
287 void toMetaObjectBuilder(QMetaObjectBuilder &)
const;
289 inline bool callJSFactoryMethod(QObject *object,
void **args)
const;
291 static bool determineMetaObjectSizes(
const QMetaObject &mo,
int *fieldCount,
int *stringCount);
292 static bool addToHash(QCryptographicHash &hash,
const QMetaObject &mo);
294 QByteArray checksum(QHash<quintptr, QByteArray> *checksums,
bool *ok)
const;
296 QTypeRevision allowedRevision(
int index)
const {
return allowedRevisionCache[index]; }
297 void setAllowedRevision(
int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; }
299 bool isComposite()
const {
return _metaObject.isShared(); }
302 friend class QQmlEnginePrivate;
303 friend class QQmlCompiler;
304 template <
typename T>
friend class QQmlPropertyCacheCreator;
305 template <
typename T>
friend class QQmlPropertyCacheAliasCreator;
306 template <
typename T>
friend class QQmlComponentAndAliasResolver;
307 friend class QQmlMetaObject;
308 friend class ::tst_qqmlpropertycache;
311 const QQmlMetaObjectPointer &metaObject,
312 OverrideSemantics::HandlerRef handleOverride = OverrideSemantics::handleOverride)
313 : _handleOverride(handleOverride), _metaObject(metaObject)
317 inline QQmlPropertyCache::Ptr copy(
const QQmlMetaObjectPointer &mo,
int reserve)
const;
319 void append(
const QMetaObject *, QTypeRevision typeVersion,
320 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
321 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
322 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
325 using Error = OverrideSemantics::Status;
326 using AppendResult = q23::expected<
void, Error>;
331 AppendResult appendPropertyAttr(
const QString &name, QQmlPropertyData &&data);
332 AppendResult appendAlias(
const QString &, QQmlPropertyData::Flags flags,
int coreIndex,
333 QMetaType propType, QTypeRevision version,
int notifyIndex,
334 int encodedTargetIndex,
int targetObjectId);
335 AppendResult appendComponentWrapper(
int coreIndex,
int wrappedObjectIndex);
336 void appendSignal(
const QString &, QQmlPropertyData::Flags,
int coreIndex,
337 const QMetaType *types =
nullptr,
338 const QList<QByteArray> &names = QList<QByteArray>());
339 void appendMethod(
const QString &, QQmlPropertyData::Flags flags,
int coreIndex,
340 QMetaType returnType,
const QList<QByteArray> &names,
341 const QList<QMetaType> ¶meterTypes);
342 void appendEnum(
const QString &,
const QList<QQmlEnumValue> &);
344 QQmlPropertyCacheMethodArguments *createArgumentsObject(
int count,
345 const QList<QByteArray> &names);
347 typedef QList<QQmlPropertyData> IndexCache;
348 typedef QLinkedStringMultiHash<std::pair<
int, QQmlPropertyData *> > StringCache;
349 typedef QList<QTypeRevision> AllowedRevisionCache;
351 const QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *,
352 const QQmlRefPointer<QQmlContextData> &)
const;
353 const QQmlPropertyData *findProperty(StringCache::ConstIterator it,
const QQmlVMEMetaObject *,
354 const QQmlRefPointer<QQmlContextData> &)
const;
357 QQmlPropertyData *findNamedProperty(
const K &key)
const
359 StringCache::mapped_type *it = stringCache.value(key);
360 return it ? it->second : 0;
364 void setNamedProperty(
const K &key,
int index, QQmlPropertyData *data)
366 stringCache.insert(key, std::make_pair(index, data));
377 template <
typename String>
378 void maybeLog(OverrideSemantics::Status status,
const String &name)
const
381 case OverrideSemantics::Status::OverridingFinal: {
382 qCWarning(qqmlPropertyCacheAppend).noquote()
383 << QStringLiteral(
"Final member %1 is overridden in class %2. The "
384 "override won't be used.")
385 .arg(qPrintable(name), className());
388 case OverrideSemantics::Status::MissingBase: {
389 qCWarning(qqmlPropertyCacheAppend).noquote()
390 << QStringLiteral(
"Member %1 of the object %2 does not override anything."
391 " Consider removing \"override\". ")
392 .arg(qPrintable(name), className());
395 case OverrideSemantics::Status::OverridingNonVirtual: {
397 qCDebug(qqmlPropertyCacheAppend).noquote()
398 << QStringLiteral(
"Member %1 of the object %2 overrides a non-virtual member. "
399 "Consider renaming it or mark it virtual in the base object")
400 .arg(qPrintable(name), className());
403 case OverrideSemantics::Status::OverridingNonVirtualError: {
404 qCWarning(qqmlPropertyCacheAppend).noquote()
405 << QStringLiteral(
"Member %1 of the object %2 overrides a non-virtual member. "
406 "Consider renaming it or mark it virtual in the base object")
407 .arg(qPrintable(name), className());
410 case OverrideSemantics::Status::MissingOverrideOrFinalSpecifier: {
411 qCWarning(qqmlPropertyCacheAppend).noquote()
413 "Member %1 of the object %2 overrides a member of the base object. "
414 "Consider renaming it or adding final or override specifier")
415 .arg(qPrintable(name), className());
425 OverrideSemantics::HandlerRef _handleOverride;
427 int propertyIndexCacheStart = 0;
428 QQmlPropertyCache::ConstPtr _parent;
430 IndexCache propertyIndexCache;
431 IndexCache methodIndexCache;
432 IndexCache signalHandlerIndexCache;
433 StringCache stringCache;
434 AllowedRevisionCache allowedRevisionCache;
435 QList<QQmlEnumData> enumCache;
437 QQmlMetaObjectPointer _metaObject;
438 QByteArray _dynamicClassName;
439 QByteArray _dynamicStringData;
440 QByteArray _listPropertyAssignBehavior;
441 QString _defaultPropertyName;
442 QQmlPropertyCacheMethodArguments *argumentsCache =
nullptr;
443 int methodIndexCacheStart = 0;
444 int signalHandlerIndexCacheStart = 0;
445 int _jsFactoryMethodIndex = -1;