diff options
-rw-r--r-- | mkspecs/features/metatypes.prf | 34 | ||||
-rw-r--r-- | src/tools/moc/collectjson.cpp | 103 | ||||
-rw-r--r-- | src/tools/moc/collectjson.h | 42 | ||||
-rw-r--r-- | src/tools/moc/main.cpp | 41 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 200 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 12 | ||||
-rw-r--r-- | src/tools/moc/moc.pri | 7 | ||||
-rw-r--r-- | tests/auto/tools/moc/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/tools/moc/allmocs_baseline_in.json | 2608 | ||||
-rw-r--r-- | tests/auto/tools/moc/moc.pro | 49 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 53 |
11 files changed, 3144 insertions, 6 deletions
diff --git a/mkspecs/features/metatypes.prf b/mkspecs/features/metatypes.prf new file mode 100644 index 0000000000..a0a548eeb2 --- /dev/null +++ b/mkspecs/features/metatypes.prf @@ -0,0 +1,34 @@ +qtPrepareTool(MOC_COLLECT_JSON, moc) + +QMAKE_MOC_OPTIONS += --output-json + +moc_json_header.input = HEADERS +moc_json_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}.json +moc_json_header.CONFIG = no_link moc_verify +moc_json_header.depends = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)} +moc_json_header.commands = $$escape_expand(\\n) # force creation of rule +moc_json_header.variable_out = MOC_JSON_FILES + +moc_json_source.input = SOURCES +moc_json_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}.json +moc_json_source.CONFIG = no_link moc_verify +moc_json_source.depends = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} +moc_json_source.commands = $$escape_expand(\\n) # force creation of rule +moc_json_source.variable_out = MOC_JSON_FILES + +MOC_COLLECT_JSON_OUTPUT = $$lower($$basename(TARGET))_metatypes.json + +moc_collect_json.CONFIG += no_link combine +moc_collect_json.commands = $$MOC_COLLECT_JSON --collect-json -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} +moc_collect_json.input = MOC_JSON_FILES +moc_collect_json.output = $$MOC_COLLECT_JSON_OUTPUT +moc_collect_json.name = Collect moc JSON output into central file + +install_metatypes { + do_install.path = $$[QT_INSTALL_LIBS]/metatypes + do_install.files = $$OUT_PWD/$$MOC_COLLECT_JSON_OUTPUT + prefix_build: INSTALLS += do_install + else: COPIES += do_install +} + +QMAKE_EXTRA_COMPILERS += moc_collect_json moc_json_header moc_json_source diff --git a/src/tools/moc/collectjson.cpp b/src/tools/moc/collectjson.cpp new file mode 100644 index 0000000000..4029bca5e9 --- /dev/null +++ b/src/tools/moc/collectjson.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qfile.h> +#include <qjsonarray.h> +#include <qjsondocument.h> +#include <qjsonobject.h> +#include <qhashfunctions.h> +#include <qstringlist.h> +#include <cstdlib> + +static bool readFromDevice(QIODevice *device, QJsonArray *allMetaObjects) +{ + const QByteArray contents = device->readAll(); + if (contents.isEmpty()) + return true; + + QJsonParseError error {}; + QJsonDocument metaObjects = QJsonDocument::fromJson(contents, &error); + if (error.error != QJsonParseError::NoError) { + fprintf(stderr, "%s at %d\n", error.errorString().toUtf8().constData(), error.offset); + return false; + } + + allMetaObjects->append(metaObjects.object()); + return true; +} + +int collectJson(const QStringList &jsonFiles, const QString &outputFile) +{ + qSetGlobalQHashSeed(0); + + QFile output; + if (outputFile.isEmpty()) { + if (!output.open(stdout, QIODevice::WriteOnly)) { + fprintf(stderr, "Error opening stdout for writing\n"); + return EXIT_FAILURE; + } + } else { + output.setFileName(outputFile); + if (!output.open(QIODevice::WriteOnly)) { + fprintf(stderr, "Error opening %s for writing\n", qPrintable(outputFile)); + return EXIT_FAILURE; + } + } + + QJsonArray allMetaObjects; + if (jsonFiles.isEmpty()) { + QFile f; + if (!f.open(stdin, QIODevice::ReadOnly)) { + fprintf(stderr, "Error opening stdin for reading\n"); + return EXIT_FAILURE; + } + + if (!readFromDevice(&f, &allMetaObjects)) { + fprintf(stderr, "Error parsing data from stdin\n"); + return EXIT_FAILURE; + } + } + + for (const QString &jsonFile: jsonFiles) { + QFile f(jsonFile); + if (!f.open(QIODevice::ReadOnly)) { + fprintf(stderr, "Error opening %s for reading\n", qPrintable(jsonFile)); + return EXIT_FAILURE; + } + + if (!readFromDevice(&f, &allMetaObjects)) { + fprintf(stderr, "Error parsing %s\n", qPrintable(jsonFile)); + return EXIT_FAILURE; + } + } + + QJsonDocument doc(allMetaObjects); + output.write(doc.toJson()); + + return EXIT_SUCCESS; +} diff --git a/src/tools/moc/collectjson.h b/src/tools/moc/collectjson.h new file mode 100644 index 0000000000..9d329c96ca --- /dev/null +++ b/src/tools/moc/collectjson.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COLLECTJSON_H +#define COLLECTJSON_H + +#include <qglobal.h> +#include <qstring.h> +#include <qstringlist.h> + +QT_BEGIN_NAMESPACE + +int collectJson(const QStringList &jsonFiles, const QString &outputFile); + +QT_END_NAMESPACE + +#endif // COLLECTOJSON_H diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index ba559b572f..4aa040a9bb 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -30,6 +30,7 @@ #include "preprocessor.h" #include "moc.h" #include "outputrevision.h" +#include "collectjson.h" #include <qfile.h> #include <qfileinfo.h> @@ -37,10 +38,12 @@ #include <stdio.h> #include <stdlib.h> #include <ctype.h> +#include <errno.h> #include <qcoreapplication.h> #include <qcommandlineoption.h> #include <qcommandlineparser.h> +#include <qscopedpointer.h> QT_BEGIN_NAMESPACE @@ -77,6 +80,10 @@ void error(const char *msg = "Invalid argument") fprintf(stderr, "moc: %s\n", msg); } +struct ScopedPointerFileCloser +{ + static inline void cleanup(FILE *handle) { if (handle) fclose(handle); } +}; static inline bool hasNext(const Symbols &symbols, int i) { return (i < symbols.size()); } @@ -293,10 +300,20 @@ int runMoc(int argc, char **argv) ignoreConflictsOption.setDescription(QStringLiteral("Ignore all options that conflict with compilers, like -pthread conflicting with moc's -p option.")); parser.addOption(ignoreConflictsOption); + QCommandLineOption jsonOption(QStringLiteral("output-json")); + jsonOption.setDescription(QStringLiteral("In addition to generating C++ code, create a machine-readable JSON file in a file that matches the output file and an extra .json extension.")); + parser.addOption(jsonOption); + + QCommandLineOption collectOption(QStringLiteral("collect-json")); + collectOption.setDescription(QStringLiteral("Instead of processing C++ code, collect previously generated JSON output into a single file.")); + parser.addOption(collectOption); + parser.addPositionalArgument(QStringLiteral("[header-file]"), QStringLiteral("Header file to read from, otherwise stdin.")); parser.addPositionalArgument(QStringLiteral("[@option-file]"), QStringLiteral("Read additional options from option-file.")); + parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"), + QStringLiteral("MOC generated json output")); const QStringList arguments = argumentsFromCommandLineAndFile(app.arguments()); if (arguments.isEmpty()) @@ -305,6 +322,10 @@ int runMoc(int argc, char **argv) parser.process(arguments); const QStringList files = parser.positionalArguments(); + output = parser.value(outputOption); + if (parser.isSet(collectOption)) + return collectJson(files, output); + if (files.count() > 1) { error(qPrintable(QLatin1String("Too many input files specified: '") + files.join(QLatin1String("' '")) + QLatin1Char('\''))); parser.showHelp(1); @@ -313,7 +334,6 @@ int runMoc(int argc, char **argv) } const bool ignoreConflictingOptions = parser.isSet(ignoreConflictsOption); - output = parser.value(outputOption); pp.preprocessOnly = parser.isSet(preprocessOption); if (parser.isSet(noIncludeOption)) { moc.noInclude = true; @@ -485,6 +505,8 @@ int runMoc(int argc, char **argv) // 3. and output meta object code + QScopedPointer<FILE, ScopedPointerFileCloser> jsonOutput; + if (output.size()) { // output file specified #if defined(_MSC_VER) if (_wfopen_s(&out, reinterpret_cast<const wchar_t *>(output.utf16()), L"w") != 0) @@ -496,6 +518,21 @@ int runMoc(int argc, char **argv) fprintf(stderr, "moc: Cannot create %s\n", QFile::encodeName(output).constData()); return 1; } + + if (parser.isSet(jsonOption)) { + const QString jsonOutputFileName = output + QLatin1String(".json"); + FILE *f; +#if defined(_MSC_VER) + if (_wfopen_s(&f, reinterpret_cast<const wchar_t *>(jsonOutputFileName.utf16()), L"w") != 0) +#else + f = fopen(QFile::encodeName(jsonOutputFileName).constData(), "w"); + if (!f) +#endif + fprintf(stderr, "moc: Cannot create JSON output file %s. %s\n", + QFile::encodeName(jsonOutputFileName).constData(), + strerror(errno)); + jsonOutput.reset(f); + } } else { // use stdout out = stdout; } @@ -506,7 +543,7 @@ int runMoc(int argc, char **argv) if (moc.classList.isEmpty()) moc.note("No relevant classes found. No output generated."); else - moc.generate(out); + moc.generate(out, jsonOutput.data()); } if (output.size()) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 50946443be..8cc605fd8a 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -35,6 +35,7 @@ #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> #include <QtCore/qdir.h> +#include <QtCore/qjsondocument.h> // for normalizeTypeInternal #include <private/qmetaobject_moc_p.h> @@ -999,7 +1000,7 @@ static QByteArrayList requiredQtContainers(const QVector<ClassDef> &classes) return required; } -void Moc::generate(FILE *out) +void Moc::generate(FILE *out, FILE *jsonOutput) { QByteArray fn = filename; int i = filename.length()-1; @@ -1062,6 +1063,23 @@ void Moc::generate(FILE *out) fprintf(out, "QT_WARNING_POP\n"); fprintf(out, "QT_END_MOC_NAMESPACE\n"); + + if (jsonOutput) { + QJsonObject mocData; + mocData[QLatin1String("outputRevision")] = mocOutputRevision; + mocData[QLatin1String("inputFile")] = QLatin1String(fn.constData()); + + QJsonArray classesJsonFormatted; + + for (const ClassDef &cdef: qAsConst(classList)) + classesJsonFormatted.append(cdef.toJson()); + + if (!classesJsonFormatted.isEmpty()) + mocData[QLatin1String("classes")] = classesJsonFormatted; + + QJsonDocument jsonDoc(mocData); + fputs(jsonDoc.toJson().constData(), jsonOutput); + } } void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) @@ -1784,6 +1802,186 @@ void Moc::checkProperties(ClassDef *cdef) } } +QJsonObject ClassDef::toJson() const +{ + QJsonObject cls; + cls[QLatin1String("className")] = QString::fromUtf8(classname.constData()); + cls[QLatin1String("qualifiedClassName")] = QString::fromUtf8(qualified.constData()); + + QJsonArray classInfos; + for (const auto &info: qAsConst(classInfoList)) { + QJsonObject infoJson; + infoJson[QLatin1String("name")] = QString::fromUtf8(info.name); + infoJson[QLatin1String("value")] = QString::fromUtf8(info.value); + classInfos.append(infoJson); + } + + if (classInfos.size()) + cls[QLatin1String("classInfos")] = classInfos; + + const auto appendFunctions = [&cls](const QString &type, const QVector<FunctionDef> &funcs) { + QJsonArray jsonFuncs; + + for (const FunctionDef &fdef: funcs) + jsonFuncs.append(fdef.toJson()); + + if (!jsonFuncs.isEmpty()) + cls[type] = jsonFuncs; + }; + + appendFunctions(QLatin1String("signals"), signalList); + appendFunctions(QLatin1String("slots"), slotList); + appendFunctions(QLatin1String("constructors"), constructorList); + appendFunctions(QLatin1String("methods"), methodList); + + QJsonArray props; + + for (const PropertyDef &propDef: qAsConst(propertyList)) + props.append(propDef.toJson()); + + if (!props.isEmpty()) + cls[QLatin1String("properties")] = props; + + if (hasQGadget) + cls[QLatin1String("gadget")] = true; + + QJsonArray superClasses; + + for (const auto &super: qAsConst(superclassList)) { + const auto name = super.first; + const auto access = super.second; + QJsonObject superCls; + superCls[QLatin1String("name")] = QString::fromUtf8(name); + FunctionDef::accessToJson(&superCls, access); + superClasses.append(superCls); + } + + if (!superClasses.isEmpty()) + cls[QLatin1String("superClasses")] = superClasses; + + QJsonArray enums; + for (const EnumDef &enumDef: qAsConst(enumList)) + enums.append(enumDef.toJson(*this)); + if (!enums.isEmpty()) + cls[QLatin1String("enums")] = enums; + + QJsonArray ifaces; + for (const QVector<Interface> &ifaceList: interfaceList) { + QJsonArray jsonList; + for (const Interface &iface: ifaceList) { + QJsonObject ifaceJson; + ifaceJson[QLatin1String("id")] = QString::fromUtf8(iface.interfaceId); + ifaceJson[QLatin1String("className")] = QString::fromUtf8(iface.className); + jsonList.append(ifaceJson); + } + ifaces.append(jsonList); + } + if (!ifaces.isEmpty()) + cls[QLatin1String("interfaces")] = ifaces; + + return cls; +} + +QJsonObject FunctionDef::toJson() const +{ + QJsonObject fdef; + fdef[QLatin1String("name")] = QString::fromUtf8(name); + if (!tag.isEmpty()) + fdef[QLatin1String("tag")] = QString::fromUtf8(tag); + fdef[QLatin1String("returnType")] = QString::fromUtf8(normalizedType); + QJsonArray args; + for (const ArgumentDef &arg: arguments) + args.append(arg.toJson()); + + if (!args.isEmpty()) + fdef[QLatin1String("arguments")] = args; + + accessToJson(&fdef, access); + + if (revision > 0) + fdef[QLatin1String("revision")] = revision; + + return fdef; +} + +void FunctionDef::accessToJson(QJsonObject *obj, FunctionDef::Access acs) +{ + switch (acs) { + case Private: (*obj)[QLatin1String("access")] = QLatin1String("private"); break; + case Public: (*obj)[QLatin1String("access")] = QLatin1String("public"); break; + case Protected: (*obj)[QLatin1String("access")] = QLatin1String("protected"); break; + } +} + +QJsonObject ArgumentDef::toJson() const +{ + QJsonObject arg; + arg[QLatin1String("type")] = QString::fromUtf8(normalizedType); + if (!name.isEmpty()) + arg[QLatin1String("name")] = QString::fromUtf8(name); + return arg; +} + +QJsonObject PropertyDef::toJson() const +{ + QJsonObject prop; + prop[QLatin1String("name")] = QString::fromUtf8(name); + prop[QLatin1String("type")] = QString::fromUtf8(type); + + const auto jsonify = [&prop](const char *str, const QByteArray &member) { + if (!member.isEmpty()) + prop[QLatin1String(str)] = QString::fromUtf8(member); + }; + + jsonify("member", member); + jsonify("read", read); + jsonify("write", write); + jsonify("reset", reset); + jsonify("notify", notify); + jsonify("privateClass", inPrivateClass); + + const auto jsonifyBoolOrString = [&prop](const char *str, const QByteArray &boolOrString) { + QJsonValue value; + if (boolOrString == "true") + value = true; + else if (boolOrString == "false") + value = false; + else + value = QString::fromUtf8(boolOrString); // function name to query at run-time + prop[QLatin1String(str)] = value; + }; + + jsonifyBoolOrString("designable", designable); + jsonifyBoolOrString("scriptable", scriptable); + jsonifyBoolOrString("stored", stored); + jsonifyBoolOrString("user", user); + + prop[QLatin1String("constant")] = constant; + prop[QLatin1String("final")] = final; + + if (revision > 0) + prop[QLatin1String("revision")] = revision; + + return prop; +} + +QJsonObject EnumDef::toJson(const ClassDef &cdef) const +{ + QJsonObject def; + def[QLatin1String("name")] = QString::fromUtf8(name); + if (!enumName.isEmpty()) + def[QLatin1String("alias")] = QString::fromUtf8(enumName); + def[QLatin1String("isFlag")] = cdef.enumDeclarations.value(name); + def[QLatin1String("isClass")] = isEnumClass; + + QJsonArray valueArr; + for (const QByteArray &value: values) + valueArr.append(QString::fromUtf8(value)); + if (!valueArr.isEmpty()) + def[QLatin1String("values")] = valueArr; + + return def; +} QT_END_NAMESPACE diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index bb1c9501fe..687ea2552f 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -61,6 +61,7 @@ struct Type }; Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE); +struct ClassDef; struct EnumDef { QByteArray name; @@ -68,6 +69,7 @@ struct EnumDef QVector<QByteArray> values; bool isEnumClass; // c++11 enum class EnumDef() : isEnumClass(false) {} + QJsonObject toJson(const ClassDef &cdef) const; }; Q_DECLARE_TYPEINFO(EnumDef, Q_MOVABLE_TYPE); @@ -78,6 +80,8 @@ struct ArgumentDef QByteArray rightType, normalizedType, name; QByteArray typeNameForCast; // type name to be used in cast from void * in metacall bool isDefault; + + QJsonObject toJson() const; }; Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE); @@ -111,6 +115,9 @@ struct FunctionDef bool isConstructor = false; bool isDestructor = false; bool isAbstract = false; + + QJsonObject toJson() const; + static void accessToJson(QJsonObject *obj, Access acs); }; Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE); @@ -130,6 +137,8 @@ struct PropertyDef int revision = 0; bool constant = false; bool final = false; + + QJsonObject toJson() const; }; Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE); @@ -183,6 +192,7 @@ struct ClassDef : BaseDef { bool hasQObject = false; bool hasQGadget = false; + QJsonObject toJson() const; }; Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE); @@ -215,7 +225,7 @@ public: QMap<QString, QJsonArray> metaArgs; void parse(); - void generate(FILE *out); + void generate(FILE *out, FILE *jsonOutput); bool parseClassHead(ClassDef *def); inline bool inClass(const ClassDef *def) const { diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri index 90839a445b..278d5607cd 100644 --- a/src/tools/moc/moc.pri +++ b/src/tools/moc/moc.pri @@ -10,9 +10,12 @@ HEADERS = $$PWD/moc.h \ $$PWD/utils.h \ $$PWD/generator.h \ $$PWD/outputrevision.h \ - $$PWD/cbordevice.h + $$PWD/cbordevice.h \ + $$PWD/collectjson.h + SOURCES = $$PWD/moc.cpp \ $$PWD/preprocessor.cpp \ $$PWD/generator.cpp \ $$PWD/parser.cpp \ - $$PWD/token.cpp + $$PWD/token.cpp \ + $$PWD/collectjson.cpp diff --git a/tests/auto/tools/moc/.gitignore b/tests/auto/tools/moc/.gitignore index 86a604a776..59a275bc62 100644 --- a/tests/auto/tools/moc/.gitignore +++ b/tests/auto/tools/moc/.gitignore @@ -1 +1,2 @@ tst_moc +allmocs.json diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json new file mode 100644 index 0000000000..bde5a1c52b --- /dev/null +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -0,0 +1,2608 @@ +[ + { + "classes": [ + { + "className": "MyBooooooostishClass", + "qualifiedClassName": "MyBooooooostishClass", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "mySlot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "no-keywords.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Task87883", + "qualifiedClassName": "Task87883", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "task87883.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "IfdefedClass", + "qualifiedClassName": "IfdefedClass", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "c-comments.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "BackslashNewlines", + "qualifiedClassName": "BackslashNewlines", + "slots": [ + { + "access": "public", + "name": "works", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "backslash-newlines.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "OldStyleCast", + "qualifiedClassName": "OldStyleCast", + "slots": [ + { + "access": "public", + "name": "foo", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + }, + { + "type": "int*" + }, + { + "type": "const int*" + }, + { + "type": "volatile int*" + }, + { + "type": "const int*volatile*" + } + ], + "name": "bar", + "returnType": "int" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + }, + { + "type": "QObject*const" + } + ], + "name": "slot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "oldstyle-casts.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "SlotsWithVoidTemplateTest", + "qualifiedClassName": "SlotsWithVoidTemplateTest", + "signals": [ + { + "access": "public", + "arguments": [ + { + "type": "TestTemplate<void>" + } + ], + "name": "mySignal", + "returnType": "void" + }, + { + "access": "public", + "name": "myVoidSignal", + "returnType": "void" + }, + { + "access": "public", + "name": "myVoidSignal2", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "dummySlot", + "returnType": "void" + }, + { + "access": "public", + "name": "dummySlot2", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "TestTemplate<void>" + } + ], + "name": "anotherSlot", + "returnType": "void" + }, + { + "access": "public", + "name": "mySlot", + "returnType": "TestTemplate<void>" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "slots-with-void-template.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "InvokableBeforeReturnType", + "methods": [ + { + "access": "public", + "name": "foo", + "returnType": "const char*" + } + ], + "qualifiedClassName": "InvokableBeforeReturnType", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "InvokableBeforeInline", + "methods": [ + { + "access": "public", + "name": "foo", + "returnType": "void" + }, + { + "access": "public", + "name": "bar", + "returnType": "void" + } + ], + "qualifiedClassName": "InvokableBeforeInline", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "qinvokable.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Bar", + "enums": [ + { + "alias": "Flag", + "isClass": false, + "isFlag": true, + "name": "Flags", + "values": [ + "Read", + "Write" + ] + } + ], + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "flags", + "read": "flags", + "scriptable": true, + "stored": true, + "type": "Flags", + "user": false, + "write": "setFlags" + } + ], + "qualifiedClassName": "Foo::Bar", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Baz", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "flags", + "read": "flags", + "scriptable": true, + "stored": true, + "type": "Foo::Bar::Flags", + "user": false, + "write": "setFlags" + }, + { + "constant": false, + "designable": true, + "final": false, + "name": "flagsList", + "read": "flagsList", + "scriptable": true, + "stored": true, + "type": "QList<Foo::Bar::Flags>", + "user": false, + "write": "setFlagsList" + } + ], + "qualifiedClassName": "Foo::Baz", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "namespaced-flags.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Foo", + "qualifiedClassName": "BBB::Foo", + "signals": [ + { + "access": "public", + "arguments": [ + { + "type": "QList<QList<int> >" + } + ], + "name": "foo", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QList<QList<int> >" + } + ], + "name": "foo2", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QList< ::AAA::BaseA*>" + } + ], + "name": "bar", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QList< ::AAA::BaseA*>" + } + ], + "name": "bar2", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QList<const ::AAA::BaseA*>" + } + ], + "name": "bar3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + }, + { + "access": "public", + "name": "::AAA::BaseA" + } + ] + } + ], + "inputFile": "trigraphs.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "classInfos": [ + { + "name": "Test", + "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\x53" + }, + { + "name": "Test2", + "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\123" + }, + { + "name": "Test3", + "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nb" + } + ], + "className": "StringLiterals", + "qualifiedClassName": "StringLiterals", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "escapes-in-string-literals.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "CStyleEnums", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "Baz", + "values": [ + "Foo", + "Bar" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "Baz2", + "values": [ + "Foo2", + "Bar2" + ] + } + ], + "gadget": true, + "qualifiedClassName": "CStyleEnums" + } + ], + "inputFile": "cstyle-enums.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "TestQPrivateSlots", + "methods": [ + { + "access": "private", + "name": "method1", + "returnType": "void" + } + ], + "qualifiedClassName": "TestQPrivateSlots", + "slots": [ + { + "access": "private", + "name": "_q_privateslot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "qprivateslots.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "GadgetWithNoEnums", + "gadget": true, + "qualifiedClassName": "GadgetWithNoEnums" + }, + { + "className": "DerivedGadgetWithEnums", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "FooEnum", + "values": [ + "FooValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "DerivedGadgetWithEnums", + "superClasses": [ + { + "access": "public", + "name": "GadgetWithNoEnums" + } + ] + } + ], + "inputFile": "gadgetwithnoenums.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "DirInIncludePath", + "interfaces": [ + [ + { + "className": "MyInterface", + "id": "\"MyInterface\"" + } + ] + ], + "qualifiedClassName": "DirInIncludePath", + "superClasses": [ + { + "access": "public", + "name": "QObject" + }, + { + "access": "public", + "name": "MyInterface" + } + ] + } + ], + "inputFile": "dir-in-include-path.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "SingleFunctionKeywordBeforeReturnType", + "qualifiedClassName": "SingleFunctionKeywordBeforeReturnType", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "mySlot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "SingleFunctionKeywordBeforeInline", + "qualifiedClassName": "SingleFunctionKeywordBeforeInline", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "mySlot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "SingleFunctionKeywordAfterInline", + "qualifiedClassName": "SingleFunctionKeywordAfterInline", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "mySlot", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "single_function_keyword.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Task192552", + "qualifiedClassName": "Task192552", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "task192552.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "InlineSlotsWithThrowDeclaration", + "qualifiedClassName": "InlineSlotsWithThrowDeclaration", + "slots": [ + { + "access": "public", + "name": "a", + "returnType": "void" + }, + { + "access": "public", + "name": "b", + "returnType": "void" + }, + { + "access": "public", + "name": "c", + "returnType": "void" + }, + { + "access": "public", + "name": "d", + "returnType": "void" + }, + { + "access": "public", + "name": "e", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "task189996.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "TestObject", + "qualifiedClassName": "NS_A::NS_B::TestObject", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "TestMain", + "qualifiedClassName": "NS_A::NS_Main::TestMain", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "task234909.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "TypenameWithUnsigned", + "qualifiedClassName": "TypenameWithUnsigned", + "slots": [ + { + "access": "public", + "arguments": [ + { + "type": "uint" + } + ], + "name": "a", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "u", + "type": "uint" + } + ], + "name": "b", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "uint*" + } + ], + "name": "c", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "p", + "type": "uint*" + } + ], + "name": "d", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "uint&" + } + ], + "name": "e", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "r", + "type": "uint&" + } + ], + "name": "f", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "unsigned1" + } + ], + "name": "g", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "u1", + "type": "unsigned1" + } + ], + "name": "h", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "uint" + }, + { + "type": "unsigned1" + } + ], + "name": "i", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "unsigned1" + }, + { + "type": "uint" + } + ], + "name": "j", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "unsignedQImage" + } + ], + "name": "k", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "uqi", + "type": "unsignedQImage" + } + ], + "name": "l", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "task240368.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "PureVirtualSignalsTest", + "qualifiedClassName": "PureVirtualSignalsTest", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + }, + { + "access": "public", + "name": "myOtherSignal", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "foo", + "type": "int" + } + ], + "name": "mySignal2", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "PureVirtualSignalsImpl", + "qualifiedClassName": "PureVirtualSignalsImpl", + "signals": [ + { + "access": "public", + "name": "mySignal", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "name": "foo", + "type": "int" + } + ], + "name": "mySignal2", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "PureVirtualSignalsTest" + } + ] + } + ], + "inputFile": "pure-virtual-signals.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "CXX11Enums", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "EnumClass", + "values": [ + "A0", + "A1", + "A2", + "A3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "TypedEnum", + "values": [ + "B0", + "B1", + "B2", + "B3" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "TypedEnumClass", + "values": [ + "C0", + "C1", + "C2", + "C3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "NormalEnum", + "values": [ + "D2", + "D3", + "D0", + "D1" + ] + }, + { + "alias": "ClassFlag", + "isClass": true, + "isFlag": true, + "name": "ClassFlags", + "values": [ + "F0", + "F1", + "F2", + "F3" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "EnumStruct", + "values": [ + "G0", + "G1", + "G2", + "G3" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "TypedEnumStruct", + "values": [ + "H0", + "H1", + "H2", + "H3" + ] + }, + { + "alias": "StructFlag", + "isClass": true, + "isFlag": true, + "name": "StructFlags", + "values": [ + "I0", + "I1", + "I2", + "I3" + ] + } + ], + "gadget": true, + "qualifiedClassName": "CXX11Enums" + }, + { + "className": "CXX11Enums2", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "EnumClass", + "values": [ + "A0", + "A1", + "A2", + "A3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "TypedEnum", + "values": [ + "B0", + "B1", + "B2", + "B3" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "TypedEnumClass", + "values": [ + "C0", + "C1", + "C2", + "C3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "NormalEnum", + "values": [ + "D2", + "D3", + "D0", + "D1" + ] + }, + { + "alias": "ClassFlag", + "isClass": true, + "isFlag": true, + "name": "ClassFlags", + "values": [ + "F0", + "F1", + "F2", + "F3" + ] + } + ], + "gadget": true, + "qualifiedClassName": "CXX11Enums2" + } + ], + "inputFile": "cxx11-enums.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "FinalTestClassQt", + "qualifiedClassName": "FinalTestClassQt", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedFinalTestClassQt", + "qualifiedClassName": "ExportedFinalTestClassQt", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedFinalTestClassQtX", + "qualifiedClassName": "ExportedFinalTestClassQtX", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "FinalTestClassCpp11", + "qualifiedClassName": "FinalTestClassCpp11", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedFinalTestClassCpp11", + "qualifiedClassName": "ExportedFinalTestClassCpp11", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedFinalTestClassCpp11X", + "qualifiedClassName": "ExportedFinalTestClassCpp11X", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "SealedTestClass", + "qualifiedClassName": "SealedTestClass", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedSealedTestClass", + "qualifiedClassName": "ExportedSealedTestClass", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExportedSealedTestClassX", + "qualifiedClassName": "ExportedSealedTestClassX", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "cxx11-final-classes.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "ExplicitOverrideControlBase", + "qualifiedClassName": "ExplicitOverrideControlBase", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "ExplicitOverrideControlFinalQt", + "qualifiedClassName": "ExplicitOverrideControlFinalQt", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlFinalCxx11", + "qualifiedClassName": "ExplicitOverrideControlFinalCxx11", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlSealed", + "qualifiedClassName": "ExplicitOverrideControlSealed", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlOverrideQt", + "qualifiedClassName": "ExplicitOverrideControlOverrideQt", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlOverrideCxx11", + "qualifiedClassName": "ExplicitOverrideControlOverrideCxx11", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlFinalQtOverrideQt", + "qualifiedClassName": "ExplicitOverrideControlFinalQtOverrideQt", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlFinalCxx11OverrideCxx11", + "qualifiedClassName": "ExplicitOverrideControlFinalCxx11OverrideCxx11", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + }, + { + "className": "ExplicitOverrideControlSealedOverride", + "qualifiedClassName": "ExplicitOverrideControlSealedOverride", + "slots": [ + { + "access": "private", + "name": "pureSlot0", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot1", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot2", + "returnType": "void" + }, + { + "access": "private", + "name": "pureSlot3", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "ExplicitOverrideControlBase" + } + ] + } + ], + "inputFile": "cxx11-explicit-override-control.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "ForwardDeclaredParamClass", + "qualifiedClassName": "ForwardDeclaredParamClass", + "signals": [ + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredParam" + } + ], + "name": "signalNaked", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<ForwardDeclaredParam>" + } + ], + "name": "signalFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<int>" + } + ], + "name": "signalFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<QString>" + } + ], + "name": "signalFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<FullyDefined>" + } + ], + "name": "signalFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<ForwardDeclaredParam>" + } + ], + "name": "signalQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<int>" + } + ], + "name": "signalQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<QString>" + } + ], + "name": "signalQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<FullyDefined>" + } + ], + "name": "signalQSet", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredParam" + } + ], + "name": "slotNaked", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<ForwardDeclaredParam>" + } + ], + "name": "slotFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<int>" + } + ], + "name": "slotFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<QString>" + } + ], + "name": "slotFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "ForwardDeclaredContainer<FullyDefined>" + } + ], + "name": "slotFDC", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<ForwardDeclaredParam>" + } + ], + "name": "slotQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<int>" + } + ], + "name": "slotQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<QString>" + } + ], + "name": "slotQSet", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "QSet<FullyDefined>" + } + ], + "name": "slotQSet", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "forward-declared-param.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "classInfos": [ + { + "name": "TestString", + "value": "PD_CLASSNAME" + }, + { + "name": "TestString2", + "value": "ParseDefine" + }, + { + "name": "TestString3", + "value": "TestValue" + } + ], + "className": "ParseDefine", + "qualifiedClassName": "PD::ParseDefine", + "signals": [ + { + "access": "public", + "arguments": [ + { + "name": "i", + "type": "QMap<int,int>" + } + ], + "name": "cmdlineSignal", + "returnType": "void" + }, + { + "access": "public", + "name": "signalQTBUG55853", + "returnType": "void" + } + ], + "slots": [ + { + "access": "public", + "name": "voidFunction", + "returnType": "void" + }, + { + "access": "public", + "name": "stringMethod", + "returnType": "QString" + }, + { + "access": "public", + "name": "combined1", + "returnType": "void" + }, + { + "access": "public", + "name": "combined2", + "returnType": "void" + }, + { + "access": "public", + "name": "combined3", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + }, + { + "type": "int" + } + ], + "name": "combined4", + "returnType": "void" + }, + { + "access": "public", + "name": "combined5", + "returnType": "void" + }, + { + "access": "public", + "name": "combined6", + "returnType": "void" + }, + { + "access": "public", + "name": "vararg1", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "vararg2", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + }, + { + "type": "int" + } + ], + "name": "vararg3", + "returnType": "void" + }, + { + "access": "public", + "name": "vararg4", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "vararg5", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + }, + { + "type": "int" + } + ], + "name": "vararg6", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "INNERFUNCTION", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "inner_expanded", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "expanded_method", + "returnType": "void" + }, + { + "access": "public", + "name": "conditionSlot", + "returnType": "void" + }, + { + "access": "public", + "arguments": [ + { + "type": "int" + } + ], + "name": "PD_DEFINE_ITSELF_SUFFIX", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "parse-defines.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "FunctionWithAttributes", + "qualifiedClassName": "FunctionWithAttributes", + "slots": [ + { + "access": "public", + "name": "test1", + "returnType": "void" + }, + { + "access": "public", + "name": "test2", + "returnType": "void" + } + ], + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "function-with-attributes.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "TestPluginMetaData", + "qualifiedClassName": "TestPluginMetaData", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "plugin_metadata.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "KDAB", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "Salaries", + "values": [ + "Steve" + ] + } + ], + "qualifiedClassName": "KDAB", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "single-quote-digit-separator-n3781.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "A", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "QTBUG_2151::A", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "B", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "blah", + "read": "blah", + "scriptable": true, + "stored": true, + "type": "A::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "QTBUG_2151::B", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "related-metaobjects-in-namespaces.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "A", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "QTBUG_35657::A" + } + ], + "inputFile": "qtbug-35657-gadget.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Derived", + "gadget": true, + "qualifiedClassName": "NonGadgetParent::Derived", + "superClasses": [ + { + "access": "public", + "name": "Base" + } + ] + } + ], + "inputFile": "non-gadget-parent-class.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "BaseGadget", + "gadget": true, + "qualifiedClassName": "GrandParentGadget::BaseGadget" + }, + { + "className": "DerivedGadget", + "gadget": true, + "qualifiedClassName": "GrandParentGadget::DerivedGadget", + "superClasses": [ + { + "access": "public", + "name": "Derived" + } + ] + } + ], + "inputFile": "grand-parent-gadget-class.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "B", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "blah", + "read": "blah", + "scriptable": true, + "stored": true, + "type": "A::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "QTBUG_35657::B", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "related-metaobjects-in-gadget.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "Unsused::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "Unsused::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS1::Nested::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS1::Nested::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS1::NestedUnsused::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS1::NestedUnsused::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS1::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS1::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingObject", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "gadgetPoperty", + "read": "gadgetPoperty", + "scriptable": true, + "stored": true, + "type": "Gadget::SomeEnum", + "user": false + }, + { + "constant": false, + "designable": true, + "final": false, + "name": "objectPoperty", + "read": "objectPoperty", + "scriptable": true, + "stored": true, + "type": "Object::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS1::DependingObject", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingNestedGadget", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "nestedGadgetPoperty", + "read": "nestedGadgetPoperty", + "scriptable": true, + "stored": true, + "type": "Nested::Gadget::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS1::DependingNestedGadget", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingNestedObject", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "nestedObjectPoperty", + "read": "nestedObjectPoperty", + "scriptable": true, + "stored": true, + "type": "Nested::Object::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS1::DependingNestedObject", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS2::Nested::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS2::Nested::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS2::NestedUnsused::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS2::NestedUnsused::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "Gadget", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "gadget": true, + "qualifiedClassName": "NS2::Gadget" + }, + { + "className": "Object", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "SomeEnum", + "values": [ + "SomeEnumValue" + ] + } + ], + "qualifiedClassName": "NS2::Object", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingObject", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "gadgetPoperty", + "read": "gadgetPoperty", + "scriptable": true, + "stored": true, + "type": "Gadget::SomeEnum", + "user": false + }, + { + "constant": false, + "designable": true, + "final": false, + "name": "objectPoperty", + "read": "objectPoperty", + "scriptable": true, + "stored": true, + "type": "Object::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS2::DependingObject", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingNestedGadget", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "nestedGadgetPoperty", + "read": "nestedGadgetPoperty", + "scriptable": true, + "stored": true, + "type": "Nested::Gadget::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS2::DependingNestedGadget", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + }, + { + "className": "DependingNestedObject", + "properties": [ + { + "constant": false, + "designable": true, + "final": false, + "name": "nestedObjectPoperty", + "read": "nestedObjectPoperty", + "scriptable": true, + "stored": true, + "type": "Nested::Object::SomeEnum", + "user": false + } + ], + "qualifiedClassName": "NS2::DependingNestedObject", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] + } + ], + "inputFile": "related-metaobjects-name-conflict.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "FooNamespace", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "Enum1", + "values": [ + "Key1", + "Key2" + ] + } + ], + "gadget": true, + "qualifiedClassName": "FooNamespace" + }, + { + "className": "FooNestedNamespace", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "Enum2", + "values": [ + "Key3", + "Key4" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "Enum3", + "values": [ + "Key5", + "Key6" + ] + } + ], + "gadget": true, + "qualifiedClassName": "FooNamespace::FooNestedNamespace" + }, + { + "className": "FooMoreNestedNamespace", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "Enum4", + "values": [ + "Key7", + "Key8" + ] + } + ], + "gadget": true, + "qualifiedClassName": "FooNamespace::FooNestedNamespace::FooMoreNestedNamespace" + } + ], + "inputFile": "namespace.h", + "outputRevision": 67 + }, + { + "classes": [ + { + "className": "ClassInNamespace", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "GadEn", + "values": [ + "Value" + ] + } + ], + "gadget": true, + "qualifiedClassName": "CXX17Namespace::A::B::C::D::ClassInNamespace" + }, + { + "className": "D", + "enums": [ + { + "isClass": false, + "isFlag": false, + "name": "NamEn", + "values": [ + "Value" + ] + } + ], + "gadget": true, + "qualifiedClassName": "CXX17Namespace::A::B::C::D" + } + ], + "inputFile": "cxx17-namespaces.h", + "outputRevision": 67 + } +] diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro index ad8c093add..1794bafd2c 100644 --- a/tests/auto/tools/moc/moc.pro +++ b/tests/auto/tools/moc/moc.pro @@ -32,6 +32,9 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n namespace.h cxx17-namespaces.h \ cxx-attributes.h +# No platform specifics in the JSON files, so that we can compare them +JSON_HEADERS = $$HEADERS +JSON_HEADERS -= cxx-attributes.h if(*-g++*|*-icc*|*-clang*|*-llvm):!win32-*: HEADERS += os9-newlines.h win-newlines.h if(*-g++*|*-clang*): HEADERS += dollars.h @@ -50,3 +53,49 @@ QMAKE_MOC_OPTIONS += -Muri=com.company.app -Muri=com.company.app.private # Define macro on the command lines used in parse-defines.h QMAKE_MOC_OPTIONS += "-DDEFINE_CMDLINE_EMPTY=" "\"-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)\"" +QMAKE_MOC_OPTIONS += --output-json + +debug_and_release { + CONFIG(debug, debug|release) { + MOC_CPP_DIR = $$MOC_DIR/debug + } else { + MOC_CPP_DIR = $$MOC_DIR/release + } +} else { + MOC_CPP_DIR = $$MOC_DIR +} + +moc_json_header.input = JSON_HEADERS +moc_json_header.output = $$MOC_CPP_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}.json +moc_json_header.CONFIG = no_link moc_verify +moc_json_header.depends = $$MOC_CPP_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)} +moc_json_header.commands = $$escape_expand(\\n) # force creation of rule +moc_json_header.variable_out = MOC_JSON_HEADERS + +BASELINE_IN = allmocs_baseline_in.json +copy_baseline.commands = $${QMAKE_COPY} $$shell_path(${QMAKE_FILE_NAME}) ${QMAKE_FILE_OUT} +copy_baseline.input = BASELINE_IN +copy_baseline.output = $$OUT_PWD/allmocs_baseline.json +copy_baseline.CONFIG = no_link + +qtPrepareTool(MOC_COLLECT_JSON, moc) +jsoncollector.CONFIG += combine +jsoncollector.commands = $$MOC_COLLECT_JSON --collect-json -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} +jsoncollector.input = MOC_JSON_HEADERS +jsoncollector.output = $$OUT_PWD/allmocs.json +jsoncollector.variable_out = GENERATED_FILES + +allmocs_contents = \ + "<!DOCTYPE RCC><RCC version=\"1.0\">"\ + "<qresource prefix=\"/\">"\ + "<file>allmocs.json</file>"\ + "<file>allmocs_baseline.json</file>"\ + "</qresource>"\ + "</RCC>" + +allmocs_file = $$OUT_PWD/allmocs.qrc + +!write_file($$allmocs_file, allmocs_contents): error() +RESOURCES += $$allmocs_file + +QMAKE_EXTRA_COMPILERS += moc_json_header copy_baseline jsoncollector diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 89f563f11d..9fc00288fe 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -33,6 +33,7 @@ #include <stdio.h> #include <qobject.h> #include <qmetaobject.h> +#include <qjsondocument.h> #include "using-namespaces.h" #include "assign-namespace.h" @@ -717,6 +718,7 @@ private slots: void testQNamespace(); void cxx17Namespaces(); void cxxAttributes(); + void mocJsonOutput(); signals: void sigWithUnsignedArg(unsigned foo); @@ -3971,6 +3973,57 @@ void tst_Moc::cxxAttributes() QCOMPARE(meta.keyCount(), 7); } +void tst_Moc::mocJsonOutput() +{ + const auto readFile = [](const QString &fileName) { + QFile f(fileName); + f.open(QIODevice::ReadOnly); + return QJsonDocument::fromJson(f.readAll()); + }; + + const QString actualFile = QStringLiteral(":/allmocs.json"); + const QString expectedFile = QStringLiteral(":/allmocs_baseline.json"); + + QVERIFY2(QFile::exists(actualFile), qPrintable(actualFile)); + QVERIFY2(QFile::exists(expectedFile), qPrintable(expectedFile)); + + QJsonDocument actualOutput = readFile(QLatin1String(":/allmocs.json")); + QJsonDocument expectedOutput = readFile(QLatin1String(":/allmocs_baseline.json")); + + const auto showPotentialDiff = [](const QJsonDocument &actual, const QJsonDocument &expected) -> QByteArray { +#if defined(Q_OS_UNIX) + QByteArray actualStr = actual.toJson(); + QByteArray expectedStr = expected.toJson(); + + QTemporaryFile actualFile; + if (!actualFile.open()) + return "Error opening actual temp file"; + actualFile.write(actualStr); + actualFile.flush(); + + QTemporaryFile expectedFile; + if (!expectedFile.open()) + return "Error opening expected temp file"; + expectedFile.write(expectedStr); + expectedFile.flush(); + + QProcess diffProc; + diffProc.setProgram("diff"); + diffProc.setArguments(QStringList() << "-ub" << expectedFile.fileName() << actualFile.fileName()); + diffProc.start(); + if (!diffProc.waitForStarted()) + return "Error waiting for diff process to start."; + if (!diffProc.waitForFinished()) + return "Error waiting for diff process to finish."; + return diffProc.readAllStandardOutput(); +#else + return "Cannot launch diff. Please check allmocs.json and allmocs_baseline.json on disk."; +#endif + }; + + QVERIFY2(actualOutput == expectedOutput, showPotentialDiff(actualOutput, expectedOutput).constData()); +} + QTEST_MAIN(tst_Moc) // the generated code must compile with QT_NO_KEYWORDS |