summaryrefslogtreecommitdiffstats
path: root/src/qdoc/qdocindexfiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qdoc/qdocindexfiles.cpp')
-rw-r--r--src/qdoc/qdocindexfiles.cpp534
1 files changed, 265 insertions, 269 deletions
diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp
index cdba1b548..2b957a439 100644
--- a/src/qdoc/qdocindexfiles.cpp
+++ b/src/qdoc/qdocindexfiles.cpp
@@ -105,7 +105,6 @@ void QDocIndexFiles::destroyQDocIndexFiles()
*/
void QDocIndexFiles::readIndexes(const QStringList& indexFiles)
{
- relatedList_.clear();
foreach (const QString& indexFile, indexFiles) {
QString msg = "Loading index file: " + indexFile;
Location::logToStdErr(msg);
@@ -209,8 +208,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
ns->setDocumented();
}
- }
- else if (elementName == QLatin1String("class")) {
+ } else if (elementName == QLatin1String("class")) {
node = new ClassNode(parent, name);
if (attributes.hasAttribute(QLatin1String("bases"))) {
QString bases = attributes.value(QLatin1String("bases")).toString();
@@ -225,8 +223,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
if (attributes.value(QLatin1String("abstract")) == QLatin1String("true"))
abstract = true;
node->setAbstract(abstract);
- }
- else if (elementName == QLatin1String("header")) {
+ } else if (elementName == QLatin1String("header")) {
node = new HeaderNode(parent, name);
if (attributes.hasAttribute(QLatin1String("location")))
@@ -236,8 +233,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
location = Location(indexUrl + QLatin1Char('/') + name);
else if (!indexUrl.isNull())
location = Location(name);
- }
- else if (elementName == QLatin1String("qmlclass")) {
+ } else if (elementName == QLatin1String("qmlclass")) {
QmlTypeNode* qcn = new QmlTypeNode(parent, name);
qcn->setTitle(attributes.value(QLatin1String("title")).toString());
QString logicalModuleName = attributes.value(QLatin1String("qml-module-name")).toString();
@@ -258,8 +254,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qcn;
- }
- else if (elementName == QLatin1String("jstype")) {
+ } else if (elementName == QLatin1String("jstype")) {
QmlTypeNode* qcn = new QmlTypeNode(parent, name);
qcn->setGenus(Node::JS);
qcn->setTitle(attributes.value(QLatin1String("title")).toString());
@@ -281,8 +276,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qcn;
- }
- else if (elementName == QLatin1String("qmlbasictype")) {
+ } else if (elementName == QLatin1String("qmlbasictype")) {
QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name);
qbtn->setTitle(attributes.value(QLatin1String("title")).toString());
if (attributes.hasAttribute(QLatin1String("location")))
@@ -292,8 +286,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qbtn;
- }
- else if (elementName == QLatin1String("jsbasictype")) {
+ } else if (elementName == QLatin1String("jsbasictype")) {
QmlBasicTypeNode* qbtn = new QmlBasicTypeNode(parent, name);
qbtn->setGenus(Node::JS);
qbtn->setTitle(attributes.value(QLatin1String("title")).toString());
@@ -304,8 +297,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qbtn;
- }
- else if (elementName == QLatin1String("qmlpropertygroup")) {
+ } else if (elementName == QLatin1String("qmlpropertygroup")) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent);
QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
if (attributes.hasAttribute(QLatin1String("location")))
@@ -315,8 +307,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qpgn;
- }
- else if (elementName == QLatin1String("jspropertygroup")) {
+ } else if (elementName == QLatin1String("jspropertygroup")) {
QmlTypeNode* qcn = static_cast<QmlTypeNode*>(parent);
QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
qpgn->setGenus(Node::JS);
@@ -327,8 +318,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(name);
node = qpgn;
- }
- else if (elementName == QLatin1String("qmlproperty")) {
+ } else if (elementName == QLatin1String("qmlproperty")) {
QString type = attributes.value(QLatin1String("type")).toString();
bool attached = false;
if (attributes.value(QLatin1String("attached")) == QLatin1String("true"))
@@ -337,10 +327,9 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
if (attributes.value(QLatin1String("writable")) == QLatin1String("false"))
readonly = true;
QmlPropertyNode* qpn = new QmlPropertyNode(parent, name, type, attached);
- qpn->setReadOnly(readonly);
+ qpn->markReadOnly(readonly);
node = qpn;
- }
- else if (elementName == QLatin1String("jsproperty")) {
+ } else if (elementName == QLatin1String("jsproperty")) {
QString type = attributes.value(QLatin1String("type")).toString();
bool attached = false;
if (attributes.value(QLatin1String("attached")) == QLatin1String("true"))
@@ -350,26 +339,23 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
readonly = true;
QmlPropertyNode* qpn = new QmlPropertyNode(parent, name, type, attached);
qpn->setGenus(Node::JS);
- qpn->setReadOnly(readonly);
+ qpn->markReadOnly(readonly);
node = qpn;
- }
- else if (elementName == QLatin1String("group")) {
+ } else if (elementName == QLatin1String("group")) {
CollectionNode* cn = qdb_->addGroup(name);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
- }
- else if (elementName == QLatin1String("module")) {
+ } else if (elementName == QLatin1String("module")) {
CollectionNode* cn = qdb_->addModule(name);
cn->setTitle(attributes.value(QLatin1String("title")).toString());
cn->setSubtitle(attributes.value(QLatin1String("subtitle")).toString());
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
- }
- else if (elementName == QLatin1String("qmlmodule")) {
+ } else if (elementName == QLatin1String("qmlmodule")) {
QString t = attributes.value(QLatin1String("qml-module-name")).toString();
CollectionNode* cn = qdb_->addQmlModule(t);
QStringList info;
@@ -380,8 +366,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
- }
- else if (elementName == QLatin1String("jsmodule")) {
+ } else if (elementName == QLatin1String("jsmodule")) {
QString t = attributes.value(QLatin1String("js-module-name")).toString();
CollectionNode* cn = qdb_->addJsModule(t);
QStringList info;
@@ -392,36 +377,29 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
if (attributes.value(QLatin1String("seen")) == QLatin1String("true"))
cn->markSeen();
node = cn;
- }
- else if (elementName == QLatin1String("page")) {
+ } else if (elementName == QLatin1String("page")) {
QDocAttr subtype = QDocAttrNone;
Node::PageType ptype = Node::NoPageType;
QString attr = attributes.value(QLatin1String("subtype")).toString();
if (attr == QLatin1String("attribution")) {
subtype = QDocAttrDocument;
ptype = Node::AttributionPage;
- }
- else if (attr == QLatin1String("example")) {
+ } else if (attr == QLatin1String("example")) {
subtype = QDocAttrExample;
ptype = Node::ExamplePage;
- }
- else if (attr == QLatin1String("file")) {
+ } else if (attr == QLatin1String("file")) {
subtype = QDocAttrFile;
ptype = Node::NoPageType;
- }
- else if (attr == QLatin1String("image")) {
+ } else if (attr == QLatin1String("image")) {
subtype = QDocAttrImage;
ptype = Node::NoPageType;
- }
- else if (attr == QLatin1String("page")) {
+ } else if (attr == QLatin1String("page")) {
subtype = QDocAttrDocument;
ptype = Node::ArticlePage;
- }
- else if (attr == QLatin1String("externalpage")) {
+ } else if (attr == QLatin1String("externalpage")) {
subtype = QDocAttrExternalPage;
ptype = Node::ArticlePage;
- }
- else
+ } else
goto done;
if (current && current->isExample()) {
@@ -454,8 +432,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
node = pn;
- }
- else if (elementName == QLatin1String("enum")) {
+ } else if (elementName == QLatin1String("enum")) {
EnumNode* enumNode = new EnumNode(parent, name);
if (!indexUrl.isEmpty())
@@ -480,8 +457,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
node = enumNode;
hasReadChildren = true;
- }
- else if (elementName == QLatin1String("typedef")) {
+ } else if (elementName == QLatin1String("typedef")) {
node = new TypedefNode(parent, name);
if (!indexUrl.isEmpty())
@@ -489,8 +465,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
else if (!indexUrl.isNull())
location = Location(parent->name().toLower() + ".html");
- }
- else if (elementName == QLatin1String("property")) {
+ } else if (elementName == QLatin1String("property")) {
node = new PropertyNode(parent, name);
if (!indexUrl.isEmpty())
@@ -508,12 +483,10 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
attached = true;
FunctionNode* fn = new FunctionNode(metaness, parent, name, attached);
if (fn->isCppNode()) {
- fn->setReturnType(attributes.value(QLatin1String("return")).toString());
+ fn->setReturnType(attributes.value(QLatin1String("type")).toString());
fn->setVirtualness(attributes.value(QLatin1String("virtual")).toString());
fn->setConst(attributes.value(QLatin1String("const")) == QLatin1String("true"));
fn->setStatic(attributes.value(QLatin1String("static")) == QLatin1String("true"));
- fn->setIsDeleted(attributes.value(QLatin1String("delete")) == QLatin1String("true"));
- fn->setIsDefaulted(attributes.value(QLatin1String("default")) == QLatin1String("true"));
fn->setFinal(attributes.value(QLatin1String("final")) == QLatin1String("true"));
fn->setOverride(attributes.value(QLatin1String("override")) == QLatin1String("true"));
int refness = attributes.value(QLatin1String("refness")).toUInt();
@@ -521,32 +494,31 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
fn->setRef(true);
else if (refness == 2)
fn->setRefRef(true);
- if (attributes.value(QLatin1String("overload")) == QLatin1String("true")) {
- fn->setOverloadFlag(true);
+ /*
+ Theoretically, this should ensure that each function
+ node receives the same overload number and overload
+ flag it was written with, and it should be unnecessary
+ to call normalizeOverloads() for index nodes.
+ */
+ if (attributes.value(QLatin1String("overload")) == QLatin1String("true"))
fn->setOverloadNumber(attributes.value(QLatin1String("overload-number")).toUInt());
- }
- else {
- fn->setOverloadFlag(false);
+ else
fn->setOverloadNumber(0);
- }
- if (attributes.hasAttribute(QLatin1String("relates"))) {
- QString relatesName = attributes.value(QLatin1String("relates")).toString();
- if (relatesName != parent->name())
- relatedList_.append(QPair<FunctionNode*, QString>(fn, relatesName));
- }
/*
Note: The "signature" attribute was written to the
- index file, but it is not read back in. Is that ok?
+ index file, but it is not read back in. That is ok
+ because we reconstruct the parameter list and the
+ return type, from which the signature was built in
+ the first place and from which it can be rebuilt.
*/
while (reader.readNextStartElement()) {
QXmlStreamAttributes childAttributes = reader.attributes();
if (reader.name() == QLatin1String("parameter")) {
// Do not use the default value for the parameter; it is not
// required, and has been known to cause problems.
- Parameter parameter(childAttributes.value(QLatin1String("type")).toString(),
- childAttributes.value(QLatin1String("name")).toString(),
- QString()); // childAttributes.value(QLatin1String("default"))
- fn->addParameter(parameter);
+ QString type = childAttributes.value(QLatin1String("type")).toString();
+ QString name = childAttributes.value(QLatin1String("name")).toString();
+ fn->parameters().append(type, name);
} else if (reader.name() == QLatin1String("keyword")) {
insertTarget(TargetRec::Keyword, childAttributes, fn);
} else if (reader.name() == QLatin1String("target")) {
@@ -563,28 +535,30 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
location = Location(parent->name().toLower() + ".html");
hasReadChildren = true;
- }
- else if (elementName == QLatin1String("variable")) {
+ } else if (elementName == QLatin1String("variable")) {
node = new VariableNode(parent, name);
if (!indexUrl.isEmpty())
location = Location(indexUrl + QLatin1Char('/') + parent->name().toLower() + ".html");
else if (!indexUrl.isNull())
location = Location(parent->name().toLower() + ".html");
- }
- else if (elementName == QLatin1String("keyword")) {
+ } else if (elementName == QLatin1String("keyword")) {
insertTarget(TargetRec::Keyword, attributes, current);
goto done;
- }
- else if (elementName == QLatin1String("target")) {
+ } else if (elementName == QLatin1String("target")) {
insertTarget(TargetRec::Target, attributes, current);
goto done;
- }
- else if (elementName == QLatin1String("contents")) {
+ } else if (elementName == QLatin1String("contents")) {
insertTarget(TargetRec::Contents, attributes, current);
goto done;
- }
- else
+ } else if (elementName == QLatin1String("proxy")) {
+ node = new ProxyNode(parent, name);
+ if (!indexUrl.isEmpty())
+ location = Location(indexUrl + QLatin1Char('/') + name.toLower() + ".html");
+ else if (!indexUrl.isNull())
+ location = Location(name.toLower() + ".html");
+ } else {
goto done;
+ }
{
QString access = attributes.value(QLatin1String("access")).toString();
@@ -596,12 +570,10 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
node->setAccess(Node::Private);
else
node->setAccess(Node::Public);
+ if (attributes.hasAttribute(QLatin1String("related")))
+ node->setRelatedNonmember(attributes.value(QLatin1String("related")) == QLatin1String("true"));
- if ((elementName != QLatin1String("page")) &&
- (elementName != QLatin1String("qmlclass")) &&
- (elementName != QLatin1String("qmlbasictype")) &&
- (elementName != QLatin1String("jstype")) &&
- (elementName != QLatin1String("jsbasictype"))) {
+ if (attributes.hasAttribute(QLatin1String("threadsafety"))) {
QString threadSafety = attributes.value(QLatin1String("threadsafety")).toString();
if (threadSafety == QLatin1String("non-reentrant"))
node->setThreadSafeness(Node::NonReentrant);
@@ -662,7 +634,7 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader,
}
Doc doc(location, location, QString(), emptySet, emptySet); // placeholder
node->setDoc(doc);
- node->setIndexNodeFlag();
+ node->setIndexNodeFlag(); // Important: This node came from an index file.
node->setOutputSubdirectory(project_.toLower());
QString briefAttr = attributes.value(QLatin1String("brief")).toString();
if (!briefAttr.isEmpty()) {
@@ -743,34 +715,54 @@ void QDocIndexFiles::resolveIndex()
basesList_.clear();
}
-/*
- Goes though the list of nodes that are related to other aggregates
- that were read from all index files, and tries to find the aggregate
- nodes from the database. Calls the node's setRelates() for each
- aggregate that is found in the local module (primary tree).
-
- This function is meant to be called before starting the doc generation,
- after all the index files are read.
- */
-void QDocIndexFiles::resolveRelates()
+static const QString getAccessString(Node::Access t)
{
- if (relatedList_.isEmpty())
- return;
- // Restrict searching only to the local (primary) tree
- QVector<Tree*> searchOrder = qdb_->searchOrder();
- qdb_->setLocalSearch();
+ switch (t) {
+ case Node::Public:
+ return QLatin1String("public");
+ case Node::Protected:
+ return QLatin1String("protected");
+ case Node::Private:
+ return QLatin1String("private");
+ default:
+ break;
+ }
+ return QLatin1String("public");
+}
- QPair<FunctionNode*,QString> relatedPair;
- foreach (relatedPair, relatedList_) {
- QStringList path = relatedPair.second.split("::");
- Node* n = qdb_->findRelatesNode(path);
- if (n)
- relatedPair.first->setRelates(static_cast<PageNode*>(n));
+static const QString getStatusString(Node::Status t)
+{
+ switch (t) {
+ case Node::Obsolete:
+ case Node::Deprecated:
+ return QLatin1String("obsolete");
+ case Node::Preliminary:
+ return QLatin1String("preliminary");
+ case Node::Active:
+ return QLatin1String("active");
+ case Node::Internal:
+ return QLatin1String("internal");
+ default:
+ break;
}
- // Restore original search order
- qdb_->setSearchOrder(searchOrder);
- relatedList_.clear();
+ return QLatin1String("active");
+}
+
+static const QString getThreadSafenessString(Node::ThreadSafeness t)
+{
+ switch (t) {
+ case Node::NonReentrant:
+ return QLatin1String("non-reentrant");
+ case Node::Reentrant:
+ return QLatin1String("reentrant");
+ case Node::ThreadSafe:
+ return QLatin1String("thread safe");
+ case Node::UnspecifiedSafeness:
+ default:
+ break;
+ }
+ return QLatin1String("unspecified");
}
/*!
@@ -778,12 +770,9 @@ void QDocIndexFiles::resolveRelates()
specified, returning true if an element was written, and returning
false if an element is not written.
- \node Currently \a generateInternalNodes is always \c true. If it is
- passed as \c false, then nodes marked internal or private are skipped.
+ \note Function nodes are processed in generateFunctionSection()
*/
-bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
- Node* node,
- bool generateInternalNodes)
+bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node)
{
if (!gen_)
gen_ = Generator::currentGenerator();
@@ -794,8 +783,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
*/
if (node->isIndexNode())
return false;
- if (!generateInternalNodes && (node->isInternal() || node->isPrivate()))
- return false;
QString nodeName;
QString logicalModuleName;
@@ -873,9 +860,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::Property:
nodeName = "property";
break;
- case Node::Function:
- nodeName = "function";
- break;
case Node::Variable:
nodeName = "variable";
break;
@@ -891,27 +875,10 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::JsPropertyGroup:
nodeName = "jspropertygroup";
break;
- default:
- return false;
- }
-
- QString access;
- switch (node->access()) {
- case Node::Public:
- access = "public";
- break;
- case Node::Protected:
- access = "protected";
- break;
- case Node::Private:
- /*
- Should we test generateInternalNodes here and return
- false immediately if it is set? As it is now, we are
- always writing all internal and private nodes to the
- index file.
- */
- access = "private";
+ case Node::Proxy:
+ nodeName = "proxy";
break;
+ case Node::Function: // Now processed in generateFunctionSection()
default:
return false;
}
@@ -923,46 +890,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeStartElement(nodeName);
- QXmlStreamAttributes attributes;
-
if (!node->isTextPageNode() && !node->isCollectionNode() && !node->isHeader()) {
- QString threadSafety;
- switch (node->threadSafeness()) {
- case Node::NonReentrant:
- threadSafety = "non-reentrant";
- break;
- case Node::Reentrant:
- threadSafety = "reentrant";
- break;
- case Node::ThreadSafe:
- threadSafety = "thread safe";
- break;
- case Node::UnspecifiedSafeness:
- default:
- threadSafety = "unspecified";
- break;
- }
- writer.writeAttribute("threadsafety", threadSafety);
- }
-
- QString status;
- switch (node->status()) {
- case Node::Obsolete:
- case Node::Deprecated:
- status = "obsolete";
- break;
- case Node::Preliminary:
- status = "preliminary";
- break;
- case Node::Active:
- status = "active";
- break;
- case Node::Internal:
- status = "internal";
- break;
- default:
- status = "main";
- break;
+ if (node->threadSafeness() != Node::UnspecifiedSafeness)
+ writer.writeAttribute("threadsafety", getThreadSafenessString(node->threadSafeness()));
}
writer.writeAttribute("name", objName);
@@ -1000,9 +930,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (!href.isEmpty())
writer.writeAttribute("href", href);
- writer.writeAttribute("status", status);
+ writer.writeAttribute("status", getStatusString(node->status()));
if (!node->isTextPageNode() && !node->isCollectionNode() && !node->isHeader()) {
- writer.writeAttribute("access", access);
+ writer.writeAttribute("access", getAccessString(node->access()));
if (node->isAbstract())
writer.writeAttribute("abstract", "true");
}
@@ -1014,9 +944,11 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("lineno", QString("%1").arg(declLocation.lineNo()));
}
- if (!node->since().isEmpty()) {
+ if (node->isRelatedNonmember())
+ writer.writeAttribute("related", "true");
+
+ if (!node->since().isEmpty())
writer.writeAttribute("since", node->since());
- }
QString brief = node->doc().trimmedBriefText(node->name()).toString();
switch (node->nodeType()) {
@@ -1202,68 +1134,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
- case Node::Function:
- {
- const FunctionNode* fn = static_cast<const FunctionNode*>(node);
- writer.writeAttribute("meta", fn->metanessString());
- if (fn->isCppNode()) {
- writer.writeAttribute("virtual", fn->virtualness());
- writer.writeAttribute("const", fn->isConst() ? "true":"false");
- writer.writeAttribute("static", fn->isStatic() ? "true":"false");
- writer.writeAttribute("overload", fn->isOverload() ? "true":"false");
- writer.writeAttribute("delete", fn->isDeleted() ? "true" : "false");
- writer.writeAttribute("default", fn->isDefaulted() ? "true" : "false");
- writer.writeAttribute("final", fn->isFinal() ? "true" : "false");
- writer.writeAttribute("override", fn->isOverride() ? "true" : "false");
- if (fn->isRef())
- writer.writeAttribute("refness", QString::number(1));
- else if (fn->isRefRef())
- writer.writeAttribute("refness", QString::number(2));
- if (fn->isOverload())
- writer.writeAttribute("overload-number", QString::number(fn->overloadNumber()));
- if (fn->relates())
- writer.writeAttribute("relates", fn->relates()->name());
- if (fn->hasAssociatedProperties()) {
- QStringList associatedProperties;
- foreach (PropertyNode* pn, fn->associatedProperties()) {
- associatedProperties << pn->name();
- }
- associatedProperties.sort();
- writer.writeAttribute("associated-property", associatedProperties.join(QLatin1Char(',')));
- }
- writer.writeAttribute("type", fn->returnType());
- if (!brief.isEmpty())
- writer.writeAttribute("brief", brief);
- /*
- Note: The "signature" attribute is written to the
- index file, but it is not read back in by qdoc. However,
- we need it for the webxml generator.
- */
- QString signature = fn->signature(false);
- // 'const' is already part of FunctionNode::signature()
- if (fn->isFinal())
- signature += " final";
- if (fn->isOverride())
- signature += " override";
- if (fn->isPureVirtual())
- signature += " = 0";
- else if (fn->isDeleted())
- signature += " = delete";
- else if (fn->isDefaulted())
- signature += " = default";
- writer.writeAttribute("signature", signature);
-
- for (int i = 0; i < fn->parameters().size(); ++i) {
- Parameter parameter = fn->parameters()[i];
- writer.writeStartElement("parameter");
- writer.writeAttribute("type", parameter.dataType());
- writer.writeAttribute("name", parameter.name());
- writer.writeAttribute("default", parameter.defaultValue());
- writer.writeEndElement(); // parameter
- }
- }
- }
- break;
case Node::JsProperty:
case Node::QmlProperty:
{
@@ -1351,6 +1221,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("enum",typedefNode->associatedEnum()->fullDocumentName());
}
break;
+ case Node::Function: // Now processed in generateFunctionSection()
default:
break;
}
@@ -1448,32 +1319,154 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
}
/*!
+ This function writes a <function> element for \a fn to the
+ index file using \a writer.
+ */
+void QDocIndexFiles::generateFunctionSection(QXmlStreamWriter &writer, FunctionNode *fn)
+{
+ QString objName = fn->name();
+ writer.writeStartElement("function");
+ writer.writeAttribute("name", objName);
+
+ QString fullName = fn->fullDocumentName();
+ if (fullName != objName)
+ writer.writeAttribute("fullname", fullName);
+ QString href = gen_->fullDocumentLocation(fn);
+ if (!href.isEmpty())
+ writer.writeAttribute("href", href);
+ if (fn->threadSafeness() != Node::UnspecifiedSafeness)
+ writer.writeAttribute("threadsafety", getThreadSafenessString(fn->threadSafeness()));
+ writer.writeAttribute("status", getStatusString(fn->status()));
+ writer.writeAttribute("access", getAccessString(fn->access()));
+
+ const Location &declLocation = fn->declLocation();
+ if (!declLocation.fileName().isEmpty())
+ writer.writeAttribute("location", declLocation.fileName());
+ if (!declLocation.filePath().isEmpty()) {
+ writer.writeAttribute("filepath", declLocation.filePath());
+ writer.writeAttribute("lineno", QString("%1").arg(declLocation.lineNo()));
+ }
+
+ if (fn->isRelatedNonmember())
+ writer.writeAttribute("related", "true");
+ if (!fn->since().isEmpty())
+ writer.writeAttribute("since", fn->since());
+
+ QString brief = fn->doc().trimmedBriefText(fn->name()).toString();
+ writer.writeAttribute("meta", fn->metanessString());
+ if (fn->isCppNode()) {
+ writer.writeAttribute("virtual", fn->virtualness());
+ writer.writeAttribute("const", fn->isConst() ? "true" : "false");
+ writer.writeAttribute("static", fn->isStatic() ? "true" : "false");
+ writer.writeAttribute("final", fn->isFinal() ? "true" : "false");
+ writer.writeAttribute("override", fn->isOverride() ? "true" : "false");
+ /*
+ This ensures that for functions that have overloads,
+ the first function written is the one that is not an
+ overload, and the overloads follow it immediately in
+ the index file numbered from 1 to n.
+ */
+ if (fn->isOverload() && (fn->overloadNumber() > 0)) {
+ writer.writeAttribute("overload", "true");
+ writer.writeAttribute("overload-number", QString::number(fn->overloadNumber()));
+ }
+ if (fn->isRef())
+ writer.writeAttribute("refness", QString::number(1));
+ else if (fn->isRefRef())
+ writer.writeAttribute("refness", QString::number(2));
+ if (fn->hasAssociatedProperties()) {
+ QStringList associatedProperties;
+ foreach (Node *n, fn->associatedProperties()) {
+ associatedProperties << n->name();
+ }
+ associatedProperties.sort();
+ writer.writeAttribute("associated-property", associatedProperties.join(QLatin1Char(',')));
+ }
+ writer.writeAttribute("type", fn->returnType());
+ if (!brief.isEmpty())
+ writer.writeAttribute("brief", brief);
+ /*
+ Note: The "signature" attribute is written to the
+ index file, but it is not read back in by qdoc. However,
+ we need it for the webxml generator.
+ */
+ QString signature = fn->signature(false, false);
+ // 'const' is already part of FunctionNode::signature()
+ if (fn->isFinal())
+ signature += " final";
+ if (fn->isOverride())
+ signature += " override";
+ if (fn->isPureVirtual())
+ signature += " = 0";
+ writer.writeAttribute("signature", signature);
+
+ for (int i = 0; i < fn->parameters().count(); ++i) {
+ const Parameter &parameter = fn->parameters().at(i);
+ writer.writeStartElement("parameter");
+ writer.writeAttribute("type", parameter.type());
+ writer.writeAttribute("name", parameter.name());
+ writer.writeAttribute("default", parameter.defaultValue());
+ writer.writeEndElement(); // parameter
+ }
+ }
+ writer.writeEndElement();
+}
+
+/*!
+ This function outputs a <function> element to the index file
+ for each FunctionNode in \a aggregate using the \a writer.
+ The \a aggregate has a function map that contains all the
+ function nodes indexed by function name. But the map is not
+ used as a multimap, so if the \a aggregate contains multiple
+ functions with the same name, only one of those functions is
+ in the function map index. The others are linked to that
+ function using the next overload pointer.
+
+ So this function generates a <function> element for a function
+ followed by a function element for each of its overloads. If a
+ <function> element represents an overload, it has an \c overload
+ attribute set to \c true and an \c {overload-number} attribute
+ set to the function's overload number. If the <function>
+ element does not represent an overload, the <function> element
+ has neither of these attributes.
+ */
+void QDocIndexFiles::generateFunctionSections(QXmlStreamWriter &writer, Aggregate *aggregate)
+{
+ FunctionMap &functionMap = aggregate->functionMap();
+ if (!functionMap.isEmpty()) {
+ FunctionMap::iterator i = functionMap.begin();
+ while (i != functionMap.end()) {
+ FunctionNode *fn = i.value();
+ while (fn != nullptr) {
+ generateFunctionSection(writer, fn);
+ fn = fn->nextOverload();
+ }
+ i++;
+ }
+ }
+}
+
+/*!
Generate index sections for the child nodes of the given \a node
- using the \a writer specified. If \a generateInternalNodes is true,
- nodes marked as internal will be included in the index; otherwise,
- they will be omitted.
+ using the \a writer specified.
*/
-void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
- Node* node,
- bool generateInternalNodes)
+void QDocIndexFiles::generateIndexSections(QXmlStreamWriter &writer, Node *node)
{
/*
Note that groups, modules, and QML modules are written
after all the other nodes.
*/
- if (node->isGroup() || node->isModule() || node->isQmlModule() || node->isJsModule())
+ if (node->isCollectionNode() ||
+ node->isGroup() || node->isModule() || node->isQmlModule() || node->isJsModule())
return;
- if (generateIndexSection(writer, node, generateInternalNodes)) {
+ if (generateIndexSection(writer, node)) {
if (node->isAggregate()) {
- const Aggregate* aggregate = static_cast<const Aggregate*>(node);
-
- NodeList cnodes = aggregate->childNodes();
- std::sort(cnodes.begin(), cnodes.end(), Node::nodeNameLessThan);
-
- foreach (Node* child, cnodes) {
- generateIndexSections(writer, child, generateInternalNodes);
- }
+ Aggregate *aggregate = static_cast<Aggregate *>(node);
+ // First write the function children, then write the nonfunction children.
+ generateFunctionSections(writer, aggregate);
+ foreach (Node *n, aggregate->nonfunctionList())
+ generateIndexSections(writer, n);
}
if (node == root_) {
@@ -1489,7 +1482,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
if (!groups.isEmpty()) {
CNMap::ConstIterator g = groups.constBegin();
while (g != groups.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ if (generateIndexSection(writer, g.value()))
writer.writeEndElement();
++g;
}
@@ -1499,7 +1492,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
if (!modules.isEmpty()) {
CNMap::ConstIterator g = modules.constBegin();
while (g != modules.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ if (generateIndexSection(writer, g.value()))
writer.writeEndElement();
++g;
}
@@ -1509,7 +1502,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
if (!qmlModules.isEmpty()) {
CNMap::ConstIterator g = qmlModules.constBegin();
while (g != qmlModules.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ if (generateIndexSection(writer, g.value()))
writer.writeEndElement();
++g;
}
@@ -1519,7 +1512,7 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
if (!jsModules.isEmpty()) {
CNMap::ConstIterator g = jsModules.constBegin();
while (g != jsModules.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ if (generateIndexSection(writer, g.value()))
writer.writeEndElement();
++g;
}
@@ -1531,13 +1524,16 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
}
/*!
- Outputs an index file.
+ Writes aqdoc module index in XML to a file named \afilerName.
+ \a url becaomes the \c url attribute of the <INDEX> element.
+ \a title becomes the \c title attribute of the <INDEX> element.
+ \a g is used to get the Config object that contains the variables
+ from the module's .qdocconf file.
*/
void QDocIndexFiles::generateIndex(const QString& fileName,
const QString& url,
const QString& title,
- Generator* g,
- bool generateInternalNodes)
+ Generator *g)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text))
@@ -1562,7 +1558,7 @@ void QDocIndexFiles::generateIndex(const QString& fileName,
if (!root_->tree()->indexTitle().isEmpty())
writer.writeAttribute("indexTitle", root_->tree()->indexTitle());
- generateIndexSections(writer, root_, generateInternalNodes);
+ generateIndexSections(writer, root_);
writer.writeEndElement(); // INDEX
writer.writeEndElement(); // QDOCINDEX