31#include <QtCore/qxmlstream.h>
52
53
54
55
60
61
69
70
78
79
80
83 if (s_qdocIndexFiles ==
nullptr)
85 return s_qdocIndexFiles;
89
90
93 if (s_qdocIndexFiles !=
nullptr) {
94 delete s_qdocIndexFiles;
95 s_qdocIndexFiles =
nullptr;
100
101
104 for (
const QString &file : indexFiles) {
105 qCDebug(lcQdoc) <<
"Loading index file: " << file;
111
112
118 if (!file.open(QFile::ReadOnly)) {
119 qWarning() <<
"Could not read index file" << path;
123 QXmlStreamReader reader(&file);
124 reader.setNamespaceProcessing(
false);
126 if (!reader.readNextStartElement())
129 if (reader.name() != QLatin1String(
"INDEX"))
132 QXmlStreamAttributes attrs = reader.attributes();
134 QString indexUrl {attrs.value(QLatin1String(
"url")).toString()};
141 if (!Config::installDir.isEmpty() && indexUrl == Config::instance().get(
CONFIG_URL).asString()) {
144 QDir installDir(path.section(
'/', 0, -3) +
'/' + Generator::outputSubdir());
145 indexUrl = installDir.relativeFilePath(path).section(
'/', 0, -2);
147 m_project = attrs.value(QLatin1String(
"project")).toString();
148 QString indexTitle = attrs.value(QLatin1String(
"indexTitle")).toString();
150 m_relatedNodes.clear();
154 qWarning() <<
"Issue parsing index tree" << path;
158 root
->tree()->setIndexTitle(indexTitle);
162 while (reader.readNextStartElement()) {
163 readIndexSection(reader, root, indexUrl);
172
173
174
176 const QString &indexUrl)
178 QXmlStreamAttributes attributes = reader.attributes();
179 QStringView elementName = reader.name();
181 QString name = attributes.value(QLatin1String(
"name")).toString();
182 QString href = attributes.value(QLatin1String(
"href")).toString();
186 bool hasReadChildren =
false;
188 if (current->isAggregate())
189 parent =
static_cast<Aggregate *>(current);
191 if (attributes.hasAttribute(QLatin1String(
"related"))) {
192 bool isIntTypeRelatedValue =
false;
193 int relatedIndex = attributes.value(QLatin1String(
"related")).toInt(&isIntTypeRelatedValue);
194 if (isIntTypeRelatedValue) {
195 if (adoptRelatedNode(parent, relatedIndex)) {
196 reader.skipCurrentElement();
200 QList<Node *>::iterator nodeIterator =
201 std::find_if(m_relatedNodes.begin(), m_relatedNodes.end(), [&](
const Node *relatedNode) {
202 return (name == relatedNode->name() && href == relatedNode->url().section(QLatin1Char(
'/'), -1));
205 if (nodeIterator != m_relatedNodes.end() && parent) {
207 reader.skipCurrentElement();
215 if (attributes.hasAttribute(QLatin1String(
"filepath"))) {
216 filePath = attributes.value(QLatin1String(
"filepath")).toString();
217 lineNo = attributes.value(
"lineno").toInt();
219 if (parent && elementName == QLatin1String(
"namespace")) {
221 node = namespaceNode;
222 if (!indexUrl.isEmpty())
223 location
= Location(indexUrl + QLatin1Char(
'/') + name.toLower() +
".html");
224 else if (!indexUrl.isNull())
225 location
= Location(name.toLower() +
".html");
226 }
else if (parent && (elementName == QLatin1String(
"class") || elementName == QLatin1String(
"struct")
227 || elementName == QLatin1String(
"union"))) {
229 if (elementName == QLatin1String(
"class"))
231 else if (elementName == QLatin1String(
"struct"))
233 else if (elementName == QLatin1String(
"union"))
235 node =
new ClassNode(type, parent, name);
236 if (attributes.hasAttribute(QLatin1String(
"bases"))) {
237 QString bases = attributes.value(QLatin1String(
"bases")).toString();
238 if (!bases.isEmpty())
240 std::pair<ClassNode *, QString>(
static_cast<ClassNode *>(node), bases));
242 if (!indexUrl.isEmpty())
243 location
= Location(indexUrl + QLatin1Char(
'/') + name.toLower() +
".html");
244 else if (!indexUrl.isNull())
245 location
= Location(name.toLower() +
".html");
246 bool abstract =
false;
247 if (attributes.value(QLatin1String(
"abstract")) == QLatin1String(
"true"))
250 }
else if (parent && elementName == QLatin1String(
"header")) {
253 if (attributes.hasAttribute(QLatin1String(
"location")))
254 name = attributes.value(QLatin1String(
"location")).toString();
256 if (!indexUrl.isEmpty())
257 location
= Location(indexUrl + QLatin1Char(
'/') + name);
258 else if (!indexUrl.isNull())
260 }
else if (parent && ((elementName == QLatin1String(
"qmlclass") || elementName == QLatin1String(
"qmlvaluetype")
261 || elementName == QLatin1String(
"qmlbasictype")))) {
264 QString logicalModuleName = attributes.value(QLatin1String(
"qml-module-name")).toString();
265 if (!logicalModuleName.isEmpty())
266 m_qdb->addToQmlModule(logicalModuleName, qmlTypeNode);
267 bool abstract =
false;
268 if (attributes.value(QLatin1String(
"abstract")) == QLatin1String(
"true"))
270 qmlTypeNode->setAbstract(abstract);
271 if (attributes.value(QLatin1String(
"singleton")) == QLatin1String(
"true"))
272 qmlTypeNode->setSingleton();
273 else if (attributes.value(QLatin1String(
"uncreatable")) == QLatin1String(
"true"))
274 qmlTypeNode->setUncreatable();
275 QString qmlFullBaseName = attributes.value(QLatin1String(
"qml-base-type")).toString();
276 if (!qmlFullBaseName.isEmpty()) {
277 qmlTypeNode->setQmlBaseName(qmlFullBaseName);
279 if (attributes.hasAttribute(QLatin1String(
"location")))
280 name = attributes.value(
"location").toString();
281 if (!indexUrl.isEmpty())
282 location
= Location(indexUrl + QLatin1Char(
'/') + name);
283 else if (!indexUrl.isNull())
286 }
else if (parent && elementName == QLatin1String(
"qmlproperty")) {
288 QString propertyGroup = attributes.value(
"inpropertygroup").toString();
290 if (attributes.value(
"propertygroup") ==
"true") {
292 propertyGroup = attributes.value(
"fullname").toString();
294 QString type = attributes.value(QLatin1String(
"type")).toString();
295 bool attached =
false;
296 if (attributes.value(QLatin1String(
"attached")) == QLatin1String(
"true"))
298 bool readonly =
false;
299 if (attributes.value(QLatin1String(
"writable")) == QLatin1String(
"false"))
302 qmlPropertyNode->markReadOnly(readonly);
303 if (attributes.value(QLatin1String(
"required")) == QLatin1String(
"true"))
304 qmlPropertyNode->setRequired();
306 node = qmlPropertyNode;
309 if (!propertyGroup.isEmpty()) {
314 scn =
new SharedCommentNode(
static_cast<QmlTypeNode *>(parent), 0, propertyGroup.split(
".").last());
322 hasReadChildren =
true;
325 }
else if (elementName == QLatin1String(
"group")) {
326 auto *collectionNode = m_qdb->addGroup(name);
327 collectionNode->setTitle(attributes.value(QLatin1String(
"title")).toString());
328 collectionNode->setSubtitle(attributes.value(QLatin1String(
"subtitle")).toString());
329 if (attributes.value(QLatin1String(
"seen")) == QLatin1String(
"true"))
330 collectionNode->markSeen();
331 node = collectionNode;
332 }
else if (elementName == QLatin1String(
"module")) {
333 auto *collectionNode = m_qdb->addModule(name);
334 collectionNode->setTitle(attributes.value(QLatin1String(
"title")).toString());
335 collectionNode->setSubtitle(attributes.value(QLatin1String(
"subtitle")).toString());
336 if (attributes.value(QLatin1String(
"seen")) == QLatin1String(
"true"))
337 collectionNode->markSeen();
338 node = collectionNode;
339 }
else if (elementName == QLatin1String(
"concept")) {
340 auto *collectionNode = m_qdb->addConcept(name);
341 collectionNode->setTitle(attributes.value(QLatin1String(
"title")).toString());
342 collectionNode->setSubtitle(attributes.value(QLatin1String(
"subtitle")).toString());
343 if (attributes.value(QLatin1String(
"seen")) == QLatin1String(
"true"))
344 collectionNode->markSeen();
345 node = collectionNode;
346 }
else if (elementName == QLatin1String(
"qmlmodule")) {
347 auto *collectionNode = m_qdb->addQmlModule(name);
348 const QStringList info = QStringList()
350 << QString(attributes.value(QLatin1String(
"qml-module-version")).toString());
351 collectionNode->setLogicalModuleInfo(info);
352 collectionNode->setTitle(attributes.value(QLatin1String(
"title")).toString());
353 collectionNode->setSubtitle(attributes.value(QLatin1String(
"subtitle")).toString());
354 if (attributes.value(QLatin1String(
"seen")) == QLatin1String(
"true"))
355 collectionNode->markSeen();
356 node = collectionNode;
357 }
else if (elementName == QLatin1String(
"page")) {
359 QString attr = attributes.value(QLatin1String(
"subtype")).toString();
360 if (attr == QLatin1String(
"attribution")) {
362 }
else if (attr == QLatin1String(
"example")) {
364 }
else if (attr == QLatin1String(
"file")) {
366 }
else if (attr == QLatin1String(
"image")) {
368 }
else if (attr == QLatin1String(
"page")) {
370 }
else if (attr == QLatin1String(
"externalpage")) {
376 auto *exampleNode =
static_cast<ExampleNode *>(current);
378 exampleNode->appendFile(name);
381 exampleNode->appendImage(name);
391 pageNode =
new PageNode(parent, name);
395 pageNode->setTitle(attributes.value(QLatin1String(
"title")).toString());
397 if (attributes.hasAttribute(QLatin1String(
"location")))
398 name = attributes.value(QLatin1String(
"location")).toString();
400 if (!indexUrl.isEmpty())
401 location
= Location(indexUrl + QLatin1Char(
'/') + name);
402 else if (!indexUrl.isNull())
407 }
else if (parent && (elementName == QLatin1String(
"enum") || elementName == QLatin1String(
"qmlenum"))) {
409 if (elementName == QLatin1String(
"enum"))
410 enumNode =
new EnumNode(parent, name, attributes.hasAttribute(
"scoped"));
414 if (!indexUrl.isEmpty())
415 location
= Location(indexUrl + QLatin1Char(
'/') + parent->name().toLower() +
".html");
416 else if (!indexUrl.isNull())
417 location
= Location(parent->name().toLower() +
".html");
419 if (attributes.value(
"anonymous") ==
"true")
422 while (reader.readNextStartElement()) {
423 QXmlStreamAttributes childAttributes = reader.attributes();
424 if (reader.name() == QLatin1String(
"value")) {
425 EnumItem item(childAttributes.value(QLatin1String(
"name")).toString(),
426 childAttributes.value(QLatin1String(
"value")).toString(),
427 childAttributes.value(QLatin1String(
"since")).toString()
430 }
else if (reader.name() == QLatin1String(
"keyword")) {
432 }
else if (reader.name() == QLatin1String(
"target")) {
435 reader.skipCurrentElement();
440 hasReadChildren =
true;
441 }
else if (parent && elementName == QLatin1String(
"typedef")) {
443 if (attributes.hasAttribute(
"aliasedtype"))
444 typedefNode =
new TypeAliasNode(parent, name, attributes.value(QLatin1String(
"aliasedtype")).toString());
449 if (attributes.hasAttribute(
"enum")) {
450 auto path = attributes.value(QLatin1String(
"enum")).toString();
451 const Node *enode = m_qdb->findNodeForTarget(path, typedefNode);
453 const EnumNode *n =
static_cast<
const EnumNode *>(enode);
459 if (!indexUrl.isEmpty())
460 location
= Location(indexUrl + QLatin1Char(
'/') + parent->name().toLower() +
".html");
461 else if (!indexUrl.isNull())
462 location
= Location(parent->name().toLower() +
".html");
463 }
else if (parent && elementName == QLatin1String(
"property")) {
466 if (attributes.value(QLatin1String(
"bindable")) == QLatin1String(
"true"))
469 propNode->setWritable(attributes.value(QLatin1String(
"writable")) != QLatin1String(
"false"));
470 propNode->setDataType(attributes.value(QLatin1String(
"dataType")).toString());
472 if (attributes.value(QLatin1String(
"constant")) == QLatin1String(
"true"))
473 propNode->setConstant();
475 if (!indexUrl.isEmpty())
476 location
= Location(indexUrl + QLatin1Char(
'/') + parent->name().toLower() +
".html");
477 else if (!indexUrl.isNull())
478 location
= Location(parent->name().toLower() +
".html");
480 }
else if (parent && elementName == QLatin1String(
"function")) {
481 QString t = attributes.value(QLatin1String(
"meta")).toString();
482 bool attached =
false;
485 metaness = FunctionNode::getMetaness(t);
486 if (attributes.value(QLatin1String(
"attached")) == QLatin1String(
"true"))
488 auto *fn =
new FunctionNode(metaness, parent, name, attached);
490 fn->setReturnType(attributes.value(QLatin1String(
"type")).toString());
492 const auto &declaredTypeAttr = attributes.value(QLatin1String(
"declaredtype"));
493 if (!declaredTypeAttr.isEmpty())
494 fn->setDeclaredReturnType(declaredTypeAttr.toString());
496 if (fn->isCppNode()) {
497 fn->setVirtualness(attributes.value(QLatin1String(
"virtual")).toString());
498 fn->setConst(attributes.value(QLatin1String(
"const")) == QLatin1String(
"true"));
499 fn->setStatic(attributes.value(QLatin1String(
"static")) == QLatin1String(
"true"));
500 fn->setFinal(attributes.value(QLatin1String(
"final")) == QLatin1String(
"true"));
501 fn->setOverride(attributes.value(QLatin1String(
"override")) == QLatin1String(
"true"));
503 if (attributes.value(QLatin1String(
"explicit")) == QLatin1String(
"true"))
506 if (attributes.value(QLatin1String(
"constexpr")) == QLatin1String(
"true"))
509 if (attributes.value(QLatin1String(
"explicitly-defaulted")) == QLatin1String(
"true"))
510 fn->markExplicitlyDefaulted();
512 if (attributes.value(QLatin1String(
"deleted")) == QLatin1String(
"true"))
513 fn->markDeletedAsWritten();
514 if (attributes.value(QLatin1String(
"hidden-friend")) == QLatin1String(
"true"))
515 fn->setHiddenFriend(
true);
517 if (attributes.value(QLatin1String(
"noexcept")) == QLatin1String(
"true")) {
518 fn->markNoexcept(attributes.value(
"noexcept_expression").toString());
521 if (attributes.hasAttribute(QLatin1String(
"trailing_requires")))
522 fn->setTrailingRequiresClause(attributes.value(QLatin1String(
"trailing_requires")).toString());
524 qsizetype refness = attributes.value(QLatin1String(
"refness")).toUInt();
527 else if (refness == 2)
530
531
532
533
534
535 if (attributes.value(QLatin1String(
"overload")) == QLatin1String(
"true"))
536 fn->setOverloadNumber(attributes.value(QLatin1String(
"overload-number")).toUInt());
538 fn->setOverloadNumber(0);
542
543
544
545
546
547
548 while (reader.readNextStartElement()) {
549 QXmlStreamAttributes childAttributes = reader.attributes();
550 if (reader.name() == QLatin1String(
"parameter")) {
551 QString type = childAttributes.value(QLatin1String(
"type")).toString();
552 QString name = childAttributes.value(QLatin1String(
"name")).toString();
553 QString default_ = childAttributes.value(QLatin1String(
"default")).toString();
554 fn->parameters().append(type, name, default_);
555 }
else if (reader.name() == QLatin1String(
"keyword")) {
557 }
else if (reader.name() == QLatin1String(
"target")) {
560 reader.skipCurrentElement();
564 if (!indexUrl.isEmpty())
565 location
= Location(indexUrl + QLatin1Char(
'/') + parent->name().toLower() +
".html");
566 else if (!indexUrl.isNull())
567 location
= Location(parent->name().toLower() +
".html");
569 hasReadChildren =
true;
570 }
else if (parent && elementName == QLatin1String(
"variable")) {
572 varNode->setLeftType(attributes.value(
"type").toString());
573 varNode->setStatic((attributes.value(
"static").toString() ==
"true") ?
true :
false);
575 if (!indexUrl.isEmpty())
576 location
= Location(indexUrl + QLatin1Char(
'/') + parent->name().toLower() +
".html");
577 else if (!indexUrl.isNull())
578 location
= Location(parent->name().toLower() +
".html");
579 }
else if (elementName == QLatin1String(
"keyword")) {
582 }
else if (elementName == QLatin1String(
"target")) {
585 }
else if (elementName == QLatin1String(
"contents")) {
588 }
else if (parent && elementName == QLatin1String(
"proxy")) {
590 if (!indexUrl.isEmpty())
591 location
= Location(indexUrl + QLatin1Char(
'/') + name.toLower() +
".html");
592 else if (!indexUrl.isNull())
593 location
= Location(name.toLower() +
".html");
601 auto *cn =
static_cast<CollectionNode *>(node);
602 if (attributes.hasAttribute(QLatin1String(
"cmakepackage")))
603 cn->setCMakePackage(attributes.value(QLatin1String(
"cmakepackage")).toString());
604 if (attributes.hasAttribute(QLatin1String(
"cmakecomponent")))
605 cn->setCMakeComponent(attributes.value(QLatin1String(
"cmakecomponent")).toString());
606 if (attributes.hasAttribute(QLatin1String(
"cmaketargetitem")))
607 cn->setCMakeTargetItem(attributes.value(QLatin1String(
"cmaketargetitem")).toString());
608 if (attributes.hasAttribute(QLatin1String(
"qtvariable")))
609 cn->setQtVariable(attributes.value(QLatin1String(
"qtvariable")).toString());
611 if (node
->isAggregate() && attributes.hasAttribute(QLatin1String(
"includefile"))) {
612 auto *agg =
static_cast<Aggregate *>(node);
613 agg->setIncludeFile(attributes.value(QLatin1String(
"includefile")).toString());
616 if (!href.isEmpty()) {
620 node->setUrl(indexUrl + QLatin1Char(
'/') + href);
623 const QString access = attributes.value(QLatin1String(
"access")).toString();
624 if (access ==
"protected")
626 else if (access ==
"private")
631 if (attributes.hasAttribute(QLatin1String(
"related"))) {
633 m_relatedNodes << node;
636 if (attributes.hasAttribute(QLatin1String(
"threadsafety"))) {
637 QString threadSafety = attributes.value(QLatin1String(
"threadsafety")).toString();
638 if (threadSafety == QLatin1String(
"non-reentrant"))
640 else if (threadSafety == QLatin1String(
"reentrant"))
642 else if (threadSafety == QLatin1String(
"thread safe"))
649 const QString category = attributes.value(QLatin1String(
"comparison_category")).toString();
652 QString status = attributes.value(QLatin1String(
"status")).toString();
654 if (status == QLatin1String(
"obsolete") || status == QLatin1String(
"deprecated"))
656 else if (status == QLatin1String(
"preliminary"))
658 else if (status == QLatin1String(
"internal"))
660 else if (status == QLatin1String(
"internal-auto"))
662 else if (status == QLatin1String(
"ignored"))
667 QString physicalModuleName = attributes.value(QLatin1String(
"module")).toString();
668 if (!physicalModuleName.isEmpty())
669 m_qdb->addToModule(physicalModuleName, node);
671 QString since = attributes.value(QLatin1String(
"since")).toString();
672 if (!since.isEmpty()) {
673 node->setSince(since);
676 if (attributes.hasAttribute(QLatin1String(
"documented"))) {
677 if (attributes.value(QLatin1String(
"documented")) == QLatin1String(
"true"))
681 QString groupsAttr = attributes.value(QLatin1String(
"groups")).toString();
682 if (!groupsAttr.isEmpty()) {
683 const QStringList groupNames = groupsAttr.split(QLatin1Char(
','));
684 for (
const auto &group : groupNames) {
685 m_qdb->addToGroup(group, node);
690 QSet<QString> emptySet;
692 if (!filePath.isEmpty()) {
697 Doc doc(location, location, QString(), emptySet, emptySet);
698 if (attributes.value(QLatin1String(
"auto-generated")) == QLatin1String(
"true"))
702 QString briefAttr = attributes.value(QLatin1String(
"brief")).toString();
703 if (!briefAttr.isEmpty()) {
704 node->setReconstitutedBrief(briefAttr);
707 if (
const auto sortKey = attributes.value(QLatin1String(
"sortkey")).toString(); !sortKey.isEmpty()) {
710 metaMap->insert(
"sortkey", sortKey);
712 if (!hasReadChildren) {
713 bool useParent = (elementName == QLatin1String(
"namespace") && name.isEmpty());
714 while (reader.readNextStartElement()) {
716 readIndexSection(reader, parent, indexUrl);
718 readIndexSection(reader, node, indexUrl);
724 while (!reader.isEndElement()) {
725 if (reader.readNext() == QXmlStreamReader::Invalid) {
732 const QXmlStreamAttributes &attributes,
Node *node)
749 QString name = attributes.value(QLatin1String(
"name")).toString();
750 QString title = attributes.value(QLatin1String(
"title")).toString();
751 m_qdb->insertTarget(name, title, type, node, priority);
755
756
757
758
759
760
761
762
763
764
765
766
767
770 for (
const auto &pair : std::as_const(m_basesList)) {
771 const QStringList bases = pair.second.split(QLatin1Char(
','));
772 for (
const auto &base : bases) {
773 QStringList basePath = base.split(QString(
"::"));
774 Node *n = m_qdb->findClassNode(basePath);
776 pair.first->addResolvedBaseClass(Access::Public,
static_cast<ClassNode *>(n));
778 pair.first->addUnresolvedBaseClass(Access::Public, basePath);
790 return QLatin1String(
"public");
791 case Access::Protected:
792 return QLatin1String(
"protected");
793 case Access::Private:
794 return QLatin1String(
"private");
798 return QLatin1String(
"public");
805 return QLatin1String(
"deprecated");
807 return QLatin1String(
"preliminary");
809 return QLatin1String(
"active");
811 return QLatin1String(
"internal");
813 return QLatin1String(
"internal-auto");
815 return QLatin1String(
"ignored");
819 return QLatin1String(
"active");
826 return QLatin1String(
"non-reentrant");
828 return QLatin1String(
"reentrant");
830 return QLatin1String(
"thread safe");
835 return QLatin1String(
"unspecified");
839
840
843 qsizetype i = m_relatedNodes.indexOf(node);
845 i = m_relatedNodes.size();
846 m_relatedNodes << node;
852
853
854
855static void writeNonEmpty(QXmlStreamWriter &writer,
const QString &name,
const QString &value)
857 if (!value.isEmpty())
858 writer.writeAttribute(name, value);
862
863
864
867 Node *related = m_relatedNodes.value(index);
869 if (adoptiveParent && related) {
878
879
880
881
882
886 for (
const Atom *target : std::as_const(node->doc().targets())) {
887 const QString &title = target->string();
888 const QString &name{TextUtils::asAsciiPrintable(title)};
889 writer.writeStartElement(
"target");
890 writer.writeAttribute(
"name", node->isExternalPage() ? title : name);
892 writer.writeAttribute(
"title", title);
893 writer.writeEndElement();
897 for (
const Atom *keyword : std::as_const(node->doc().keywords())) {
898 const QString &title = keyword->string();
899 const QString &name{TextUtils::asAsciiPrintable(title)};
900 writer.writeStartElement(
"keyword");
901 writer.writeAttribute(
"name", name);
903 writer.writeAttribute(
"title", title);
904 writer.writeEndElement();
910
911
912
913
914
915
916
917
926
927
932 QString logicalModuleName;
933 QString logicalModuleVersion;
934 QString qmlFullBaseName;
935 QString baseNameAttr;
936 QString moduleNameAttr;
937 QString moduleVerAttr;
941 nodeName =
"namespace";
956 nodeName =
"qmlenum";
961 logicalModuleName = node->logicalModuleName();
962 baseNameAttr =
"qml-base-type";
963 moduleNameAttr =
"qml-module-name";
964 moduleVerAttr =
"qml-module-version";
965 qmlFullBaseName = node->qmlFullBaseName();
979 nodeName =
"concept";
982 nodeName =
"qmlmodule";
983 moduleNameAttr =
"qml-module-name";
984 moduleVerAttr =
"qml-module-version";
985 logicalModuleName = node->logicalModuleName();
986 logicalModuleVersion = node->logicalModuleVersion();
993 nodeName =
"typedef";
996 nodeName =
"property";
999 nodeName =
"variable";
1005 nodeName =
"qmlproperty";
1008 nodeName =
"qmlproperty";
1018 QString objName = node->name();
1023 writer.writeStartElement(nodeName);
1027 writer.writeAttribute(
"threadsafety", getThreadSafenessString(node->threadSafeness()));
1030 writer.writeAttribute(
"name", objName);
1033 writer.writeAttribute(
"propertygroup",
"true");
1038 if (!moduleNameAttr.isEmpty()) {
1039 if (!logicalModuleName.isEmpty())
1040 writer.writeAttribute(moduleNameAttr, logicalModuleName);
1041 if (!logicalModuleVersion.isEmpty())
1042 writer.writeAttribute(moduleVerAttr, logicalModuleVersion);
1044 if (!baseNameAttr.isEmpty() && !qmlFullBaseName.isEmpty())
1045 writer.writeAttribute(baseNameAttr, qmlFullBaseName);
1046 else if (!baseNameAttr.isEmpty()) {
1047 const auto &qmlBase =
static_cast<QmlTypeNode *>(node)->qmlBaseName();
1048 writeNonEmpty(writer, baseNameAttr, qmlBase);
1053 QString fullName = node->fullDocumentName();
1054 if (fullName != objName)
1055 writer.writeAttribute(
"fullname", fullName);
1056 href = m_gen->fullDocumentLocation(node);
1058 href = node->name();
1064 writeNonEmpty(writer,
"href", href);
1066 writer.writeAttribute(
"status", getStatusString(node->status()));
1068 writer.writeAttribute(
"access", getAccessString(node->access()));
1070 writer.writeAttribute(
"abstract",
"true");
1073 writeNonEmpty(writer,
"location", declLocation.fileName());
1074 if (m_storeLocationInfo && !declLocation.filePath().isEmpty()) {
1075 writer.writeAttribute(
"filepath", declLocation.filePath());
1076 writer.writeAttribute(
"lineno", QString(
"%1").arg(declLocation
.lineNo()));
1080 writer.writeAttribute(
"related", QString::number(indexForNode(node)));
1082 writeNonEmpty(writer,
"since", node->since());
1085 writer.writeAttribute(
"documented",
"true");
1087 QStringList groups = m_qdb->groupNamesForNode(node);
1088 if (!groups.isEmpty())
1089 writer.writeAttribute(
"groups", groups.join(QLatin1Char(
',')));
1092 if (
const auto sortKey = metamap->value(
"sortkey"); !sortKey.isEmpty())
1093 writer.writeAttribute(
"sortkey", sortKey);
1097 auto *cn =
static_cast<CollectionNode *>(node);
1098 writeNonEmpty(writer,
"cmakepackage", cn->cmakePackage());
1099 writeNonEmpty(writer,
"cmakecomponent", cn->cmakeComponent());
1100 writeNonEmpty(writer,
"cmaketargetitem", cn->cmakeTargetItem());
1101 writeNonEmpty(writer,
"qtvariable", cn->qtVariable());
1105 auto *agg =
static_cast<Aggregate *>(node);
1106 if (agg->includeFile())
1107 writer.writeAttribute(
"includefile", *agg->includeFile());
1110 QString brief = node
->doc().trimmedBriefText(node->name()).toString();
1116 const auto *classNode =
static_cast<
const ClassNode *>(node);
1117 const QList<RelatedClass> &bases = classNode->baseClasses();
1118 QSet<QString> baseStrings;
1119 for (
const auto &related : bases) {
1120 ClassNode *n = related.m_node;
1122 baseStrings.insert(n->fullName());
1123 else if (!related.m_path.isEmpty())
1124 baseStrings.insert(related.m_path.join(QLatin1String(
"::")));
1126 if (!baseStrings.isEmpty()) {
1127 QStringList baseStringsAsList = baseStrings.values();
1128 baseStringsAsList.sort();
1129 writer.writeAttribute(
"bases", baseStringsAsList.join(QLatin1Char(
',')));
1131 writeNonEmpty(writer,
"module", node->physicalModuleName());
1132 writeNonEmpty(writer,
"brief", brief);
1137 const auto *headerNode =
static_cast<
const HeaderNode *>(node);
1138 writeNonEmpty(writer,
"module", headerNode->physicalModuleName());
1139 writeNonEmpty(writer,
"brief", brief);
1140 writer.writeAttribute(
"title", headerNode->title());
1141 writer.writeAttribute(
"fulltitle", headerNode->fullTitle());
1142 writer.writeAttribute(
"subtitle", headerNode->subtitle());
1145 const auto *namespaceNode =
static_cast<
const NamespaceNode *>(node);
1146 writeNonEmpty(writer,
"module", namespaceNode->physicalModuleName());
1147 writeNonEmpty(writer,
"brief", brief);
1148 writeNonEmpty(writer,
"whereDocumented", namespaceNode->whereDocumented());
1152 const auto *qmlTypeNode =
static_cast<
const QmlTypeNode *>(node);
1153 writeNonEmpty(writer,
"title", qmlTypeNode->title());
1154 writeNonEmpty(writer,
"fulltitle", qmlTypeNode->fullTitle());
1155 writeNonEmpty(writer,
"subtitle", qmlTypeNode->subtitle());
1156 if (qmlTypeNode->isSingleton())
1157 writer.writeAttribute(
"singleton",
"true");
1158 if (qmlTypeNode->isUncreatable())
1159 writer.writeAttribute(
"uncreatable",
"true");
1160 writeNonEmpty(writer,
"brief", brief);
1161 if (
ClassNode *cn = qmlTypeNode->classNode()) {
1162 writer.writeAttribute(
"class", cn->fullDocumentName());
1163 if (cn->access() != Access::Public || cn->status() == Status::Internal)
1164 m_basesList.append(std::pair<ClassNode *, QString>(cn, cn->fullName()));
1171 writer.writeAttribute(
"subtype",
"example");
1173 writer.writeAttribute(
"subtype",
"externalpage");
1175 writer.writeAttribute(
"subtype", (
static_cast<PageNode*>(node)->isAttribution() ?
"attribution" :
"page"));
1177 const auto *pageNode =
static_cast<
const PageNode *>(node);
1178 writeNonEmpty(writer,
"title", pageNode->title());
1179 writeNonEmpty(writer,
"fulltitle", pageNode->fullTitle());
1180 writeNonEmpty(writer,
"subtitle", pageNode->subtitle());
1181 writeNonEmpty(writer,
"brief", brief);
1187 const auto *collectionNode =
static_cast<
const CollectionNode *>(node);
1188 writer.writeAttribute(
"seen", collectionNode->wasSeen() ?
"true" :
"false");
1189 writeNonEmpty(writer,
"title", collectionNode->title());
1190 writeNonEmpty(writer,
"subtitle", collectionNode->subtitle());
1191 writeNonEmpty(writer,
"module", collectionNode->physicalModuleName());
1192 writeNonEmpty(writer,
"brief", brief);
1195 auto *qmlPropertyNode =
static_cast<QmlPropertyNode *>(node);
1196 writer.writeAttribute(
"type", qmlPropertyNode->dataType());
1197 writer.writeAttribute(
"attached", qmlPropertyNode->isAttached() ?
"true" :
"false");
1198 writer.writeAttribute(
"writable", qmlPropertyNode->isReadOnly() ?
"false" :
"true");
1199 if (qmlPropertyNode->isRequired())
1200 writer.writeAttribute(
"required",
"true");
1201 writeNonEmpty(writer,
"brief", brief);
1204 const auto *propertyNode =
static_cast<
const PropertyNode *>(node);
1207 writer.writeAttribute(
"bindable",
"true");
1209 if (!propertyNode->isWritable())
1210 writer.writeAttribute(
"writable",
"false");
1212 if (propertyNode->isConstant())
1213 writer.writeAttribute(
"constant",
"true");
1215 writer.writeAttribute(
"dataType", propertyNode->dataType());
1217 writeNonEmpty(writer,
"brief", brief);
1219 for (qsizetype i{0}; i < (qsizetype)PropertyNode::FunctionRole::NumFunctionRoles; ++i) {
1221 for (
const auto *fnNode : propertyNode->functions(role)) {
1222 writer.writeStartElement(PropertyNode::roleName(role));
1223 writer.writeAttribute(
"name", fnNode->name());
1224 writer.writeEndElement();
1229 const auto *variableNode =
static_cast<
const VariableNode *>(node);
1230 writer.writeAttribute(
"type", variableNode->dataType());
1231 writer.writeAttribute(
"static", variableNode->isStatic() ?
"true" :
"false");
1232 writeNonEmpty(writer,
"brief", brief);
1236 const auto *enumNode =
static_cast<
const EnumNode *>(node);
1237 if (enumNode->isScoped())
1238 writer.writeAttribute(
"scoped",
"true");
1239 if (enumNode->flagsType())
1240 writer.writeAttribute(
"typedef", enumNode->flagsType()->fullDocumentName());
1241 if (enumNode->isAnonymous())
1242 writer.writeAttribute(
"anonymous",
"true");
1243 const auto &items = enumNode->items();
1244 for (
const auto &item : items) {
1245 writer.writeStartElement(
"value");
1246 writer.writeAttribute(
"name", item.name());
1247 if (node->isEnumType(Genus::CPP))
1248 writer.writeAttribute(
"value", item.value());
1249 writeNonEmpty(writer,
"since", item.since());
1250 writer.writeEndElement();
1254 const auto *typedefNode =
static_cast<
const TypedefNode *>(node);
1255 if (typedefNode->associatedEnum())
1256 writer.writeAttribute(
"enum", typedefNode->associatedEnum()->fullDocumentName());
1259 writer.writeAttribute(
"aliasedtype",
static_cast<
const TypeAliasNode *>(node)->aliasedType());
1266 writeTargets(writer, node);
1269
1270
1271
1272
1273
1274
1277 for (
int i = 0; i < node
->doc().tableOfContents().size(); ++i) {
1279 int level = node
->doc().tableOfContentsLevels()[i];
1281 writer.writeStartElement(
"contents");
1282 writer.writeAttribute(
"name", Tree::refForAtom(item));
1283 writer.writeAttribute(
"title", title);
1284 writer.writeAttribute(
"level", QString::number(level));
1285 writer.writeEndElement();
1291 if (node
->isExample() && m_gen->format() != QLatin1String(
"WebXML")) {
1292 const auto *exampleNode =
static_cast<
const ExampleNode *>(node);
1293 const QString project = Generator::defaultModuleName();
1294 const QString fileExt = m_gen->fileExtension();
1295 const auto &files = exampleNode->files();
1296 const auto &images = exampleNode->images();
1297 for (
const QString &file : files) {
1298 writer.writeStartElement(
"page");
1299 writer.writeAttribute(
"name", file);
1300 writer.writeAttribute(
"href", Utilities::linkForExampleFile(file, project, fileExt));
1301 writer.writeAttribute(
"status",
"active");
1302 writer.writeAttribute(
"subtype",
"file");
1303 writer.writeAttribute(
"title",
"");
1304 writer.writeAttribute(
"fulltitle", Utilities::exampleFileTitle(file, Utilities::ExampleFileKind::File));
1305 writer.writeAttribute(
"subtitle", file);
1306 writer.writeEndElement();
1308 for (
const QString &file : images) {
1309 writer.writeStartElement(
"page");
1310 writer.writeAttribute(
"name", file);
1311 writer.writeAttribute(
"href", Utilities::linkForExampleFile(file, project, fileExt));
1312 writer.writeAttribute(
"status",
"active");
1313 writer.writeAttribute(
"subtype",
"image");
1314 writer.writeAttribute(
"title",
"");
1315 writer.writeAttribute(
"fulltitle", Utilities::exampleFileTitle(file, Utilities::ExampleFileKind::Image));
1316 writer.writeAttribute(
"subtitle", file);
1317 writer.writeEndElement();
1329
1330
1331
1334 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1339 const QString objName = fn->name();
1340 writer.writeStartElement(
"function");
1341 writer.writeAttribute(
"name", objName);
1343 const QString fullName = fn->fullDocumentName();
1344 if (fullName != objName)
1345 writer.writeAttribute(
"fullname", fullName);
1346 const QString href = m_gen->fullDocumentLocation(fn);
1347 writeNonEmpty(writer,
"href", href);
1349 writer.writeAttribute(
"threadsafety", getThreadSafenessString(fn->threadSafeness()));
1350 writer.writeAttribute(
"status", getStatusString(fn->status()));
1351 writer.writeAttribute(
"access", getAccessString(fn->access()));
1354 writeNonEmpty(writer,
"location", declLocation.fileName());
1355 if (m_storeLocationInfo && !declLocation.filePath().isEmpty()) {
1356 writer.writeAttribute(
"filepath", declLocation.filePath());
1357 writer.writeAttribute(
"lineno", QString(
"%1").arg(declLocation
.lineNo()));
1361 writer.writeAttribute(
"documented",
"true");
1363 writer.writeAttribute(
"auto-generated",
"true");
1365 writer.writeAttribute(
"related", QString::number(indexForNode(fn)));
1366 writeNonEmpty(writer,
"since", fn->since());
1368 const QString brief = fn
->doc().trimmedBriefText(fn->name()).toString();
1369 writer.writeAttribute(
"meta", fn->metanessString());
1372 writer.writeAttribute(
"virtual", fn->virtualness());
1375 writer.writeAttribute(
"const",
"true");
1377 writer.writeAttribute(
"static",
"true");
1379 writer.writeAttribute(
"final",
"true");
1381 writer.writeAttribute(
"override",
"true");
1383 writer.writeAttribute(
"explicit",
"true");
1385 writer.writeAttribute(
"constexpr",
"true");
1387 writer.writeAttribute(
"explicitly-defaulted",
"true");
1389 writer.writeAttribute(
"deleted",
"true");
1391 writer.writeAttribute(
"hidden-friend",
"true");
1393 if (
auto noexcept_info = fn->getNoexcept()) {
1394 writer.writeAttribute(
"noexcept",
"true");
1395 writeNonEmpty(writer,
"noexcept_expression", *noexcept_info);
1398 if (
const auto &trailing_requires = fn->trailingRequiresClause(); trailing_requires && !trailing_requires->isEmpty())
1399 writer.writeAttribute(
"trailing_requires", *trailing_requires);
1402
1403
1404
1405
1406
1408 writer.writeAttribute(
"overload",
"true");
1409 writer.writeAttribute(
"overload-number", QString::number(fn->overloadNumber()));
1412 writer.writeAttribute(
"refness", QString::number(1));
1414 writer.writeAttribute(
"refness", QString::number(2));
1416 QStringList associatedProperties;
1417 for (
const auto *node : fn->associatedProperties()) {
1418 associatedProperties << node->name();
1420 associatedProperties.sort();
1421 writer.writeAttribute(
"associated-property",
1422 associatedProperties.join(QLatin1Char(
',')));
1426 writer.writeAttribute(
"attached",
"true");
1429 const auto &return_type = fn->returnType();
1430 if (!return_type.isEmpty())
1431 writer.writeAttribute(
"type",
std::move(return_type));
1433 const auto &declared_return_type = fn->declaredReturnType();
1434 if (declared_return_type.has_value())
1435 writer.writeAttribute(
"declaredtype", declared_return_type.value());
1438 writeNonEmpty(writer,
"brief", brief);
1441
1442
1443
1444
1445 const QString signature = appendAttributesToSignature(fn);
1446 writer.writeAttribute(
"signature", signature);
1448 QStringList groups = m_qdb->groupNamesForNode(fn);
1449 if (!groups.isEmpty())
1450 writer.writeAttribute(
"groups", groups.join(QLatin1Char(
',')));
1455 writer.writeStartElement(
"parameter");
1456 writer.writeAttribute(
"type", parameter.type());
1457 writer.writeAttribute(
"name", parameter.name());
1458 writer.writeAttribute(
"default", parameter.defaultValue());
1459 writer.writeEndElement();
1462 writeTargets(writer, fn);
1468 writer.writeEndElement();
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1487 signature +=
" final";
1489 signature +=
" override";
1491 signature +=
" = 0";
1492 if (
const auto &req = fn->trailingRequiresClause(); req && !req->isEmpty())
1493 signature +=
" requires " + *req;
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1511 for (
auto functions : std::as_const(aggregate->functionMap())) {
1512 std::for_each(functions.begin(), functions.end(),
1513 [
this,&writer](FunctionNode *fn) {
1514 generateFunctionSection(writer, fn);
1521
1522
1523
1524
1528 Q_ASSERT(generator);
1531
1532
1533
1538 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1543 if (generateIndexSection(writer, node, generator, post)) {
1545 auto *aggregate =
static_cast<Aggregate *>(node);
1547 generateFunctionSections(writer, aggregate);
1548 const auto &nonFunctionList = aggregate->nonfunctionList();
1549 for (
auto *node : nonFunctionList)
1550 generateIndexSections(writer, node, generator, post);
1553 if (node ==
root_) {
1555
1556
1557
1558
1559
1560
1562 if (!groups.isEmpty()) {
1563 for (
auto it = groups.constBegin(); it != groups.constEnd(); ++it) {
1564 if (generateIndexSection(writer, it.value(), generator, post))
1565 writer.writeEndElement();
1570 if (!modules.isEmpty()) {
1571 for (
auto it = modules.constBegin(); it != modules.constEnd(); ++it) {
1572 if (generateIndexSection(writer, it.value(), generator, post))
1573 writer.writeEndElement();
1578 if (!qmlModules.isEmpty()) {
1579 for (
auto it = qmlModules.constBegin(); it != qmlModules.constEnd(); ++it) {
1580 if (generateIndexSection(writer, it.value(), generator, post))
1581 writer.writeEndElement();
1586 if (!concepts.isEmpty()) {
1587 for (
auto it = concepts.constBegin(); it != concepts.constEnd(); ++it) {
1588 if (generateIndexSection(writer, it.value(), generator, post))
1589 writer.writeEndElement();
1593 for (
auto *p : m_qdb->primaryTree()->proxies()) {
1594 if (generateIndexSection(writer, p, generator, post)) {
1595 auto aggregate =
static_cast<Aggregate *>(p);
1596 generateFunctionSections(writer, aggregate);
1597 for (
auto *n : aggregate->nonfunctionList())
1598 generateIndexSections(writer, n, generator, post);
1599 writer.writeEndElement();
1604 writer.writeEndElement();
1609
1610
1611
1612
1613
1614
1615void QDocIndexFiles::generateIndex(
const QString &fileName,
const QString &url,
1616 const QString &title,
const Generator *hrefGenerator)
1618 Q_ASSERT(hrefGenerator);
1619 m_gen = hrefGenerator;
1621 QFile file(fileName);
1622 if (!file.open(QFile::WriteOnly | QFile::Text))
1625 qCDebug(lcQdoc) <<
"Writing index file:" << fileName;
1628 m_basesList.clear();
1630 QXmlStreamWriter writer(&file);
1631 writer.setAutoFormatting(
true);
1632 writer.writeStartDocument();
1633 writer.writeDTD(
"<!DOCTYPE QDOCINDEX>");
1635 writer.writeStartElement(
"INDEX");
1636 writer.writeAttribute(
"url", url);
1637 writer.writeAttribute(
"title", title);
1638 writer.writeAttribute(
"version", m_qdb->version());
1639 writer.writeAttribute(
"project", Config::instance().get(
CONFIG_PROJECT).asString());
1642 writeNonEmpty(writer,
"indexTitle",
root_->tree()->indexTitle());
1644 generateIndexSections(writer,
root_, m_gen,
nullptr);
1646 writer.writeEndElement();
1647 writer.writeEndElement();
1648 writer.writeEndDocument();
void adoptChild(Node *child)
This Aggregate becomes the adoptive parent of child.
The Atom class is the fundamental unit for representing documents internally.
The ClassNode represents a C++ class.
bool hasTableOfContents() const
void markAutoGenerated()
Marks this documentation as auto-generated by QDoc.
QStringMultiMap * metaTagMap() const
void constructExtra() const
void setFlagsType(TypedefNode *typedefNode)
void addItem(const EnumItem &item)
Add item to the enum type's item list.
void setAnonymous(bool anonymous)
The ExternalPageNode represents an external documentation page.
This node is used to represent any kind of function being documented.
signed short overloadNumber() const
Returns the overload number for this function.
bool isPureVirtual() const override
bool isNonvirtual() const
bool isHiddenFriend() const
bool isAttached() const override
Returns true if the QML property or QML method node is marked as attached.
bool isDeletedAsWritten() const
bool isStatic() const override
Returns true if the FunctionNode represents a static function.
bool isExplicitlyDefaulted() const
Parameters & parameters()
bool hasAssociatedProperties() const
static bool isPubliclyVisible(const InclusionPolicy &policy, const NodeContext &context)
virtual void append(QXmlStreamWriter &writer, Node *node)=0
The Location class provides a way to mark a location in a file.
int lineNo() const
Returns the current line number.
Location & operator=(const Location &other)
The assignment operator does a deep copy of the entire state of other into this Location.
This class represents a C++ namespace.
Tree * tree() const override
Returns a pointer to the Tree that contains this NamespaceNode.
A PageNode is a Node that generates a documentation page.
The Parameter class describes one function parameter.
This class describes one instance of using the Q_PROPERTY macro.
A class for representing an Aggregate that is documented in a different module.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
const CNMap & qmlModules()
Returns a const reference to the collection of all QML module nodes in the primary tree.
NamespaceNode * primaryTreeRoot()
Returns a pointer to the root node of the primary tree.
const CNMap & modules()
Returns a const reference to the collection of all module nodes in the primary tree.
const CNMap & groups()
Returns a const reference to the collection of all group nodes in the primary tree.
This class handles qdoc index files.
Status
Specifies the status of the QQmlIncubator.
static Text sectionHeading(const Atom *sectionBegin)
static std::string comparisonCategoryAsString(ComparisonCategory category)
#define CONFIG_LOCATIONINFO
Metaness
Specifies the kind of function a FunctionNode represents.
Combined button and popup list for selecting options.
QMap< QString, CollectionNode * > CNMap
static QHash< QString, SharedCommentNode * > sharedDocNodes_
static QString getAccessString(Access t)
static IndexSectionWriter * post_
static QString getThreadSafenessString(Node::ThreadSafeness t)
static QString getStatusString(Status t)
static void writeNonEmpty(QXmlStreamWriter &writer, const QString &name, const QString &value)
Write an attribute to the current element using the writer for the attribute with the given name if t...
The Node class is the base class for all the nodes in QDoc's parse tree.
bool isExternalPage() const
Returns true if the node type is ExternalPage.
const Doc & doc() const
Returns a reference to the node's Doc data member.
bool isQmlNode() const
Returns true if this node's Genus value is QML.
bool isGroup() const
Returns true if the node type is Group.
void setAccess(Access t)
Sets the node's access type to t.
void setIndexNodeFlag(bool isIndexNode=true)
Sets a flag in this Node that indicates the node was created for something in an index file.
virtual bool isAbstract() const
Returns true if the ClassNode or QmlTypeNode is marked abstract.
SharedCommentNode * sharedCommentNode()
ComparisonCategory comparisonCategory() const
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
bool isHeader() const
Returns true if the node type is HeaderFile.
NodeType nodeType() const override
Returns this node's type.
Genus genus() const override
Returns this node's Genus.
virtual bool isPageNode() const
Returns true if this node represents something that generates a documentation page.
bool isEnumType() const
Returns true if the node type is Enum.
virtual bool isTextPageNode() const
Returns true if the node is a PageNode but not an Aggregate.
Aggregate * parent() const
Returns the node's parent pointer.
void setLocation(const Location &t)
Sets the node's declaration location, its definition location, or both, depending on the suffix of th...
virtual bool isAggregate() const
Returns true if this node is an aggregate, which means it inherits Aggregate and can therefore have c...
virtual void setRelatedNonmember(bool b)
Sets a flag in the node indicating whether this node is a related nonmember of something.
void setComparisonCategory(const ComparisonCategory &category)
bool isProxyNode() const
Returns true if the node type is Proxy.
ThreadSafeness threadSafeness() const
Returns the thread safeness value for whatever this node represents.
virtual Tree * tree() const
Returns a pointer to the Tree this node is in.
const Location & declLocation() const
Returns the Location where this node's declaration was seen.
NodeContext createContext() const
void setDoc(const Doc &doc, bool replace=false)
Sets this Node's Doc to doc.
bool isModule() const
Returns true if the node type is Module.
virtual bool isPropertyGroup() const
Returns true if the node is a SharedCommentNode for documenting multiple C++ properties or multiple Q...
ThreadSafeness
An unsigned char that specifies the degree of thread-safeness of the element.
bool isSharingComment() const
This function returns true if the node is sharing a comment with other nodes.
virtual void setAbstract(bool)
If this node is a ClassNode or a QmlTypeNode, the node's abstract flag data member is set to b.
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
bool isCppNode() const
Returns true if this node's Genus value is CPP.
virtual void setStatus(Status t)
Sets the node's status to t.
virtual bool isCollectionNode() const
Returns true if this is an instance of CollectionNode.
void setThreadSafeness(ThreadSafeness t)
Sets the node's thread safeness to t.
bool isQmlModule() const
Returns true if the node type is QmlModule.
bool isExample() const
Returns true if the node type is Example.
bool isIndexNode() const
Returns true if this node was created from something in an index file.
const Parameter & at(int i) const
A record of a linkable target within the documentation.
TargetType
A type of a linkable target record.