36class QQmlTypePrivate final :
public QQmlRefCounted<QQmlTypePrivate>
38 Q_DISABLE_COPY_MOVE(QQmlTypePrivate)
40 struct ProxyMetaObjects
44 for (
const QQmlProxyMetaObject::ProxyData &metaObject : std::as_const(data))
45 free(metaObject.metaObject);
48 QList<QQmlProxyMetaObject::ProxyData> data;
49 bool containsRevisionedAttributes =
false;
54 enum Scoping { Scoped, Unscoped };
57 qDeleteAll(scopedEnums);
58 qDeleteAll(unscopedEnums);
61 QStringHash<
int> enums;
62 QStringHash<
int> scopedEnumIndex;
63 QStringHash<
int> unscopedEnumIndex;
64 QList<QStringHash<
int> *> scopedEnums;
65 QList<QStringHash<
int> *> unscopedEnums;
68 QQmlTypePrivate(QQmlType::RegistrationType type);
70 const ProxyMetaObjects *init()
const;
72 QUrl sourceUrl()
const
75 case QQmlType::CompositeType:
76 return extraData.compositeTypeData;
77 case QQmlType::CompositeSingletonType:
78 return extraData.singletonTypeData->singletonInstanceInfo->url;
79 case QQmlType::InlineComponentType:
80 return extraData.inlineComponentTypeData;
81 case QQmlType::JavaScriptType:
82 return extraData.javaScriptTypeData;
88 const QQmlTypePrivate *attachedPropertiesBase(QQmlTypeLoader *typeLoader)
const
90 for (
const QQmlTypePrivate *d =
this; d;
91 d = d->resolveCompositeBaseType(typeLoader).d.data()) {
92 if (d->regType == QQmlType::CppType)
93 return d->extraData.cppTypeData->attachedPropertiesType ? d :
nullptr;
95 if (d->regType != QQmlType::CompositeType)
101 bool isComposite()
const
104 case QQmlType::CompositeType:
105 case QQmlType::CompositeSingletonType:
106 case QQmlType::InlineComponentType:
115 bool isValueType()
const
117 return regType == QQmlType::CppType && !(typeId.flags() & QMetaType::PointerToQObject);
120 QQmlType resolveCompositeBaseType(QQmlTypeLoader *typeLoader)
const;
121 QQmlPropertyCache::ConstPtr compositePropertyCache(QQmlTypeLoader *typeLoader)
const;
123 struct QQmlCppTypeData
126 void (*newFunc)(
void *,
void *);
127 void *userdata =
nullptr;
128 QString noCreationReason;
129 QVariant (*createValueTypeFunc)(
const QJSValue &);
130 int parserStatusCast;
131 QObject *(*extFunc)(QObject *);
132 const QMetaObject *extMetaObject;
133 QQmlCustomParser *customParser;
134 QQmlAttachedPropertiesFunc attachedPropertiesFunc;
135 const QMetaObject *attachedPropertiesType;
136 int propertyValueSourceCast;
137 int propertyValueInterceptorCast;
139 bool registerEnumClassesUnscoped;
140 bool registerEnumsFromRelatedTypes;
141 bool constructValueType;
142 bool populateValueType;
145 struct QQmlSingletonTypeData
147 QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo;
148 QObject *(*extFunc)(QObject *);
149 const QMetaObject *extMetaObject;
158 QQmlCppTypeData *cppTypeData;
159 QQmlSingletonTypeData *singletonTypeData;
160 QUrl compositeTypeData;
161 QUrl javaScriptTypeData;
162 QUrl inlineComponentTypeData;
163 QMetaSequence sequentialContainerTypeData;
164 const char *interfaceTypeData;
166 static_assert(
sizeof(extraData) ==
sizeof(
void *));
168 QHashedString module;
173 QQmlType::RegistrationType regType;
174 QTypeRevision version;
175 QTypeRevision revision = QTypeRevision::zero();
176 const QMetaObject *baseMetaObject =
nullptr;
178 void setName(
const QString &uri,
const QString &element);
180 template<
typename String>
181 static int enumValue(
182 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
183 const String &name,
bool *ok)
185 const auto *rv = doGetEnumOp<
const int *>(
186 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
187 return enums->enums.value(name);
188 }, [](
const int *p) {
return !!p; }, ok);
189 return rv ? *rv : -1;
192 template<Enums::Scoping scoping,
typename String>
193 static int enumIndex(
194 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
195 const String &name,
bool *ok)
197 const auto *rv = doGetEnumOp<
const int *> (
198 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
199 if constexpr (scoping == Enums::Scoped)
200 return enums->scopedEnumIndex.value(name);
202 return enums->unscopedEnumIndex.value(name);
203 }, [](
const int *p) {
return !!p; }, ok);
204 return rv ? *rv : -1;
207 template<Enums::Scoping scoping,
typename String>
208 static int enumValue(
209 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
int index,
210 const String &name,
bool *ok)
212 const auto *rv = doGetEnumOp<
const int *>(
213 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
214 if constexpr (scoping == Enums::Scoped) {
215 Q_ASSERT(index > -1 && index < enums->scopedEnums.size());
216 return enums->scopedEnums.at(index)->value(name);
218 Q_ASSERT(index > -1 && index < enums->unscopedEnums.size());
219 return enums->unscopedEnums.at(index)->value(name);
221 }, [](
const int *p) {
return !!p; }, ok);
222 return rv ? *rv : -1;
225 template<Enums::Scoping scoping,
typename String1,
typename String2>
226 static int enumValue(
227 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
228 const String1 &scopedEnumName,
const String2 &name,
bool *ok)
230 const auto *rv = doGetEnumOp<
const int *>(
231 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
232 const QStringHash<
int> *enumIndex;
233 const QList<QStringHash<
int> *> *_enums;
234 if constexpr (scoping == Enums::Scoped) {
235 enumIndex = &enums->scopedEnumIndex;
236 _enums = &enums->scopedEnums;
238 enumIndex = &enums->unscopedEnumIndex;
239 _enums = &enums->unscopedEnums;
242 const int *rv = enumIndex->value(scopedEnumName);
244 return static_cast<
int *>(
nullptr);
246 const int index = *rv;
247 Q_ASSERT(index > -1 && index < _enums->size());
248 return _enums->at(index)->value(name);
249 }, [](
const int *p) {
return !!p; }, ok);
250 return rv ? *rv : -1;
253 template<Enums::Scoping scoping>
254 static QString enumKey(
255 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
256 int index,
int value,
bool *ok)
258 return doGetEnumOp<QString>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
259 const QList<QStringHash<
int> *> *_enums;
260 if constexpr (scoping == Enums::Scoped)
261 _enums = &enums->scopedEnums;
263 _enums = &enums->unscopedEnums;
265 Q_ASSERT(index > -1 && index < _enums->size());
266 const auto hash = _enums->at(index);
267 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
268 if (it.value() == value)
269 return QString(it.key());
272 }, [](
const QString &s) {
return !s.isEmpty(); }, ok);
275 template<Enums::Scoping scoping>
276 static QStringList enumKeys(
277 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
278 int index,
int value,
bool *ok)
280 return doGetEnumOp<QStringList>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
281 const QList<QStringHash<
int> *> *_enums;
282 if constexpr (scoping == Enums::Scoped)
283 _enums = &enums->scopedEnums;
285 _enums = &enums->unscopedEnums;
287 Q_ASSERT(index > -1 && index < _enums->size());
289 const auto hash = _enums->at(index);
290 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
291 if (it.value() == value)
292 keys.append(QString(it.key()));
294 std::reverse(keys.begin(), keys.end());
296 }, [](
const QStringList &l) {
return !l.empty(); }, ok);
299 const QMetaObject *metaObject()
const
302 return metaObjectForValueType();
304 const QQmlTypePrivate::ProxyMetaObjects *proxies = init();
305 return proxies->data.isEmpty()
307 : proxies->data.constFirst().metaObject;
310 const QMetaObject *metaObjectForValueType()
const
312 Q_ASSERT(isValueType());
316 if (
const QMetaObject *extensionMetaObject = extraData.cppTypeData->extMetaObject) {
319 if (extensionMetaObject->metaType().flags() & QMetaType::IsGadget)
320 return extensionMetaObject;
323 if (baseMetaObject) {
326 if (baseMetaObject->metaType().flags() & QMetaType::IsGadget)
327 return baseMetaObject;
333 static QQmlType visibleQmlTypeByName(
334 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
335 const QString &elementName, QQmlTypeLoader *typeLoader)
339 return unit->typeNameCache->query<QQmlImport::AllowRecursion>(
340 elementName, typeLoader).type;
350 static QQmlType visibleQmlTypeByName(
351 const QV4::ExecutableCompilationUnit *unit,
int elementNameId,
352 QQmlTypeLoader *typeLoader =
nullptr)
354 const auto &base = unit->baseCompilationUnit();
355 const auto it = base->resolvedTypes.constFind(elementNameId);
356 if (it == base->resolvedTypes.constEnd()) {
357 return visibleQmlTypeByName(
358 base, base->stringAt(elementNameId),
359 typeLoader ? typeLoader : unit->engine->typeLoader());
362 return (*it)->type();
366 mutable QAtomicPointer<
const ProxyMetaObjects> proxyMetaObjects;
367 mutable QAtomicPointer<
const Enums> enums;
370 friend class QQmlRefCounted<QQmlTypePrivate>;
374 QString metaObjectName;
377 QString metaEnumScope;
381 template<
typename Ret,
typename Op,
typename Check>
382 static Ret doGetEnumOp(
const QQmlRefPointer<
const QQmlTypePrivate> &d,
383 QQmlTypeLoader *typeLoader, Op &&op, Check &&check,
bool *ok)
387 if (
const QQmlTypePrivate::Enums *enums = d->initEnums(typeLoader)) {
388 if (Ret rv = op(enums); check(rv)) {
399 const Enums *initEnums(QQmlTypeLoader *typeLoader)
const;
400 void insertEnums(Enums *enums,
const QMetaObject *metaObject)
const;
401 void insertEnumsFromPropertyCache(Enums *enums,
const QQmlPropertyCache::ConstPtr &cache)
const;
403 void createListOfPossibleConflictingItems(
const QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path)
const;
404 void createEnumConflictReport(
const QMetaObject *metaObject,
const QString &conflictingKey)
const;