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>bb10
parent
9b58fe5c26
commit
d884420b94
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -2008,6 +2023,19 @@ QString FunctionNode::signature(bool values) const
|
|||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
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.
|
||||
*/
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue