12#include <QtCore/qcborarray.h>
13#include <QtCore/qcbormap.h>
14#include <QtCore/qfile.h>
15#include <QtCore/qjsondocument.h>
16#include <QtCore/qqueue.h>
29std::vector<std::unique_ptr<MetaTypePrivate>>
s_pool;
34 if (jsonValue.isArray())
36 if (jsonValue.isObject())
47 if (qualified != unqualified) {
67 metaObjects =
fromJson(
f.readAll(), &parseError);
70 <<
"Failed to parse JSON:" << parseError.
error
86 }
else if (metaObjects.
isMap()) {
89 error(
source) <<
"JSON is not an object or an array";
101 error(
types) <<
"Cannot open foreign types file";
109 <<
"Failed to parse JSON:" << parseError.
error
114 const QCborArray foreignObjectsArray = foreignMetaObjects.toArray();
138template<
typename String>
153 sortTypes(m_foreignTypes);
163 for (
const auto &
obj: m_types) {
165 const QString qualifiedClassName =
obj.qualifiedClassName().toString();
170 bool isSingleton =
false;
171 bool isExplicitlyUncreatable =
false;
172 bool isNamespace =
obj.kind() == MetaType::Kind::Namespace;
178 qmlElements.append(u
"QML_NAMED_ELEMENT("_s +
className + u
")"_s);
180 qmlElements.append(u
"QML_ANONYMOUS"_s);
182 qmlElements.append(u
"QML_NAMED_ELEMENT("_s +
value.toString() + u
")");
185 isExplicitlyUncreatable =
true;
187 qmlUncreatable = u
"QML_UNCREATABLE(\""_s +
value.toString() + u
"\")";
189 qmlAttached = u
"QML_ATTACHED("_s +
value.toString() + u
")";
194 if (qmlElements.isEmpty())
198 registrationHelper += u
"\nnamespace "_s + foreignClassName + u
"{\n Q_NAMESPACE\n"_s;
199 registrationHelper += spaces + u
"QML_FOREIGN_NAMESPACE(" + qualifiedClassName + u
")\n"_s;
201 registrationHelper += u
"\nstruct "_s + foreignClassName + u
"{\n Q_GADGET\n"_s;
202 registrationHelper += spaces + u
"QML_FOREIGN(" + qualifiedClassName + u
")\n"_s;
204 registrationHelper += spaces + qmlElements.join(u
"\n"_s) + u
"\n"_s;
206 registrationHelper += spaces + u
"QML_SINGLETON\n"_s;
207 if (isExplicitlyUncreatable) {
208 if (qmlUncreatable.isEmpty())
209 registrationHelper += spaces + uR
"(QML_UNCREATABLE(""))" + u"n";
211 registrationHelper += spaces + qmlUncreatable + u
"\n";
213 if (!qmlAttached.isEmpty())
214 registrationHelper += spaces + qmlAttached + u
"\n";
215 registrationHelper += u
"}";
217 registrationHelper += u
";";
218 registrationHelper += u
"\n";
220 return registrationHelper;
223MetaTypesJsonProcessor::PreProcessResult MetaTypesJsonProcessor::preProcess(
224 const MetaType &classDef, PopulateMode populateMode)
232 RegistrationMode
mode = NoRegistration;
233 bool isSelfExtendingValueType =
false;
234 bool hasJavaScriptExtension =
false;
235 bool isRootObject =
false;
236 bool isSequence =
false;
238 for (
const ClassInfo &classInfo : classDef.classInfos()) {
240 foreign = classInfo.value;
242 aliases.append(classInfo.value);
244 hasJavaScriptExtension = (classInfo.value ==
S_TRUE);
245 else if (classInfo.name ==
S_EXTENDED && classDef.kind() == MetaType::Kind::Gadget)
246 isSelfExtendingValueType = classInfo.value == classDef.className();
247 else if (classInfo.name ==
S_ROOT)
248 isRootObject = (classInfo.value ==
S_TRUE);
251 else if (populateMode == PopulateMode::Yes && classInfo.name ==
S_ELEMENT) {
252 switch (classDef.kind()) {
253 case MetaType::Kind::Object:
254 mode = ObjectRegistration;
256 case MetaType::Kind::Gadget:
257 mode = GadgetRegistration;
259 case MetaType::Kind::Namespace:
260 mode = NamespaceRegistration;
264 <<
"Not registering a classInfo which is neither an object,"
265 <<
"nor a gadget, nor a namespace:"
266 << classInfo.name.toString();
272 return PreProcessResult {
274 (!isRootObject && (isSequence || isSelfExtendingValueType || hasJavaScriptExtension))
285 return string.visit([
seed](
auto view) {
297 return a.qualifiedClassName() <
b.qualifiedClassName();
300void MetaTypesJsonProcessor::addRelatedTypes()
302 QSet<QAnyStringView> processedRelatedNativeNames;
303 QSet<QAnyStringView> processedRelatedJavaScriptNames;
304 QSet<QAnyStringView> unresolvedForeignNames;
305 QQueue<MetaType> typeQueue;
306 typeQueue.append(m_types);
308 const auto addRelatedName
311 m_types, m_foreignTypes, relatedName,
namespaces)) {
313 if (!related.javaScript.isEmpty())
314 processedRelatedJavaScriptNames.insert(related.javaScript.qualifiedClassName());
316 if (!related.native.isEmpty())
317 processedRelatedNativeNames.insert(related.native.qualifiedClassName());
327 if (
type.inputFile().isEmpty())
328 processedRelatedJavaScriptNames.insert(qualifiedName);
330 processedRelatedNativeNames.insert(qualifiedName);
335 addRelatedType(
type);
340 unresolvedForeignNames.insert(foreign);
348 for (
const MetaType &foreignType :
std::as_const(m_foreignTypes)) {
349 bool seenQmlPrefix =
false;
353 addRelatedType(foreignType);
354 seenQmlPrefix =
true;
358 if (!addRelatedName(foreign,
namespaces(foreignType)))
359 unresolvedForeignNames.insert(foreign);
365 const auto addReference = [&](
const MetaType &
type, QSet<QAnyStringView> *processedRelatedNames,
370 m_referencedTypes.
append(qualifiedName);
372 processedRelatedNames->insert(qualifiedName);
374 if (processedRelatedNames->size() ==
size)
377 typeQueue.enqueue(
type);
383 const auto insert = std::lower_bound(
384 m_types.constBegin(), m_types.constEnd(),
type,
391 m_includes.
append(inputFile);
394 const auto remove = std::equal_range(
395 m_foreignTypes.constBegin(), m_foreignTypes.constEnd(),
type,
399 m_foreignTypes.erase(
it);
405 const auto addInterface
409 if (!
other.native.isEmpty()) {
410 addReference(
other.native, &processedRelatedNativeNames,
other.nativeOrigin);
416 unresolvedForeignNames.insert(
typeName);
419 processedRelatedNativeNames.insert(
typeName);
427 addReference(
other.native, &processedRelatedNativeNames,
other.nativeOrigin);
428 addReference(
other.javaScript, &processedRelatedJavaScriptNames,
other.javaScriptOrigin);
440 for (
const Enum &enumerator :
other.native.enums()) {
441 if (enumerator.name != enumName && enumerator.alias != enumName)
444 addReference(
other.native, &processedRelatedNativeNames,
other.nativeOrigin);
446 other.javaScript, &processedRelatedJavaScriptNames,
447 other.javaScriptOrigin);
465 processedRelatedNativeNames.insert(
typeName);
466 processedRelatedJavaScriptNames.insert(
typeName);
475 other.native, &processedRelatedNativeNames,
other.nativeOrigin);
477 other.javaScript, &processedRelatedJavaScriptNames,
other.javaScriptOrigin);
489 bool warnAboutSupers =
context.kind() != MetaType::Kind::Gadget;
491 QList<QAnyStringView> missingSupers;
499 warnAboutSupers =
false;
507 && !unresolvedForeignNames.contains(
typeName)
512 processedRelatedNativeNames.insert(
typeName);
513 processedRelatedJavaScriptNames.insert(
typeName);
521 if (!resolved.type.isEmpty())
533 if (!resolved.type.isEmpty())
538 if (!resolved.type.isEmpty())
548 if (!resolved.type.isEmpty())
573 while (!typeQueue.isEmpty()) {
576 const MetaType classDef = typeQueue.dequeue();
590 m_foreignTypes, {}, foreignClassName,
namespaces)) {
592 const QList<QAnyStringView> otherNamespaces
594 addSupers(
other, otherNamespaces);
595 addProperties(
other, otherNamespaces);
596 addMethods(
other, otherNamespaces);
597 addEnums(
other, otherNamespaces);
600 if (addRelation(classDef,
obj, otherNamespaces))
606 unresolvedForeign = foreignClassName;
610 if (!unresolvedForeign.isEmpty() && !isPrimitive(unresolvedForeign)) {
613 <<
"is declared as foreign type, but cannot be found.";
623void MetaTypesJsonProcessor::sortTypes(QVector<MetaType> &
types)
630 if (!m_privateIncludes)
647 const MetaType classDef(cls.toMap(), include);
649 const PreProcessResult preprocessed = preProcess(classDef, PopulateMode::Yes);
650 switch (preprocessed.mode) {
651 case NamespaceRegistration:
652 case GadgetRegistration:
653 case ObjectRegistration: {
661 <<
"Class" << classDef.qualifiedClassName()
662 <<
"is declared in" << include <<
"which appears not to be a header."
663 <<
"The compilation of its registration to QML may fail.";
665 m_includes.
append(include);
666 m_types.emplaceBack(classDef);
670 m_foreignTypes.emplaceBack(classDef);
674 if (!preprocessed.foreignPrimitive.isEmpty()) {
675 m_primitiveTypes.
emplaceBack(preprocessed.foreignPrimitive);
676 m_primitiveTypes.
append(preprocessed.primitiveAliases);
686 const MetaType classDef(cls.toMap(), include);
687 PreProcessResult preprocessed = preProcess(classDef, PopulateMode::No);
689 m_foreignTypes.emplaceBack(classDef);
690 if (!preprocessed.foreignPrimitive.isEmpty()) {
691 m_primitiveTypes.
emplaceBack(preprocessed.foreignPrimitive);
692 m_primitiveTypes.
append(preprocessed.primitiveAliases);
700 return it == cbor.
end()
778 if (
type ==
"QQmlV4FunctionPtr"_L1 ||
type ==
"QQmlV4Function*"_L1)
797 , inputFile(inputFile)
803 for (
const QCborValue &superClass : cborSuperClasses)
807 for (
const QCborValue &classInfo : cborClassInfos)
825 sigs.emplace_back(sig.toMap(),
false);
828 for (
const QCborValue &constructor : cborConstructors)
832 for (
const QCborValue &enumerator : cborEnums)
833 enums.emplace_back(enumerator.toMap());
static JNINativeMethod methods[]
constexpr qsizetype size() const noexcept
Returns the size of this string view, in the encoding's code points.
QString toString() const
Returns a deep copy of this string view's data as a QString.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
iterator end()
Returns a map iterator representing an element just past the last element in the map.
iterator find(qint64 key)
\inmodule QtCore\reentrant
QCborArray toArray() const
bool isArray() const
Returns true if this QCborValue is of the array type.
static QCborValue fromJsonValue(const QJsonValue &v)
Converts the JSON value contained in v into its corresponding CBOR value and returns it.
bool isMap() const
Returns true if this QCborValue is of the map type.
\inmodule QtCore\reentrant
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
iterator erase(const_iterator begin, const_iterator end)
reference emplaceBack(Args &&... args)
void append(parameter_type t)
const_iterator constEnd() const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static constexpr QTypeRevision fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given value.
T & emplace_back(Args &&...args)
cache insert(employee->id(), employee)
QSet< QString >::iterator it
QList< QVariant > arguments
QAnyStringView toStringView(const QCborValue &value)
bool endsWith(QAnyStringView whole, QLatin1StringView part)
bool startsWith(QAnyStringView whole, QLatin1StringView part)
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError * error
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 QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum GLenum * types
GLsizei GLsizei GLchar * source
static QStringList aliases(const QQmlJSScope::ConstPtr &scope)
QAnyStringView interfaceName(const Interface &iface)
QDebug warning(QAnyStringView fileName, int lineNumber)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
static void split(QT_FT_Vector *b)
QLatin1StringView QLatin1String
ReturnedValue read(const char *data)
const char className[16]
[1]
gzip write("uncompressed data")
settings remove("monkey")
obj metaObject() -> className()
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
value toMap().value(key)
[3]
std::vector< Method > Container
Argument::Container arguments
bool isJavaScriptFunction
\inmodule QtCore\reentrant
QString errorString() const
\variable QJsonParseError::error
\inmodule QtCore \reentrant
static FoundType findType(const QVector< MetaType > &types, const QVector< MetaType > &foreign, const QAnyStringView &name, const QList< QAnyStringView > &namespaces)
QT_BEGIN_NAMESPACE bool toBool(const QString &str)