aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-25 10:10:30 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-26 06:20:37 +0000
commit0f247c44a76f26587a5ea0ac9414e054da1f35e1 (patch)
tree22601446acf2c28fb5f5e3f38b5d40d9512cc220
parent44b03e3ded688aabe8352e8bda66df8677acc8a4 (diff)
shiboken6: Port QtDocGenerator to the new text stream
Finally remove the old indentor. Change-Id: I25150f61f914c1a6adc13341057a94c8bd281296 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken6/generator/indentor.h99
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp140
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h22
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp162
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.h11
-rw-r--r--sources/shiboken6/generator/qtdoc/rstformat.h16
6 files changed, 156 insertions, 294 deletions
diff --git a/sources/shiboken6/generator/indentor.h b/sources/shiboken6/generator/indentor.h
deleted file mode 100644
index 4516cbbab..000000000
--- a/sources/shiboken6/generator/indentor.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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$
-**
-****************************************************************************/
-
-#ifndef INDENTOR_H
-#define INDENTOR_H
-
-#include <QtCore/QTextStream>
-
-/**
-* Utility class to store the indentation level, use it in a QTextStream.
-*/
-
-template <int tabWidth>
-class IndentorBase
-{
-public:
- int total() const { return tabWidth * indent; }
-
- int indent = 0;
-};
-
-using Indentor = IndentorBase<4>;
-using Indentor1 = IndentorBase<1>;
-
-/**
-* Class that use the RAII idiom to set and unset the indentation level.
-*/
-
-template <int tabWidth>
-class IndentationBase
-{
-public:
- using Indentor = IndentorBase<tabWidth>;
-
- IndentationBase(Indentor &indentor, int count = 1) : m_count(count), indentor(indentor)
- {
- indentor.indent += m_count;
- }
-
- ~IndentationBase()
- {
- indentor.indent -= m_count;
- }
-
-private:
- const int m_count;
- Indentor &indentor;
-};
-
-using Indentation4 = IndentationBase<4>;
-
-template <int tabWidth>
-inline QTextStream &operator <<(QTextStream &s, const IndentorBase<tabWidth> &indentor)
-{
- for (int i = 0, total = indentor.total(); i < total; ++i)
- s << ' ';
- return s;
-}
-
-template <int tabWidth>
-const char *indent(IndentorBase<tabWidth> &indentor)
-{
- ++indentor.indent;
- return "";
-}
-
-template <int tabWidth>
-const char *outdent(IndentorBase<tabWidth> &indentor)
-{
- --indentor.indent;
- return "";
-}
-
-#endif // GENERATOR_H
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
index a84426ccf..9a53bd97a 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -28,7 +28,6 @@
#include "qtdocgenerator.h"
#include "qtxmltosphinx.h"
-#include "indentor.h"
#include "rstformat.h"
#include "ctypenames.h"
#include <abstractmetaenum.h>
@@ -40,6 +39,7 @@
#include <modifications.h>
#include <propertyspec.h>
#include <reporthandler.h>
+#include <textstream.h>
#include <typesystem.h>
#include <qtdocparser.h>
#include <doxygenparser.h>
@@ -51,8 +51,6 @@
#include <algorithm>
#include <limits>
-static Indentor INDENT;
-
static inline QString additionalDocumentationOption() { return QStringLiteral("additional-documentation"); }
static inline QString briefStartElement() { return QStringLiteral("<brief>"); }
@@ -179,7 +177,7 @@ QString QtDocGenerator::fileNameForContext(const GeneratorContext &context) cons
return fileNameBase + fileNameSuffix();
}
-void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc,
+void QtDocGenerator::writeFormattedText(TextStream &s, const Documentation &doc,
const AbstractMetaClass *metaClass,
Documentation::Type docType) const
{
@@ -189,7 +187,7 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
metaClassName = metaClass->fullName();
if (doc.format() == Documentation::Native) {
- QtXmlToSphinx x(this, INDENT, doc.value(docType), metaClassName);
+ QtXmlToSphinx x(this, doc.value(docType), metaClassName);
s << x;
} else {
const QString &value = doc.value(docType);
@@ -205,17 +203,16 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
if (typesystemIndentation == std::numeric_limits<int>::max())
typesystemIndentation = 0;
for (const auto &line : lines) {
- s << INDENT
- << (typesystemIndentation > 0 && typesystemIndentation < line.size()
+ s << (typesystemIndentation > 0 && typesystemIndentation < line.size()
? line.right(line.size() - typesystemIndentation) : line)
- << Qt::endl;
+ << '\n';
}
}
- s << Qt::endl;
+ s << '\n';
}
-static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses)
+static void writeInheritedByList(TextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses)
{
AbstractMetaClassList res;
for (AbstractMetaClass *c : allClasses) {
@@ -230,7 +227,7 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
QStringList classes;
for (AbstractMetaClass *c : qAsConst(res))
classes << QLatin1String(":ref:`") + c->name() + QLatin1Char('`');
- s << classes.join(QLatin1String(", ")) << Qt::endl << Qt::endl;
+ s << classes.join(QLatin1String(", ")) << "\n\n";
}
// Extract the <brief> section from a WebXML (class) documentation and remove it
@@ -257,9 +254,8 @@ static bool extractBrief(Documentation *sourceDoc, Documentation *brief)
return true;
}
-void QtDocGenerator::generateClass(TextStream &ts, const GeneratorContext &classContext)
+void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classContext)
{
- QTextStream &s = ts.textStream();
const AbstractMetaClass *metaClass = classContext.metaClass();
qCDebug(lcShibokenDoc).noquote().nospace() << "Generating Documentation for " << metaClass->fullName();
@@ -272,16 +268,16 @@ void QtDocGenerator::generateClass(TextStream &ts, const GeneratorContext &class
s << ".. _" << className << ":" << "\n\n";
s << ".. currentmodule:: " << metaClass->package() << "\n\n\n";
- s << className << Qt::endl;
- s << Pad('*', className.count()) << Qt::endl << Qt::endl;
+ s << className << '\n';
+ s << Pad('*', className.count()) << "\n\n";
auto documentation = metaClass->documentation();
Documentation brief;
if (extractBrief(&documentation, &brief))
writeFormattedText(s, brief.value(), metaClass);
- s << ".. inheritance-diagram:: " << metaClass->fullName() << Qt::endl
- << " :parts: 2" << Qt::endl << Qt::endl;
+ s << ".. inheritance-diagram:: " << metaClass->fullName()<< '\n'
+ << " :parts: 2\n\n";
// TODO: This would be a parameter in the future...
@@ -331,7 +327,7 @@ void QtDocGenerator::generateClass(TextStream &ts, const GeneratorContext &class
writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass, nullptr);
}
-void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass* cppClass)
+void QtDocGenerator::writeFunctionList(TextStream& s, const AbstractMetaClass* cppClass)
{
QStringList functionList;
QStringList virtualList;
@@ -387,24 +383,23 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
}
}
-void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions)
+void QtDocGenerator::writeFunctionBlock(TextStream& s, const QString& title, QStringList& functions)
{
if (!functions.isEmpty()) {
- s << title << Qt::endl
- << QString(title.size(), QLatin1Char('^')) << Qt::endl;
+ s << title << '\n'
+ << Pad('^', title.size()) << '\n';
std::sort(functions.begin(), functions.end());
s << ".. container:: function_list\n\n";
- Indentation4 indentation(INDENT);
+ Indentation indentation(s);
for (const QString &func : qAsConst(functions))
- s << INDENT << '*' << ' ' << func << Qt::endl;
-
- s << Qt::endl << Qt::endl;
+ s << "* " << func << '\n';
+ s << "\n\n";
}
}
-void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClass) const
+void QtDocGenerator::writeEnums(TextStream& s, const AbstractMetaClass* cppClass) const
{
static const QString section_title = QLatin1String(".. attribute:: ");
@@ -418,7 +413,7 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
}
-void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppClass) const
+void QtDocGenerator::writeFields(TextStream& s, const AbstractMetaClass* cppClass) const
{
static const QString section_title = QLatin1String(".. attribute:: ");
@@ -428,7 +423,7 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla
}
}
-void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass* cppClass) const
+void QtDocGenerator::writeConstructors(TextStream& s, const AbstractMetaClass* cppClass) const
{
static const QString sectionTitle = QLatin1String(".. class:: ");
@@ -441,25 +436,24 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
bool first = true;
QHash<QString, AbstractMetaArgument> arg_map;
- IndentorBase<1> indent1;
- indent1.indent = INDENT.total();
if (lst.isEmpty()) {
s << sectionTitle << cppClass->fullName();
} else {
+ QByteArray pad;
for (AbstractMetaFunction *func : qAsConst(lst)) {
- s << indent1;
+ s << pad;
if (first) {
first = false;
s << sectionTitle;
- indent1.indent += sectionTitle.size();
+ pad = QByteArray(sectionTitle.size(), ' ');
}
s << functionSignature(cppClass, func) << "\n\n";
const auto version = versionOf(func->typeEntry());
if (!version.isNull())
- s << indent1 << rstVersionAdded(version);
+ s << pad << rstVersionAdded(version);
if (func->attributes().testFlag(AbstractMetaAttributes::Deprecated))
- s << indent1 << rstDeprecationNote("constructor");
+ s << pad << rstDeprecationNote("constructor");
const AbstractMetaArgumentList &arguments = func->arguments();
for (const AbstractMetaArgument &arg : arguments) {
@@ -470,14 +464,15 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
}
}
- s << Qt::endl;
+ s << '\n';
for (auto it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
- Indentation4 indentation(INDENT, 2);
+ s.indent(2);
writeParameterType(s, cppClass, it.value());
+ s.outdent(2);
}
- s << Qt::endl;
+ s << '\n';
for (AbstractMetaFunction *func : qAsConst(lst))
writeFormattedText(s, func->documentation().value(), cppClass);
@@ -531,12 +526,12 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */
return ret;
}
-void QtDocGenerator::writeDocSnips(QTextStream &s,
+void QtDocGenerator::writeDocSnips(TextStream &s,
const CodeSnipList &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language)
{
- Indentation4 indentation(INDENT);
+ Indentation indentation(s);
QStringList invalidStrings;
const static QString startMarkup = QLatin1String("[sphinx-begin]");
const static QString endMarkup = QLatin1String("[sphinx-end]");
@@ -568,7 +563,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
if (row.trimmed().size() == 0) {
if (currentRow == 0)
continue;
- s << Qt::endl;
+ s << '\n';
}
if (currentRow == 0) {
@@ -582,7 +577,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
break;
}
}
- s << QStringView{row}.mid(offset) << Qt::endl;
+ s << QStringView{row}.mid(offset) << '\n';
currentRow++;
}
@@ -591,12 +586,12 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
}
}
-bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
+bool QtDocGenerator::writeInjectDocumentation(TextStream& s,
TypeSystem::DocModificationMode mode,
const AbstractMetaClass* cppClass,
const AbstractMetaFunction* func)
{
- Indentation4 indentation(INDENT);
+ Indentation indentation(s);
bool didSomething = false;
const DocModificationList &mods = cppClass->typeEntry()->docModifications();
@@ -622,7 +617,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
}
}
- s << Qt::endl;
+ s << '\n';
// TODO: Deprecate the use of doc string on glue code.
// This is pre "add-function" and "inject-documentation" tags.
@@ -707,17 +702,17 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
return strType;
}
-void QtDocGenerator::writeParameterType(QTextStream& s, const AbstractMetaClass* cppClass,
+void QtDocGenerator::writeParameterType(TextStream& s, const AbstractMetaClass* cppClass,
const AbstractMetaArgument &arg) const
{
- s << INDENT << ":param " << arg.name() << ": "
- << translateToPythonType(arg.type(), cppClass) << Qt::endl;
+ s << ":param " << arg.name() << ": "
+ << translateToPythonType(arg.type(), cppClass) << '\n';
}
-void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
+void QtDocGenerator::writeFunctionParametersType(TextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction *func) const
{
- s << Qt::endl;
+ s << '\n';
const AbstractMetaArgumentList &funcArgs = func->arguments();
for (const AbstractMetaArgument &arg : funcArgs) {
@@ -742,27 +737,27 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractM
if (retType.isEmpty())
retType = translateToPythonType(func->type(), cppClass);
- s << INDENT << ":rtype: " << retType << Qt::endl;
+ s << ":rtype: " << retType << '\n';
}
- s << Qt::endl;
+ s << '\n';
}
-void QtDocGenerator::writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
+void QtDocGenerator::writeFunction(TextStream& s, const AbstractMetaClass* cppClass,
const AbstractMetaFunction* func, bool indexed)
{
s << functionSignature(cppClass, func);
{
- Indentation4 indentation(INDENT);
+ Indentation indentation(s);
if (!indexed)
- s << QLatin1Char('\n') << INDENT << QLatin1String(":noindex:");
+ s << "\n:noindex:";
s << "\n\n";
writeFunctionParametersType(s, cppClass, func);
const auto version = versionOf(func->typeEntry());
if (!version.isNull())
- s << INDENT << rstVersionAdded(version);
+ s << rstVersionAdded(version);
if (func->attributes().testFlag(AbstractMetaAttributes::Deprecated))
- s << INDENT << rstDeprecationNote("function");
+ s << rstDeprecationNote("function");
}
writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, cppClass, func);
if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, cppClass, func)) {
@@ -772,7 +767,7 @@ void QtDocGenerator::writeFunction(QTextStream& s, const AbstractMetaClass* cppC
writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
}
-static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 2)
+static void writeFancyToc(TextStream& s, const QStringList& items, int cols = 2)
{
using TocMap = QMap<QChar, QStringList>;
TocMap tocMap;
@@ -796,14 +791,14 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 2
int itemsPerCol = (items.size() + tocMap.size()*2) / cols;
QString currentColData;
int i = 0;
- QTextStream ss(&currentColData);
+ TextStream ss(&currentColData);
QMutableMapIterator<QChar, QStringList> it(tocMap);
while (it.hasNext()) {
it.next();
std::sort(it.value().begin(), it.value().end());
if (i)
- ss << Qt::endl;
+ ss << '\n';
ss << "**" << it.key() << "**\n\n";
i += 2; // a letter title is equivalent to two entries in space
@@ -831,7 +826,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 2
table.appendRow(row);
table.normalize();
s << ".. container:: pysidetoc\n\n";
- table.format(s, INDENT);
+ table.format(s);
}
bool QtDocGenerator::finishGeneration()
@@ -851,16 +846,15 @@ void QtDocGenerator::writeModuleDocumentation()
key.replace(QLatin1Char('.'), QLatin1Char('/'));
QString outputDir = outputDirectory() + QLatin1Char('/') + key;
FileOut output(outputDir + QLatin1String("/index.rst"));
- QTextStream& s = output.stream.textStream();
-
- s << ".. module:: " << it.key() << Qt::endl << Qt::endl;
+ TextStream& s = output.stream;
const QString &title = it.key();
- s << title << Qt::endl;
- s << Pad('*', title.length()) << Qt::endl << Qt::endl;
+ s << ".. module:: " << title << "\n\n"
+ << title << '\n'
+ << Pad('*', title.length()) << "\n\n";
/* Avoid showing "Detailed Description for *every* class in toc tree */
- Indentation4 indentation(INDENT);
+ Indentation indentation(s);
// Store the it.key() in a QString so that it can be stripped off unwanted
// information when neeeded. For example, the RST files in the extras directory
// doesn't include the PySide# prefix in their names.
@@ -892,12 +886,12 @@ void QtDocGenerator::writeModuleDocumentation()
writeFancyToc(s, it.value());
- s << INDENT << ".. container:: hide\n\n" << indent(INDENT)
- << INDENT << ".. toctree::\n" << indent(INDENT)
- << INDENT << ":maxdepth: 1\n\n";
+ s << ".. container:: hide\n\n" << indent
+ << ".. toctree::\n" << indent
+ << ":maxdepth: 1\n\n";
for (const QString &className : qAsConst(it.value()))
- s << INDENT << className << Qt::endl;
- s << "\n\n" << outdent(INDENT) << outdent(INDENT)
+ s << className << '\n';
+ s << "\n\n" << outdent << outdent
<< "Detailed Description\n--------------------\n\n";
// module doc is always wrong and C++istic, so go straight to the extra directory!
@@ -911,7 +905,7 @@ void QtDocGenerator::writeModuleDocumentation()
if (moduleDoc.format() == Documentation::Native) {
QString context = it.key();
QtXmlToSphinx::stripPythonQualifiers(&context);
- QtXmlToSphinx x(this, INDENT, moduleDoc.value(), context);
+ QtXmlToSphinx x(this, moduleDoc.value(), context);
s << x;
} else {
s << moduleDoc.value();
@@ -973,7 +967,7 @@ void QtDocGenerator::writeAdditionalDocumentation() const
const QString rstFileName = fi.baseName() + rstSuffix;
const QString rstFile = targetDir + QLatin1Char('/') + rstFileName;
const QString context = targetDir.mid(targetDir.lastIndexOf(QLatin1Char('/')) + 1);
- if (QtXmlToSphinx::convertToRst(this, INDENT, fi.absoluteFilePath(),
+ if (QtXmlToSphinx::convertToRst(this, fi.absoluteFilePath(),
rstFile, context, &errorMessage)) {
++successCount;
qCDebug(lcShibokenDoc).nospace().noquote() << __FUNCTION__
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index 50b5575a6..356a0e210 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -77,26 +77,26 @@ protected:
bool finishGeneration() override;
private:
- void writeEnums(QTextStream& s, const AbstractMetaClass* cppClass) const;
+ void writeEnums(TextStream& s, const AbstractMetaClass* cppClass) const;
- void writeFields(QTextStream &s, const AbstractMetaClass *cppClass) const;
+ void writeFields(TextStream &s, const AbstractMetaClass *cppClass) const;
static QString functionSignature(const AbstractMetaClass* cppClass,
const AbstractMetaFunction* func);
- void writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
+ void writeFunction(TextStream& s, const AbstractMetaClass* cppClass,
const AbstractMetaFunction* func, bool indexed = true);
- void writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
+ void writeFunctionParametersType(TextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction* func) const;
- void writeFunctionList(QTextStream& s, const AbstractMetaClass* cppClass);
- void writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions);
- void writeParameterType(QTextStream &s, const AbstractMetaClass *cppClass,
+ void writeFunctionList(TextStream& s, const AbstractMetaClass* cppClass);
+ void writeFunctionBlock(TextStream& s, const QString& title, QStringList& functions);
+ void writeParameterType(TextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaArgument &arg) const;
- void writeConstructors(QTextStream &s, const AbstractMetaClass *cppClass) const;
- void writeFormattedText(QTextStream &s, const Documentation &doc,
+ void writeConstructors(TextStream &s, const AbstractMetaClass *cppClass) const;
+ void writeFormattedText(TextStream &s, const Documentation &doc,
const AbstractMetaClass *metaclass = nullptr,
Documentation::Type docType = Documentation::Detailed) const;
- bool writeInjectDocumentation(QTextStream& s, TypeSystem::DocModificationMode mode, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
- void writeDocSnips(QTextStream &s, const CodeSnipList &codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
+ bool writeInjectDocumentation(TextStream& s, TypeSystem::DocModificationMode mode, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
+ void writeDocSnips(TextStream &s, const CodeSnipList &codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
void writeModuleDocumentation();
void writeAdditionalDocumentation() const;
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index eff4b5121..427421a17 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -28,7 +28,6 @@
#include "qtxmltosphinx.h"
#include "fileout.h"
-#include "indentor.h"
#include "messages.h"
#include "rstformat.h"
#include "qtdocgenerator.h"
@@ -49,33 +48,6 @@ static inline QString titleAttribute() { return QStringLiteral("title"); }
static inline QString fullTitleAttribute() { return QStringLiteral("fulltitle"); }
static inline QString briefAttribute() { return QStringLiteral("brief"); }
-static QTextStream &formatCode(QTextStream &s, const QString &code, const Indentor &indentor)
-{
- const auto lines= QStringView{code}.split(QLatin1Char('\n'));
- for (const auto &line : lines) {
- // Do not indent preprocessor lines
- if (!line.isEmpty() && !line.startsWith(QLatin1Char('#')))
- s << indentor;
- s << line << '\n';
- }
- return s;
-}
-
-// Return last character of a QString-buffered stream.
-static QChar lastChar(const QTextStream &str)
-{
- const QString *string = str.string();
- Q_ASSERT(string);
- return string->isEmpty() ? QChar() : *(string->crbegin());
-}
-
-static QTextStream &ensureEndl(QTextStream &s)
-{
- if (lastChar(s) != QLatin1Char('\n'))
- s << '\n';
- return s;
-}
-
struct QtXmlToSphinx::LinkContext
{
enum Type
@@ -119,7 +91,7 @@ static const char *linkKeyWord(QtXmlToSphinx::LinkContext::Type type)
return "";
}
-QTextStream &operator<<(QTextStream &str, const QtXmlToSphinx::LinkContext &linkContext)
+TextStream &operator<<(TextStream &str, const QtXmlToSphinx::LinkContext &linkContext)
{
// Temporarily turn off bold/italic since links do not work within
if (linkContext.flags & QtXmlToSphinx::LinkContext::InsideBold)
@@ -150,10 +122,11 @@ QTextStream &operator<<(QTextStream &str, const QtXmlToSphinx::LinkContext &link
return str;
}
-QtXmlToSphinx::QtXmlToSphinx(const QtDocGenerator *generator, Indentor &indentor,
+QtXmlToSphinx::QtXmlToSphinx(const QtDocGenerator *generator,
const QString& doc, const QString& context)
- : m_tableHasHeader(false), m_context(context), m_generator(generator),
- INDENT(indentor), m_insideBold(false), m_insideItalic(false)
+ : m_output(static_cast<QString *>(nullptr)),
+ m_tableHasHeader(false), m_context(context), m_generator(generator),
+ m_insideBold(false), m_insideItalic(false)
{
m_handlerMap.insert(QLatin1String("heading"), &QtXmlToSphinx::handleHeadingTag);
m_handlerMap.insert(QLatin1String("brief"), &QtXmlToSphinx::handleParaTag);
@@ -305,7 +278,7 @@ QString QtXmlToSphinx::resolveContextForMethod(const QString& methodName) const
QString QtXmlToSphinx::transform(const QString& doc)
{
Q_ASSERT(m_buffers.isEmpty());
- Indentation4 indentation(INDENT);
+ Indentation indentation(m_output);
if (doc.trimmed().isEmpty())
return doc;
@@ -320,7 +293,7 @@ QString QtXmlToSphinx::transform(const QString& doc)
QTextStream(&message) << "XML Error "
<< reader.errorString() << " at " << reader.lineNumber()
<< ':' << reader.columnNumber() << '\n' << doc;
- m_output << INDENT << message;
+ m_output << message;
qCWarning(lcShibokenDoc).noquote().nospace() << message;
break;
}
@@ -345,10 +318,10 @@ QString QtXmlToSphinx::transform(const QString& doc)
if (!m_inlineImages.isEmpty()) {
// Write out inline image definitions stored in handleInlineImageTag().
- m_output << '\n';
+ m_output << '\n' << disableIndent;
for (const InlineImage &img : qAsConst(m_inlineImages))
m_output << ".. |" << img.tag << "| image:: " << img.href << '\n';
- m_output << '\n';
+ m_output << '\n' << enableIndent;
m_inlineImages.clear();
}
@@ -451,11 +424,12 @@ void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
else
type = types[typeIdx];
} else if (token == QXmlStreamReader::EndElement) {
- m_output << Pad(type, headingSize) << "\n\n";
+ m_output << disableIndent << Pad(type, headingSize) << "\n\n"
+ << enableIndent;
} else if (token == QXmlStreamReader::Characters) {
- m_output << "\n\n";
+ m_output << "\n\n" << disableIndent;
headingSize = writeEscapedRstText(m_output, reader.text().trimmed());
- m_output << '\n';
+ m_output << '\n' << enableIndent;
}
}
@@ -471,16 +445,16 @@ void QtXmlToSphinx::handleParaTag(QXmlStreamReader& reader)
else if (result.startsWith(QLatin1String("**Note:**")))
result.replace(0, 9, QLatin1String(".. note:: "));
- m_output << INDENT << result << "\n\n";
+ m_output << result << "\n\n";
} else if (token == QXmlStreamReader::Characters) {
const auto text = reader.text();
- const QChar end = lastChar(m_output);
- if (!text.isEmpty() && INDENT.indent == 0 && !end.isNull()) {
+ const QChar end = m_output.lastChar();
+ if (!text.isEmpty() && m_output.indentation() == 0 && !end.isNull()) {
QChar start = text[0];
if ((end == QLatin1Char('*') || end == QLatin1Char('`')) && start != QLatin1Char(' ') && !start.isPunct())
m_output << '\\';
}
- m_output << INDENT << escape(text);
+ m_output << escape(text);
}
}
@@ -548,7 +522,7 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
{
switch (reader.tokenType()) {
case QXmlStreamReader::StartElement:
- m_output << INDENT << ".. seealso:: ";
+ m_output << ".. seealso:: ";
break;
case QXmlStreamReader::Characters: {
// Direct embedded link: <see-also>rootIsDecorated()</see-also>
@@ -584,7 +558,7 @@ static inline bool snippetComparison()
}
template <class Indent> // const char*/class Indentor
-void formatSnippet(QTextStream &str, Indent indent, const QString &snippet)
+void formatSnippet(TextStream &str, Indent indent, const QString &snippet)
{
const auto lines = QStringView{snippet}.split(QLatin1Char('\n'));
for (const auto &line : lines) {
@@ -597,17 +571,15 @@ void formatSnippet(QTextStream &str, Indent indent, const QString &snippet)
static QString msgSnippetComparison(const QString &location, const QString &identifier,
const QString &pythonCode, const QString &fallbackCode)
{
- QString result;
- QTextStream str(&result);
+ StringStream str;
+ str.setTabWidth(2);
str << "Python snippet " << location;
if (!identifier.isEmpty())
str << " [" << identifier << ']';
- str << ":\n";
- formatSnippet(str, " ", pythonCode);
- str << "Corresponding fallback snippet:\n";
- formatSnippet(str, " ", fallbackCode);
- str << "-- end --\n";
- return result;
+ str << ":\n" << indent << pythonCode << ensureEndl << outdent
+ << "Corresponding fallback snippet:\n"
+ << indent << fallbackCode << ensureEndl << outdent << "-- end --\n";
+ return str;
}
void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
@@ -646,14 +618,14 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
qCDebug(lcShibokenDoc, "%s", qPrintable(msgSnippetComparison(location, identifier, pythonCode, fallbackCode)));
if (!consecutiveSnippet)
- m_output << INDENT << "::\n\n";
+ m_output << "::\n\n";
- Indentation4 indentation(INDENT);
+ Indentation indentation(m_output);
const QString code = pythonCode.isEmpty() ? fallbackCode : pythonCode;
if (code.isEmpty())
- m_output << INDENT << "<Code snippet \"" << location << ':' << identifier << "\" not found>\n";
+ m_output << "<Code snippet \"" << location << ':' << identifier << "\" not found>\n";
else
- formatSnippet(m_output, INDENT, code);
+ m_output << code << ensureEndl;
m_output << '\n';
}
}
@@ -667,18 +639,17 @@ void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
m_output.flush();
m_output.string()->chop(2);
} else {
- m_output << INDENT << "::\n\n";
+ m_output << "::\n\n";
}
- Indentation4 indentation(INDENT);
+ Indentation indentation(m_output);
pushOutputBuffer();
- m_output << INDENT;
int indent = reader.attributes().value(QLatin1String("indent")).toInt();
for (int i = 0; i < indent; ++i)
m_output << ' ';
} else if (token == QXmlStreamReader::Characters) {
m_output << reader.text().toString();
} else if (token == QXmlStreamReader::EndElement) {
- m_output << popOutputBuffer() << "\n\n\n";
+ m_output << disableIndent << popOutputBuffer() << "\n\n\n" << enableIndent;
}
}
@@ -693,7 +664,7 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
m_currentTable.setHeaderEnabled(m_tableHasHeader);
m_currentTable.normalize();
m_output << ensureEndl;
- m_currentTable.format(m_output, INDENT);
+ m_currentTable.format(m_output);
m_currentTable.clear();
}
}
@@ -767,21 +738,21 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
TableCell(QLatin1String("Description"))});
m_tableHasHeader = true;
}
- INDENT.indent--;
+ m_output.indent();
} else if (token == QXmlStreamReader::EndElement) {
- INDENT.indent++;
+ m_output.outdent();
if (!m_currentTable.isEmpty()) {
switch (listType) {
case BulletList:
case OrderedList: {
m_output << '\n';
const char *separator = listType == BulletList ? "* " : "#. ";
- const char *indent = listType == BulletList ? " " : " ";
+ const char *indentLine = listType == BulletList ? " " : " ";
for (const TableCell &cell : m_currentTable.constFirst()) {
const auto itemLines = QStringView{cell.data}.split(QLatin1Char('\n'));
- m_output << INDENT << separator << itemLines.constFirst() << '\n';
+ m_output << separator << itemLines.constFirst() << '\n';
for (int i = 1, max = itemLines.count(); i < max; ++i)
- m_output << INDENT << indent << itemLines[i] << '\n';
+ m_output << indentLine << itemLines[i] << '\n';
}
m_output << '\n';
}
@@ -790,7 +761,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
m_currentTable.setHeaderEnabled(m_tableHasHeader);
m_currentTable.normalize();
m_output << ensureEndl;
- m_currentTable.format(m_output, INDENT);
+ m_currentTable.format(m_output);
break;
}
}
@@ -989,7 +960,7 @@ void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
return;
const QString href = reader.attributes().value(QLatin1String("href")).toString();
if (copyImage(href))
- m_output << INDENT << ".. image:: " << href << "\n\n";
+ m_output << ".. image:: " << href << "\n\n";
}
void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
@@ -1019,11 +990,10 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
QString format = reader.attributes().value(QLatin1String("format")).toString();
- m_output << INDENT << ".. raw:: " << format.toLower() << "\n\n";
+ m_output << ".. raw:: " << format.toLower() << "\n\n";
} else if (token == QXmlStreamReader::Characters) {
- const auto lst(reader.text().split(QLatin1Char('\n')));
- for (const auto &row : lst)
- m_output << INDENT << INDENT << row << '\n';
+ Indentation indent(m_output);
+ m_output << reader.text();
} else if (token == QXmlStreamReader::EndElement) {
m_output << "\n\n";
}
@@ -1033,15 +1003,12 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- m_output << INDENT << "::\n\n";
- INDENT.indent++;
+ m_output << "::\n\n" << indent;
} else if (token == QXmlStreamReader::Characters) {
- const auto lst(reader.text().split(QLatin1Char('\n')));
- for (const auto &row : lst)
- m_output << INDENT << INDENT << row << '\n';
+ Indentation indent(m_output);
+ m_output << reader.text();
} else if (token == QXmlStreamReader::EndElement) {
- m_output << "\n\n";
- INDENT.indent--;
+ m_output << outdent << "\n\n";
}
}
@@ -1071,6 +1038,8 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader)
if (reader.tokenType() != QXmlStreamReader::StartElement)
return;
+ m_output << disableIndent;
+
const auto title = reader.attributes().value(titleAttribute());
if (!title.isEmpty())
m_output << rstLabel(title.toString());
@@ -1080,7 +1049,8 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader)
? writeEscapedRstText(m_output, title)
: writeEscapedRstText(m_output, fullTitle);
- m_output << '\n' << Pad('*', size) << "\n\n";
+ m_output << '\n' << Pad('*', size) << "\n\n"
+ << enableIndent;
}
void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader)
@@ -1089,7 +1059,7 @@ void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader)
return;
const auto name = reader.attributes().value(nameAttribute());
if (!name.isEmpty())
- m_output << INDENT << rstLabel(name.toString());
+ m_output << rstLabel(name.toString());
}
void QtXmlToSphinx::handleIgnoredTag(QXmlStreamReader&)
@@ -1115,7 +1085,7 @@ void QtXmlToSphinx::handleAnchorTag(QXmlStreamReader& reader)
m_opened_anchor = anchor;
if (!m_context.isEmpty())
anchor.prepend(m_context + QLatin1Char('_'));
- m_output << INDENT << rstLabel(anchor);
+ m_output << rstLabel(anchor);
}
} else if (token == QXmlStreamReader::EndElement) {
m_opened_anchor.clear();
@@ -1138,18 +1108,17 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
QString code = readFromLocation(location, QString(), &errorMessage);
if (!errorMessage.isEmpty())
qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
- m_output << INDENT << "::\n\n";
- Indentation4 indentation(INDENT);
+ m_output << "::\n\n";
+ Indentation indentation(m_output);
if (code.isEmpty())
- m_output << INDENT << "<Code snippet \"" << location << "\" not found>\n";
+ m_output << "<Code snippet \"" << location << "\" not found>\n";
else
- formatCode(m_output, code, INDENT);
+ m_output << code << ensureEndl;
m_output << '\n';
}
}
bool QtXmlToSphinx::convertToRst(const QtDocGenerator *generator,
- Indentor &indentor,
const QString &sourceFileName,
const QString &targetFileName,
const QString &context, QString *errorMessage)
@@ -1164,8 +1133,8 @@ bool QtXmlToSphinx::convertToRst(const QtDocGenerator *generator,
sourceFile.close();
FileOut targetFile(targetFileName);
- QtXmlToSphinx x(generator, indentor, doc, context);
- targetFile.stream.textStream() << x;
+ QtXmlToSphinx x(generator, doc, context);
+ targetFile.stream << x;
return targetFile.done(errorMessage) != FileOut::Failure;
}
@@ -1225,7 +1194,7 @@ void QtXmlToSphinx::Table::normalize()
m_normalized = true;
}
-void QtXmlToSphinx::Table::format(QTextStream& s, const Indentor &INDENT) const
+void QtXmlToSphinx::Table::format(TextStream& s) const
{
if (isEmpty())
return;
@@ -1264,7 +1233,7 @@ void QtXmlToSphinx::Table::format(QTextStream& s, const Indentor &INDENT) const
const QtXmlToSphinx::TableRow& row = m_rows.at(i);
// print line
- s << INDENT << '+';
+ s << '+';
for (int col = 0; col < headerColumnCount; ++col) {
char c;
if (col >= row.length() || row[col].rowSpan == -1)
@@ -1284,24 +1253,23 @@ void QtXmlToSphinx::Table::format(QTextStream& s, const Indentor &INDENT) const
for (int maxJ = std::min(int(row.count()), headerColumnCount); j < maxJ; ++j) { // for each column
const QtXmlToSphinx::TableCell& cell = row[j];
const auto rowLines = QStringView{cell.data}.split(QLatin1Char('\n')); // FIXME: Cache this!!!
- if (!j) // First column, so we need print the identation
- s << INDENT;
if (!j || !cell.colSpan)
s << '|';
else
s << ' ';
+ const int width = colWidths.at(j);
if (rowLine < rowLines.count())
- s << qSetFieldWidth(colWidths[j]) << Qt::left << rowLines.at(rowLine) << qSetFieldWidth(0);
+ s << AlignedField(rowLines.at(rowLine), width);
else
- s << Pad(' ', colWidths.at(j));
+ s << Pad(' ', width);
}
for ( ; j < headerColumnCount; ++j) // pad
s << '|' << Pad(' ', colWidths.at(j));
s << "|\n";
}
}
- s << INDENT << horizontalLine << "\n\n";
+ s << horizontalLine << "\n\n";
}
void QtXmlToSphinx::stripPythonQualifiers(QString *s)
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
index 636897fc4..7b6b7231d 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
@@ -29,7 +29,7 @@
#ifndef QTXMLTOSPHINX_H
#define QTXMLTOSPHINX_H
-#include "indentor.h"
+#include <textstream.h>
#include <QtCore/QHash>
#include <QtCore/QList>
@@ -102,7 +102,7 @@ public:
TableRow &first() { return m_rows.first(); }
TableRow &last() { return m_rows.last(); }
- void format(QTextStream& s, const Indentor &indent) const;
+ void format(TextStream& s) const;
private:
QList<TableRow> m_rows;
@@ -111,13 +111,11 @@ public:
};
explicit QtXmlToSphinx(const QtDocGenerator *generator,
- Indentor &indentor,
const QString& doc,
const QString& context = QString());
~QtXmlToSphinx();
static bool convertToRst(const QtDocGenerator *generator,
- Indentor &indentor,
const QString &sourceFileName,
const QString &targetFileName,
const QString &context = QString(),
@@ -174,7 +172,7 @@ private:
typedef void (QtXmlToSphinx::*TagHandler)(QXmlStreamReader&);
QHash<QString, TagHandler> m_handlerMap;
QStack<TagHandler> m_handlers;
- QTextStream m_output;
+ TextStream m_output;
QString m_result;
QStack<QString*> m_buffers;
@@ -186,7 +184,6 @@ private:
bool m_tableHasHeader;
QString m_context;
const QtDocGenerator* m_generator;
- Indentor &INDENT;
bool m_insideBold;
bool m_insideItalic;
QString m_lastTagName;
@@ -203,7 +200,7 @@ private:
bool copyImage(const QString &href) const;
};
-inline QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx& xmlToSphinx)
+inline TextStream& operator<<(TextStream& s, const QtXmlToSphinx& xmlToSphinx)
{
return s << xmlToSphinx.result();
}
diff --git a/sources/shiboken6/generator/qtdoc/rstformat.h b/sources/shiboken6/generator/qtdoc/rstformat.h
index 628f33157..d14ecc55d 100644
--- a/sources/shiboken6/generator/qtdoc/rstformat.h
+++ b/sources/shiboken6/generator/qtdoc/rstformat.h
@@ -29,6 +29,8 @@
#ifndef RSTFORMAT_H
#define RSTFORMAT_H
+#include <textstream.h>
+
#include <QtCore/QByteArray>
#include <QtCore/QString>
#include <QtCore/QTextStream>
@@ -41,7 +43,7 @@ struct rstVersionAdded
const QVersionNumber m_version;
};
-inline QTextStream &operator<<(QTextStream &s, const rstVersionAdded &v)
+inline TextStream &operator<<(TextStream &s, const rstVersionAdded &v)
{
s << ".. versionadded:: "<< v.m_version.toString() << "\n\n";
return s;
@@ -58,7 +60,7 @@ class Pad
public:
explicit Pad(char c, int count) : m_char(c), m_count(count) {}
- void write(QTextStream &str) const
+ void write(TextStream &str) const
{
for (int i = 0; i < m_count; ++i)
str << m_char;
@@ -69,14 +71,14 @@ private:
const int m_count;
};
-inline QTextStream &operator<<(QTextStream &str, const Pad &pad)
+inline TextStream &operator<<(TextStream &str, const Pad &pad)
{
pad.write(str);
return str;
}
template <class String>
-inline int writeEscapedRstText(QTextStream &str, const String &s)
+inline int writeEscapedRstText(TextStream &str, const String &s)
{
int escaped = 0;
for (const QChar &c : s) {
@@ -99,13 +101,13 @@ class escape
public:
explicit escape(QStringView s) : m_string(s) {}
- void write(QTextStream &str) const { writeEscapedRstText(str, m_string); }
+ void write(TextStream &str) const { writeEscapedRstText(str, m_string); }
private:
const QStringView m_string;
};
-inline QTextStream &operator<<(QTextStream &str, const escape &e)
+inline TextStream &operator<<(TextStream &str, const escape &e)
{
e.write(str);
return str;
@@ -131,7 +133,7 @@ class rstLabel
public:
explicit rstLabel(const QString &l) : m_label(l) {}
- friend QTextStream &operator<<(QTextStream &str, const rstLabel &a)
+ friend TextStream &operator<<(TextStream &str, const rstLabel &a)
{
str << ".. _" << toRstLabel(a.m_label) << ":\n\n";
return str;