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
qqmlpropertycache.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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/qqmlengine_p.h>
7#include <private/qqmlbinding_p.h>
8#include <private/qqmlvmemetaobject_p.h>
9
10#include <private/qmetaobject_p.h>
11#include <private/qmetaobjectbuilder_p.h>
12#include <private/qqmlpropertycachemethodarguments_p.h>
13#include <private/qqmlsignalnames_p.h>
14
15#include <private/qv4value_p.h>
16
17#include <QtCore/qdebug.h>
18#include <QtCore/QCryptographicHash>
19#include <QtCore/private/qtools_p.h>
20
21#include <limits.h>
22#include <algorithm>
23
24#ifdef Q_CC_MSVC
25// nonstandard extension used : zero-sized array in struct/union.
26# pragma warning( disable : 4200 )
27#endif
28
30
31#define Q_INT16_MAX 32767
32
34{
35 int signalCount = 0;
36 for (const QMetaObject *obj = metaObject; obj; obj = obj->superClass())
37 signalCount += QMetaObjectPrivate::get(obj)->signalCount;
38 return signalCount;
39}
40
43{
45
46 flags.setIsConstant(p.isConstant());
47 flags.setIsWritable(p.isWritable());
48 flags.setIsResettable(p.isResettable());
49 flags.setIsFinal(p.isFinal());
50 flags.setIsRequired(p.isRequired());
51 flags.setIsBindable(p.isBindable());
52
53
54 const QMetaType metaType = p.metaType();
55 int propType = metaType.id();
56 if (p.isEnumType()) {
57 flags.setType(QQmlPropertyData::Flags::EnumType);
58 } else if (metaType.flags() & QMetaType::PointerToQObject) {
59 flags.setType(QQmlPropertyData::Flags::QObjectDerivedType);
60 } else if (propType == QMetaType::QVariant) {
61 flags.setType(QQmlPropertyData::Flags::QVariantType);
62 } else if (metaType.flags() & QMetaType::IsQmlList) {
63 flags.setType(QQmlPropertyData::Flags::QListType);
64 }
65
66 return flags;
67}
68
70{
71 Q_ASSERT(p.revision() <= std::numeric_limits<quint16>::max());
72 setCoreIndex(p.propertyIndex());
76 QMetaType type = p.metaType();
78}
79
81{
82 setCoreIndex(m.methodIndex());
83 m_flags.setType(Flags::FunctionType);
84
85 // We need to set the constructor, signal, constant, arguments, V4Function, cloned flags.
86 // These are specific to methods and change with each method.
87 // The same QQmlPropertyData may be loaded with multiple methods in sequence.
88
89 switch (m.methodType()) {
91 m_flags.setIsSignal(true);
92 m_flags.setIsConstructor(false);
93 setPropType(m.returnMetaType());
94 break;
96 m_flags.setIsSignal(false);
97 m_flags.setIsConstructor(true);
98 setPropType(QMetaType::fromType<QObject *>());
99 break;
100 default:
101 m_flags.setIsSignal(false);
102 m_flags.setIsConstructor(false);
103 setPropType(m.returnMetaType());
104 break;
105 }
106
107 m_flags.setIsConstant(m.isConst());
108
109 const int paramCount = m.parameterCount();
110 if (paramCount) {
111 m_flags.setHasArguments(true);
112 m_flags.setIsV4Function(
113 paramCount == 1 &&
114 m.parameterMetaType(0) == QMetaType::fromType<QQmlV4FunctionPtr>());
115 } else {
116 m_flags.setHasArguments(false);
117 m_flags.setIsV4Function(false);
118 }
119
120 m_flags.setIsCloned(m.attributes() & QMetaMethod::Cloned);
121
122 Q_ASSERT(m.revision() <= std::numeric_limits<quint16>::max());
124}
125
132 const QMetaObject *metaObject, QTypeRevision metaObjectRevision)
133{
135
136 Ptr result;
137 if (const QMetaObject *super = metaObject->superClass()) {
139 super, metaObjectRevision)->copyAndAppend(metaObject, metaObjectRevision);
140 } else {
142 result->update(metaObject);
143 }
144
145 if (metaObjectRevision.isValid() && metaObjectRevision != QTypeRevision::zero()) {
146 // Set the revision of the meta object that this cache describes to be
147 // 'metaObjectRevision'. This is useful when constructing a property cache
148 // from a type that was created directly in C++, and not through QML. For such
149 // types, the revision for each recorded QMetaObject would normally be zero, which
150 // would exclude any revisioned properties.
151 for (int metaObjectOffset = 0; metaObjectOffset < result->allowedRevisionCache.size();
152 ++metaObjectOffset) {
153 result->allowedRevisionCache[metaObjectOffset] = metaObjectRevision;
154 }
155 }
156
157 return result;
158}
159
161{
162 QQmlPropertyCacheMethodArguments *args = argumentsCache;
163 while (args) {
165 delete args->names;
166 free(args);
167 args = next;
168 }
169
170 // We must clear this prior to releasing the parent incase it is a
171 // linked hash
172 stringCache.clear();
173}
174
176{
179 cache->_parent.reset(this);
180 cache->propertyIndexCacheStart = propertyIndexCache.size() + propertyIndexCacheStart;
181 cache->methodIndexCacheStart = methodIndexCache.size() + methodIndexCacheStart;
182 cache->signalHandlerIndexCacheStart = signalHandlerIndexCache.size() + signalHandlerIndexCacheStart;
183 cache->stringCache.linkAndReserve(stringCache, reserve);
184 cache->allowedRevisionCache = allowedRevisionCache;
185 cache->_defaultPropertyName = _defaultPropertyName;
186 cache->_listPropertyAssignBehavior = _listPropertyAssignBehavior;
187
188 return cache;
189}
190
192{
193 return copy(_metaObject, 0);
194}
195
197 int propertyCount, int methodCount, int signalCount, int enumCount) const
198{
201 rv->propertyIndexCache.reserve(propertyCount);
202 rv->methodIndexCache.reserve(methodCount);
203 rv->signalHandlerIndexCache.reserve(signalCount);
204 rv->enumCache.reserve(enumCount);
205 return rv;
206}
207
214 int coreIndex, QMetaType propType, QTypeRevision version,
215 int notifyIndex)
216{
218 data.setPropType(propType);
219 data.setCoreIndex(coreIndex);
220 data.setNotifyIndex(notifyIndex);
221 data.setFlags(flags);
222 data.setTypeVersion(version);
223
224 const OverrideResult overrideResult = handleOverride(name, &data);
225 if (overrideResult == InvalidOverride)
226 return;
227
228 int index = propertyIndexCache.size();
229 propertyIndexCache.append(data);
230
231 setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index);
232}
233
235 int coreIndex, const QMetaType *types,
236 const QList<QByteArray> &names)
237{
240 data.setCoreIndex(coreIndex);
241 data.setFlags(flags);
242 data.setArguments(nullptr);
243
244 QQmlPropertyData handler = data;
245 handler.m_flags.setIsSignalHandler(true);
246
247 if (types) {
248 const auto argumentCount = names.size();
249 QQmlPropertyCacheMethodArguments *args = createArgumentsObject(argumentCount, names);
250 new (args->types) QMetaType; // Invalid return type
251 ::memcpy(args->types + 1, types, argumentCount * sizeof(QMetaType));
252 data.setArguments(args);
253 }
254
255 const OverrideResult overrideResult = handleOverride(name, &data);
256 if (overrideResult == InvalidOverride)
257 return;
258
259 int methodIndex = methodIndexCache.size();
260 methodIndexCache.append(data);
261
262 int signalHandlerIndex = signalHandlerIndexCache.size();
263 signalHandlerIndexCache.append(handler);
264
266
267 setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex);
268 setNamedProperty(handlerName, signalHandlerIndex + signalOffset(),
269 signalHandlerIndexCache.data() + signalHandlerIndex);
270}
271
273 int coreIndex, QMetaType returnType,
274 const QList<QByteArray> &names,
275 const QVector<QMetaType> &parameterTypes)
276{
277 int argumentCount = names.size();
278
280 data.setPropType(returnType);
281 data.setCoreIndex(coreIndex);
282 data.setFlags(flags);
283 const OverrideResult overrideResult = handleOverride(name, &data);
284 if (overrideResult == InvalidOverride)
285 return;
286
287 QQmlPropertyCacheMethodArguments *args = createArgumentsObject(argumentCount, names);
288 new (args->types) QMetaType(returnType);
289 for (int ii = 0; ii < argumentCount; ++ii)
290 new (args->types + ii + 1) QMetaType(parameterTypes.at(ii));
291 data.setArguments(args);
292
293 int methodIndex = methodIndexCache.size();
294 methodIndexCache.append(data);
295
296 setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex);
297}
298
299void QQmlPropertyCache::appendEnum(const QString &name, const QVector<QQmlEnumValue> &values)
300{
302 data.name = name;
303 data.values = values;
304 enumCache.append(data);
305}
306
307// Returns this property cache's metaObject, creating it if necessary.
309{
310 if (_metaObject.isNull()) {
311 QMetaObjectBuilder builder;
312 toMetaObjectBuilder(builder);
313 builder.setSuperClass(_parent->createMetaObject());
314 _metaObject.setSharedOnce(builder.toMetaObject());
315 }
316
317 return _metaObject.metaObject();
318}
319
321{
322 if (index < 0 || index >= propertyCount())
323 return nullptr;
324
325 const QQmlPropertyData *rv = nullptr;
326 if (index < propertyIndexCacheStart)
327 return _parent->maybeUnresolvedProperty(index);
328 else
329 rv = const_cast<const QQmlPropertyData *>(&propertyIndexCache.at(index - propertyIndexCacheStart));
330 return rv;
331}
332
334{
335 return property(defaultPropertyName(), nullptr, nullptr);
336}
337
339{
340 if (_parent != newParent)
341 _parent = std::move(newParent);
342}
343
346 QTypeRevision typeVersion,
347 QQmlPropertyData::Flags propertyFlags,
348 QQmlPropertyData::Flags methodFlags,
349 QQmlPropertyData::Flags signalFlags) const
350{
352
353 // Reserve enough space in the name hash for all the methods (including signals), all the
354 // signal handlers and all the properties. This assumes no name clashes, but this is the
355 // common case.
361
362 rv->append(metaObject, typeVersion, propertyFlags, methodFlags, signalFlags);
363
364 return rv;
365}
366
371
377
378
379void QQmlPropertyCache::append(const QMetaObject *metaObject,
380 QTypeRevision typeVersion,
381 QQmlPropertyData::Flags propertyFlags,
382 QQmlPropertyData::Flags methodFlags,
383 QQmlPropertyData::Flags signalFlags)
384{
385 allowedRevisionCache.append(QTypeRevision::zero());
386
390 int classInfoCount = QMetaObjectPrivate::get(metaObject)->classInfoCount;
391
392 if (classInfoCount) {
393 int classInfoOffset = metaObject->classInfoOffset();
394 for (int ii = 0; ii < classInfoCount; ++ii) {
395 int idx = ii + classInfoOffset;
397 const char *name = mci.name();
398 if (0 == qstrcmp(name, "DefaultProperty")) {
399 _defaultPropertyName = QString::fromUtf8(mci.value());
400 } else if (0 == qstrcmp(name, "qt_QmlJSWrapperFactoryMethod")) {
401 const char * const factoryMethod = mci.value();
402 _jsFactoryMethodIndex = metaObject->indexOfSlot(factoryMethod);
403 if (_jsFactoryMethodIndex != -1)
404 _jsFactoryMethodIndex -= metaObject->methodOffset();
405 } else if (0 == qstrcmp(name, "QML.ListPropertyAssignBehavior")) {
406 _listPropertyAssignBehavior = mci.value();
407 }
408 }
409 }
410
411 //Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
412 static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
413 static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
414 static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
415 // These indices don't apply to gadgets, so don't block them.
416 // It is enough to check for QObject::staticMetaObject here because the loop below excludes
417 // methods of parent classes: It starts at metaObject->methodOffset()
418 const bool preventDestruction = (metaObject == &QObject::staticMetaObject);
419
422
423 // update() should have reserved enough space in the vector that this doesn't cause a realloc
424 // and invalidate the stringCache.
425 methodIndexCache.resize(methodCount - methodIndexCacheStart);
426 signalHandlerIndexCache.resize(signalCount - signalHandlerIndexCacheStart);
427 int signalHandlerIndex = signalOffset;
428 for (int ii = methodOffset; ii < methodCount; ++ii) {
429 if (preventDestruction && (ii == destroyedIdx1 || ii == destroyedIdx2 || ii == deleteLaterIdx))
430 continue;
432 if (m.access() == QMetaMethod::Private)
433 continue;
434
435 // Extract method name
436 // It's safe to keep the raw name pointer
438 const char *rawName = m.name().constData();
439 const char *cptr = rawName;
440 char utf8 = 0;
441 while (*cptr) {
442 utf8 |= *cptr & 0x80;
443 ++cptr;
444 }
445
446 QQmlPropertyData *data = &methodIndexCache[ii - methodIndexCacheStart];
447 QQmlPropertyData *sigdata = nullptr;
448
449 if (m.methodType() == QMetaMethod::Signal)
450 data->setFlags(signalFlags);
451 else
452 data->setFlags(methodFlags);
453
454 data->load(m);
455
456 Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
457 data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
458
459 if (data->isSignal()) {
460 sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHandlerIndexCacheStart];
461 *sigdata = *data;
462 sigdata->m_flags.setIsSignalHandler(true);
463 }
464
465 QQmlPropertyData *old = nullptr;
466
467 const auto doSetNamedProperty = [&](const auto &methodName) {
468 if (StringCache::mapped_type *it = stringCache.value(methodName)) {
469 if (handleOverride(methodName, data, (old = it->second)) == InvalidOverride)
470 return;
471 }
472
473 setNamedProperty(methodName, ii, data);
474
475 if (data->isSignal()) {
476
477 // TODO: Remove this once we can. Signals should not be overridable.
478 if (!utf8)
479 data->m_flags.setIsOverridableSignal(true);
480
481 setNamedProperty(signalNameToHandlerName(methodName), ii, sigdata);
482 ++signalHandlerIndex;
483 }
484 };
485
486 if (utf8)
487 doSetNamedProperty(QHashedString(QString::fromUtf8(rawName, cptr - rawName)));
488 else
489 doSetNamedProperty(QHashedCStringRef(rawName, cptr - rawName));
490 }
491
493 int propOffset = metaObject->propertyOffset();
494
495 // update() should have reserved enough space in the vector that this doesn't cause a realloc
496 // and invalidate the stringCache.
497 propertyIndexCache.resize(propCount - propertyIndexCacheStart);
498 for (int ii = propOffset; ii < propCount; ++ii) {
500 if (!p.isScriptable())
501 continue;
502
503 const char *str = p.name();
504 char utf8 = 0;
505 const char *cptr = str;
506 while (*cptr != 0) {
507 utf8 |= *cptr & 0x80;
508 ++cptr;
509 }
510
511 QQmlPropertyData *data = &propertyIndexCache[ii - propertyIndexCacheStart];
512
513 data->setFlags(propertyFlags);
514 data->load(p);
515 data->setTypeVersion(typeVersion);
516
517 Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
518 data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
519
520 QQmlPropertyData *old = nullptr;
521
522 if (utf8) {
523 QHashedString propName(QString::fromUtf8(str, cptr - str));
524 if (StringCache::mapped_type *it = stringCache.value(propName)) {
525 if (handleOverride(propName, data, (old = it->second)) == InvalidOverride)
526 continue;
527 }
528 setNamedProperty(propName, ii, data);
529 } else {
530 QHashedCStringRef propName(str, cptr - str);
531 if (StringCache::mapped_type *it = stringCache.value(propName)) {
532 if (handleOverride(propName, data, (old = it->second)) == InvalidOverride)
533 continue;
534 }
535 setNamedProperty(propName, ii, data);
536 }
537
538 bool isGadget = true;
539 for (const QMetaObject *it = metaObject; it != nullptr; it = it->superClass()) {
540 if (it == &QObject::staticMetaObject)
541 isGadget = false;
542 }
543
544 // otherwise always dispatch over a 'normal' meta-call so the QQmlValueType can intercept
545 if (!isGadget)
546 data->trySetStaticMetaCallFunction(metaObject->d.static_metacall, ii - propOffset);
547 }
548}
549
551{
553 stringCache.clear();
554
555 // Preallocate enough space in the index caches for all the properties/methods/signals that
556 // are not cached in a parent cache so that the caches never need to be reallocated as this
557 // would invalidate pointers stored in the stringCache.
558 int pc = metaObject->propertyCount();
559 int mc = metaObject->methodCount();
561 propertyIndexCache.reserve(pc - propertyIndexCacheStart);
562 methodIndexCache.reserve(mc - methodIndexCacheStart);
563 signalHandlerIndexCache.reserve(sc - signalHandlerIndexCacheStart);
564
565 // Reserve enough space in the stringCache for all properties/methods/signals including those
566 // cached in a parent cache.
567 stringCache.reserve(pc + mc + sc);
568
569 if (metaObject)
570 append(metaObject, QTypeRevision());
571}
572
578{
579 propertyIndexCache.clear();
580 methodIndexCache.clear();
581 signalHandlerIndexCache.clear();
582
583 argumentsCache = nullptr;
584
585 int pc = metaObject->propertyCount();
586 int mc = metaObject->methodCount();
588 int reserve = pc + mc + sc;
589
590 if (parent()) {
591 propertyIndexCacheStart = parent()->propertyIndexCache.size() + parent()->propertyIndexCacheStart;
592 methodIndexCacheStart = parent()->methodIndexCache.size() + parent()->methodIndexCacheStart;
593 signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.size() + parent()->signalHandlerIndexCacheStart;
594 stringCache.linkAndReserve(parent()->stringCache, reserve);
595 append(metaObject, QTypeRevision());
596 } else {
597 propertyIndexCacheStart = 0;
598 methodIndexCacheStart = 0;
599 signalHandlerIndexCacheStart = 0;
601 }
602}
603
604const QQmlPropertyData *QQmlPropertyCache::findProperty(
605 StringCache::ConstIterator it, QObject *object,
606 const QQmlRefPointer<QQmlContextData> &context) const
607{
608 QQmlData *data = (object ? QQmlData::get(object) : nullptr);
609 const QQmlVMEMetaObject *vmemo = nullptr;
610 if (data && data->hasVMEMetaObject) {
612 vmemo = static_cast<const QQmlVMEMetaObject *>(op->metaObject);
613 }
614 return findProperty(it, vmemo, context);
615}
616
617namespace {
618
619inline bool contextHasNoExtensions(const QQmlRefPointer<QQmlContextData> &context)
620{
621 // This context has no extension if its parent is the engine's rootContext,
622 // which has children but no imports
623 const QQmlRefPointer<QQmlContextData> parent = context->parent();
624 return (!parent || !parent->imports());
625}
626
627inline int maximumIndexForProperty(const QQmlPropertyData *prop, const int methodCount, const int signalCount, const int propertyCount)
628{
629 return prop->isFunction() ? methodCount
630 : prop->isSignalHandler() ? signalCount
631 : propertyCount;
632}
633
634}
635
636const QQmlPropertyData *QQmlPropertyCache::findProperty(
637 StringCache::ConstIterator it, const QQmlVMEMetaObject *vmemo,
638 const QQmlRefPointer<QQmlContextData> &context) const
639{
640 StringCache::ConstIterator end = stringCache.end();
641
642 if (it != end) {
643 const QQmlPropertyData *result = it.value().second;
644
645 // If there exists a typed property (not a function or signal handler), of the
646 // right name available to the specified context, we need to return that
647 // property rather than any subsequent override
648
649 if (vmemo && context && !contextHasNoExtensions(context)) {
650 // Find the meta-object that corresponds to the supplied context
651 do {
652 if (vmemo->ctxt.contextData().data() == context.data())
653 break;
654
655 vmemo = vmemo->parentVMEMetaObject();
656 } while (vmemo);
657 }
658
659 if (vmemo) {
660 const int methodCount = vmemo->cache->methodCount();
661 const int signalCount = vmemo->cache->signalCount();
662 const int propertyCount = vmemo->cache->propertyCount();
663
664 // Ensure that the property we resolve to is accessible from this meta-object
665 do {
666 const StringCache::mapped_type &property(it.value());
667
668 if (property.first < maximumIndexForProperty(property.second, methodCount, signalCount, propertyCount)) {
669 // This property is available in the specified context
670 if (property.second->isFunction() || property.second->isSignalHandler()) {
671 // Prefer the earlier resolution
672 } else {
673 // Prefer the typed property to any previous property found
674 result = property.second;
675 }
676 break;
677 }
678
679 // See if there is a better candidate
680 it = stringCache.findNext(it);
681 } while (it != end);
682 }
683
684 return result;
685 }
686
687 return nullptr;
688}
689
691{
692 if (!object)
693 return QString();
694
695 return name(object->metaObject());
696}
697
699{
700 if (!metaObject || coreIndex() == -1)
701 return QString();
702
703 if (isFunction()) {
705
706 return QString::fromUtf8(m.name().constData());
707 } else {
709 return QString::fromUtf8(p.name());
710 }
711}
712
714{
715 Q_ASSERT(predecessor != this);
716 if (predecessor->isFinal())
717 return false;
718
719 setOverrideIndexIsProperty(!predecessor->isFunction());
720 setOverrideIndex(predecessor->coreIndex());
721 predecessor->m_flags.setIsOverridden(true);
722 Q_ASSERT(predecessor->isOverridden());
723 return true;
724}
725
726QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(
727 int argc, const QList<QByteArray> &names)
728{
730 A *args = static_cast<A *>(malloc(sizeof(A) + argc * sizeof(QMetaType)));
731 args->names = argc ? new QList<QByteArray>(names) : nullptr;
732 args->next = argumentsCache;
733 argumentsCache = args;
734 return args;
735}
736
737QString QQmlPropertyCache::signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList<QByteArray> &parameterNameList, QString *errorString)
738{
739 bool unnamedParameter = false;
740 const QSet<QString> &illegalNames = engine->illegalNames();
741 QString parameters;
742
743 const qsizetype count = parameterNameList.size();
744 if (count > std::numeric_limits<quint16>::max())
745 *errorString = QCoreApplication::translate("QQmlRewrite", "Signal has an excessive number of parameters: %1").arg(count);
746
747 for (qsizetype i = 0; i < count; ++i) {
748 if (i > 0)
749 parameters += QLatin1Char(',');
750 const QByteArray &param = parameterNameList.at(i);
751 if (param.isEmpty()) {
752 unnamedParameter = true;
753 } else if (unnamedParameter) {
754 if (errorString)
755 *errorString = QCoreApplication::translate("QQmlRewrite", "Signal uses unnamed parameter followed by named parameter.");
756 return QString();
757 } else if (illegalNames.contains(QString::fromUtf8(param))) {
758 if (errorString)
759 *errorString = QCoreApplication::translate("QQmlRewrite", "Signal parameter \"%1\" hides global variable.").arg(QString::fromUtf8(param));
760 return QString();
761 }
762 parameters += QString::fromUtf8(param);
763 }
764
765 return parameters;
766}
767
769{
770 while (signal(index)->isCloned())
771 --index;
772 return index;
773}
774
776{
777 QQmlData *data = QQmlData::get(object);
778 if (data && data->propertyCache) {
779 const QQmlPropertyCache *cache = data->propertyCache.data();
780 const QQmlPropertyData *sig = cache->signal(index);
781 while (sig && sig->isCloned()) {
782 --index;
783 sig = cache->signal(index);
784 }
785 } else {
786 while (QMetaObjectPrivate::signal(object->metaObject(), index).attributes() & QMetaMethod::Cloned)
787 --index;
788 }
789 return index;
790}
791
792template<typename T>
794{
796
798
799 /* It's important to check the method list before checking for properties;
800 * otherwise, if the meta object is dynamic, a property will be created even
801 * if not found and it might obscure a method having the same name. */
802
803 //Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
804 static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
805 static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
806 static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
807 // These indices don't apply to gadgets, so don't block them.
808 const bool preventDestruction = metaObject->superClass() || metaObject == &QObject::staticMetaObject;
809
810 int methodCount = metaObject->methodCount();
811 for (int ii = methodCount - 1; ii >= 0; --ii) {
812 if (preventDestruction && (ii == destroyedIdx1 || ii == destroyedIdx2 || ii == deleteLaterIdx))
813 continue;
814 QMetaMethod m = metaObject->method(ii);
815 if (m.access() == QMetaMethod::Private)
816 continue;
817
818 if (m.name() == propertyName) {
819 rv.load(m);
820 return rv;
821 }
822 }
823
824 {
825 const QMetaObject *cmo = metaObject;
826 while (cmo) {
827 int idx = cmo->indexOfProperty(propertyName);
828 if (idx != -1) {
829 QMetaProperty p = cmo->property(idx);
830 if (p.isScriptable()) {
831 rv.load(p);
832 return rv;
833 } else {
834 bool changed = false;
835 while (cmo && cmo->propertyOffset() >= idx) {
836 cmo = cmo->superClass();
837 changed = true;
838 }
839 /* If the "cmo" variable didn't change, set it to 0 to
840 * avoid running into an infinite loop */
841 if (!changed) cmo = nullptr;
842 }
843 } else {
844 cmo = nullptr;
845 }
846 }
847 }
848 return rv;
849}
850
851static inline const char *qQmlPropertyCacheToString(QLatin1String string)
852{
853 return string.data();
854}
855
857{
858 return string.toUtf8();
859}
860
862{
863 return string->toQString().toUtf8();
864}
865
866template<typename T>
867const QQmlPropertyData *
868qQmlPropertyCacheProperty(QObject *obj, T name, const QQmlRefPointer<QQmlContextData> &context,
869 QQmlPropertyData *local)
870{
871 const QQmlPropertyCache *cache = nullptr;
872
873 QQmlData *ddata = QQmlData::get(obj, false);
874
875 if (ddata && ddata->propertyCache) {
876 cache = ddata->propertyCache.data();
877 } else if (auto newCache = QQmlMetaType::propertyCache(obj)) {
878 cache = newCache.data();
879 ddata = QQmlData::get(obj, true);
880 ddata->propertyCache = std::move(newCache);
881 }
882
883 const QQmlPropertyData *rv = nullptr;
884
885 if (cache) {
886 rv = cache->property(name, obj, context);
887 } else if (local) {
889 if (local->isValid())
890 rv = local;
891 }
892
893 return rv;
894}
895
897 QObject *obj, const QV4::String *name, const QQmlRefPointer<QQmlContextData> &context,
898 QQmlPropertyData *local)
899{
900 return qQmlPropertyCacheProperty<const QV4::String *>(obj, name, context, local);
901}
902
904 QObject *obj, QStringView name, const QQmlRefPointer<QQmlContextData> &context,
905 QQmlPropertyData *local)
906{
907 return qQmlPropertyCacheProperty<const QStringView &>(obj, name, context, local);
908}
909
911 QObject *obj, const QLatin1String &name, const QQmlRefPointer<QQmlContextData> &context,
912 QQmlPropertyData *local)
913{
914 return qQmlPropertyCacheProperty<const QLatin1String &>(obj, name, context, local);
915}
916
917// this function is copied from qmetaobject.cpp
918static inline const QByteArray stringData(const QMetaObject *mo, int index)
919{
920 uint offset = mo->d.stringdata[2*index];
921 uint length = mo->d.stringdata[2*index + 1];
922 const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
923 return QByteArray::fromRawData(string, length);
924}
925
927{
928 if (const QMetaObject *mo = _metaObject.metaObject())
929 return mo->className();
930 else
931 return _dynamicClassName.constData();
932}
933
935{
936 struct Sort { static bool lt(const QPair<QString, const QQmlPropertyData *> &lhs,
937 const QPair<QString, const QQmlPropertyData *> &rhs) {
938 return lhs.second->coreIndex() < rhs.second->coreIndex();
939 } };
940
941 struct Insert { static void in(const QQmlPropertyCache *This,
942 QList<QPair<QString, const QQmlPropertyData *> > &properties,
943 QList<QPair<QString, const QQmlPropertyData *> > &methods,
945 if (data->isSignalHandler())
946 return;
947
948 if (data->isFunction()) {
949 if (data->coreIndex() < This->methodIndexCacheStart)
950 return;
951
952 QPair<QString, const QQmlPropertyData *> entry = qMakePair((QString)iter.key(), data);
953 // Overrides can cause the entry to already exist
954 if (!methods.contains(entry)) methods.append(entry);
955
956 data = This->overrideData(data);
957 if (data && !data->isFunction()) Insert::in(This, properties, methods, iter, data);
958 } else {
959 if (data->coreIndex() < This->propertyIndexCacheStart)
960 return;
961
962 QPair<QString, const QQmlPropertyData *> entry = qMakePair((QString)iter.key(), data);
963 // Overrides can cause the entry to already exist
964 if (!properties.contains(entry)) properties.append(entry);
965
966 data = This->overrideData(data);
967 if (data) Insert::in(This, properties, methods, iter, data);
968 }
969
970 } };
971
972 builder.setClassName(_dynamicClassName);
973
974 QList<QPair<QString, const QQmlPropertyData *> > properties;
975 QList<QPair<QString, const QQmlPropertyData *> > methods;
976
977 for (StringCache::ConstIterator iter = stringCache.begin(), cend = stringCache.end(); iter != cend; ++iter)
978 Insert::in(this, properties, methods, iter, iter.value().second);
979
980 Q_ASSERT(properties.size() == propertyIndexCache.size());
981 Q_ASSERT(methods.size() == methodIndexCache.size());
982
983 std::sort(properties.begin(), properties.end(), Sort::lt);
984 std::sort(methods.begin(), methods.end(), Sort::lt);
985
986 for (int ii = 0; ii < properties.size(); ++ii) {
987 const QQmlPropertyData *data = properties.at(ii).second;
988
989 int notifierId = -1;
990 if (data->notifyIndex() != -1)
991 notifierId = data->notifyIndex() - signalHandlerIndexCacheStart;
992
993 QMetaPropertyBuilder property = builder.addProperty(properties.at(ii).first.toUtf8(),
994 data->propType().name(),
995 data->propType(),
996 notifierId);
997
998 property.setReadable(true);
999 property.setWritable(data->isWritable());
1000 property.setResettable(data->isResettable());
1001 property.setBindable(data->isBindable());
1002 property.setAlias(data->isAlias());
1003 }
1004
1005 for (int ii = 0; ii < methods.size(); ++ii) {
1006 const QQmlPropertyData *data = methods.at(ii).second;
1007
1008 QByteArray returnType;
1009 if (data->propType().isValid())
1010 returnType = data->propType().name();
1011
1012 QByteArray signature;
1013 // '+=' reserves extra capacity. Follow-up appending will be probably free.
1014 signature += methods.at(ii).first.toUtf8() + '(';
1015
1017 if (data->hasArguments()) {
1018 arguments = data->arguments();
1019 for (int ii = 0, end = arguments->names ? arguments->names->size() : 0;
1020 ii < end; ++ii) {
1021 if (ii != 0)
1022 signature.append(',');
1023 signature.append(arguments->types[1 + ii].name());
1024 }
1025 }
1026
1027 signature.append(')');
1028
1030 if (data->isSignal()) {
1031 method = builder.addSignal(signature);
1032 } else {
1033 method = builder.addSlot(signature);
1034 }
1035 method.setAccess(QMetaMethod::Public);
1036
1037 if (arguments && arguments->names)
1038 method.setParameterNames(*arguments->names);
1039
1040 if (!returnType.isEmpty())
1041 method.setReturnType(returnType);
1042 }
1043
1044 for (int ii = 0; ii < enumCache.size(); ++ii) {
1045 const QQmlEnumData &enumData = enumCache.at(ii);
1046 QMetaEnumBuilder enumeration = builder.addEnumerator(enumData.name.toUtf8());
1047 enumeration.setIsScoped(true);
1048 for (int jj = 0; jj < enumData.values.size(); ++jj) {
1049 const QQmlEnumValue &value = enumData.values.at(jj);
1050 enumeration.addKey(value.namedValue.toUtf8(), value.value);
1051 }
1052 }
1053
1054 if (!_defaultPropertyName.isEmpty()) {
1055 const QQmlPropertyData *dp = property(_defaultPropertyName, nullptr, nullptr);
1056 if (dp && dp->coreIndex() >= propertyIndexCacheStart) {
1057 Q_ASSERT(!dp->isFunction());
1058 builder.addClassInfo("DefaultProperty", _defaultPropertyName.toUtf8());
1059 }
1060 }
1061
1062 if (!_listPropertyAssignBehavior.isEmpty())
1063 builder.addClassInfo("QML.ListPropertyAssignBehavior", _listPropertyAssignBehavior);
1064}
1065
1066namespace {
1067template <typename StringVisitor, typename TypeInfoVisitor>
1068int visitMethods(const QMetaObject &mo, int methodOffset, int methodCount,
1069 StringVisitor visitString, TypeInfoVisitor visitTypeInfo)
1070{
1071 int fieldsForParameterData = 0;
1072
1073 bool hasRevisionedMethods = false;
1074
1075 for (int i = 0; i < methodCount; ++i) {
1076 const int handle = methodOffset + i * QMetaObjectPrivate::IntsPerMethod;
1077
1078 const uint flags = mo.d.data[handle + 4];
1079 if (flags & MethodRevisioned)
1080 hasRevisionedMethods = true;
1081
1082 visitString(mo.d.data[handle + 0]); // name
1083 visitString(mo.d.data[handle + 3]); // tag
1084
1085 const int argc = mo.d.data[handle + 1];
1086 const int paramIndex = mo.d.data[handle + 2];
1087
1088 fieldsForParameterData += argc * 2; // type and name
1089 fieldsForParameterData += 1; // + return type
1090
1091 // return type + args
1092 for (int i = 0; i < 1 + argc; ++i) {
1093 // type name (maybe)
1094 visitTypeInfo(mo.d.data[paramIndex + i]);
1095
1096 // parameter name
1097 if (i > 0)
1098 visitString(mo.d.data[paramIndex + argc + i]);
1099 }
1100 }
1101
1102 int fieldsForRevisions = 0;
1103 if (hasRevisionedMethods)
1104 fieldsForRevisions = methodCount;
1105
1106 return methodCount * QMetaObjectPrivate::IntsPerMethod
1107 + fieldsForRevisions + fieldsForParameterData;
1108}
1109
1110template <typename StringVisitor, typename TypeInfoVisitor>
1111int visitProperties(const QMetaObject &mo, StringVisitor visitString, TypeInfoVisitor visitTypeInfo)
1112{
1113 const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data);
1114
1115 for (int i = 0; i < priv->propertyCount; ++i) {
1116 const int handle = priv->propertyData + i * QMetaObjectPrivate::IntsPerProperty;
1117
1118 visitString(mo.d.data[handle]); // name
1119 visitTypeInfo(mo.d.data[handle + 1]);
1120 }
1121
1122 return priv->propertyCount * QMetaObjectPrivate::IntsPerProperty;
1123}
1124
1125template <typename StringVisitor>
1126int visitClassInfo(const QMetaObject &mo, StringVisitor visitString)
1127{
1128 const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data);
1129 const int intsPerClassInfo = 2;
1130
1131 for (int i = 0; i < priv->classInfoCount; ++i) {
1132 const int handle = priv->classInfoData + i * intsPerClassInfo;
1133
1134 visitString(mo.d.data[handle]); // key
1135 visitString(mo.d.data[handle + 1]); // value
1136 }
1137
1138 return priv->classInfoCount * intsPerClassInfo;
1139}
1140
1141template <typename StringVisitor>
1142int visitEnumerations(const QMetaObject &mo, StringVisitor visitString)
1143{
1144 const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data);
1145
1146 int fieldCount = priv->enumeratorCount * QMetaObjectPrivate::IntsPerEnum;
1147
1148 for (int i = 0; i < priv->enumeratorCount; ++i) {
1149 const uint *enumeratorData = mo.d.data + priv->enumeratorData + i * QMetaObjectPrivate::IntsPerEnum;
1150
1151 const uint keyCount = enumeratorData[3];
1152 fieldCount += keyCount * 2;
1153
1154 visitString(enumeratorData[0]); // name
1155 visitString(enumeratorData[1]); // enum name
1156
1157 const uint keyOffset = enumeratorData[4];
1158
1159 for (uint j = 0; j < keyCount; ++j) {
1160 visitString(mo.d.data[keyOffset + 2 * j]);
1161 }
1162 }
1163
1164 return fieldCount;
1165}
1166
1167template <typename StringVisitor>
1168int countMetaObjectFields(const QMetaObject &mo, StringVisitor stringVisitor)
1169{
1170 const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data);
1171
1172 const auto typeInfoVisitor = [&stringVisitor](uint typeInfo) {
1173 if (typeInfo & IsUnresolvedType)
1174 stringVisitor(typeInfo & TypeNameIndexMask);
1175 };
1176
1177 int fieldCount = MetaObjectPrivateFieldCount;
1178
1179 fieldCount += visitMethods(mo, priv->methodData, priv->methodCount, stringVisitor,
1180 typeInfoVisitor);
1181 fieldCount += visitMethods(mo, priv->constructorData, priv->constructorCount, stringVisitor,
1182 typeInfoVisitor);
1183
1184 fieldCount += visitProperties(mo, stringVisitor, typeInfoVisitor);
1185 fieldCount += visitClassInfo(mo, stringVisitor);
1186 fieldCount += visitEnumerations(mo, stringVisitor);
1187
1188 return fieldCount;
1189}
1190
1191} // anonymous namespace
1192
1193static_assert(QMetaObjectPrivate::OutputRevision == 12, "Check and adjust determineMetaObjectSizes");
1194
1196 int *stringCount)
1197{
1198 const QMetaObjectPrivate *priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data);
1200 return false;
1201
1202 uint highestStringIndex = 0;
1203 const auto stringIndexVisitor = [&highestStringIndex](uint index) {
1204 highestStringIndex = qMax(highestStringIndex, index);
1205 };
1206
1207 *fieldCount = countMetaObjectFields(mo, stringIndexVisitor);
1208 *stringCount = highestStringIndex + 1;
1209
1210 return true;
1211}
1212
1214{
1215 int fieldCount = 0;
1216 int stringCount = 0;
1217 if (!determineMetaObjectSizes(mo, &fieldCount, &stringCount)) {
1218 return false;
1219 }
1220
1221 hash.addData({reinterpret_cast<const char *>(mo.d.data), qsizetype(fieldCount * sizeof(uint))});
1222 for (int i = 0; i < stringCount; ++i) {
1223 hash.addData(stringData(&mo, i));
1224 }
1225
1226 return true;
1227}
1228
1229QByteArray QQmlPropertyCache::checksum(QHash<quintptr, QByteArray> *checksums, bool *ok) const
1230{
1231 auto it = checksums->constFind(quintptr(this));
1232 if (it != checksums->constEnd()) {
1233 *ok = true;
1234 return *it;
1235 }
1236
1237 // Generate a checksum on the meta-object data only on C++ types.
1238 if (_metaObject.isShared()) {
1239 *ok = false;
1240 return QByteArray();
1241 }
1242
1244
1245 if (_parent) {
1246 hash.addData(_parent->checksum(checksums, ok));
1247 if (!*ok)
1248 return QByteArray();
1249 }
1250
1251 if (!addToHash(hash, *_metaObject.metaObject())) {
1252 *ok = false;
1253 return QByteArray();
1254 }
1255
1256 const QByteArray result = hash.result();
1257 if (result.isEmpty()) {
1258 *ok = false;
1259 } else {
1260 *ok = true;
1261 checksums->insert(quintptr(this), result);
1262 }
1263 return result;
1264}
1265
1271{
1272 const QQmlPropertyData *signalData = signal(index);
1273 if (signalData && signalData->hasArguments()) {
1275 if (args && args->names)
1276 return *args->names;
1278 return method.parameterNames();
1279 }
1280 return QList<QByteArray>();
1281}
1282
static JNINativeMethod methods[]
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
Definition qbytearray.h:600
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
ConstIterator end() const
typename QStringHash< T >::template Iterator< ConstIteratorData, const T > ConstIterator
ConstIterator begin() const
T * value(const ConstIterator &iter)
void linkAndReserve(const QLinkedStringHash< T > &other, int additionalReserve)
ConstIterator findNext(const ConstIterator &iter) const
typename QLinkedStringHash< QPair< int, QQmlPropertyData * > >::ConstIterator ConstIterator
Definition qlist.h:75
qsizetype size() const noexcept
Definition qlist.h:397
\inmodule QtCore
const char * name() const
Returns the name of this item.
void setIsScoped(bool value)
Sets this enumerator to be a scoped enum if \value is true.
int addKey(const QByteArray &name, int value)
Adds a new key called name to this enumerator, associated with value.
\inmodule QtCore
Definition qmetaobject.h:19
void setSuperClass(const QMetaObject *meta)
Sets the superclass meta object of the class being constructed by this meta object builder to meta.
QMetaEnumBuilder addEnumerator(const QByteArray &name)
Adds a new enumerator to this class with the specified name.
QMetaObject * toMetaObject() const
Converts this meta object builder into a concrete QMetaObject.
QMetaMethodBuilder addSignal(const QByteArray &signature)
Adds a new signal to this class with the specified signature.
int addClassInfo(const QByteArray &name, const QByteArray &value)
Adds name and value as an item of class information to this class.
QMetaPropertyBuilder addProperty(const QByteArray &name, const QByteArray &type, int notifierId=-1)
Adds a new readable/writable property to this class with the specified name and type.
void setClassName(const QByteArray &name)
Sets the name of the class being constructed by this meta object builder.
QMetaMethodBuilder addSlot(const QByteArray &signature)
Adds a new public slot to this class with the specified signature.
void setReadable(bool value)
Sets this property to readable if value is true.
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:341
constexpr TypeFlags flags() const
Definition qmetatype.h:2658
int id(int=0) const
Definition qmetatype.h:475
@ PointerToQObject
Definition qmetatype.h:406
friend class QVariant
Definition qmetatype.h:796
QDynamicMetaObjectData * metaObject
Definition qobject.h:90
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:150
\inmodule QtCore
Definition qobject.h:103
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
const QMetaObject * metaObject() const
void setSharedOnce(QMetaObject *shared) const
static QQmlPropertyCache::ConstPtr propertyCache(QObject *object, QTypeRevision version=QTypeRevision())
Returns a QQmlPropertyCache for obj if one is available.
QByteArray checksum(QHash< quintptr, QByteArray > *checksums, bool *ok) const
static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo)
void invalidate(const QMetaObject *)
QQmlPropertyCache::Ptr copyAndAppend(const QMetaObject *, QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags=QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags=QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags=QQmlPropertyData::Flags()) const
QQmlPropertyCache()=default
const QQmlPropertyData * maybeUnresolvedProperty(int) const
void appendSignal(const QString &, QQmlPropertyData::Flags, int coreIndex, const QMetaType *types=nullptr, const QList< QByteArray > &names=QList< QByteArray >())
QQmlRefPointer< QQmlPropertyCache > Ptr
void appendEnum(const QString &, const QVector< QQmlEnumValue > &)
QList< QByteArray > signalParameterNames(int index) const
static QString signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList< QByteArray > &parameterNameList, QString *errorString=nullptr)
const QQmlPropertyData * property(const K &key, QObject *object, const QQmlRefPointer< QQmlContextData > &context) const
const QQmlPropertyData * overrideData(const QQmlPropertyData *) const
const QQmlPropertyData * defaultProperty() const
QQmlPropertyCache::Ptr copy() const
const QMetaObject * metaObject() const
static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount)
void setParent(QQmlPropertyCache::ConstPtr newParent)
QQmlPropertyCache::Ptr copyAndReserve(int propertyCount, int methodCount, int signalCount, int enumCount) const
void update(const QMetaObject *)
void toMetaObjectBuilder(QMetaObjectBuilder &) const
const QQmlPropertyCache::ConstPtr & parent() const
const QMetaObject * firstCppMetaObject() const
void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex, QMetaType returnType, const QList< QByteArray > &names, const QVector< QMetaType > &parameterTypes)
void appendProperty(const QString &, QQmlPropertyData::Flags flags, int coreIndex, QMetaType propType, QTypeRevision revision, int notifyIndex)
const char * className() const
QString defaultPropertyName() const
static Ptr createStandalone(const QMetaObject *, QTypeRevision metaObjectRevision=QTypeRevision::zero())
Creates a standalone QQmlPropertyCache of metaObject.
const QMetaObject * createMetaObject() const
int originalClone(int index) const
void setRevision(QTypeRevision revision)
void setNotifyIndex(int idx)
QMetaType propType() const
void setOverrideIndexIsProperty(bool onoff)
void setCoreIndex(int idx)
void setPropType(QMetaType pt)
bool markAsOverrideOf(QQmlPropertyData *predecessor)
void setOverrideIndex(int idx)
static Flags flagsForProperty(const QMetaProperty &)
void load(const QMetaProperty &)
bool isSignalHandler() const
QString name(QObject *) const
const QMetaObject * metaObject() const
int count() const
static QString signalNameToHandlerName(QAnyStringView signal)
const_iterator constEnd() const noexcept
Definition qset.h:143
const_iterator constFind(const T &value) const
Definition qset.h:161
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QByteArray toUtf8() const &
Definition qstring.h:634
\inmodule QtCore
static constexpr QTypeRevision zero()
Produces a QTypeRevision with major and minor version {0}.
constexpr bool isValid() const
Returns true if the major version or the minor version is known, otherwise false.
static constexpr QTypeRevision fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given value.
QHash< int, QWidget * > hash
[35multi]
QString str
[2]
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
set reserve(20000)
auto signal
auto mo
[7]
QList< QVariant > arguments
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
static void * context
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
static const QCssKnownValue properties[NumProperties - 1]
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 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 int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QString methodName(const QDBusIntrospection::Method &method)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static QByteArray stringData(const QMetaObject *mo, int index)
static const QMetaObjectPrivate * priv(const uint *data)
@ MetaObjectPrivateFieldCount
@ MethodRevisioned
@ IsUnresolvedType
@ TypeNameIndexMask
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
n varying highp vec2 A
GLenum GLsizei GLsizei GLint * values
[15]
GLuint64 GLenum void * handle
const GLfloat * m
GLuint index
[2]
GLuint GLuint end
GLsizei GLenum GLenum * types
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLbitfield flags
GLenum const GLint * param
GLenum GLuint GLintptr offset
GLenum GLuint GLsizei propCount
GLuint name
GLhandleARB obj
[2]
GLuint GLuint * names
GLuint entry
GLuint in
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition qpair.h:19
const QQmlPropertyData * qQmlPropertyCacheProperty(QObject *obj, T name, const QQmlRefPointer< QQmlContextData > &context, QQmlPropertyData *local)
static const QByteArray stringData(const QMetaObject *mo, int index)
static QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const T &propertyName)
#define Q_INT16_MAX
static const char * qQmlPropertyCacheToString(QLatin1String string)
static QHashedString signalNameToHandlerName(const QHashedString &methodName)
static int metaObjectSignalCount(const QMetaObject *metaObject)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
const char property[13]
Definition qwizard.cpp:101
obj metaObject() -> className()
QObject::connect nullptr
QJSValueList args
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
static Q_CORE_EXPORT QMetaMethod signal(const QMetaObject *m, int signal_index)
static const QMetaObjectPrivate * get(const QMetaObject *metaobject)
static Q_CORE_EXPORT int signalIndex(const QMetaMethod &m)
\inmodule QtCore
int propertyCount() const
Returns the number of properties in this class, including the number of properties provided by each b...
QMetaClassInfo classInfo(int index) const
Returns the meta-data for the item of class information with the given index.
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
int indexOfSlot(const char *slot) const
Finds slot and returns its index; otherwise returns -1.
int methodCount() const
Returns the number of methods in this class, including the number of methods provided by each base cl...
int indexOfProperty(const char *name) const
Finds property name and returns its index; otherwise returns -1.
int methodOffset() const
Returns the method offset for this class; i.e.
const QMetaObject * superClass() const
Returns the meta-object of the superclass, or \nullptr if there is no such object.
struct QMetaObject::Data d
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
int propertyOffset() const
Returns the property offset for this class; i.e.
int classInfoOffset() const
Returns the class information offset for this class; i.e.