34class QQmlTypePrivate final :
public QQmlRefCounted<QQmlTypePrivate>
36 Q_DISABLE_COPY_MOVE(QQmlTypePrivate)
38 struct ProxyMetaObjects
42 for (
const QQmlProxyMetaObject::ProxyData &metaObject : data)
43 free(metaObject.metaObject);
46 QList<QQmlProxyMetaObject::ProxyData> data;
47 bool containsRevisionedAttributes =
false;
52 enum Scoping { Scoped, Unscoped };
55 qDeleteAll(scopedEnums);
56 qDeleteAll(unscopedEnums);
59 QStringHash<
int> enums;
60 QStringHash<
int> scopedEnumIndex;
61 QStringHash<
int> unscopedEnumIndex;
62 QList<QStringHash<
int> *> scopedEnums;
63 QList<QStringHash<
int> *> unscopedEnums;
66 QQmlTypePrivate(QQmlType::RegistrationType type);
68 const ProxyMetaObjects *init()
const;
70 QUrl sourceUrl()
const
73 case QQmlType::CompositeType:
74 return extraData.compositeTypeData;
75 case QQmlType::CompositeSingletonType:
76 return extraData.singletonTypeData->singletonInstanceInfo->url;
77 case QQmlType::InlineComponentType:
78 return extraData.inlineComponentTypeData;
79 case QQmlType::JavaScriptType:
80 return extraData.javaScriptTypeData;
86 const QQmlTypePrivate *attachedPropertiesBase(QQmlTypeLoader *typeLoader)
const
88 for (
const QQmlTypePrivate *d =
this; d;
89 d = d->resolveCompositeBaseType(typeLoader).d.data()) {
90 if (d->regType == QQmlType::CppType)
91 return d->extraData.cppTypeData->attachedPropertiesType ? d :
nullptr;
93 if (d->regType != QQmlType::CompositeType)
99 bool isComposite()
const
101 return regType == QQmlType::CompositeType || regType == QQmlType::CompositeSingletonType;
104 bool isValueType()
const
106 return regType == QQmlType::CppType && !(typeId.flags() & QMetaType::PointerToQObject);
109 QQmlType resolveCompositeBaseType(QQmlTypeLoader *typeLoader)
const;
110 QQmlPropertyCache::ConstPtr compositePropertyCache(QQmlTypeLoader *typeLoader)
const;
112 struct QQmlCppTypeData
115 void (*newFunc)(
void *,
void *);
116 void *userdata =
nullptr;
117 QString noCreationReason;
118 QVariant (*createValueTypeFunc)(
const QJSValue &);
119 int parserStatusCast;
120 QObject *(*extFunc)(QObject *);
121 const QMetaObject *extMetaObject;
122 QQmlCustomParser *customParser;
123 QQmlAttachedPropertiesFunc attachedPropertiesFunc;
124 const QMetaObject *attachedPropertiesType;
125 int propertyValueSourceCast;
126 int propertyValueInterceptorCast;
128 bool registerEnumClassesUnscoped;
129 bool registerEnumsFromRelatedTypes;
130 bool constructValueType;
131 bool populateValueType;
134 struct QQmlSingletonTypeData
136 QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo;
137 QObject *(*extFunc)(QObject *);
138 const QMetaObject *extMetaObject;
147 QQmlCppTypeData *cppTypeData;
148 QQmlSingletonTypeData *singletonTypeData;
149 QUrl compositeTypeData;
150 QUrl javaScriptTypeData;
151 QUrl inlineComponentTypeData;
152 QMetaSequence sequentialContainerTypeData;
153 const char *interfaceTypeData;
155 static_assert(
sizeof(extraData) ==
sizeof(
void *));
157 QHashedString module;
162 QQmlType::RegistrationType regType;
163 QTypeRevision version;
164 QTypeRevision revision = QTypeRevision::zero();
165 const QMetaObject *baseMetaObject =
nullptr;
167 void setName(
const QString &uri,
const QString &element);
169 template<
typename String>
170 static int enumValue(
171 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
172 const String &name,
bool *ok)
174 const auto *rv = doGetEnumOp<
const int *>(
175 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
176 return enums->enums.value(name);
177 }, [](
const int *p) {
return !!p; }, ok);
178 return rv ? *rv : -1;
181 template<Enums::Scoping scoping,
typename String>
182 static int enumIndex(
183 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
184 const String &name,
bool *ok)
186 const auto *rv = doGetEnumOp<
const int *> (
187 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
188 if constexpr (scoping == Enums::Scoped)
189 return enums->scopedEnumIndex.value(name);
191 return enums->unscopedEnumIndex.value(name);
192 }, [](
const int *p) {
return !!p; }, ok);
193 return rv ? *rv : -1;
196 template<Enums::Scoping scoping,
typename String>
197 static int enumValue(
198 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
int index,
199 const String &name,
bool *ok)
201 const auto *rv = doGetEnumOp<
const int *>(
202 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
203 if constexpr (scoping == Enums::Scoped) {
204 Q_ASSERT(index > -1 && index < enums->scopedEnums.size());
205 return enums->scopedEnums.at(index)->value(name);
207 Q_ASSERT(index > -1 && index < enums->unscopedEnums.size());
208 return enums->unscopedEnums.at(index)->value(name);
210 }, [](
const int *p) {
return !!p; }, ok);
211 return rv ? *rv : -1;
214 template<Enums::Scoping scoping,
typename String1,
typename String2>
215 static int enumValue(
216 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
217 const String1 &scopedEnumName,
const String2 &name,
bool *ok)
219 const auto *rv = doGetEnumOp<
const int *>(
220 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
221 const QStringHash<
int> *enumIndex;
222 const QList<QStringHash<
int> *> *_enums;
223 if constexpr (scoping == Enums::Scoped) {
224 enumIndex = &enums->scopedEnumIndex;
225 _enums = &enums->scopedEnums;
227 enumIndex = &enums->unscopedEnumIndex;
228 _enums = &enums->unscopedEnums;
231 const int *rv = enumIndex->value(scopedEnumName);
233 return static_cast<
int *>(
nullptr);
235 const int index = *rv;
236 Q_ASSERT(index > -1 && index < _enums->size());
237 return _enums->at(index)->value(name);
238 }, [](
const int *p) {
return !!p; }, ok);
239 return rv ? *rv : -1;
242 template<Enums::Scoping scoping>
243 static QString enumKey(
244 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
245 int index,
int value,
bool *ok)
247 return doGetEnumOp<QString>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
248 const QList<QStringHash<
int> *> *_enums;
249 if constexpr (scoping == Enums::Scoped)
250 _enums = &enums->scopedEnums;
252 _enums = &enums->unscopedEnums;
254 Q_ASSERT(index > -1 && index < _enums->size());
255 const auto hash = _enums->at(index);
256 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
257 if (it.value() == value)
258 return QString(it.key());
261 }, [](
const QString &s) {
return !s.isEmpty(); }, ok);
264 template<Enums::Scoping scoping>
265 static QStringList enumKeys(
266 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
267 int index,
int value,
bool *ok)
269 return doGetEnumOp<QStringList>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
270 const QList<QStringHash<
int> *> *_enums;
271 if constexpr (scoping == Enums::Scoped)
272 _enums = &enums->scopedEnums;
274 _enums = &enums->unscopedEnums;
276 Q_ASSERT(index > -1 && index < _enums->size());
278 const auto hash = _enums->at(index);
279 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
280 if (it.value() == value)
281 keys.append(QString(it.key()));
283 std::reverse(keys.begin(), keys.end());
285 }, [](
const QStringList &l) {
return !l.empty(); }, ok);
288 const QMetaObject *metaObject()
const
291 return metaObjectForValueType();
293 const QQmlTypePrivate::ProxyMetaObjects *proxies = init();
294 return proxies->data.isEmpty()
296 : proxies->data.constFirst().metaObject;
299 const QMetaObject *metaObjectForValueType()
const
301 Q_ASSERT(isValueType());
305 if (
const QMetaObject *extensionMetaObject = extraData.cppTypeData->extMetaObject) {
308 if (extensionMetaObject->metaType().flags() & QMetaType::IsGadget)
309 return extensionMetaObject;
312 if (baseMetaObject) {
315 if (baseMetaObject->metaType().flags() & QMetaType::IsGadget)
316 return baseMetaObject;
322 static QQmlType visibleQmlTypeByName(
323 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
324 const QString &elementName, QQmlTypeLoader *typeLoader)
326 const QQmlType qmltype = unit->typeNameCache->query<QQmlImport::AllowRecursion>(
327 elementName, typeLoader).type;
329 if (qmltype.isValid() && qmltype.isInlineComponentType()
330 && !QQmlMetaType::obtainCompilationUnit(qmltype.typeId())) {
346 static QQmlType visibleQmlTypeByName(
347 const QV4::ExecutableCompilationUnit *unit,
int elementNameId,
348 QQmlTypeLoader *typeLoader =
nullptr)
350 const auto &base = unit->baseCompilationUnit();
351 const auto it = base->resolvedTypes.constFind(elementNameId);
352 if (it == base->resolvedTypes.constEnd()) {
353 return visibleQmlTypeByName(
354 base, base->stringAt(elementNameId),
355 typeLoader ? typeLoader : unit->engine->typeLoader());
358 return (*it)->type();
362 mutable QAtomicPointer<
const ProxyMetaObjects> proxyMetaObjects;
363 mutable QAtomicPointer<
const Enums> enums;
366 friend class QQmlRefCounted<QQmlTypePrivate>;
370 QString metaObjectName;
373 QString metaEnumScope;
377 template<
typename Ret,
typename Op,
typename Check>
378 static Ret doGetEnumOp(
const QQmlRefPointer<
const QQmlTypePrivate> &d,
379 QQmlTypeLoader *typeLoader, Op &&op, Check &&check,
bool *ok)
383 if (
const QQmlTypePrivate::Enums *enums = d->initEnums(typeLoader)) {
384 if (Ret rv = op(enums); check(rv)) {
395 const Enums *initEnums(QQmlTypeLoader *typeLoader)
const;
396 void insertEnums(Enums *enums,
const QMetaObject *metaObject)
const;
397 void insertEnumsFromPropertyCache(Enums *enums,
const QQmlPropertyCache::ConstPtr &cache)
const;
399 void createListOfPossibleConflictingItems(
const QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path)
const;
400 void createEnumConflictReport(
const QMetaObject *metaObject,
const QString &conflictingKey)
const;