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