From 693ba33e7838c40578076ddbd8a59ff45d438df0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 20 Feb 2018 13:07:57 +0100 Subject: QtDocParser: Fix and refactor queries - Use a QTextStream for better readability - Extract a helper function to format the function parameter type query: - Fix the function parameter type attribute ("left"->"type") - Fully qualify enumeration and other non-primitive types Task-number: PYSIDE-363 Change-Id: I529e839fb737f30bd9b70d10a48fcfb0c9141f8f Reviewed-by: Alexandru Croitor --- sources/shiboken2/ApiExtractor/qtdocparser.cpp | 92 ++++++++++++++++---------- 1 file changed, 58 insertions(+), 34 deletions(-) (limited to 'sources/shiboken2/ApiExtractor') diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp index 508faa6dc..0ac87bd16 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include Documentation QtDocParser::retrieveModuleDocumentation() @@ -41,6 +42,45 @@ Documentation QtDocParser::retrieveModuleDocumentation() return retrieveModuleDocumentation(packageName()); } +static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgument *arg) +{ + const AbstractMetaType *metaType = arg->type(); + if (metaType->isConstant()) + str << "const " ; + switch (metaType->typeUsagePattern()) { + case AbstractMetaType::PrimitivePattern: + str << metaType->name(); + break; + case AbstractMetaType::FlagsPattern: { + // Modify qualified name "QFlags" with name "Alignment" + // to "Qt::Alignment" as seen by qdoc. + const FlagsTypeEntry *flagsEntry = static_cast(metaType->typeEntry()); + QString name = flagsEntry->qualifiedCppName(); + if (name.endsWith(QLatin1Char('>')) && name.startsWith(QLatin1String("QFlags<"))) { + const int lastColon = name.lastIndexOf(QLatin1Char(':')); + if (lastColon != -1) { + name.replace(lastColon + 1, name.size() - lastColon - 1, metaType->name()); + name.remove(0, 7); + } else { + name = metaType->name(); // QFlags<> of enum in global namespace + } + } + str << name; + } + break; + default: // Fully qualify enums (Qt::AlignmentFlag), nested classes, etc. + str << metaType->typeEntry()->qualifiedCppName(); + break; + } + + if (metaType->referenceType() == LValueReference) + str << " &"; + else if (metaType->referenceType() == RValueReference) + str << " &&"; + else if (metaType->indirections()) + str << ' ' << QByteArray(metaType->indirections(), '*'); +} + void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) { if (!metaClass) @@ -74,9 +114,10 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) QString className = metaClass->name(); // Class/Namespace documentation - QString type = metaClass->isNamespace() ? QLatin1String("namespace") : QLatin1String("class"); - QString query = QLatin1String("/WebXML/document/") + type + QLatin1String("[@name=\"") - + className + QLatin1String("\"]/description"); + const QString classQuery = QLatin1String("/WebXML/document/") + + (metaClass->isNamespace() ? QLatin1String("namespace") : QLatin1String("class")) + + QLatin1String("[@name=\"") + className + QLatin1String("\"]"); + QString query = classQuery + QLatin1String("/description"); DocModificationList signedModifs, classModifs; const DocModificationList &mods = metaClass->typeEntry()->docModifications(); @@ -96,41 +137,25 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) //Functions Documentation const AbstractMetaFunctionList &funcs = DocParser::documentableFunctions(metaClass); for (AbstractMetaFunction *func : funcs) { - QString query = QLatin1String("/WebXML/document/") + type - + QLatin1String("[@name=\"") + className + QLatin1String("\"]"); + query.clear(); + QTextStream str(&query); + str << classQuery; // properties if (func->isPropertyReader() || func->isPropertyWriter() || func->isPropertyResetter()) { - query += QLatin1String("/property[@name=\"") + func->propertySpec()->name() - + QLatin1String("\"]"); + str << "/property[@name=\"" << func->propertySpec()->name() << "\"]"; } else { // normal methods - QString isConst = func->isConstant() ? QLatin1String("true") : QLatin1String("false"); - query += QLatin1String("/function[@name=\"") + func->originalName() - + QLatin1String("\" and count(parameter)=") - + QString::number(func->arguments().count()) - + QLatin1String(" and @const=\"") + isConst + QLatin1String("\"]"); + str << "/function[@name=\"" << func->originalName() << "\" and count(parameter)=" + << func->arguments().count() << " and @const=\"" + << (func->isConstant() ? "true" : "false") << "\"]"; const AbstractMetaArgumentList &arguments = func->arguments(); for (int i = 0, size = arguments.size(); i < size; ++i) { - const AbstractMetaArgument *arg = arguments.at(i); - QString type = arg->type()->name(); - - if (arg->type()->isConstant()) - type.prepend(QLatin1String("const ")); - - if (arg->type()->referenceType() == LValueReference) { - type += QLatin1String(" &"); - } else if (arg->type()->referenceType() == RValueReference) { - type += QLatin1String(" &&"); - } else if (arg->type()->indirections()) { - type += QLatin1Char(' '); - for (int j = 0, max = arg->type()->indirections(); j < max; ++j) - type += QLatin1Char('*'); - } - query += QLatin1String("/parameter[") + QString::number(i + 1) - + QLatin1String("][@left=\"") + type + QLatin1String("\"]/.."); + str << "/parameter[" << (i + 1) << "][@type=\""; + formatFunctionArgTypeQuery(str, arguments.at(i)); + str << "\"]/.."; } } - query += QLatin1String("/description"); + str << "/description"; DocModificationList funcModifs; for (const DocModification &funcModif : qAsConst(signedModifs)) { if (funcModif.signature() == func->minimalSignature()) @@ -158,10 +183,9 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) // Enums const AbstractMetaEnumList &enums = metaClass->enums(); for (AbstractMetaEnum *meta_enum : enums) { - QString query = QLatin1String("/WebXML/document/") + type - + QLatin1String("[@name=\"") - + className + QLatin1String("\"]/enum[@name=\"") - + meta_enum->name() + QLatin1String("\"]/description"); + query.clear(); + QTextStream(&query) << classQuery << "/enum[@name=\"" + << meta_enum->name() << "\"]/description"; doc.setValue(getDocumentation(xquery, query, DocModificationList())); if (doc.isEmpty()) { qCWarning(lcShiboken(), "%s", -- cgit v1.2.3