From 02c22119cf62873b785f9ae1628d530bcafb9ec1 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 26 Jun 2009 13:51:51 +0200 Subject: qdoc: Changed handling of reimplemented functions. There are now sections for "Reimplemented Public Functions" and "Reimplemented Protected Functions" in the summaries for each class. This isn't complete yet. It introduces a lot of qdoc warnings about undocumented parameters, but I will fix those. There is more to be done here but i want to get some feedback already. Task-number: 162182, 222650 --- tools/qdoc3/codemarker.cpp | 64 +++++++++++++++++++++------- tools/qdoc3/codemarker.h | 8 ++++ tools/qdoc3/cppcodemarker.cpp | 77 ++++++++++++++++++++++++++------- tools/qdoc3/cppcodeparser.cpp | 3 ++ tools/qdoc3/generator.cpp | 29 +++++++++++-- tools/qdoc3/generator.h | 4 ++ tools/qdoc3/htmlgenerator.cpp | 99 +++++++++++++++++++++++++++++++++++++++---- tools/qdoc3/htmlgenerator.h | 4 ++ 8 files changed, 245 insertions(+), 43 deletions(-) diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp index 728f9fa..e95153d 100644 --- a/tools/qdoc3/codemarker.cpp +++ b/tools/qdoc3/codemarker.cpp @@ -331,7 +331,10 @@ QString CodeMarker::sortName(const Node *node) return QLatin1Char('B') + nodeName; } -void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle style, Status status) +void CodeMarker::insert(FastSection &fastSection, + Node *node, + SynopsisStyle style, + Status status) { bool inheritedMember = (!node->relates() && (node->parent() != (const InnerNode *)fastSection.innerNode)); @@ -339,12 +342,14 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl if (node->access() == Node::Private) { irrelevant = true; - } else if (node->type() == Node::Function) { + } + else if (node->type() == Node::Function) { FunctionNode *func = (FunctionNode *) node; irrelevant = (inheritedMember && (func->metaness() == FunctionNode::Ctor || func->metaness() == FunctionNode::Dtor)); - } else if (node->type() == Node::Class || node->type() == Node::Enum + } + else if (node->type() == Node::Class || node->type() == Node::Enum || node->type() == Node::Typedef) { irrelevant = (inheritedMember && style != SeparateList); if (!irrelevant && style == Detailed && node->type() == Node::Typedef) { @@ -357,9 +362,11 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl if (!irrelevant) { if (status == Compat) { irrelevant = (node->status() != Node::Compat); - } else if (status == Obsolete) { + } + else if (status == Obsolete) { irrelevant = (node->status() != Node::Obsolete); - } else { + } + else { irrelevant = (node->status() == Node::Compat || node->status() == Node::Obsolete); } @@ -370,7 +377,8 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl QString key = sortName(node); if (!fastSection.memberMap.contains(key)) fastSection.memberMap.insert(key, node); - } else { + } + else { if (node->parent()->type() == Node::Class) { if (fastSection.inherited.isEmpty() || fastSection.inherited.last().first != node->parent()) { @@ -383,16 +391,42 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl } } -void CodeMarker::append(QList
& sectionList, - const FastSection& fastSection) +/*! + Returns true if \a node represents a reimplemented member function. + If it is, then it is inserted in the reimplemented member map in the + section \a fs. And, the test is only performed if \a status is \e OK. + Otherwise, false is returned. + */ +bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status) +{ + if (node->access() == Node::Private) + return false; + + const FunctionNode* fn = static_cast(node); + if ((fn->reimplementedFrom() != 0) && (status == Okay)) { + bool inherited = (!fn->relates() && (fn->parent() != (const InnerNode*)fs.innerNode)); + if (!inherited) { + QString key = sortName(fn); + if (!fs.reimpMemberMap.contains(key)) { + fs.reimpMemberMap.insert(key,node); + return true; + } + } + } + return false; + } + +/*! + If \a fs is not empty, convert it to a Section and append + the new Section to \a sectionList. + */ +void CodeMarker::append(QList
& sectionList, const FastSection& fs) { - if (!fastSection.memberMap.isEmpty() || - !fastSection.inherited.isEmpty()) { - Section section(fastSection.name, - fastSection.singularMember, - fastSection.pluralMember); - section.members = fastSection.memberMap.values(); - section.inherited = fastSection.inherited; + if (!fs.isEmpty()) { + Section section(fs.name,fs.singularMember,fs.pluralMember); + section.members = fs.memberMap.values(); + section.reimpMembers = fs.reimpMemberMap.values(); + section.inherited = fs.inherited; sectionList.append(section); } } diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index 483dc4d..67b1064 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -61,6 +61,7 @@ struct Section QString singularMember; QString pluralMember; NodeList members; + NodeList reimpMembers; QList > inherited; Section() { } @@ -79,6 +80,7 @@ struct FastSection QString singularMember; QString pluralMember; QMap memberMap; + QMap reimpMemberMap; QList > inherited; FastSection(const InnerNode *innerNode0, @@ -89,6 +91,11 @@ struct FastSection name(name0), singularMember(singularMember0), pluralMember(pluralMember0) { } + bool isEmpty() const { + return (memberMap.isEmpty() && inherited.isEmpty() && + reimpMemberMap.isEmpty()); + } + }; class CodeMarker @@ -150,6 +157,7 @@ class CodeMarker Node *node, SynopsisStyle style, Status status); + bool insertReimpFunc(FastSection& fs, Node* node, Status status); void append(QList
& sectionList, const FastSection& fastSection); private: diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index 6760c65..f807609 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -43,6 +43,7 @@ cppcodemarker.cpp */ +#include #include "atom.h" #include "cppcodemarker.h" #include "node.h" @@ -411,6 +412,21 @@ QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */) return "^\\}$"; } +#if 0 + FastSection privateReimpFuncs(classe, + "Private Reimplemented Functions", + "private reimplemented function", + "private reimplemented functions"); + FastSection protectedReimpFuncs(classe, + "Protected Reimplemented Functions", + "protected reimplemented function", + "protected reimplemented functions"); + FastSection publicReimpFuncs(classe, + "Public Reimplemented Functions", + "public reimplemented function", + "public reimplemented functions"); +#endif + QList
CppCodeMarker::sections(const InnerNode *inner, SynopsisStyle style, Status status) @@ -421,29 +437,55 @@ QList
CppCodeMarker::sections(const InnerNode *inner, const ClassNode *classe = static_cast(inner); if (style == Summary) { - FastSection privateFunctions(classe, "Private Functions", "private function", + FastSection privateFunctions(classe, + "Private Functions", + "private function", "private functions"); FastSection privateSlots(classe, "Private Slots", "private slot", "private slots"); FastSection privateTypes(classe, "Private Types", "private type", "private types"); - FastSection protectedFunctions(classe, "Protected Functions", "protected function", + FastSection protectedFunctions(classe, + "Protected Functions", + "protected function", "protected functions"); - FastSection protectedSlots(classe, "Protected Slots", "protected slot", "protected slots"); - FastSection protectedTypes(classe, "Protected Types", "protected type", "protected types"); - FastSection protectedVariables(classe, "Protected Variables", "protected type", "protected variables"); - FastSection publicFunctions(classe, "Public Functions", "public function", - "public functions"); + FastSection protectedSlots(classe, + "Protected Slots", + "protected slot", + "protected slots"); + FastSection protectedTypes(classe, + "Protected Types", + "protected type", + "protected types"); + FastSection protectedVariables(classe, + "Protected Variables", + "protected type", + "protected variables"); + FastSection publicFunctions(classe, + "Public Functions", + "public function", + "public functions"); FastSection publicSignals(classe, "Signals", "signal", "signals"); FastSection publicSlots(classe, "Public Slots", "public slot", "public slots"); FastSection publicTypes(classe, "Public Types", "public type", "public types"); - FastSection publicVariables(classe, "Public Variables", "public type", "public variables"); + FastSection publicVariables(classe, + "Public Variables", + "public type", + "public variables"); FastSection properties(classe, "Properties", "property", "properties"); - FastSection relatedNonMembers(classe, "Related Non-Members", "related non-member", + FastSection relatedNonMembers(classe, + "Related Non-Members", + "related non-member", "related non-members"); - FastSection staticPrivateMembers(classe, "Static Private Members", "static private member", + FastSection staticPrivateMembers(classe, + "Static Private Members", + "static private member", "static private members"); - FastSection staticProtectedMembers(classe, "Static Protected Members", - "static protected member", "static protected members"); - FastSection staticPublicMembers(classe, "Static Public Members", "static public member", + FastSection staticProtectedMembers(classe, + "Static Protected Members", + "static protected member", + "static protected members"); + FastSection staticPublicMembers(classe, + "Static Public Members", + "static public member", "static public members"); FastSection macros(inner, "Macros", "macro", "macros"); @@ -505,7 +547,8 @@ QList
CppCodeMarker::sections(const InnerNode *inner, insert(publicVariables, *c, style, status); } else if ((*c)->type() == Node::Function) { - insert(publicFunctions, *c, style, status); + if (!insertReimpFunc(publicFunctions,*c,status)) + insert(publicFunctions, *c, style, status); } else { insert(publicTypes, *c, style, status); @@ -525,7 +568,8 @@ QList
CppCodeMarker::sections(const InnerNode *inner, insert(protectedVariables, *c, style, status); } else if ((*c)->type() == Node::Function) { - insert(protectedFunctions, *c, style, status); + if (!insertReimpFunc(protectedFunctions,*c,status)) + insert(protectedFunctions, *c, style, status); } else { insert(protectedTypes, *c, style, status); @@ -541,7 +585,8 @@ QList
CppCodeMarker::sections(const InnerNode *inner, insert(staticPrivateMembers, *c, style, status); } else if ((*c)->type() == Node::Function) { - insert(privateFunctions, *c, style, status); + if (!insertReimpFunc(privateFunctions,*c,status)) + insert(privateFunctions, *c, style, status); } else { insert(privateTypes, *c, style, status); diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index a7d6ae7..792190d 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -739,8 +739,11 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, // Note: Setting the access to Private hides the documentation, // but setting the status to Internal makes the node available // in the XML output when the WebXMLGenerator is used. +#if 0 + // Reimplemented functions now reported in separate sections. func->setAccess(Node::Private); func->setStatus(Node::Internal); +#endif } else { doc.location().warning(tr("Ignored '\\%1' in %2") diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 3652071..fa55b8a 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -44,7 +44,7 @@ */ #include - +#include #include "codemarker.h" #include "config.h" #include "doc.h" @@ -307,6 +307,12 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) .arg(marker->plainFullName(node))); } else { + if (node->type() == Node::Function) { + const FunctionNode *func = static_cast(node); + if (func->reimplementedFrom() != 0) + generateReimplementedFrom(func, marker); + } + generateText(node->doc().body(), node, marker); if (node->type() == Node::Enum) { @@ -345,7 +351,6 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } else if (node->type() == Node::Function) { const FunctionNode *func = static_cast(node); - QSet definedParams; QList::ConstIterator p = func->parameters().begin(); while (p != func->parameters().end()) { @@ -404,9 +409,11 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) if (!body.contains("return", Qt::CaseInsensitive)) node->doc().location().warning(tr("Undocumented return value")); } - +#if 0 + // Now we put this at the top, before the other text. if (func->reimplementedFrom() != 0) generateReimplementedFrom(func, marker); +#endif } } @@ -859,7 +866,8 @@ void Generator::generateReimplementedFrom(const FunctionNode *func, if (from->access() != Node::Private && from->parent()->access() != Node::Private) { Text text; text << Atom::ParaLeft << "Reimplemented from "; - appendFullName(text, from->parent(), func, marker, from); + QString fullName = from->parent()->name() + "::" + from->name() + "()"; + appendFullName(text, from->parent(), fullName, from); text << "." << Atom::ParaRight; generateText(text, func, marker); } @@ -939,6 +947,19 @@ void Generator::appendFullName(Text& text, << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); } +void Generator::appendFullName(Text& text, + const Node *apparentNode, + const QString& fullName, + const Node *actualNode) +{ + if (actualNode == 0) + actualNode = apparentNode; + text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode)) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, fullName) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); +} + void Generator::appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index d0909a6..75134d2 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -150,6 +150,10 @@ class Generator const Node *relative, CodeMarker *marker, const Node *actualNode = 0); + void appendFullName(Text& text, + const Node *apparentNode, + const QString& fullName, + const Node *actualNode); void appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 2a49f81..c007b9b 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1076,16 +1076,34 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); s = sections.begin(); while (s != sections.end()) { - if (s->members.isEmpty()) { + if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { if (!s->inherited.isEmpty()) needOtherSection = true; - } else { - out() << "
\n"; - out() << "\n"; - out() << "

" << protect((*s).name) << "

\n"; - generateSectionList(*s, inner, marker, CodeMarker::Summary); + } + else { + if (!s->members.isEmpty()) { + out() << "
\n"; + out() << "\n"; + out() << "

" << protect((*s).name) << "

\n"; + generateSection(s->members, inner, marker, CodeMarker::Summary); + } + if (!s->reimpMembers.isEmpty()) { + QString name = QString("Reimplemented ") + (*s).name; + out() << "
\n"; + out() << "\n"; + out() << "

" << protect(name) << "

\n"; + generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); + } + + if (!s->inherited.isEmpty()) { + out() << "
    \n"; + generateSectionInheritedList(*s, inner, marker, true); + out() << "
\n"; + } } ++s; } @@ -2211,6 +2229,71 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m } #ifdef QDOC_NAME_ALIGNMENT +void HtmlGenerator::generateSection(const NodeList& nl, + const Node *relative, + CodeMarker *marker, + CodeMarker::SynopsisStyle style) +{ + bool name_alignment = true; + if (!nl.isEmpty()) { + bool twoColumn = false; + if (style == CodeMarker::SeparateList) { + name_alignment = false; + twoColumn = (nl.count() >= 16); + } + else if (nl.first()->type() == Node::Property) { + twoColumn = (nl.count() >= 5); + name_alignment = false; + } + if (name_alignment) { + out() << "\n"; + } + else { + if (twoColumn) + out() << "

\n" + << "\n"; + else + out() << "\n"; + i++; + ++m; + } + if (name_alignment) + out() << "
"; + out() << "
    \n"; + } + + int i = 0; + NodeList::ConstIterator m = nl.begin(); + while (m != nl.end()) { + if ((*m)->access() == Node::Private) { + ++m; + continue; + } + + if (name_alignment) { + out() << "
"; + } + else { + if (twoColumn && i == (int) (nl.count() + 1) / 2) + out() << "
    \n"; + out() << "
  • "; + } + + generateSynopsis(*m, relative, marker, style, name_alignment); + if (name_alignment) + out() << "
\n"; + else { + out() << "\n"; + if (twoColumn) + out() << "\n

\n"; + } + } +} + void HtmlGenerator::generateSectionList(const Section& section, const Node *relative, CodeMarker *marker, diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index a1c2a34..dc5e5cf 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -146,6 +146,10 @@ class HtmlGenerator : public PageGenerator CodeMarker *marker, CodeMarker::SynopsisStyle style); #ifdef QDOC_NAME_ALIGNMENT + void generateSection(const NodeList& nl, + const Node *relative, + CodeMarker *marker, + CodeMarker::SynopsisStyle style); void generateSynopsis(const Node *node, const Node *relative, CodeMarker *marker, -- cgit v0.12