diff options
Diffstat (limited to 'sources/shiboken6/ApiExtractor/docparser.cpp')
-rw-r--r-- | sources/shiboken6/ApiExtractor/docparser.cpp | 196 |
1 files changed, 137 insertions, 59 deletions
diff --git a/sources/shiboken6/ApiExtractor/docparser.cpp b/sources/shiboken6/ApiExtractor/docparser.cpp index 9445adf81..468fe1098 100644 --- a/sources/shiboken6/ApiExtractor/docparser.cpp +++ b/sources/shiboken6/ApiExtractor/docparser.cpp @@ -1,44 +1,25 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + #include "docparser.h" +#include "abstractmetaargument.h" #include "abstractmetaenum.h" -#include "abstractmetafield.h" #include "abstractmetafunction.h" #include "abstractmetalang.h" +#include "abstractmetatype.h" #include "messages.h" #include "modifications.h" #include "reporthandler.h" -#include "typesystem.h" +#include "enumtypeentry.h" +#include "complextypeentry.h" #include "xmlutils.h" + +#include <QtCore/QBuffer> #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QTextStream> -#include <QBuffer> + +#include "qtcompat.h" #include <cstdlib> #ifdef HAVE_LIBXSLT @@ -48,15 +29,39 @@ #include <algorithm> -DocParser::DocParser() +using namespace Qt::StringLiterals; + +static inline bool isXpathDocModification(const DocModification &mod) { -#ifdef HAVE_LIBXSLT - xmlSubstituteEntitiesDefault(1); -#endif + return mod.mode() == TypeSystem::DocModificationXPathReplace; } +static inline bool isNotXpathDocModification(const DocModification &mod) +{ + return mod.mode() != TypeSystem::DocModificationXPathReplace; +} + +static void removeXpathDocModifications(DocModificationList *l) +{ + l->erase(std::remove_if(l->begin(), l->end(), isXpathDocModification), l->end()); +} + +static void removeNonXpathDocModifications(DocModificationList *l) +{ + l->erase(std::remove_if(l->begin(), l->end(), isNotXpathDocModification), l->end()); +} + +DocParser::DocParser() = default; DocParser::~DocParser() = default; +void DocParser::fillGlobalFunctionDocumentation(const AbstractMetaFunctionPtr &) +{ +} + +void DocParser::fillGlobalEnumDocumentation(AbstractMetaEnum &) +{ +} + QString DocParser::getDocumentation(const XQueryPtr &xquery, const QString& query, const DocModificationList& mods) { @@ -73,9 +78,16 @@ QString DocParser::execXQuery(const XQueryPtr &xquery, const QString& query) return result; } +static bool usesRValueReference(const AbstractMetaArgument &a) +{ + return a.type().referenceType() == RValueReference; +} + bool DocParser::skipForQuery(const AbstractMetaFunctionCPtr &func) { // Skip private functions and copies created by AbstractMetaClass::fixFunctions() + // Note: Functions inherited from templates will cause warnings about missing + // documentation, but they should at least be listed. if (!func || func->isPrivate() || func->attributes().testFlag(AbstractMetaFunction::AddedMethod) || func->isModifiedRemoved() @@ -91,25 +103,95 @@ bool DocParser::skipForQuery(const AbstractMetaFunctionCPtr &func) default: break; } - return false; + + return std::any_of(func->arguments().cbegin(), func->arguments().cend(), + usesRValueReference); } -AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClass *metaClass) +DocModificationList DocParser::getDocModifications(const AbstractMetaClassCPtr &cppClass) + { - auto result = metaClass->functionsInTargetLang(); - for (int i = result.size() - 1; i >= 0; --i) { - if (DocParser::skipForQuery(result.at(i)) || result.at(i)->isUserAdded()) - result.removeAt(i); + auto result = cppClass->typeEntry()->docModifications(); + removeXpathDocModifications(&result); + return result; +} + +static void filterBySignature(const AbstractMetaFunctionCPtr &func, DocModificationList *l) +{ + if (!l->isEmpty()) { + const QString minimalSignature = func->minimalSignature(); + const auto filter = [&minimalSignature](const DocModification &mod) { + return mod.signature() != minimalSignature; + }; + l->erase(std::remove_if(l->begin(), l->end(), filter), l->end()); + } +} + +DocModificationList DocParser::getDocModifications(const AbstractMetaFunctionCPtr &func, + const AbstractMetaClassCPtr &cppClass) +{ + DocModificationList result; + if (func->isUserAdded()) { + result = func->addedFunctionDocModifications(); + removeXpathDocModifications(&result); + } else if (cppClass != nullptr) { + result = cppClass->typeEntry()->functionDocModifications(); + removeXpathDocModifications(&result); + filterBySignature(func, &result); } return result; } -static inline bool isXpathDocModification(const DocModification &mod) +DocModificationList DocParser::getXpathDocModifications(const AbstractMetaClassCPtr &cppClass) { - return mod.mode() == TypeSystem::DocModificationXPathReplace; + auto result = cppClass->typeEntry()->docModifications(); + removeNonXpathDocModifications(&result); + return result; +} + +DocModificationList DocParser::getXpathDocModifications(const AbstractMetaFunctionCPtr &func, + const AbstractMetaClassCPtr &cppClass) +{ + DocModificationList result; + if (func->isUserAdded()) { + result = func->addedFunctionDocModifications(); + removeNonXpathDocModifications(&result); + } else if (cppClass != nullptr) { + result = cppClass->typeEntry()->functionDocModifications(); + removeNonXpathDocModifications(&result); + filterBySignature(func, &result); + } + return result; } -QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml) +QString DocParser::enumBaseClass(const AbstractMetaEnum &e) +{ + switch (e.typeEntry()->pythonEnumType()) { + case TypeSystem::PythonEnumType::IntEnum: + return u"IntEnum"_s; + case TypeSystem::PythonEnumType::Flag: + return u"Flag"_s; + case TypeSystem::PythonEnumType::IntFlag: + return u"IntFlag"_s; + default: + break; + } + return e.typeEntry()->flags() != nullptr ? u"Flag"_s : u"Enum"_s; +} + +AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClassCPtr &metaClass) +{ + auto result = metaClass->functionsInTargetLang(); + for (auto i = result.size() - 1; i >= 0; --i) { + if (DocParser::skipForQuery(result.at(i)) || result.at(i)->isUserAdded()) + result.removeAt(i); + } + result.append(metaClass->cppSignalFunctions()); + return result; +} + +QString DocParser::applyDocModifications(const DocModificationList& xpathMods, + const QString& xml) { const char xslPrefix[] = R"(<xsl:template match="/"> @@ -123,32 +205,28 @@ R"(<xsl:template match="/"> </xsl:template> )"; - if (mods.isEmpty() || xml.isEmpty() - || !std::any_of(mods.cbegin(), mods.cend(), isXpathDocModification)) { + if (xpathMods.isEmpty() || xml.isEmpty()) return xml; - } - QString xsl = QLatin1String(xslPrefix); - for (const DocModification &mod : mods) { - if (isXpathDocModification(mod)) { - QString xpath = mod.xpath(); - xpath.replace(QLatin1Char('"'), QLatin1String(""")); - xsl += QLatin1String("<xsl:template match=\"") - + xpath + QLatin1String("\">") - + mod.code() + QLatin1String("</xsl:template>\n"); - } + QString xsl = QLatin1StringView(xslPrefix); + for (const DocModification &mod : xpathMods) { + Q_ASSERT(isXpathDocModification(mod)); + QString xpath = mod.xpath(); + xpath.replace(u'"', u"""_s); + xsl += "<xsl:template match=\""_L1 + xpath + "\">"_L1 + + mod.code() + "</xsl:template>\n"_L1; } QString errorMessage; const QString result = xsl_transform(xml, xsl, &errorMessage); if (!errorMessage.isEmpty()) qCWarning(lcShibokenDoc, "%s", - qPrintable(msgXpathDocModificationError(mods, errorMessage))); + qPrintable(msgXpathDocModificationError(xpathMods, errorMessage))); if (result == xml) { - const QString message = QLatin1String("Query did not result in any modifications to \"") - + xml + QLatin1Char('"'); + const QString message = u"Query did not result in any modifications to \""_s + + xml + u'"'; qCWarning(lcShibokenDoc, "%s", - qPrintable(msgXpathDocModificationError(mods, message))); + qPrintable(msgXpathDocModificationError(xpathMods, message))); } return result; } |