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
103 return regType == QQmlType::CompositeType || regType == QQmlType::CompositeSingletonType;
106 bool isValueType()
const
108 return regType == QQmlType::CppType && !(typeId.flags() & QMetaType::PointerToQObject);
111 QQmlType resolveCompositeBaseType(QQmlTypeLoader *typeLoader)
const;
112 QQmlPropertyCache::ConstPtr compositePropertyCache(QQmlTypeLoader *typeLoader)
const;
114 struct QQmlCppTypeData
117 void (*newFunc)(
void *,
void *);
118 void *userdata =
nullptr;
119 QString noCreationReason;
120 QVariant (*createValueTypeFunc)(
const QJSValue &);
121 int parserStatusCast;
122 QObject *(*extFunc)(QObject *);
123 const QMetaObject *extMetaObject;
124 QQmlCustomParser *customParser;
125 QQmlAttachedPropertiesFunc attachedPropertiesFunc;
126 const QMetaObject *attachedPropertiesType;
127 int propertyValueSourceCast;
128 int propertyValueInterceptorCast;
130 bool registerEnumClassesUnscoped;
131 bool registerEnumsFromRelatedTypes;
132 bool constructValueType;
133 bool populateValueType;
136 struct QQmlSingletonTypeData
138 QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo;
139 QObject *(*extFunc)(QObject *);
140 const QMetaObject *extMetaObject;
149 QQmlCppTypeData *cppTypeData;
150 QQmlSingletonTypeData *singletonTypeData;
151 QUrl compositeTypeData;
152 QUrl javaScriptTypeData;
153 QUrl inlineComponentTypeData;
154 QMetaSequence sequentialContainerTypeData;
155 const char *interfaceTypeData;
157 static_assert(
sizeof(extraData) ==
sizeof(
void *));
159 QHashedString module;
164 QQmlType::RegistrationType regType;
165 QTypeRevision version;
166 QTypeRevision revision = QTypeRevision::zero();
167 const QMetaObject *baseMetaObject =
nullptr;
169 void setName(
const QString &uri,
const QString &element);
171 template<
typename String>
172 static int enumValue(
173 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
174 const String &name,
bool *ok)
176 const auto *rv = doGetEnumOp<
const int *>(
177 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
178 return enums->enums.value(name);
179 }, [](
const int *p) {
return !!p; }, ok);
180 return rv ? *rv : -1;
183 template<Enums::Scoping scoping,
typename String>
184 static int enumIndex(
185 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
186 const String &name,
bool *ok)
188 const auto *rv = doGetEnumOp<
const int *> (
189 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
190 if constexpr (scoping == Enums::Scoped)
191 return enums->scopedEnumIndex.value(name);
193 return enums->unscopedEnumIndex.value(name);
194 }, [](
const int *p) {
return !!p; }, ok);
195 return rv ? *rv : -1;
198 template<Enums::Scoping scoping,
typename String>
199 static int enumValue(
200 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
int index,
201 const String &name,
bool *ok)
203 const auto *rv = doGetEnumOp<
const int *>(
204 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
205 if constexpr (scoping == Enums::Scoped) {
206 Q_ASSERT(index > -1 && index < enums->scopedEnums.size());
207 return enums->scopedEnums.at(index)->value(name);
209 Q_ASSERT(index > -1 && index < enums->unscopedEnums.size());
210 return enums->unscopedEnums.at(index)->value(name);
212 }, [](
const int *p) {
return !!p; }, ok);
213 return rv ? *rv : -1;
216 template<Enums::Scoping scoping,
typename String1,
typename String2>
217 static int enumValue(
218 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
219 const String1 &scopedEnumName,
const String2 &name,
bool *ok)
221 const auto *rv = doGetEnumOp<
const int *>(
222 d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
223 const QStringHash<
int> *enumIndex;
224 const QList<QStringHash<
int> *> *_enums;
225 if constexpr (scoping == Enums::Scoped) {
226 enumIndex = &enums->scopedEnumIndex;
227 _enums = &enums->scopedEnums;
229 enumIndex = &enums->unscopedEnumIndex;
230 _enums = &enums->unscopedEnums;
233 const int *rv = enumIndex->value(scopedEnumName);
235 return static_cast<
int *>(
nullptr);
237 const int index = *rv;
238 Q_ASSERT(index > -1 && index < _enums->size());
239 return _enums->at(index)->value(name);
240 }, [](
const int *p) {
return !!p; }, ok);
241 return rv ? *rv : -1;
244 template<Enums::Scoping scoping>
245 static QString enumKey(
246 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
247 int index,
int value,
bool *ok)
249 return doGetEnumOp<QString>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
250 const QList<QStringHash<
int> *> *_enums;
251 if constexpr (scoping == Enums::Scoped)
252 _enums = &enums->scopedEnums;
254 _enums = &enums->unscopedEnums;
256 Q_ASSERT(index > -1 && index < _enums->size());
257 const auto hash = _enums->at(index);
258 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
259 if (it.value() == value)
260 return QString(it.key());
263 }, [](
const QString &s) {
return !s.isEmpty(); }, ok);
266 template<Enums::Scoping scoping>
267 static QStringList enumKeys(
268 const QQmlRefPointer<
const QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
269 int index,
int value,
bool *ok)
271 return doGetEnumOp<QStringList>(d, typeLoader, [&](
const QQmlTypePrivate::Enums *enums) {
272 const QList<QStringHash<
int> *> *_enums;
273 if constexpr (scoping == Enums::Scoped)
274 _enums = &enums->scopedEnums;
276 _enums = &enums->unscopedEnums;
278 Q_ASSERT(index > -1 && index < _enums->size());
280 const auto hash = _enums->at(index);
281 for (
auto it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
282 if (it.value() == value)
283 keys.append(QString(it.key()));
285 std::reverse(keys.begin(), keys.end());
287 }, [](
const QStringList &l) {
return !l.empty(); }, ok);
290 const QMetaObject *metaObject()
const
293 return metaObjectForValueType();
295 const QQmlTypePrivate::ProxyMetaObjects *proxies = init();
296 return proxies->data.isEmpty()
298 : proxies->data.constFirst().metaObject;
301 const QMetaObject *metaObjectForValueType()
const
303 Q_ASSERT(isValueType());
307 if (
const QMetaObject *extensionMetaObject = extraData.cppTypeData->extMetaObject) {
310 if (extensionMetaObject->metaType().flags() & QMetaType::IsGadget)
311 return extensionMetaObject;
314 if (baseMetaObject) {
317 if (baseMetaObject->metaType().flags() & QMetaType::IsGadget)
318 return baseMetaObject;
324 static QQmlType visibleQmlTypeByName(
325 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
326 const QString &elementName, QQmlTypeLoader *typeLoader)
330 return unit->typeNameCache->query<QQmlImport::AllowRecursion>(
331 elementName, typeLoader).type;
341 static QQmlType visibleQmlTypeByName(
342 const QV4::ExecutableCompilationUnit *unit,
int elementNameId,
343 QQmlTypeLoader *typeLoader =
nullptr)
345 const auto &base = unit->baseCompilationUnit();
346 const auto it = base->resolvedTypes.constFind(elementNameId);
347 if (it == base->resolvedTypes.constEnd()) {
348 return visibleQmlTypeByName(
349 base, base->stringAt(elementNameId),
350 typeLoader ? typeLoader : unit->engine->typeLoader());
353 return (*it)->type();
357 mutable QAtomicPointer<
const ProxyMetaObjects> proxyMetaObjects;
358 mutable QAtomicPointer<
const Enums> enums;
361 friend class QQmlRefCounted<QQmlTypePrivate>;
365 QString metaObjectName;
368 QString metaEnumScope;
372 template<
typename Ret,
typename Op,
typename Check>
373 static Ret doGetEnumOp(
const QQmlRefPointer<
const QQmlTypePrivate> &d,
374 QQmlTypeLoader *typeLoader, Op &&op, Check &&check,
bool *ok)
378 if (
const QQmlTypePrivate::Enums *enums = d->initEnums(typeLoader)) {
379 if (Ret rv = op(enums); check(rv)) {
390 const Enums *initEnums(QQmlTypeLoader *typeLoader)
const;
391 void insertEnums(Enums *enums,
const QMetaObject *metaObject)
const;
392 void insertEnumsFromPropertyCache(Enums *enums,
const QQmlPropertyCache::ConstPtr &cache)
const;
394 void createListOfPossibleConflictingItems(
const QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path)
const;
395 void createEnumConflictReport(
const QMetaObject *metaObject,
const QString &conflictingKey)
const;