aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp')
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp218
1 files changed, 85 insertions, 133 deletions
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index 12d13f6b7..66c267852 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -27,19 +27,13 @@
****************************************************************************/
#include "qtxmltosphinx.h"
-#include "fileout.h"
-#include "messages.h"
+#include "qtxmltosphinxinterface.h"
#include "rstformat.h"
-#include "qtdocgenerator.h"
-#include <abstractmetafunction.h>
-#include <abstractmetalang.h>
-#include <reporthandler.h>
-#include <typedatabase.h>
-#include <typesystem.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
+#include <QtCore/QLoggingCategory>
#include <QtCore/QRegularExpression>
#include <QtCore/QXmlStreamReader>
@@ -47,6 +41,34 @@ static inline QString nameAttribute() { return QStringLiteral("name"); }
static inline QString titleAttribute() { return QStringLiteral("title"); }
static inline QString fullTitleAttribute() { return QStringLiteral("fulltitle"); }
+QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &message)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "While handling <";
+ const auto currentTag = reader.name();
+ if (currentTag.isEmpty())
+ str << tag;
+ else
+ str << currentTag;
+ str << "> in " << context << ", line "<< reader.lineNumber()
+ << ": " << message;
+ return result;
+}
+
+QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &location,
+ const QString &identifier, const QString &fallback)
+{
+ QString message = QLatin1String("Falling back to \"")
+ + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"")
+ + location + QLatin1Char('"');
+ if (!identifier.isEmpty())
+ message += QLatin1String(" [") + identifier + QLatin1Char(']');
+ return msgTagWarning(reader, context, tag, message);
+}
+
struct QtXmlToSphinx::LinkContext
{
enum Type
@@ -211,10 +233,12 @@ static const WebXmlTagHash &webXmlTagHash()
return result;
}
-QtXmlToSphinx::QtXmlToSphinx(const QtDocGenerator *generator,
+QtXmlToSphinx::QtXmlToSphinx(const QtXmlToSphinxDocGeneratorInterface *docGenerator,
+ const QtXmlToSphinxParameters &parameters,
const QString& doc, const QString& context)
: m_output(static_cast<QString *>(nullptr)),
- m_tableHasHeader(false), m_context(context), m_generator(generator),
+ m_tableHasHeader(false), m_context(context),
+ m_generator(docGenerator), m_parameters(parameters),
m_insideBold(false), m_insideItalic(false)
{
m_result = transform(doc);
@@ -362,6 +386,16 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
}
}
+void QtXmlToSphinx::formatCurrentTable()
+{
+ if (m_currentTable.isEmpty())
+ return;
+ m_currentTable.setHeaderEnabled(m_tableHasHeader);
+ m_currentTable.normalize();
+ m_output << ensureEndl;
+ m_currentTable.format(m_output);
+}
+
void QtXmlToSphinx::pushOutputBuffer()
{
auto *buffer = new QString();
@@ -379,60 +413,6 @@ QString QtXmlToSphinx::popOutputBuffer()
return strcpy;
}
-QString QtXmlToSphinx::expandFunction(const QString& function) const
-{
- const int firstDot = function.indexOf(QLatin1Char('.'));
- const AbstractMetaClass *metaClass = nullptr;
- if (firstDot != -1) {
- const auto className = QStringView{function}.left(firstDot);
- for (const AbstractMetaClass *cls : m_generator->classes()) {
- if (cls->name() == className) {
- metaClass = cls;
- break;
- }
- }
- }
-
- return metaClass
- ? metaClass->typeEntry()->qualifiedTargetLangName()
- + function.right(function.size() - firstDot)
- : function;
-}
-
-QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) const
-{
- const auto currentClass = QStringView{m_context}.split(QLatin1Char('.')).constLast();
-
- const AbstractMetaClass *metaClass = nullptr;
- for (const AbstractMetaClass *cls : m_generator->classes()) {
- if (cls->name() == currentClass) {
- metaClass = cls;
- break;
- }
- }
-
- if (metaClass) {
- AbstractMetaFunctionCList funcList;
- const auto &methods = metaClass->queryFunctionsByName(methodName);
- for (const auto &func : methods) {
- if (methodName == func->name())
- funcList.append(func);
- }
-
- const AbstractMetaClass *implementingClass = nullptr;
- for (const auto &func : qAsConst(funcList)) {
- implementingClass = func->implementingClass();
- if (implementingClass->name() == currentClass)
- break;
- }
-
- if (implementingClass)
- return implementingClass->typeEntry()->qualifiedTargetLangName();
- }
-
- return QLatin1Char('~') + m_context;
-}
-
QString QtXmlToSphinx::transform(const QString& doc)
{
Q_ASSERT(m_buffers.isEmpty());
@@ -452,7 +432,7 @@ QString QtXmlToSphinx::transform(const QString& doc)
<< reader.errorString() << " at " << reader.lineNumber()
<< ':' << reader.columnNumber() << '\n' << doc;
m_output << message;
- qCWarning(lcShibokenDoc).noquote().nospace() << message;
+ warn(message);
break;
}
@@ -513,7 +493,8 @@ QString QtXmlToSphinx::readFromLocations(const QStringList &locations, const QSt
<< locations.join(QLatin1String("\", \""));
return QString(); // null
}
- qCDebug(lcShibokenDoc).noquote().nospace() << "snippet file " << path
+ qCDebug(m_generator->loggingCategory()).noquote().nospace()
+ << "snippet file " << path
<< " [" << identifier << ']' << " resolved to " << resolvedPath;
return readFromLocation(resolvedPath, identifier, errorMessage);
}
@@ -708,11 +689,6 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
static inline QString fallbackPathAttribute() { return QStringLiteral("path"); }
-static inline bool snippetComparison()
-{
- return ReportHandler::debugLevel() >= ReportHandler::FullDebug;
-}
-
template <class Indent> // const char*/class Indentor
void formatSnippet(TextStream &str, Indent indent, const QString &snippet)
{
@@ -752,26 +728,26 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
QString identifier = reader.attributes().value(QLatin1String("identifier")).toString();
QString errorMessage;
const QString pythonCode =
- readFromLocations(m_generator->codeSnippetDirs(), location, identifier, &errorMessage);
+ readFromLocations(m_parameters.codeSnippetDirs, location, identifier, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ warn(msgTagWarning(reader, m_context, m_lastTagName, errorMessage));
// Fall back to C++ snippet when "path" attribute is present.
// Also read fallback snippet when comparison is desired.
QString fallbackCode;
- if ((pythonCode.isEmpty() || snippetComparison())
+ if ((pythonCode.isEmpty() || m_parameters.snippetComparison)
&& reader.attributes().hasAttribute(fallbackPathAttribute())) {
const QString fallback = reader.attributes().value(fallbackPathAttribute()).toString();
if (QFileInfo::exists(fallback)) {
if (pythonCode.isEmpty())
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback)));
+ warn(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback));
fallbackCode = readFromLocation(fallback, identifier, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ warn(msgTagWarning(reader, m_context, m_lastTagName, errorMessage));
}
}
- if (!pythonCode.isEmpty() && !fallbackCode.isEmpty() && snippetComparison())
- qCDebug(lcShibokenDoc, "%s", qPrintable(msgSnippetComparison(location, identifier, pythonCode, fallbackCode)));
+ if (!pythonCode.isEmpty() && !fallbackCode.isEmpty() && m_parameters.snippetComparison)
+ debug(msgSnippetComparison(location, identifier, pythonCode, fallbackCode));
if (!consecutiveSnippet)
m_output << "::\n\n";
@@ -817,10 +793,7 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
m_tableHasHeader = false;
} else if (token == QXmlStreamReader::EndElement) {
// write the table on m_output
- m_currentTable.setHeaderEnabled(m_tableHasHeader);
- m_currentTable.normalize();
- m_output << ensureEndl;
- m_currentTable.format(m_output);
+ formatCurrentTable();
m_currentTable.clear();
}
}
@@ -914,10 +887,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
}
break;
case EnumeratedList:
- m_currentTable.setHeaderEnabled(m_tableHasHeader);
- m_currentTable.normalize();
- m_output << ensureEndl;
- m_currentTable.format(m_output);
+ formatCurrentTable();
break;
}
}
@@ -965,32 +935,23 @@ QtXmlToSphinx::LinkContext *QtXmlToSphinx::handleLinkStart(const QString &type,
result->type = LinkContext::Method;
const auto rawlinklist = QStringView{result->linkRef}.split(QLatin1Char('.'));
if (rawlinklist.size() == 1 || rawlinklist.constFirst() == m_context) {
- QString context = resolveContextForMethod(rawlinklist.constLast().toString());
+ const auto lastRawLink = rawlinklist.constLast().toString();
+ QString context = m_generator->resolveContextForMethod(m_context, lastRawLink);
if (!result->linkRef.startsWith(context))
result->linkRef.prepend(context + QLatin1Char('.'));
} else {
- result->linkRef = expandFunction(result->linkRef);
+ result->linkRef = m_generator->expandFunction(result->linkRef);
}
} else if (type == functionLinkType() && m_context.isEmpty()) {
result->type = LinkContext::Function;
} else if (type == classLinkType()) {
result->type = LinkContext::Class;
- if (const TypeEntry *type = TypeDatabase::instance()->findType(result->linkRef)) {
- result->linkRef = type->qualifiedTargetLangName();
- } else { // fall back to the old heuristic if the type wasn't found.
- const auto rawlinklist = QStringView{result->linkRef}.split(QLatin1Char('.'));
- QStringList splittedContext = m_context.split(QLatin1Char('.'));
- if (rawlinklist.size() == 1 || rawlinklist.constFirst() == splittedContext.constLast()) {
- splittedContext.removeLast();
- result->linkRef.prepend(QLatin1Char('~') + splittedContext.join(QLatin1Char('.'))
- + QLatin1Char('.'));
- }
- }
+ result->linkRef = m_generator->expandClass(m_context, result->linkRef);
} else if (type == QLatin1String("enum")) {
result->type = LinkContext::Attribute;
} else if (type == QLatin1String("page")) {
// Module, external web page or reference
- if (result->linkRef == m_generator->moduleName())
+ if (result->linkRef == m_parameters.moduleName)
result->type = LinkContext::Module;
else if (result->linkRef.startsWith(QLatin1String("http")))
result->type = LinkContext::External;
@@ -1049,7 +1010,7 @@ void QtXmlToSphinx::handleLinkEnd(LinkContext *linkContext)
// by qdoc to a matching subdirectory under the "rst/PySide6/<module>" directory
static bool copyImage(const QString &href, const QString &docDataDir,
const QString &context, const QString &outputDir,
- QString *errorMessage)
+ const QLoggingCategory &lc, QString *errorMessage)
{
const QChar slash = QLatin1Char('/');
const int lastSlash = href.lastIndexOf(slash);
@@ -1092,7 +1053,7 @@ static bool copyImage(const QString &href, const QString &docDataDir,
<< source.errorString();
return false;
}
- qCDebug(lcShibokenDoc()).noquote().nospace() << __FUNCTION__ << " href=\""
+ qCDebug(lc).noquote().nospace() << __FUNCTION__ << " href=\""
<< href << "\", context=\"" << context << "\", docDataDir=\""
<< docDataDir << "\", outputDir=\"" << outputDir << "\", copied \""
<< source.fileName() << "\"->\"" << targetFileName << '"';
@@ -1103,10 +1064,12 @@ bool QtXmlToSphinx::copyImage(const QString &href) const
{
QString errorMessage;
const bool result =
- ::copyImage(href, m_generator->docDataDir(), m_context,
- m_generator->outputDirectory(), &errorMessage);
+ ::copyImage(href, m_parameters.docDataDir, m_context,
+ m_parameters.outputDirectory,
+ m_generator->loggingCategory(),
+ &errorMessage);
if (!result)
- qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
+ warn(errorMessage);
return result;
}
@@ -1171,8 +1134,10 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader)
void QtXmlToSphinx::handleUnknownTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement)
- qCDebug(lcShibokenDoc).noquote().nospace() << "Unknown QtDoc tag: \"" << reader.name().toString() << "\".";
+ if (token == QXmlStreamReader::StartElement) {
+ qCDebug(m_generator->loggingCategory()).noquote().nospace()
+ << "Unknown QtDoc tag: \"" << reader.name().toString() << "\".";
+ }
}
void QtXmlToSphinx::handleSuperScriptTag(QXmlStreamReader& reader)
@@ -1259,11 +1224,11 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::Characters) {
QString location = reader.text().toString();
- location.prepend(m_generator->libSourceDir() + QLatin1Char('/'));
+ location.prepend(m_parameters.libSourceDir + QLatin1Char('/'));
QString errorMessage;
QString code = readFromLocation(location, QString(), &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ warn(msgTagWarning(reader, m_context, m_lastTagName, errorMessage));
m_output << "::\n\n";
Indentation indentation(m_output);
if (code.isEmpty())
@@ -1274,26 +1239,6 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
}
}
-bool QtXmlToSphinx::convertToRst(const QtDocGenerator *generator,
- const QString &sourceFileName,
- const QString &targetFileName,
- const QString &context, QString *errorMessage)
-{
- QFile sourceFile(sourceFileName);
- if (!sourceFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- if (errorMessage)
- *errorMessage = msgCannotOpenForReading(sourceFile);
- return false;
- }
- const QString doc = QString::fromUtf8(sourceFile.readAll());
- sourceFile.close();
-
- FileOut targetFile(targetFileName);
- QtXmlToSphinx x(generator, doc, context);
- targetFile.stream << x;
- return targetFile.done(errorMessage) != FileOut::Failure;
-}
-
void QtXmlToSphinx::Table::normalize()
{
if (m_normalized || isEmpty())
@@ -1355,10 +1300,7 @@ void QtXmlToSphinx::Table::format(TextStream& s) const
if (isEmpty())
return;
- if (!isNormalized()) {
- qCDebug(lcShibokenDoc) << "Attempt to print an unnormalized table!";
- return;
- }
+ Q_ASSERT(isNormalized());
// calc width and height of each column and row
const int headerColumnCount = m_rows.constFirst().count();
@@ -1434,3 +1376,13 @@ void QtXmlToSphinx::stripPythonQualifiers(QString *s)
if (lastSep != -1)
s->remove(0, lastSep + 1);
}
+
+void QtXmlToSphinx::warn(const QString &message) const
+{
+ qCWarning(m_generator->loggingCategory(), "%s", qPrintable(message));
+}
+
+void QtXmlToSphinx::debug(const QString &message) const
+{
+ qCDebug(m_generator->loggingCategory(), "%s", qPrintable(message));
+}