aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-12-12 14:13:28 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-01-17 12:00:43 +0100
commit81ae1853d8510909413a46ab0c27c5eb68a7816e (patch)
treecc18134fc255c004e70c499e2028036aaf0e8d5e /sources/shiboken6/generator
parentc8ec3e32cb30dc7afe65a60675426e425e6ecbd1 (diff)
Documentation: Use more domain directives from sphinx
PySide's class pages were documents with the class name as anchor and a headline with the class name. The content was written out flat with fully qualified function/property/enum names. Besides having the fully qualified names in the text, this causes problems like duplicated module prefixes in the sphinx inventory and in tooltips. Change this to - Use the :class: domain directive from sphinx along with the module for classes at the top - Indent the following class description accordingly - Change constructors to be listed as __init__() methods - List enums as nested classes - Write enums before properties - Use standard references for methods in the functions TOC (which strips the parameters, hence build unique lists). Task-number: PYSIDE-1106 Task-number: PYSIDE-2215 Change-Id: I92ab39af1c35317cddf47cebbf97da5dc852eb33 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken6/generator')
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp222
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h11
2 files changed, 71 insertions, 162 deletions
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
index 7dd125c4c..6be090aba 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -81,8 +81,7 @@ struct GeneratorDocumentation
AbstractMetaFunctionCPtr notify;
};
- AbstractMetaFunctionCList constructors;
- AbstractMetaFunctionCList allFunctions; // Except constructors
+ AbstractMetaFunctionCList allFunctions;
AbstractMetaFunctionCList tocNormalFunctions; // Index lists
AbstractMetaFunctionCList tocVirtuals;
AbstractMetaFunctionCList tocSignalFunctions;
@@ -98,13 +97,12 @@ static bool operator<(const GeneratorDocumentation::Property &lhs,
return lhs.name < rhs.name;
}
-static QString propertyRefTarget(const AbstractMetaClassCPtr &cppClass, const QString &name)
+static QString propertyRefTarget(const QString &name)
{
- QString result = cppClass->fullName() + u'.' + name;
- result.replace(u"::"_s, u"."_s);
+ QString result = name;
// For sphinx referencing, disambiguate the target from the getter name
- // by inserting an invisible "Hangul choseong filler" character.
- result.insert(1, QChar(0x115F));
+ // by appending an invisible "Hangul choseong filler" character.
+ result.append(QChar(0x115F));
return result;
}
@@ -147,7 +145,9 @@ static bool shouldSkip(const AbstractMetaFunctionCPtr &func)
static bool functionSort(const AbstractMetaFunctionCPtr &func1, const AbstractMetaFunctionCPtr &func2)
{
- return func1->name() < func2->name();
+ const bool ctor1 = func1->isConstructor();
+ const bool ctor2 = func2->isConstructor();
+ return ctor1 != ctor2 ? ctor1 : func1->name() < func2->name();
}
static inline QVersionNumber versionOf(const TypeEntryCPtr &te)
@@ -160,28 +160,18 @@ static inline QVersionNumber versionOf(const TypeEntryCPtr &te)
return {};
}
-// Format a documentation reference (meth/attr): ":meth:`name<target>`"
-// We do not use the short form ":meth:`~target`" since that adds parentheses ()
-// for functions where we list the parameters instead.
struct docRef
{
- explicit docRef(const char *kind, const QString &name,
- const AbstractMetaClassCPtr &cppClass) :
- m_kind(kind), m_name(name), m_cppClass(cppClass) {}
+ explicit docRef(const char *kind, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
const char *m_kind;
- const QString &m_name;
- const AbstractMetaClassCPtr m_cppClass;
+ QAnyStringView m_name;
};
static TextStream &operator<<(TextStream &s, const docRef &dr)
{
- QString className = dr.m_cppClass->fullName();
- className.replace(u"::"_s, u"."_s);
- s << ':' << dr.m_kind << ":`" << dr.m_name << '<';
- if (!dr.m_name.startsWith(className))
- s << className << '.';
- s << dr.m_name << ">`";
+ s << ':' << dr.m_kind << ":`" << dr.m_name << '`';
return s;
}
@@ -189,42 +179,29 @@ static TextStream &operator<<(TextStream &s, const docRef &dr)
// by using '~'), usable for property/attributes ("attr").
struct shortDocRef
{
- explicit shortDocRef(const char *kind, const QString &target) :
- m_kind(kind), m_target(target) {}
+ explicit shortDocRef(const char *kind, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
const char *m_kind;
- const QString &m_target;
+ QAnyStringView m_name;
};
static TextStream &operator<<(TextStream &s, const shortDocRef &sdr)
{
- s << ':' << sdr.m_kind << ":`~" << sdr.m_target << '`';
+ s << ':' << sdr.m_kind << ":`~" << sdr.m_name << '`';
return s;
}
struct functionRef : public docRef
{
- explicit functionRef(const QString &name, const AbstractMetaClassCPtr &cppClass) :
- docRef("meth", name, cppClass) {}
+ explicit functionRef(QAnyStringView name) : docRef("meth", name) {}
};
-struct functionTocEntry // Format a TOC entry for a function
+struct classRef : public shortDocRef
{
- explicit functionTocEntry(const AbstractMetaFunctionCPtr& func,
- const AbstractMetaClassCPtr &cppClass) :
- m_func(func), m_cppClass(cppClass) {}
-
- AbstractMetaFunctionCPtr m_func;
- const AbstractMetaClassCPtr m_cppClass;
+ explicit classRef(QAnyStringView name) : shortDocRef("class", name) {}
};
-static TextStream &operator<<(TextStream &s, const functionTocEntry &ft)
-{
- s << functionRef(QtDocGenerator::getFuncName(ft.m_func), ft.m_cppClass)
- << ' ' << QtDocGenerator::formatArgs(ft.m_func);
- return s;
-}
-
struct propRef : public shortDocRef // Attribute/property (short) reference
{
explicit propRef(const QString &target) :
@@ -246,16 +223,16 @@ static TextStream &operator<<(TextStream &s, const headline &h)
return s;
}
-struct anchor
+struct pyClass
{
- explicit anchor(QAnyStringView ref) : m_ref(ref) {}
+ explicit pyClass(QAnyStringView name) : m_name(name) {}
- QAnyStringView m_ref;
+ QAnyStringView m_name;
};
-static TextStream &operator<<(TextStream &s, const anchor &a)
+static TextStream &operator<<(TextStream &s, pyClass c)
{
- s << ".. _" << a.m_ref << ":\n\n";
+ s << ".. py:class:: " << c.m_name << "\n\n";
return s;
}
@@ -348,7 +325,7 @@ static void writeInheritanceList(TextStream &s, const AbstractMetaClassCList& cl
for (qsizetype i = 0, size = classes.size(); i < size; ++i) {
if (i > 0)
s << ", ";
- s << ":ref:`" << classes.at(i)->name() << '`';
+ s << classRef(classes.at(i)->fullName());
}
s << "\n\n";
}
@@ -390,9 +367,8 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
m_docParser->setPackageName(metaClass->package());
m_docParser->fillDocumentation(std::const_pointer_cast<AbstractMetaClass>(metaClass));
- QString className = metaClass->name();
- s << anchor(className) << currentModule(metaClass->package())
- << headline(className, '*');
+ s << currentModule(metaClass->package()) << pyClass(metaClass->name());
+ Indentation indent(s);
auto documentation = metaClass->documentation();
const QString scope = classScope(metaClass);
@@ -418,12 +394,12 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
if (!doc.allFunctions.isEmpty() || !doc.properties.isEmpty()) {
s << '\n' << headline("Synopsis");
- writePropertyToc(s, doc, metaClass);
- writeFunctionToc(s, u"Functions"_s, metaClass, doc.tocNormalFunctions);
- writeFunctionToc(s, u"Virtual functions"_s, metaClass, doc.tocVirtuals);
- writeFunctionToc(s, u"Slots"_s, metaClass, doc.tocSlotFunctions);
- writeFunctionToc(s, u"Signals"_s, metaClass, doc.tocSignalFunctions);
- writeFunctionToc(s, u"Static functions"_s, metaClass, doc.tocStaticFunctions);
+ writePropertyToc(s, doc);
+ writeFunctionToc(s, u"Methods"_s, doc.tocNormalFunctions);
+ writeFunctionToc(s, u"Virtual methods"_s, doc.tocVirtuals);
+ writeFunctionToc(s, u"Slots"_s, doc.tocSlotFunctions);
+ writeFunctionToc(s, u"Signals"_s, doc.tocSignalFunctions);
+ writeFunctionToc(s, u"Static functions"_s, doc.tocStaticFunctions);
}
s << "\n.. note::\n"
@@ -440,13 +416,11 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
writeFormattedDetailedText(s, documentation, scope);
writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass);
- if (!metaClass->isNamespace())
- writeConstructors(s, metaClass, doc.constructors);
+ writeEnums(s, metaClass->enums(), scope);
if (!doc.properties.isEmpty())
writeProperties(s, doc, metaClass);
- writeEnums(s, metaClass->enums(), scope);
if (!metaClass->isNamespace())
writeFields(s, metaClass);
@@ -454,21 +428,25 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
}
void QtDocGenerator::writeFunctionToc(TextStream &s, const QString &title,
- const AbstractMetaClassCPtr &cppClass,
const AbstractMetaFunctionCList &functions)
{
if (!functions.isEmpty()) {
s << headline(title, '^')
<< ".. container:: function_list\n\n" << indent;
- for (const auto &func : functions)
- s << "* def " << functionTocEntry(func, cppClass) << '\n';
+ // Functions are sorted by the Metabuilder; erase overloads
+ QStringList toc;
+ toc.reserve(functions.size());
+ std::transform(functions.cbegin(), functions.end(),
+ std::back_inserter(toc), getFuncName);
+ toc.erase(std::unique(toc.begin(), toc.end()), toc.end());
+ for (const auto &func : toc)
+ s << "* def " << functionRef(func) << '\n';
s << outdent << "\n\n";
}
}
void QtDocGenerator::writePropertyToc(TextStream &s,
- const GeneratorDocumentation &doc,
- const AbstractMetaClassCPtr &cppClass)
+ const GeneratorDocumentation &doc)
{
if (doc.properties.isEmpty())
return;
@@ -476,7 +454,7 @@ void QtDocGenerator::writePropertyToc(TextStream &s,
s << headline("Properties", '^')
<< ".. container:: function_list\n\n" << indent;
for (const auto &prop : doc.properties) {
- s << "* " << propRef(propertyRefTarget(cppClass, prop.name));
+ s << "* " << propRef(propertyRefTarget(prop.name));
if (prop.documentation.hasBrief())
s << " - " << prop.documentation.brief();
s << '\n';
@@ -495,19 +473,19 @@ void QtDocGenerator::writeProperties(TextStream &s,
const QString scope = classScope(cppClass);
for (const auto &prop : doc.properties) {
const QString type = translateToPythonType(prop.type, cppClass, /* createRef */ false);
- s << ".. py:property:: " << propertyRefTarget(cppClass, prop.name)
+ s << ".. py:property:: " << propertyRefTarget(prop.name)
<< "\n :type: " << type << "\n\n\n";
if (!prop.documentation.isEmpty())
writeFormattedText(s, prop.documentation.detailed(), Documentation::Native, scope);
s << "**Access functions:**\n";
if (prop.getter)
- s << " * " << functionTocEntry(prop.getter, cppClass) << '\n';
+ s << " * " << functionRef(prop.getter->name()) << '\n';
if (prop.setter)
- s << " * " << functionTocEntry(prop.setter, cppClass) << '\n';
+ s << " * " << functionRef(prop.setter->name()) << '\n';
if (prop.reset)
- s << " * " << functionTocEntry(prop.reset, cppClass) << '\n';
+ s << " * " << functionRef(prop.reset->name()) << '\n';
if (prop.notify)
- s << " * Signal " << functionTocEntry(prop.notify, cppClass) << '\n';
+ s << " * Signal " << functionRef(prop.notify->name()) << '\n';
s << '\n';
}
}
@@ -515,10 +493,9 @@ void QtDocGenerator::writeProperties(TextStream &s,
void QtDocGenerator::writeEnums(TextStream &s, const AbstractMetaEnumList &enums,
const QString &scope) const
{
- constexpr auto section_title = ".. attribute:: "_L1;
-
for (const AbstractMetaEnum &en : enums) {
- s << section_title << scope << '.' << en.name() << "\n\n";
+ s << pyClass(en.name());
+ Indentation indent(s);
writeFormattedDetailedText(s, en.documentation(), scope);
const auto version = versionOf(en.typeEntry());
if (!version.isNull())
@@ -538,57 +515,6 @@ void QtDocGenerator::writeFields(TextStream &s, const AbstractMetaClassCPtr &cpp
}
}
-void QtDocGenerator::writeConstructors(TextStream &s, const AbstractMetaClassCPtr &cppClass,
- const AbstractMetaFunctionCList &constructors) const
-{
- constexpr auto sectionTitle = ".. class:: "_L1;
-
- bool first = true;
- QHash<QString, AbstractMetaArgument> arg_map;
- const QString scope = classScope(cppClass);
-
- if (constructors.isEmpty()) {
- s << sectionTitle << cppClass->fullName();
- } else {
- QByteArray pad;
- for (const auto &func : constructors) {
- s << pad;
- if (first) {
- first = false;
- s << sectionTitle;
- pad = QByteArray(sectionTitle.size(), ' ');
- }
- s << functionSignature(func, scope) << "\n\n";
-
- const auto version = versionOf(func->typeEntry());
- if (!version.isNull())
- s << pad << rstVersionAdded(version);
- if (func->isDeprecated())
- s << pad << rstDeprecationNote("constructor");
-
- const AbstractMetaArgumentList &arguments = func->arguments();
- for (const AbstractMetaArgument &arg : arguments) {
- if (!arg_map.contains(arg.name())) {
- arg_map.insert(arg.name(), arg);
- }
- }
- }
- }
-
- s << '\n';
-
- for (auto it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
- s.indent(2);
- writeParameterType(s, cppClass, it.value());
- s.outdent(2);
- }
-
- s << '\n';
-
- for (const auto &func : constructors)
- writeFunctionDocumentation(s, func, DocParser::getDocModifications(func, cppClass), scope);
-}
-
QString QtDocGenerator::formatArgs(const AbstractMetaFunctionCPtr &func)
{
QString ret = u"("_s;
@@ -753,22 +679,9 @@ bool QtDocGenerator::writeInjectDocumentation(TextStream &s,
return didSomething;
}
-QString QtDocGenerator::functionSignature(const AbstractMetaFunctionCPtr &func,
- const QString &scope)
-{
- QString result = scope;
- if (!func->isConstructor()) {
- if (!result.isEmpty())
- result += u'.';
- result += getFuncName(func);
- }
-
- return result + formatArgs(func);
-}
-
static QString inline toRef(const QString &t)
{
- return ":any:`"_L1 + t + u'`';
+ return ":class:`~"_L1 + t + u'`';
}
QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
@@ -811,8 +724,17 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
if (type.isFlags()) {
const auto fte = std::static_pointer_cast<const FlagsTypeEntry>(type.typeEntry());
- auto enumName = fte->originator()->targetLangName();
+ auto enumTypeEntry = fte->originator();
+ auto enumName = enumTypeEntry->targetLangName();
+ if (createRef)
+ enumName.prepend(enumTypeEntry->targetLangPackage() + u'.');
return "Combination of "_L1 + (createRef ? toRef(enumName) : enumName);
+ } else if (type.isEnum()) {
+ auto enumTypeEntry = std::static_pointer_cast<const EnumTypeEntry>(type.typeEntry());
+ auto enumName = enumTypeEntry->targetLangName();
+ if (createRef)
+ enumName.prepend(enumTypeEntry->targetLangPackage() + u'.');
+ return createRef ? toRef(enumName) : enumName;
}
if (type.isConstant() && name == "char"_L1 && type.indirections() == 1)
@@ -838,13 +760,15 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
}
if (auto k = AbstractMetaClass::findClass(api().classes(), type.typeEntry()))
- return createRef ? toRef(k->fullName()) : k->fullName();
+ return createRef ? toRef(k->fullName()) : k->name();
return createRef ? toRef(name) : name;
}
QString QtDocGenerator::getFuncName(const AbstractMetaFunctionCPtr &cppFunc)
{
+ if (cppFunc->isConstructor())
+ return "__init__"_L1;
QString result = cppFunc->name();
if (cppFunc->isOperatorOverload()) {
const QString pythonOperator = Generator::pythonOperatorFunctionName(result);
@@ -917,7 +841,7 @@ void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr
s << ".. py:function:: ";
else
s << (func->isStatic() ? ".. py:staticmethod:: " : ".. py:method:: ");
- s << functionSignature(func, scope);
+ s << getFuncName(func) << formatArgs(func);
Indentation indentation(s);
if (!indexed)
s << "\n:noindex:";
@@ -938,7 +862,7 @@ void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr
if (auto propIndex = func->propertySpecIndex(); propIndex >= 0) {
const QString name = cppClass->propertySpecs().at(propIndex).name();
- const QString target = propertyRefTarget(cppClass, name);
+ const QString target = propertyRefTarget(name);
if (func->isPropertyReader())
s << "\nGetter of property " << propRef(target) << " .\n\n";
else if (func->isPropertyWriter())
@@ -1190,7 +1114,7 @@ void QtDocGenerator::writeModuleDocumentation()
}
writeFancyToc(s, "List of Classes", fileListToToc(docPackage.classPages),
- "doc"_L1);
+ "class"_L1);
writeFancyToc(s, "List of Functions", functionListToToc(docPackage.globalFunctions),
"py:func"_L1);
writeFancyToc(s, "List of Enumerations", enumListToToc(docPackage.globalEnums),
@@ -1461,14 +1385,8 @@ GeneratorDocumentation
GeneratorDocumentation result;
const auto allFunctions = cppClass->functions();
result.allFunctions.reserve(allFunctions.size());
- for (const auto &func : allFunctions) {
- if (!shouldSkip(func)) {
- if (func->isConstructor())
- result.constructors.append(func);
- else
- result.allFunctions.append(func);
- }
- }
+ std::remove_copy_if(allFunctions.cbegin(), allFunctions.cend(),
+ std::back_inserter(result.allFunctions), shouldSkip);
std::sort(result.allFunctions.begin(), result.allFunctions.end(), functionSort);
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index bac9bbb84..3b1c82e74 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -64,8 +64,6 @@ private:
const QString &scope) const;
void writeFields(TextStream &s, const AbstractMetaClassCPtr &cppClass) const;
- static QString functionSignature(const AbstractMetaFunctionCPtr &func,
- const QString &scope = {});
void writeFunctions(TextStream &s, const AbstractMetaFunctionCList &funcs,
const AbstractMetaClassCPtr &cppClass, const QString &scope);
void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
@@ -77,21 +75,14 @@ private:
void writeFunctionParametersType(TextStream &s, const AbstractMetaClassCPtr &cppClass,
const AbstractMetaFunctionCPtr &func) const;
static void writeFunctionToc(TextStream &s, const QString &title,
- const AbstractMetaClassCPtr &cppClass,
const AbstractMetaFunctionCList &functions);
static void writePropertyToc(TextStream &s,
- const GeneratorDocumentation &doc,
- const AbstractMetaClassCPtr &cppClass);
+ const GeneratorDocumentation &doc);
void writeProperties(TextStream &s,
const GeneratorDocumentation &doc,
const AbstractMetaClassCPtr &cppClass) const;
void writeParameterType(TextStream &s, const AbstractMetaClassCPtr &cppClass,
const AbstractMetaArgument &arg) const;
-
- void writeConstructors(TextStream &s,
- const AbstractMetaClassCPtr &cppClass,
- const AbstractMetaFunctionCList &constructors) const;
-
void writeFormattedText(TextStream &s, const QString &doc,
Documentation::Format format,
const QString &scope = {}) const;