diff options
author | Martin Smith <martin.smith@digia.com> | 2015-06-03 14:18:51 +0200 |
---|---|---|
committer | Martin Smith <martin.smith@digia.com> | 2015-06-10 12:47:02 +0000 |
commit | d884420b94abc637b2fcef6585a1fb5c93b69c2c (patch) | |
tree | bb229430f4c1ec3b986423994ca4bd04ef6e8fa4 /src | |
parent | 9b58fe5c264cabe6912bb4fb7b045c2aecd98cb7 (diff) |
qdoc: Improve documentation for properties
This update changes how qdoc handles getter, setter, resetter,
and notifier functions for properties. With this update, if you
provide documentation for any of these functions associated with
a property, links to that function will go to the documentation
for that function, instead of to the associated property.
Additionally, the documentation for the function will have a note
added, e.g. "Note: Notifier signal for property fubar," where the
fubar property name is a link to the documentation for property
fubar.
Change-Id: I1f821fd4a6c2de142da4718ef3bdde314dc59627
Task-number: QTBUG-45620
Reviewed-by: Venugopal Shivashankar <venugopal.shivashankar@digia.com>
Reviewed-by: Topi Reiniƶ <topi.reinio@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/qdoc/cppcodemarker.cpp | 10 | ||||
-rw-r--r-- | src/tools/qdoc/generator.cpp | 19 | ||||
-rw-r--r-- | src/tools/qdoc/htmlgenerator.cpp | 66 | ||||
-rw-r--r-- | src/tools/qdoc/htmlgenerator.h | 1 | ||||
-rw-r--r-- | src/tools/qdoc/node.cpp | 48 | ||||
-rw-r--r-- | src/tools/qdoc/node.h | 24 | ||||
-rw-r--r-- | src/tools/qdoc/qdocindexfiles.cpp | 8 | ||||
-rw-r--r-- | src/tools/qdoc/tree.cpp | 2 |
8 files changed, 125 insertions, 53 deletions
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 43ba29faa0..9aec902860 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -537,11 +537,9 @@ QList<Section> CppCodeMarker::sections(const Aggregate *inner, isSlot = (func->metaness() == FunctionNode::Slot); isSignal = (func->metaness() == FunctionNode::Signal); isStatic = func->isStatic(); - if (func->associatedProperty()) { - if (func->associatedProperty()->status() == Node::Obsolete) { - ++c; - continue; - } + if (func->hasAssociatedProperties() && !func->hasActiveAssociatedProperty()) { + ++c; + continue; } } else if ((*c)->type() == Node::Variable) { @@ -685,7 +683,7 @@ QList<Section> CppCodeMarker::sections(const Aggregate *inner, } else if ((*c)->type() == Node::Function) { FunctionNode *function = static_cast<FunctionNode *>(*c); - if (!function->associatedProperty()) + if (!function->hasAssociatedProperties() || !function->doc().isEmpty()) insert(memberFunctions, function, style, status); } ++c; diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 4f44adc68d..831d975591 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -564,20 +564,19 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) break; case Node::Function: { - const FunctionNode *functionNode = - static_cast<const FunctionNode *>(node); + const FunctionNode *fn = static_cast<const FunctionNode *>(node); - if (functionNode->metaness() == FunctionNode::Dtor) - anchorRef = "#dtor." + functionNode->name().mid(1); + if (fn->metaness() == FunctionNode::Dtor) + anchorRef = "#dtor." + fn->name().mid(1); - else if (functionNode->associatedProperty()) - return fullDocumentLocation(functionNode->associatedProperty()); + else if (fn->hasOneAssociatedProperty() && fn->doc().isEmpty()) + return fullDocumentLocation(fn->firstAssociatedProperty()); - else if (functionNode->overloadNumber() > 0) - anchorRef = QLatin1Char('#') + cleanRef(functionNode->name()) - + QLatin1Char('-') + QString::number(functionNode->overloadNumber()); + else if (fn->overloadNumber() > 0) + anchorRef = QLatin1Char('#') + cleanRef(fn->name()) + + QLatin1Char('-') + QString::number(fn->overloadNumber()); else - anchorRef = QLatin1Char('#') + cleanRef(functionNode->name()); + anchorRef = QLatin1Char('#') + cleanRef(fn->name()); break; } /* diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 5eda23e216..77c4c7a929 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -3729,8 +3729,8 @@ QString HtmlGenerator::refForNode(const Node *node) break; case Node::Function: func = static_cast<const FunctionNode *>(node); - if (func->associatedProperty()) { - return refForNode(func->associatedProperty()); + if (func->hasOneAssociatedProperty() && func->doc().isEmpty()) { + return refForNode(func->firstAssociatedProperty()); } else { ref = func->name(); @@ -3918,24 +3918,22 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const Aggregate *relative, CodeMarker *marker) { - const EnumNode *enume; - + const EnumNode *etn; #ifdef GENERATE_MAC_REFS generateMacRef(node, marker); #endif generateExtractionMark(node, MemberMark); generateKeywordAnchors(node); QString nodeRef = refForNode(node); - if (node->type() == Node::Enum - && (enume = static_cast<const EnumNode *>(node))->flagsType()) { + if (node->isEnumType() && (etn = static_cast<const EnumNode *>(node))->flagsType()) { #ifdef GENERATE_MAC_REFS - generateMacRef(enume->flagsType(), marker); + generateMacRef(etn->flagsType(), marker); #endif out() << "<h3 class=\"flags\" id=\"" << nodeRef << "\">"; out() << "<a name=\"" + nodeRef + "\"></a>"; - generateSynopsis(enume, relative, marker, CodeMarker::Detailed); + generateSynopsis(etn, relative, marker, CodeMarker::Detailed); out() << "<br/>"; - generateSynopsis(enume->flagsType(), + generateSynopsis(etn->flagsType(), relative, marker, CodeMarker::Detailed); @@ -3954,7 +3952,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node, generateThreadSafeness(node, marker); generateSince(node, marker); - if (node->type() == Node::Property) { + if (node->isProperty()) { const PropertyNode *property = static_cast<const PropertyNode *>(node); Section section; @@ -3980,16 +3978,17 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const FunctionNode* fn = static_cast<const FunctionNode*>(node); if (fn->isPrivateSignal()) generatePrivateSignalNote(node, marker); + generateAssociatedPropertyNotes(fn); } - else if (node->type() == Node::Enum) { - const EnumNode *enume = static_cast<const EnumNode *>(node); - if (enume->flagsType()) { - out() << "<p>The " << protectEnc(enume->flagsType()->name()) + else if (node->isEnumType()) { + const EnumNode *etn = static_cast<const EnumNode *>(node); + if (etn->flagsType()) { + out() << "<p>The " << protectEnc(etn->flagsType()->name()) << " type is a typedef for " << "<a href=\"" << qflagsHref_ << "\">QFlags</a><" - << protectEnc(enume->name()) + << protectEnc(etn->name()) << ">. It stores an OR combination of " - << protectEnc(enume->name()) + << protectEnc(etn->name()) << " values.</p>\n"; } } @@ -4364,7 +4363,7 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType if (markType == MemberMark) { if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); - if (!func->associatedProperty()) { + if (!func->hasAssociatedProperties()) { if (func->overloadNumber() == 0) out() << "[overload1]"; out() << "$$$" + func->name() + func->rawParameters().remove(' '); @@ -4874,4 +4873,37 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) } } +/*! + Generates bold Note lines that explain how function \a fn + is associated with each of its associated properties. + */ +void HtmlGenerator::generateAssociatedPropertyNotes(const FunctionNode* fn) +{ + if (fn->hasAssociatedProperties()) { + out() << "<p><b>Note:</b> "; + foreach (const PropertyNode* pn, fn->associatedProperties()) { + QString msg; + switch (pn->role(fn)) { + case PropertyNode::Getter: + msg = QStringLiteral("Getter function "); + break; + case PropertyNode::Setter: + msg = QStringLiteral("Setter function "); + break; + case PropertyNode::Resetter: + msg = QStringLiteral("Resetter function "); + break; + case PropertyNode::Notifier: + msg = QStringLiteral("Notifier signal "); + break; + default: + break; + } + QString link = linkForNode(pn, 0); + out() << msg << "for property <a href=\"" << link << "\">" << pn->name() << "</a>. "; + } + out() << "</p>"; + } +} + QT_END_NAMESPACE diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 615de8e8a3..6a550c2b39 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -106,6 +106,7 @@ protected: void generateManifestFile(const QString &manifest, const QString &element); void readManifestMetaContent(const Config &config); void generateKeywordAnchors(const Node* node); + void generateAssociatedPropertyNotes(const FunctionNode* fn); private: enum SubTitleSize { SmallSubTitle, LargeSubTitle }; diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 7cc380375a..f20020cd15 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -606,7 +606,6 @@ QString Node::fileBase() const base.replace(QLatin1Char(' '), QLatin1Char('-')); return base.toLower(); } -#endif /*! Returns this node's Universally Unique IDentifier as a QString. Creates the UUID first, if it has not been created. @@ -617,6 +616,7 @@ QString Node::guid() const uuid_ = idForNode(); return uuid_; } +#endif /*! If this node is a QML or JS type node, return a pointer to @@ -1822,8 +1822,7 @@ FunctionNode::FunctionNode(Aggregate *parent, const QString& name) attached_(false), privateSignal_(false), overload_(false), - reimplementedFrom_(0), - associatedProperty_(0) + reimplementedFrom_(0) { setGenus(Node::CPP); } @@ -1846,8 +1845,7 @@ FunctionNode::FunctionNode(NodeType type, Aggregate *parent, const QString& name attached_(attached), privateSignal_(false), overload_(false), - reimplementedFrom_(0), - associatedProperty_(0) + reimplementedFrom_(0) { setGenus(Node::QML); if (type == QmlMethod || type == QmlSignal) { @@ -1925,12 +1923,29 @@ void FunctionNode::setReimplementedFrom(FunctionNode *f) } /*! - Sets the "associated" property to \a property. The function - might be the setter or getter for a property, for example. + Adds the "associated" property \a p to this function node. + The function might be the setter or getter for a property, + for example. */ -void FunctionNode::setAssociatedProperty(PropertyNode *p) +void FunctionNode::addAssociatedProperty(PropertyNode *p) { - associatedProperty_ = p; + associatedProperties_.append(p); +} + +/*! + Returns true if this function has at least one property + that is active, i.e. at least one property that is not + obsolete. + */ +bool FunctionNode::hasActiveAssociatedProperty() const +{ + if (associatedProperties_.isEmpty()) + return false; + foreach (const PropertyNode* p, associatedProperties_) { + if (!p->isObsolete()) + return true; + } + return false; } /*! \fn unsigned char FunctionNode::overloadNumber() const @@ -2009,6 +2024,19 @@ QString FunctionNode::signature(bool values) const } /*! + Returns true if function \a fn has role \a r for this + property. + */ +PropertyNode::FunctionRole PropertyNode::role(const FunctionNode* fn) const +{ + for (int i=0; i<4; i++) { + if (functions_[i].contains((Node*)fn)) + return (FunctionRole) i; + } + return Notifier; +} + +/*! Print some debugging stuff. */ void FunctionNode::debug() const @@ -2493,6 +2521,7 @@ QString Node::cleanId(const QString &str) return clean; } +#if 0 /*! Creates a string that can be used as a UUID for the node, depending on the type and subtype of the node. Uniquenss @@ -2720,6 +2749,7 @@ QString Node::idForNode() const } return str; } +#endif /*! Prints the inner node's list of children. diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index f78da0e131..f852e480a6 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -59,6 +59,7 @@ class CollectionNode; class QmlPropertyNode; typedef QList<Node*> NodeList; +typedef QList<PropertyNode*> PropNodeList; typedef QMap<QString, Node*> NodeMap; typedef QMultiMap<QString, Node*> NodeMultiMap; typedef QPair<int, int> NodeTypePair; @@ -202,6 +203,7 @@ public: virtual bool isJsType() const { return false; } virtual bool isQmlBasicType() const { return false; } virtual bool isJsBasicType() const { return false; } + virtual bool isEnumType() const { return false; } virtual bool isExample() const { return false; } virtual bool isExampleFile() const { return false; } virtual bool isHeaderFile() const { return false; } @@ -297,7 +299,7 @@ public: void clearRelated() { relatesTo_ = 0; } - QString guid() const; + //QString guid() const; QString extractClassName(const QString &string) const; virtual QString qmlTypeName() const { return name_; } virtual QString qmlFullBaseName() const { return QString(); } @@ -318,7 +320,7 @@ public: virtual void setOutputSubdirectory(const QString& t) { outSubDir_ = t; } QString fullDocumentName() const; static QString cleanId(const QString &str); - QString idForNode() const; + //QString idForNode() const; static FlagValue toFlagValue(bool b); static bool fromFlagValue(FlagValue fv, bool defaultValue); @@ -357,7 +359,7 @@ private: QString since_; QString templateStuff_; QString reconstitutedBrief_; - mutable QString uuid_; + //mutable QString uuid_; QString outSubDir_; static QStringMap operators_; static int propertyGroupCount_; @@ -776,6 +778,7 @@ public: void addItem(const EnumItem& item); void setFlagsType(TypedefNode* typedeff); bool hasItem(const QString &name) const { return names_.contains(name); } + virtual bool isEnumType() const Q_DECL_OVERRIDE { return true; } const QList<EnumItem>& items() const { return items_; } Access itemAccess(const QString& name) const; @@ -908,8 +911,12 @@ public: QString rawParameters(bool names = false, bool values = false) const; const FunctionNode* reimplementedFrom() const { return reimplementedFrom_; } const QList<FunctionNode*> &reimplementedBy() const { return reimplementedBy_; } - const PropertyNode* associatedProperty() const { return associatedProperty_; } + const PropNodeList& associatedProperties() const { return associatedProperties_; } const QStringList& parentPath() const { return parentPath_; } + bool hasAssociatedProperties() const { return !associatedProperties_.isEmpty(); } + bool hasOneAssociatedProperty() const { return (associatedProperties_.size() == 1); } + PropertyNode* firstAssociatedProperty() const { return associatedProperties_[0]; } + bool hasActiveAssociatedProperty() const; QStringList reconstructParameters(bool values = false) const; QString signature(bool values = false) const; @@ -932,7 +939,7 @@ public: void debug() const; private: - void setAssociatedProperty(PropertyNode* property); + void addAssociatedProperty(PropertyNode* property); friend class Aggregate; friend class PropertyNode; @@ -950,7 +957,7 @@ private: unsigned char overloadNumber_; QList<Parameter> parameters_; const FunctionNode* reimplementedFrom_; - const PropertyNode* associatedProperty_; + PropNodeList associatedProperties_; QList<FunctionNode*> reimplementedBy_; }; @@ -987,6 +994,7 @@ public: NodeList setters() const { return functions(Setter); } NodeList resetters() const { return functions(Resetter); } NodeList notifiers() const { return functions(Notifier); } + FunctionRole role(const FunctionNode* fn) const; bool isStored() const { return fromFlagValue(stored_, storedDefault()); } bool isDesignable() const { return fromFlagValue(designable_, designableDefault()); } bool isScriptable() const { return fromFlagValue(scriptable_, scriptableDefault()); } @@ -1028,13 +1036,13 @@ inline void FunctionNode::setParameters(const QList<Parameter> &p) inline void PropertyNode::addFunction(FunctionNode* function, FunctionRole role) { functions_[(int)role].append(function); - function->setAssociatedProperty(this); + function->addAssociatedProperty(this); } inline void PropertyNode::addSignal(FunctionNode* function, FunctionRole role) { functions_[(int)role].append(function); - function->setAssociatedProperty(this); + function->addAssociatedProperty(this); } inline NodeList PropertyNode::functions() const diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index b80b1cc249..74b0b14347 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -1189,9 +1189,11 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, if (functionNode->relates()) { writer.writeAttribute("relates", functionNode->relates()->name()); } - const PropertyNode* propertyNode = functionNode->associatedProperty(); - if (propertyNode) - writer.writeAttribute("associated-property", propertyNode->name()); + if (functionNode->hasAssociatedProperties()) { + foreach (PropertyNode* pn, functionNode->associatedProperties()) { + writer.writeAttribute("associated-property", pn->name()); + } + } writer.writeAttribute("type", functionNode->returnType()); if (!brief.isEmpty()) writer.writeAttribute("brief", brief); diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 629514e7d1..d55367dce2 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -327,6 +327,8 @@ Aggregate* Tree::findRelatesNode(const QStringList& path) } /*! + Inserts function name \a funcName and function role \a funcRole into + the property function map for the specified \a property. */ void Tree::addPropertyFunction(PropertyNode* property, const QString& funcName, |