35class QQmlTypePrivate final :
public QQmlRefCounted<QQmlTypePrivate>
37 Q_DISABLE_COPY_MOVE(QQmlTypePrivate)
39 struct ProxyMetaObjects
43 for (
const QQmlProxyMetaObject::ProxyData &metaObject : std::as_const(data))
44 free(metaObject.metaObject);
47 QList<QQmlProxyMetaObject::ProxyData> data;
48 bool containsRevisionedAttributes =
false;
53 enum Scoping { Scoped, Unscoped };
56 qDeleteAll(scopedEnums);
57 qDeleteAll(unscopedEnums);
60 QStringHash<
int> enums;
61 QStringHash<
int> scopedEnumIndex;
62 QStringHash<
int> unscopedEnumIndex;
63 QList<QStringHash<
int> *> scopedEnums;
64 QList<QStringHash<
int> *> unscopedEnums;
67 QQmlTypePrivate(QQmlType::RegistrationType type);
69 const ProxyMetaObjects *init()
const;
71 QUrl sourceUrl()
const
74 case QQmlType::CompositeType:
75 return extraData.compositeTypeData;
76 case QQmlType::CompositeSingletonType:
77 return extraData.singletonTypeData->singletonInstanceInfo->url;
78 case QQmlType::InlineComponentType:
79 return extraData.inlineComponentTypeData;
80 case QQmlType::JavaScriptType:
81 return extraData.javaScriptTypeData;
87 const QQmlTypePrivate *attachedPropertiesBase(QQmlTypeLoader *typeLoader)
const
89 for (
const QQmlTypePrivate *d =
this; d;
90 d = d->resolveCompositeBaseType(typeLoader).d.data()) {
91 if (d->regType == QQmlType::CppType)
92 return d->extraData.cppTypeData->attachedPropertiesType ? d :
nullptr;
94 if (d->regType != QQmlType::CompositeType)
100 bool isComposite()
const
102 return regType == QQmlType::CompositeType || regType == QQmlType::CompositeSingletonType;
105 bool isValueType()
const
107 return regType == QQmlType::CppType && !(typeId.flags() & QMetaType::PointerToQObject);
110 QQmlType resolveCompositeBaseType(QQmlTypeLoader *typeLoader)
const;
111 QQmlPropertyCache::ConstPtr compositePropertyCache(QQmlTypeLoader *typeLoader)
const;
113 struct QQmlCppTypeData
116 void (*newFunc)(
void *,
void *);
117 void *userdata =
nullptr;
118 QString noCreationReason;
119 QVariant (*createValueTypeFunc)(
const QJSValue &);
120 int parserStatusCast;
121 QObject *(*extFunc)(QObject *);
122 const QMetaObject *extMetaObject;
123 QQmlCustomParser *customParser;
124 QQmlAttachedPropertiesFunc attachedPropertiesFunc;
125 const QMetaObject *attachedPropertiesType;
126 int propertyValueSourceCast;
127 int propertyValueInterceptorCast;
129 bool registerEnumClassesUnscoped;
130 bool registerEnumsFromRelatedTypes;
131 bool constructValueType;
132 bool populateValueType;
135 struct QQmlSingletonTypeData
137 QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo;
138 QObject *(*extFunc)(QObject *);
139 const QMetaObject *extMetaObject;
148 QQmlCppTypeData *cppTypeData;
149 QQmlSingletonTypeData *singletonTypeData;
150 QUrl compositeTypeData;
151 QUrl javaScriptTypeData;
152 QUrl inlineComponentTypeData;
153 QMetaSequence sequentialContainerTypeData;
154 const char *interfaceTypeData;
156 static_assert(
sizeof(extraData) ==
sizeof(
void *));
158 QHashedString module;
163 QQmlType::RegistrationType regType;
164 QTypeRevision version;
165 QTypeRevision revision = QTypeRevision::zero();
166 const QMetaObject *baseMetaObject =
nullptr;
168 void setName(
const QString &uri,
const QString &element);
170 template<
typename String>
171 static int enumValue(
172 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
173 const String &name,
bool *ok)
175 const auto *rv = doGetEnumOp<
const int *>(
176 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
177 return enums->enums.value(name);
178 }, [](
const int *p) {
return !!p; }, ok);
179 return rv ? *rv : -1;
182 template<Enums::Scoping scoping,
typename String>
183 static int enumIndex(
184 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
185 const String &name,
bool *ok)
187 const auto *rv = doGetEnumOp<
const int *> (
188 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
189 if constexpr (scoping == Enums::Scoped)
190 return enums->scopedEnumIndex.value(name);
192 return enums->unscopedEnumIndex.value(name);
193 }, [](
const int *p) {
return !!p; }, ok);
194 return rv ? *rv : -1;
197 template<Enums::Scoping scoping,
typename String>
198 static int enumValue(
199 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
int index,
200 const String &name,
bool *ok)
202 const auto *rv = doGetEnumOp<
const int *>(
203 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
204 if constexpr (scoping == Enums::Scoped) {
205 Q_ASSERT(index > -1 && index < enums->scopedEnums.size());
206 return enums->scopedEnums.at(index)->value(name);
208 Q_ASSERT(index > -1 && index < enums->unscopedEnums.size());
209 return enums->unscopedEnums.at(index)->value(name);
211 }, [](
const int *p) {
return !!p; }, ok);
212 return rv ? *rv : -1;
215 template<Enums::Scoping scoping,
typename String1,
typename String2>
216 static int enumValue(
217 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
218 const String1 &scopedEnumName,
const String2 &name,
bool *ok)
220 const auto *rv = doGetEnumOp<
const int *>(
221 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
222 const QStringHash<
int> *enumIndex;
223 const QList<QStringHash<
int> *> *_enums;
224 if constexpr (scoping == Enums::Scoped) {
225 enumIndex = &enums->scopedEnumIndex;
226 _enums = &enums->scopedEnums;
228 enumIndex = &enums->unscopedEnumIndex;
229 _enums = &enums->unscopedEnums;
232 const int *rv = enumIndex->value(scopedEnumName);
234 return static_cast<
int *>(
nullptr);
236 const int index = *rv;
237 Q_ASSERT(index > -1 && index < _enums->size());
238 return _enums->at(index)->value(name);
239 }, [](
const int *p) {
return !!p; }, ok);
240 return rv ? *rv : -1;
243 template<Enums::Scoping scoping>
244 static QString enumKey(
245 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
246 int index,
int value,
bool *ok)
248 return doGetEnumOp<QString>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
249 const QList<QStringHash<
int> *> *_enums;
250 if constexpr (scoping == Enums::Scoped)
251 _enums = &enums->scopedEnums;
253 _enums = &enums->unscopedEnums;
255 Q_ASSERT(index > -1 && index < _enums->size());
256 const auto hash = _enums->at(index);
257 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
258 if (it.value() == value)
259 return QString(it.key());
262 }, [](
const QString &s) {
return !s.isEmpty(); }, ok);
265 template<Enums::Scoping scoping>
266 static QStringList enumKeys(
267 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
268 int index,
int value,
bool *ok)
270 return doGetEnumOp<QStringList>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
271 const QList<QStringHash<
int> *> *_enums;
272 if constexpr (scoping == Enums::Scoped)
273 _enums = &enums->scopedEnums;
275 _enums = &enums->unscopedEnums;
277 Q_ASSERT(index > -1 && index < _enums->size());
279 const auto hash = _enums->at(index);
280 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
281 if (it.value() == value)
282 keys.append(QString(it.key()));
284 std::reverse(keys.begin(), keys.end());
286 }, [](
const QStringList &l) {
return !l.empty(); }, ok);
289 const QMetaObject *metaObject()
const
292 return metaObjectForValueType();
294 const QQmlTypePrivate::ProxyMetaObjects *proxies = init();
295 return proxies->data.isEmpty()
297 : proxies->data.constFirst().metaObject;
300 const QMetaObject *metaObjectForValueType()
const
302 Q_ASSERT(isValueType());
306 if (
const QMetaObject *extensionMetaObject = extraData.cppTypeData->extMetaObject) {
309 if (extensionMetaObject->metaType().flags() & QMetaType::IsGadget)
310 return extensionMetaObject;
313 if (baseMetaObject) {
316 if (baseMetaObject->metaType().flags() & QMetaType::IsGadget)
317 return baseMetaObject;
323 static QQmlType visibleQmlTypeByName(
324 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
325 const QString &elementName, QQmlTypeLoader *typeLoader)
329 return unit->typeNameCache->query<QQmlImport::AllowRecursion>(
330 elementName, typeLoader).type;
340 static QQmlType visibleQmlTypeByName(
341 const QV4::ExecutableCompilationUnit *unit,
int elementNameId,
342 QQmlTypeLoader *typeLoader =
nullptr)
344 const auto &base = unit->baseCompilationUnit();
345 const auto it = base->resolvedTypes.constFind(elementNameId);
346 if (it == base->resolvedTypes.constEnd()) {
347 return visibleQmlTypeByName(
348 base, base->stringAt(elementNameId),
349 typeLoader ? typeLoader : unit->engine->typeLoader());
352 return (*it)->type();
356 mutable QAtomicPointer<
const ProxyMetaObjects> proxyMetaObjects;
357 mutable QAtomicPointer<
const Enums> enums;
360 friend class QQmlRefCounted<QQmlTypePrivate>;
364 QString metaObjectName;
367 QString metaEnumScope;
371 template<
typename Ret,
typename Op,
typename Check>
372 static Ret doGetEnumOp(
const QQmlRefPointer<
const QQmlTypePrivate> &d,
373 QQmlTypeLoader *typeLoader, Op &&op, Check &&check,
bool *ok)
377 if (
const QQmlTypePrivate::Enums *enums = d->initEnums(typeLoader)) {
378 if (Ret rv = op(enums); check(rv)) {
389 const Enums *initEnums(QQmlTypeLoader *typeLoader)
const;
390 void insertEnums(Enums *enums,
const QMetaObject *metaObject)
const;
391 void insertEnumsFromPropertyCache(Enums *enums,
const QQmlPropertyCache::ConstPtr &cache)
const;
393 void createListOfPossibleConflictingItems(
const QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path)
const;
394 void createEnumConflictReport(
const QMetaObject *metaObject,
const QString &conflictingKey)
const;