diff options
-rw-r--r-- | src/qdoc/generator.cpp | 21 | ||||
-rw-r--r-- | src/qdoc/node.cpp | 75 | ||||
-rw-r--r-- | src/qdoc/node.h | 12 | ||||
-rw-r--r-- | src/qdoc/qdocdatabase.cpp | 4 | ||||
-rw-r--r-- | src/qdoc/qdocindexfiles.cpp | 17 |
5 files changed, 110 insertions, 19 deletions
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp index 71da36e3c..e80fa5a4c 100644 --- a/src/qdoc/generator.cpp +++ b/src/qdoc/generator.cpp @@ -1294,12 +1294,27 @@ void Generator::generateReimplementsClause(const FunctionNode *fn, CodeMarker *m ClassNode* cn = static_cast<ClassNode*>(fn->parent()); const FunctionNode *overrides = cn->findOverriddenFunction(fn); if (overrides && !overrides->isPrivate() && !overrides->parent()->isPrivate()) { + if (overrides->hasDoc()) { + Text text; + text << Atom::ParaLeft << "Reimplements: "; + QString fullName = overrides->parent()->name() + "::" + overrides->signature(false, true); + appendFullName(text, overrides->parent(), fullName, overrides); + text << "." << Atom::ParaRight; + generateText(text, fn, marker); + return; + } + } + const PropertyNode* sameName = cn->findOverriddenProperty(fn); + if (sameName && sameName->hasDoc()) { Text text; - text << Atom::ParaLeft << "Reimplements: "; - QString fullName = overrides->parent()->name() + "::" + overrides->signature(false, true); - appendFullName(text, overrides->parent(), fullName, overrides); + text << Atom::ParaLeft << "Reimplements an access function for property: "; + QString fullName = sameName->parent()->name() + "::" + sameName->name(); + appendFullName(text, sameName->parent(), fullName, sameName); text << "." << Atom::ParaRight; generateText(text, fn, marker); + } else { + fn->doc().location().warning(tr("Illegal \\reimp; no documented virtual function for %1") + .arg(fn->plainSignature())); } } } diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp index c664aea63..2ec58dc3a 100644 --- a/src/qdoc/node.cpp +++ b/src/qdoc/node.cpp @@ -307,6 +307,7 @@ Node::Node(NodeType type, Aggregate *parent, const QString& name) status_(Active), indexNodeFlag_(false), relatedNonmember_(false), + hadDoc_(false), parent_(parent), sharedCommentNode_(nullptr), name_(name) @@ -1084,7 +1085,7 @@ FunctionNode *Aggregate::findFunctionChild(const QString &name, const Parameters /*! Find the function node that is a child of this node, such that the function described has the same name and signature - as the function described by the \a clone node. + as the function described by the function node \a clone. */ FunctionNode *Aggregate::findFunctionChild(const FunctionNode *clone) { @@ -1856,7 +1857,7 @@ FunctionNode* ClassNode::findOverriddenFunction(const FunctionNode* fn) } if (cn != nullptr) { FunctionNode *result = cn->findFunctionChild(fn); - if (result != nullptr && !result->isNonvirtual() && result->hasDoc()) + if (result != nullptr && !result->isInternal() && !result->isNonvirtual() && result->hasDoc()) return result; result = cn->findOverriddenFunction(fn); if (result != nullptr && !result->isNonvirtual()) @@ -1868,6 +1869,44 @@ FunctionNode* ClassNode::findOverriddenFunction(const FunctionNode* fn) } /*! + \a fn is an overriding function in this class or in a class + derived from this class. Find the node for the property that + \a fn overrides in this class's children or in one of this + class's base classes. Return a pointer to the overridden + property or return 0. + */ +PropertyNode* ClassNode::findOverriddenProperty(const FunctionNode* fn) +{ + QList<RelatedClass>::Iterator bc = bases_.begin(); + while (bc != bases_.end()) { + ClassNode *cn = bc->node_; + if (cn == nullptr) { + cn = QDocDatabase::qdocDB()->findClassNode(bc->path_); + bc->node_ = cn; + } + if (cn != nullptr) { + const NodeList &children = cn->childNodes(); + NodeList::const_iterator i = children.begin(); + while (i != children.end()) { + if ((*i)->isProperty()) { + PropertyNode *pn = static_cast<PropertyNode*>(*i); + if (pn->name() == fn->name() || pn->hasAccessFunction(fn->name())) { + if (pn->hasDoc()) + return pn; + } + } + i++; + } + PropertyNode *result = cn->findOverriddenProperty(fn); + if (result != nullptr) + return result; + } + ++bc; + } + return nullptr; +} + +/*! Returns true if the class or struct represented by this class node must be documented. If this function returns true, then qdoc must find a qdoc comment for this class. If it returns @@ -2732,6 +2771,38 @@ QString PropertyNode::qualifiedDataType() const } } +/*! + Returns true if this property has an access function named \a name. + */ +bool PropertyNode::hasAccessFunction(const QString &name) const +{ + NodeList::const_iterator i = getters().begin(); + while (i != getters().end()) { + if ((*i)->name() == name) + return true; + ++i; + } + i = setters().begin(); + while (i != setters().end()) { + if ((*i)->name() == name) + return true; + ++i; + } + i = resetters().begin(); + while (i != resetters().end()) { + if ((*i)->name() == name) + return true; + ++i; + } + i = notifiers().begin(); + while (i != notifiers().end()) { + if ((*i)->name() == name) + return true; + ++i; + } + return false; +} + bool QmlTypeNode::qmlOnly = false; QMultiMap<const Node*, Node*> QmlTypeNode::inheritedBy; diff --git a/src/qdoc/node.h b/src/qdoc/node.h index 6deb9f8c0..b163541b9 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -258,6 +258,7 @@ public: void setReconstitutedBrief(const QString &t) { reconstitutedBrief_ = t; } void setParent(Aggregate* n) { parent_ = n; } void setIndexNodeFlag(bool isIndexNode = true) { indexNodeFlag_ = isIndexNode; } + void setHadDoc() { hadDoc_ = true; } virtual void setRelatedNonmember(bool b) { relatedNonmember_ = b; } virtual void setOutputFileName(const QString& ) { } virtual void addMember(Node* ) { } @@ -307,7 +308,8 @@ public: const Location& defLocation() const { return defLocation_; } const Location& location() const { return (defLocation_.isEmpty() ? declLocation_ : defLocation_); } const Doc& doc() const { return doc_; } - bool hasDoc() const { return !doc_.isEmpty(); } + bool hasDoc() const { return (hadDoc_ || !doc_.isEmpty()); } + bool hadDoc() const { return hadDoc_; } Status status() const { return status_; } Status inheritedStatus() const; ThreadSafeness threadSafeness() const; @@ -369,6 +371,7 @@ private: Status status_; bool indexNodeFlag_ : 1; bool relatedNonmember_ : 1; + bool hadDoc_ : 1; Aggregate* parent_; SharedCommentNode *sharedCommentNode_; @@ -533,7 +536,7 @@ class NamespaceNode : public Aggregate { public: NamespaceNode(Aggregate* parent, const QString& name) : Aggregate(Namespace, parent, name), - seen_(false), documented_(false), tree_(nullptr), docNode_(nullptr) { } + seen_(false), tree_(nullptr), docNode_(nullptr) { } virtual ~NamespaceNode(); Tree* tree() const override { return (parent() ? parent()->tree() : tree_); } @@ -551,14 +554,11 @@ public: bool hasDocumentedChildren() const; void reportDocumentedChildrenInUndocumentedNamespace() const; bool docMustBeGenerated() const override; - void setDocumented() { documented_ = true; } - bool wasDocumented() const { return documented_; } void setDocNode(NamespaceNode* ns) { docNode_ = ns; } NamespaceNode* docNode() const { return docNode_; } private: bool seen_; - bool documented_; Tree* tree_; QString whereDocumented_; NamespaceNode* docNode_; @@ -633,6 +633,7 @@ public: PropertyNode* findPropertyNode(const QString& name); QmlTypeNode* findQmlBaseNode(); FunctionNode* findOverriddenFunction(const FunctionNode* fn); + PropertyNode* findOverriddenProperty(const FunctionNode* fn); bool docMustBeGenerated() const override; private: @@ -1130,6 +1131,7 @@ public: const NodeList &setters() const { return functions(Setter); } const NodeList &resetters() const { return functions(Resetter); } const NodeList ¬ifiers() const { return functions(Notifier); } + bool hasAccessFunction(const QString &name) const; FunctionRole role(const FunctionNode* fn) const; bool isStored() const { return fromFlagValue(stored_, storedDefault()); } bool isDesignable() const { return fromFlagValue(designable_, designableDefault()); } diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp index aefed5615..ef2b5ab33 100644 --- a/src/qdoc/qdocdatabase.cpp +++ b/src/qdoc/qdocdatabase.cpp @@ -1185,14 +1185,14 @@ void QDocDatabase::resolveNamespaces() ns = static_cast<NamespaceNode*>(n); if (ns->isDocumentedHere()) break; - else if (ns->wasDocumented()) + else if (ns->hadDoc()) somewhere = ns; ns = nullptr; } if (ns) { foreach (Node *n, namespaces) { NamespaceNode* NS = static_cast<NamespaceNode*>(n); - if (NS->wasDocumented() && NS != ns) { + if (NS->hadDoc() && NS != ns) { ns->doc().location().warning(tr("Namespace %1 documented more than once") .arg(NS->name())); NS->doc().location().warning(tr("...also seen here")); diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp index 617c132f2..efd9adefd 100644 --- a/src/qdoc/qdocindexfiles.cpp +++ b/src/qdoc/qdocindexfiles.cpp @@ -204,11 +204,6 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, location = Location(indexUrl + QLatin1Char('/') + name.toLower() + ".html"); else if (!indexUrl.isNull()) location = Location(name.toLower() + ".html"); - if (attributes.hasAttribute(QLatin1String("documented"))) { - if (attributes.value(QLatin1String("documented")) == QLatin1String("true")) - ns->setDocumented(); - } - } else if (elementName == QLatin1String("class") || elementName == QLatin1String("struct") || elementName == QLatin1String("union")) { Node::NodeType type = Node::Class; @@ -604,6 +599,11 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, node->setSince(since); } + if (attributes.hasAttribute(QLatin1String("documented"))) { + if (attributes.value(QLatin1String("documented")) == QLatin1String("true")) + node->setHadDoc(); + } + QString groupsAttr = attributes.value(QLatin1String("groups")).toString(); if (!groupsAttr.isEmpty()) { QStringList groupNames = groupsAttr.split(QLatin1Char(',')); @@ -936,6 +936,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, if (!node->since().isEmpty()) writer.writeAttribute("since", node->since()); + if (node->hasDoc()) + writer.writeAttribute("documented", "true"); + QString brief = node->doc().trimmedBriefText(node->name()).toString(); switch (node->nodeType()) { case Node::Class: @@ -970,7 +973,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, case Node::HeaderFile: { const HeaderNode* hn = static_cast<const HeaderNode*>(node); - writer.writeAttribute("documented", hn->hasDoc() ? "true" : "false"); if (!hn->physicalModuleName().isEmpty()) writer.writeAttribute("module", hn->physicalModuleName()); if (!hn->groupNames().isEmpty()) @@ -985,7 +987,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, case Node::Namespace: { const NamespaceNode* ns = static_cast<const NamespaceNode*>(node); - writer.writeAttribute("documented", ns->hasDoc() ? "true" : "false"); if (!ns->physicalModuleName().isEmpty()) writer.writeAttribute("module", ns->physicalModuleName()); if (!ns->groupNames().isEmpty()) @@ -1333,6 +1334,8 @@ void QDocIndexFiles::generateFunctionSection(QXmlStreamWriter &writer, FunctionN writer.writeAttribute("lineno", QString("%1").arg(declLocation.lineNo())); } + if (fn->hasDoc()) + writer.writeAttribute("documented", "true"); if (fn->isRelatedNonmember()) writer.writeAttribute("related", "true"); if (!fn->since().isEmpty()) |