diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-06-04 12:23:09 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-06-05 14:20:48 +0200 |
commit | 538579db546043ccc21c64230e3c2faa69569822 (patch) | |
tree | f361a96c413678681ec81762558003ef81729048 /sources | |
parent | 387ea2999c6d30aebfed30ec565e88ffae368b9c (diff) |
dumpcodemodel: Improve XML output
- Skip empty namespaces
- Add a command line option to join namespaces
- Add an XML comment with file location
- Filter out anonymous structs
Change-Id: I061540a6a4bcb583a19ee70efc268571324521ff
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources')
-rw-r--r-- | sources/shiboken2/tests/dumpcodemodel/main.cpp | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/sources/shiboken2/tests/dumpcodemodel/main.cpp b/sources/shiboken2/tests/dumpcodemodel/main.cpp index 52d64be94..37c964fc0 100644 --- a/sources/shiboken2/tests/dumpcodemodel/main.cpp +++ b/sources/shiboken2/tests/dumpcodemodel/main.cpp @@ -43,6 +43,8 @@ #include <algorithm> #include <iterator> +static bool optJoinNamespaces = false; + static inline QString languageLevelDescription() { return QLatin1String("C++ Language level (c++11..c++17, default=") @@ -69,7 +71,6 @@ static const char *primitiveTypes[] = { static inline QString nameAttribute() { return QStringLiteral("name"); } -static void formatXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp); static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass); static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en) @@ -79,10 +80,16 @@ static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en) writer.writeEndElement(); } +static bool useClass(const ClassModelItem &c) +{ + return c->classType() != CodeModel::Union && c->templateParameters().isEmpty() + && !c->name().isEmpty(); // No anonymous structs +} + static void formatXmlScopeMembers(QXmlStreamWriter &writer, const ScopeModelItem &nsp) { for (const auto &klass : nsp->classes()) { - if (klass->classType() != CodeModel::Union && klass->templateParameters().isEmpty()) + if (useClass(klass)) formatXmlClass(writer, klass); } for (const auto &en : nsp->enums()) @@ -95,12 +102,20 @@ static bool isPublicCopyConstructor(const FunctionModelItem &f) && f->accessPolicy() == CodeModel::Public && !f->isDeleted(); } +static void formatXmlLocationComment(QXmlStreamWriter &writer, const CodeModelItem &i) +{ + QString comment; + QTextStream(&comment) << ' ' << i->fileName() << ':' << i->startLine() << ' '; + writer.writeComment(comment); +} + static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass) { // Heuristics for value types: check on public copy constructors. const auto functions = klass->functions(); const bool isValueType = std::any_of(functions.cbegin(), functions.cend(), isPublicCopyConstructor); + formatXmlLocationComment(writer, klass); writer.writeStartElement(isValueType ? QStringLiteral("value-type") : QStringLiteral("object-type")); writer.writeAttribute(nameAttribute(), klass->name()); @@ -108,10 +123,51 @@ static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass writer.writeEndElement(); } +// Check whether a namespace is relevant for type system +// output, that is, has non template classes, functions or enumerations. +static bool hasMembers(const NamespaceModelItem &nsp) +{ + if (!nsp->namespaces().isEmpty() || !nsp->enums().isEmpty() + || !nsp->functions().isEmpty()) { + return true; + } + const auto classes = nsp->classes(); + return std::any_of(classes.cbegin(), classes.cend(), useClass); +} + +static void startXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp) +{ + formatXmlLocationComment(writer, nsp); + writer.writeStartElement(QStringLiteral("namespace-type")); + writer.writeAttribute(nameAttribute(), nsp->name()); +} + static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceModelItem &nsp) { - for (const auto &nested : nsp->namespaces()) - formatXmlNamespace(writer, nested); + auto nestedNamespaces = nsp->namespaces(); + for (int i = nestedNamespaces.size() - 1; i >= 0; --i) { + if (!hasMembers(nestedNamespaces.at(i))) + nestedNamespaces.removeAt(i); + } + while (!nestedNamespaces.isEmpty()) { + auto current = nestedNamespaces.takeFirst(); + startXmlNamespace(writer, current); + formatXmlNamespaceMembers(writer, current); + if (optJoinNamespaces) { + // Write out members of identical namespaces and remove + const QString name = current->name(); + for (int i = 0; i < nestedNamespaces.size(); ) { + if (nestedNamespaces.at(i)->name() == name) { + formatXmlNamespaceMembers(writer, nestedNamespaces.at(i)); + nestedNamespaces.removeAt(i); + } else { + ++i; + } + } + } + writer.writeEndElement(); + } + for (auto func : nsp->functions()) { const QString signature = func->typeSystemSignature(); if (!signature.contains(QLatin1String("operator"))) { // Skip free operators @@ -123,14 +179,6 @@ static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceM formatXmlScopeMembers(writer, nsp); } -static void formatXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp) -{ - writer.writeStartElement(QStringLiteral("namespace-type")); - writer.writeAttribute(nameAttribute(), nsp->name()); - formatXmlNamespaceMembers(writer, nsp); - writer.writeEndElement(); -} - static void formatXmlOutput(const FileModelItem &dom) { QString output; @@ -183,6 +231,10 @@ int main(int argc, char **argv) QStringLiteral("Display debug output")); parser.addOption(debugOption); + QCommandLineOption joinNamespacesOption({QStringLiteral("j"), QStringLiteral("join-namespaces")}, + QStringLiteral("Join namespaces")); + parser.addOption(joinNamespacesOption); + QCommandLineOption languageLevelOption(QStringLiteral("std"), languageLevelDescription(), QStringLiteral("level")); @@ -211,6 +263,8 @@ int main(int argc, char **argv) } } + optJoinNamespaces = parser.isSet(joinNamespacesOption); + const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, level, 0); if (dom.isNull()) { QString message = QLatin1String("Unable to parse ") + positionalArguments.join(QLatin1Char(' ')); |