From cd73be9f726da55dc4efd2a03897a5c543b5334d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Sep 2022 12:55:12 +0200 Subject: shiboken6: Fix documentation injection for added functions with parameter names Documentation modifications were matched by function signatures, which failed for added function signatures with parameter names (@). To fix this, store documentation modifications in AddedFunction similar to what is done for normal modifications. Task-number: PYSIDE-2025 Change-Id: I0b3a8c2a066c028da6feb394905510892e85e47d Reviewed-by: Cristian Maureira-Fredes --- .../ApiExtractor/abstractmetafunction.cpp | 6 +++++ .../shiboken6/ApiExtractor/abstractmetafunction.h | 2 ++ sources/shiboken6/ApiExtractor/addedfunction.h | 5 ++++ sources/shiboken6/ApiExtractor/docparser.cpp | 3 +++ .../ApiExtractor/tests/testmodifydocumentation.cpp | 28 ++++++++++++++++++++++ .../ApiExtractor/tests/testmodifydocumentation.h | 1 + .../shiboken6/ApiExtractor/typesystemparser.cpp | 20 ++++++++++++---- 7 files changed, 61 insertions(+), 4 deletions(-) diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp index d65066f1a..9768b85d1 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp @@ -1027,6 +1027,12 @@ void AbstractMetaFunction::clearModificationsCache() d->m_modificationCache.clear(); } +const DocModificationList AbstractMetaFunction::addedFunctionDocModifications() const +{ + return d->m_addedFunction.isNull() + ? DocModificationList{} : d->m_addedFunction->docModifications(); +} + QString AbstractMetaFunction::argumentName(int index, bool /* create */, const AbstractMetaClass * /* implementor */) const diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h index 4c0815540..d9d9cc2b8 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h @@ -357,6 +357,8 @@ public: const FunctionModificationList &modifications(const AbstractMetaClass *implementor = nullptr) const; void clearModificationsCache(); + const DocModificationList addedFunctionDocModifications() const; + static FunctionModificationList findClassModifications(const AbstractMetaFunction *f, const AbstractMetaClass *implementor); static FunctionModificationList findGlobalModifications(const AbstractMetaFunction *f); diff --git a/sources/shiboken6/ApiExtractor/addedfunction.h b/sources/shiboken6/ApiExtractor/addedfunction.h index 55954f650..0f5dc89ef 100644 --- a/sources/shiboken6/ApiExtractor/addedfunction.h +++ b/sources/shiboken6/ApiExtractor/addedfunction.h @@ -81,11 +81,16 @@ struct AddedFunction const FunctionModificationList &modifications() const { return m_modifications; } FunctionModificationList &modifications() { return m_modifications; } + const DocModificationList &docModifications() const { return m_docModifications; } + DocModificationList &docModifications() { return m_docModifications; } + void addDocModification(const DocModification &m) { m_docModifications.append(m); } + private: QString m_name; QList m_arguments; TypeInfo m_returnType; FunctionModificationList m_modifications; + DocModificationList m_docModifications; Access m_access = Public; bool m_isConst = false; bool m_isClassMethod = false; diff --git a/sources/shiboken6/ApiExtractor/docparser.cpp b/sources/shiboken6/ApiExtractor/docparser.cpp index 9d90d5fb2..4ea770e60 100644 --- a/sources/shiboken6/ApiExtractor/docparser.cpp +++ b/sources/shiboken6/ApiExtractor/docparser.cpp @@ -91,6 +91,9 @@ DocModificationList DocParser::getDocModifications(const AbstractMetaClass* cppC if (func.isNull()) return te->docModifications(); + if (func->isUserAdded()) + return func->addedFunctionDocModifications(); + DocModificationList result = te->functionDocModifications(); const QString minimalSignature = func->minimalSignature(); const auto filter = [&minimalSignature](const DocModification &mod) { diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp index 05fd3bf6b..6c10dcbef 100644 --- a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp @@ -4,6 +4,7 @@ #include "testmodifydocumentation.h" #include "testutil.h" #include +#include #include #include #include @@ -78,6 +79,33 @@ R"( QCOMPARE(actualDocSimplified, expectedDocSimplified); } +void TestModifyDocumentation::testInjectAddedFunctionDocumentation() +{ + const char cppCode[] ="class A {};\n"; + const char xmlCode[] = R"XML( + + + + + Injected documentation of added function foo. + + + + +)XML"; + QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); + QVERIFY(!builder.isNull()); + AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A"); + QVERIFY(classA); + const auto f = classA->findFunction(u"foo"); + QVERIFY(!f.isNull()); + QVERIFY(f->isUserAdded()); + auto docMods = f->addedFunctionDocModifications(); + QCOMPARE(docMods.size(), 1); + const QString code = docMods.constFirst().code(); + QVERIFY(code.contains(u"Injected documentation of added function foo.")); +} + // We expand QTEST_MAIN macro but using QCoreApplication instead of QApplication // because this test needs an event loop but can't use QApplication to avoid a crash // on our ARMEL/FRAMANTLE buildbot diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h index c7479f23e..c1cc8f480 100644 --- a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h +++ b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h @@ -11,6 +11,7 @@ class TestModifyDocumentation : public QObject Q_OBJECT private slots: void testModifyDocumentation(); + void testInjectAddedFunctionDocumentation(); }; #endif diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index 310976550..a12fdfcac 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -1109,8 +1109,15 @@ bool TypeSystemParser::characters(const String &ch) return true; } - if (isDocumentation(type)) - m_contextStack.top()->docModifications.last().setCode(ch); + if (isDocumentation(type)) { + const bool isAddedFunction = m_stack.value(m_stack.size() - 2, StackElement::None) + == StackElement::AddFunction; + const auto &top = m_contextStack.top(); + auto &docModifications = isAddedFunction + ? top->addedFunctions.last()->docModifications() + : top->docModifications; + docModifications.last().setCode(ch); + } return true; } @@ -1923,10 +1930,11 @@ bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &, bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement, QXmlStreamAttributes *attributes) { + const bool isAddFunction = topElement == StackElement::AddFunction; const bool validParent = isTypeEntry(topElement) || topElement == StackElement::ModifyFunction || topElement == StackElement::ModifyField - || topElement == StackElement::AddFunction; + || isAddFunction; if (!validParent) { m_error = u"inject-documentation must be inside modify-function, add-function" "modify-field or other tags that creates a type"_s; @@ -1959,7 +1967,11 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature; DocModification mod(mode, signature); mod.setFormat(lang); - m_contextStack.top()->docModifications << mod; + auto &top = m_contextStack.top(); + if (isAddFunction) + top->addedFunctions.last()->addDocModification(mod); + else + top->docModifications << mod; return true; } -- cgit v1.2.3