diff options
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r-- | src/tools/moc/moc.cpp | 200 |
1 files changed, 199 insertions, 1 deletions
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 |