29#include <QtCore/qdebug.h>
30#include <QtCore/qmap.h>
34using namespace Qt::Literals::StringLiterals;
39
40
41
42static const QMap<QString, NodeType> s_nodeTypeMap{
62 Config &config = Config::instance();
67 if (!exampleFilePatterns.isEmpty())
68 m_exampleNameFilter = exampleFilePatterns.join(
' ');
70 m_exampleNameFilter =
"*.cpp *.h *.js *.xq *.svg *.xml *.ui";
76 if (!exampleImagePatterns.isEmpty())
77 m_exampleImageFilter = exampleImagePatterns.join(
' ');
79 m_exampleImageFilter =
"*.png";
85
86
94 }
else if (s_nodeTypeMap.contains(command)) {
96
97
98
99
100
101
102
103 NodeType type = s_nodeTypeMap[command];
104 QStringList words = arg.first.split(QLatin1Char(
' '));
107 Node *node =
nullptr;
110 idx = words.size() - 1;
111 path = words[idx].split(
"::");
113 node = database->findNodeByNameAndType(path, s_nodeTypeTestFuncMap[command]);
127 if (node ==
nullptr) {
130 QStringLiteral(
"Cannot find '%1' specified with '\\%2' in any header file")
131 .arg(arg.first, command));
135 auto *ns =
static_cast<NamespaceNode *>(node);
137 ns->setWhereDocumented(ns->tree()->camelCaseModuleName());
145 setExampleFileLists(en);
167 QStringList blankSplit = arg.first.split(QLatin1Char(
' '));
169 cn->setLogicalModuleInfo(blankSplit);
184 qmid = args.first().first;
185 auto *qcn = database->findQmlTypeInPrimaryTree(qmid, arg.first);
188 if (!qcn && !qmid.isEmpty()) {
189 qcn = database->findQmlTypeInPrimaryTree(QString(), arg.first);
190 if (qcn && !qcn->logicalModuleName().isEmpty())
193 if (!qcn || qcn->nodeType() != nodeType)
196 database->addToQmlModule(qmid, qcn);
199 qcn->setSingleton(
true);
201 auto classNode = database->findClassNode(arg.first.split(u"::"_s));
202 if (classNode && classNode->isQmlSingleton())
203 qcn->setSingleton(
true);
207 return processQmlEnumTopic(doc.enumItemNames(), doc.location(), arg.first);
216
217
218
219
220
224 auto *aggregate = database->findQmlTypeInPrimaryTree(moduleName, name);
229 aggregate =
new QmlTypeNode(database->primaryTreeRoot(), name, NodeType::QmlType);
231 if (!moduleName.isEmpty())
232 database->addToQmlModule(moduleName, aggregate);
241 if (topics.isEmpty())
244 std::vector<TiedDocumentation> tied{};
246 auto firstTopicArgs =
253 auto *qmlType = findOrCreateQmlType((*firstTopicArgs).m_module, (*firstTopicArgs).m_qmltype, doc
.startLocation());
255 for (
const auto &topicCommand : topics) {
256 QString cmd = topicCommand.m_topic;
258 bool attached = cmd.contains(QLatin1String(
"attached"));
259 if (
auto qpa = QmlPropertyArguments::parse(topicCommand.m_args, doc.location(),
260 QmlPropertyArguments::ParsingOptions::RequireQualifiedPath)) {
261 if (qmlType != QDocDatabase::qdocDB()->findQmlTypeInPrimaryTree(qpa->m_module, qpa->m_qmltype)) {
262 doc.startLocation().warning(
264 "All properties in a group must belong to the same type: '%1'")
265 .arg(topicCommand.m_args));
268 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(qpa->m_name, attached);
269 if (existingProperty) {
270 processMetaCommands(doc, existingProperty);
271 if (!doc.body().isEmpty()) {
272 doc.startLocation().warning(
273 QStringLiteral(
"QML property documented multiple times: '%1'")
274 .arg(topicCommand.m_args), QStringLiteral(
"also seen here: %1")
275 .arg(existingProperty->location().toString()));
279 auto *qpn =
new QmlPropertyNode(qmlType, qpa->m_name, qpa->m_type, attached);
280 qpn->setIsList(qpa->m_isList);
281 qpn->setLocation(doc.startLocation());
282 qpn->setGenus(Genus::QML);
284 tied.emplace_back(TiedDocumentation{doc, qpn});
289 doc.startLocation().warning(
290 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
299 if (sharedNodes.size() > 1) {
303 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
304 group = (*firstTopicArgs).m_name.left(dot);
310 for (
const auto n : sharedNodes)
319
320
321
322
323
324
330 QString arg = argPair.first;
346 static_cast<Aggregate *>(node)->setIncludeFile(arg);
354 u"Found \\%1 command outside of \\%2 context."_s
358
359
360
361
362
363 processOverloadCommand(node, doc);
367 auto *fn =
static_cast<FunctionNode *>(node);
374 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
376 QStringLiteral(
"The function either doesn't exist in any "
377 "base class with the same signature or it "
378 "exists but isn't virtual."));
383 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
392 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
396 CodeParser::setLink(node, Node::NextLink, arg);
398 CodeParser::setLink(node, Node::PreviousLink, arg);
400 CodeParser::setLink(node, Node::StartLink, arg);
402 if (node->name() == arg)
403 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
405 auto *qmlType =
static_cast<QmlTypeNode *>(node);
406 qmlType->setQmlBaseName(arg);
411 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
413 processQmlNativeTypeCommand(node, command, arg, doc
.location());
416 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
418 }
else if (arg.isEmpty()) {
419 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
422 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
431 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
435 if (!nativeEnum
->resolve(argPair.first
, argPair.second
)) {
436 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
437 .arg(command, arg),
"Use \\value commands instead"_L1);
445 static_cast<QmlPropertyNode *>(node)->setRequired();
450 node->setDeprecated(argPair.second);
453 database->addToGroup(arg, node);
455 database->addToModule(arg, node);
477 if (!node->setSubtitle(arg))
480 node->setQtVariable(arg);
484 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
488 node->setCMakeComponent(arg);
491 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
495 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
498 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
502 node->setCMakePackage(arg);
505 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
509 node->setCMakeComponent(arg);
512 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
516 node->setCMakeTargetItem(arg);
519 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
525 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
528 static_cast<CollectionNode*>(node)->setState(arg);
534 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
537 static_cast<PageNode*>(node)->setNoAutoList(
true);
559 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
564
565
566
567
568
569
570
574 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
579 if (
auto category = comparisonCategoryFromString(arg.toStdString());
580 category != ComparisonCategory::None) {
583 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
584 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
589
590
591
592
596 auto *fn =
static_cast<FunctionNode *>(node);
600 if (fn->sharedCommentNode())
604 const auto &overloadArgs = doc.overloadList();
605 if (!overloadArgs.isEmpty()
606 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
613 fn->setPrimaryOverloadFlag();
615 fn->setOverloadFlag();
617 fn->setOverloadFlag();
620 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
627
628
629
630
631
634 std::vector<Node*> nodes_to_process{};
636 auto scn =
static_cast<SharedCommentNode*>(node);
638 nodes_to_process.reserve(scn->count() + 1);
639 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
652 nodes_to_process.push_back(node);
654 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
655 for (
const auto &command : metaCommandsUsed) {
656 const ArgList args = doc.metaCommandArgs(command);
657 for (
const auto &arg : args) {
658 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [
this, doc, command, arg](
auto node){
659 processMetaCommand(doc, command, arg, node);
667 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
674
675
676
677
678
679
681 const Location &location,
const QString &arg)
684 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
695 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
697 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
698 enumNode->setLocation(location);
700 for (
const auto &item : enumItemNames)
701 enumNode->addItem(EnumItem(item, 0));
707
708
710 const QString &funcArg)
715 qsizetype leftParen = funcArg.indexOf(QChar(
'('));
717 funcName = funcArg.left(leftParen);
720 qsizetype firstBlank = funcName.indexOf(QChar(
' '));
721 if (firstBlank > 0) {
722 returnType = funcName.left(firstBlank);
723 funcName = funcName.right(funcName.size() - firstBlank - 1);
726 QStringList colonSplit(funcName.split(
"::"));
727 if (colonSplit.size() < 2) {
728 QString msg =
"Unrecognizable QML module/component qualifier for " + funcArg;
729 location.warning(msg.toLatin1().data());
734 if (colonSplit.size() > 2) {
735 moduleName = colonSplit[0];
736 elementName = colonSplit[1];
738 elementName = colonSplit[0];
740 funcName = colonSplit.last();
742 auto *aggregate = findOrCreateQmlType(moduleName, elementName, location);
745 QStringList leftParenSplit = funcArg.split(
'(');
746 if (leftParenSplit.size() > 1) {
747 QStringList rightParenSplit = leftParenSplit[1].split(
')');
748 if (!rightParenSplit.empty())
749 params = rightParenSplit[0];
753 bool attached = topic.contains(QLatin1String(
"attached"));
754 auto *fn =
new FunctionNode(metaness, aggregate, funcName, attached);
756 fn->setLocation(location);
757 fn->setReturnType(returnType);
758 fn->setParameters(params);
763
764
765
766
767
772 QStringList leftParenSplit = macroArg.split(
'(');
773 if (leftParenSplit.isEmpty())
777 QStringList blankSplit = leftParenSplit[0].split(
' ');
778 if (!blankSplit.empty()) {
779 macroName = blankSplit.last();
780 oldMacroNode = database->findMacroNode(macroName);
783 if (blankSplit.size() > 1) {
784 blankSplit.removeLast();
785 returnType = blankSplit.join(
' ');
788 if (leftParenSplit.size() > 1) {
789 params = QString(
"");
790 const QString &afterParen = leftParenSplit.at(1);
791 qsizetype rightParen = afterParen.indexOf(
')');
793 params = afterParen.left(rightParen);
796 while (i < macroName.size() && !macroName.at(i).isLetter())
799 returnType += QChar(
' ') + macroName.left(i);
800 macroName = macroName.mid(i);
807 macro->setLocation(location);
808 macro->setReturnType(returnType);
809 macro->setParameters(params);
810 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
811 && compare(macro, oldMacroNode) == 0) {
812 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
813 .arg(macroArg), QStringLiteral(
"also seen here: %1")
814 .arg(oldMacroNode
->doc().location().toString()));
821 Config &config = Config::instance();
822 QString fullPath = config.getExampleProjectFile(en->name());
823 if (fullPath.isEmpty()) {
824 QString details = QLatin1String(
"Example directories: ")
827 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
832 QDir exampleDir(QFileInfo(fullPath).dir());
836 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
839 QSet<QString> excludeDocDirs(excludeDirs);
840 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
841 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
843 if (!exampleFiles.isEmpty()) {
847 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
848 if (fileName.endsWith(
"/main.cpp")) {
849 if (mainCpp.isEmpty())
853 return Utilities::isGeneratedFile(fileName);
857 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
860 if (!mainCpp.isEmpty())
861 exampleFiles.append(mainCpp);
864 exampleFiles += Config::getFilesHere(exampleDir.path(),
865 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
869 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
870 for (
auto &file : exampleFiles)
871 file = file.mid(pathLen);
872 for (
auto &file : imageFiles)
873 file = file.mid(pathLen);
875 en->setFiles(exampleFiles, fullPath.mid(pathLen));
876 en->setImages(imageFiles);
880
881
882
890
891
892
898std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
899CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
901 const Doc &doc = untied.documentation;
903 if (doc.topicsUsed().isEmpty())
906 QDocDatabase *database = QDocDatabase::qdocDB();
908 const QString topic = doc.topicsUsed().first().m_topic;
910 std::vector<TiedDocumentation> tied{};
911 std::vector<FnMatchError> errors{};
913 if (isQMLPropertyTopic(topic)) {
914 auto tied_qml = processQmlProperties(untied);
915 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
917 ArgList args = doc.metaCommandArgs(topic);
918 Node *node =
nullptr;
919 if (args.size() == 1) {
921 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
922 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
923 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
924 if (
auto *error = std::get_if<FnMatchError>(&result))
925 errors.emplace_back(*error);
927 node = std::get<Node*>(result);
930 node = parseMacroArg(doc.location(), args[0].first);
931 }
else if (isQMLMethodTopic(topic)) {
932 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
934 database->primaryTree()->addToDontDocumentMap(args[0].first);
936 node = processTopicCommand(doc, topic, args[0]);
938 if (node !=
nullptr) {
939 tied.emplace_back(TiedDocumentation{doc, node});
941 }
else if (args.size() > 1) {
942 QList<SharedCommentNode *> sharedCommentNodes;
943 for (
const auto &arg : std::as_const(args)) {
946 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
947 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
948 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
949 if (
auto *error = std::get_if<FnMatchError>(&result))
950 errors.emplace_back(*error);
952 node = std::get<Node*>(result);
955 node = parseMacroArg(doc.location(), arg.first);
956 }
else if (isQMLMethodTopic(topic)) {
957 node = parseOtherFuncArg(topic, doc.location(), arg.first);
959 node = processTopicCommand(doc, topic, arg);
961 if (node !=
nullptr) {
963 for (SharedCommentNode *scn : sharedCommentNodes) {
964 if (scn->parent() == node->parent()) {
971 auto *scn =
new SharedCommentNode(node);
972 sharedCommentNodes.append(scn);
973 tied.emplace_back(TiedDocumentation{doc, scn});
977 for (
auto *scn : sharedCommentNodes) {
980 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
985 return std::make_pair(tied, errors);
989
990
991
994 if (n->physicalModuleName().isEmpty()) {
1006 n->setPhysicalModuleName(Generator::defaultModuleName());
1009 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
1010 "using project name by default: %3")
1012 n->physicalModuleName()));
1019 for (
auto [doc, node] : tied) {
1021 processMetaCommands(doc, node);
1022 checkModuleInclusion(node);
1023 if (node->isAggregate()) {
1024 auto *aggregate =
static_cast<Aggregate *>(node);
1026 if (!aggregate->includeFile()) {
1027 const QString className = aggregate->name();
1033 QString includeFile;
1034 if (convenienceHeaderExists(className)) {
1035 includeFile = className;
1037 includeFile = computeIncludeSpelling(aggregate->declLocation());
1038 if (includeFile.isEmpty() && !className.isEmpty())
1039 includeFile = className;
1042 if (!includeFile.isEmpty())
1043 aggregate->setIncludeFile(includeFile);
1049void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1054 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1059 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1062 auto classNode = database->findClassNode(arg.split(u"::"_s));
1065 if (m_showLinkErrors) {
1067 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1073 if (qmlNode->classNode()) {
1075 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1076 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1079 qmlNode->setClassNode(classNode);
1080 classNode->insertQmlNativeType(qmlNode);
1082 if (classNode->isQmlSingleton())
1083 qmlNode->setSingleton(
true);
1089
1090
1091
1092QString stripIncludePrefix(
const QString &path)
1094 QString result = path.trimmed();
1096 static const QStringList prefixes = {
1097 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1100 for (
const QString &prefix : prefixes) {
1101 if (result.startsWith(prefix)) {
1102 result = result.mid(prefix.size()).trimmed();
1103 return QDir::cleanPath(result);
1108 if (result.startsWith(u'-'))
1111 return QDir::cleanPath(result);
1117
1118
1119
1120const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1122 if (!m_includePathsCached) {
1124 QStringList rawPaths = Config::instance().includePaths();
1125 rawPaths += Config::instance().getCanonicalPathList(
1128 for (
const QString &path : rawPaths) {
1129 QString clean = stripIncludePrefix(path);
1130 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1131 m_cleanIncludePaths.append(clean);
1133 m_includePathsCached =
true;
1135 return m_cleanIncludePaths;
1139
1140
1141
1142
1143
1144
1145bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1147 if (className.isEmpty())
1150 auto it = m_convenienceHeaderCache.constFind(className);
1151 if (it != m_convenienceHeaderCache.constEnd())
1154 bool exists =
false;
1155 for (
const QString &includePath : getCleanIncludePaths()) {
1156 QFileInfo candidate(includePath + u'/' + className);
1157 if (candidate.exists() && candidate.isFile()) {
1163 m_convenienceHeaderCache.insert(className, exists);
1168
1169
1170
1171
1172
1173
1179 return loc.fileName();
The ClassNode represents a C++ class.
static bool isWorthWarningAbout(const Doc &doc)
Test for whether a doc comment warrants warnings.
A class for holding the members of a collection of doc pages.
bool asBool() const
Returns this config variable as a boolean.
The Config class contains the configuration variables for controlling how qdoc produces documentation...
static bool generateExamples
const ExcludedPaths & getExcludedPaths()
std::vector< TiedDocumentation > processQmlProperties(const UntiedDocumentation &untied)
FunctionNode * parseOtherFuncArg(const QString &topic, const Location &location, const QString &funcArg)
Parse QML signal/method topic commands.
FunctionNode * parseMacroArg(const Location &location, const QString ¯oArg)
Parse the macro arguments in macroArg ad hoc, without using any actual parser.
void processMetaCommand(const Doc &doc, const QString &command, const ArgPair &argLocPair, Node *node)
Process the metacommand command in the context of the node associated with the topic command and the ...
CppCodeParser(FnCommandParser &&parser)
static bool isQMLMethodTopic(const QString &t)
returns true if t is {qmlsignal}, {qmlmethod}, {qmlattachedsignal}, or {qmlattachedmethod}...
void processMetaCommands(const std::vector< TiedDocumentation > &tied)
static bool isQMLPropertyTopic(const QString &t)
Returns true if t is {qmlproperty}, {qmlpropertygroup}, or {qmlattachedproperty}.
virtual Node * processTopicCommand(const Doc &doc, const QString &command, const ArgPair &arg)
Process the topic command found in the doc with argument arg.
void processMetaCommands(const Doc &doc, Node *node)
The topic command has been processed, and now doc and node are passed to this function to get the met...
const Location & location() const
Returns the starting location of a qdoc comment.
const Text & title() const
const Location & startLocation() const
Returns the starting location of a qdoc comment.
TopicList topicsUsed() const
Returns a reference to the list of topic commands used in the current qdoc comment.
The ExternalPageNode represents an external documentation page.
This node is used to represent any kind of function being documented.
The Location class provides a way to mark a location in a file.
Location()
Constructs an empty location.
bool isEmpty() const
Returns true if there is no file name set yet; returns false otherwise.
Interface implemented by Node subclasses that can refer to a C++ enum.
virtual NativeEnum * nativeEnum()=0
Encapsulates information about native (C++) enum values.
bool resolve(const QString &path, const QString ®isteredQmlName)
Locates the node specified by path and sets it as the C++ enumeration associated with this property.
A PageNode is a Node that generates a documentation page.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
void addExampleNode(ExampleNode *n)
static QDocDatabase * qdocDB()
Creates the singleton.
NamespaceNode * primaryTreeRoot()
Returns a pointer to the root node of the primary tree.
Status
Specifies the status of the QQmlIncubator.
QString toString() const
This function traverses the atom list of the Text object, extracting all the string parts.
#define COMMAND_HEADERFILE
#define COMMAND_EXTERNALPAGE
#define COMMAND_QMLINHERITS
#define COMMAND_MODULESTATE
#define COMMAND_NONREENTRANT
#define COMMAND_QMLSIGNAL
#define COMMAND_DEPRECATED
#define COMMAND_QMLSINGLETONTYPE
#define COMMAND_PRELIMINARY
#define COMMAND_NAMESPACE
#define COMMAND_CMAKETARGETITEM
#define COMMAND_REENTRANT
#define COMMAND_QMLMODULE
#define COMMAND_QMLPROPERTY
#define COMMAND_STARTPAGE
#define COMMAND_QMLDEFAULT
#define COMMAND_QMLABSTRACT
#define COMMAND_QMLNATIVETYPE
#define COMMAND_QTVARIABLE
#define COMMAND_QTCMAKEPACKAGE
#define COMMAND_NOAUTOLIST
#define COMMAND_QMLATTACHEDPROPERTY
#define COMMAND_COMPARESWITH
#define COMMAND_QTCMAKETARGETITEM
#define COMMAND_INHEADERFILE
#define COMMAND_PREVIOUSPAGE
#define COMMAND_QMLBASICTYPE
#define COMMAND_THREADSAFE
#define COMMAND_QMLMETHOD
#define COMMAND_DONTDOCUMENT
#define COMMAND_CMAKECOMPONENT
#define COMMAND_QMLREADONLY
#define COMMAND_QMLENUMERATORSFROM
#define COMMAND_INPUBLICGROUP
#define COMMAND_QMLREQUIRED
#define COMMAND_QMLVALUETYPE
#define COMMAND_ATTRIBUTION
#define COMMAND_INQMLMODULE
#define COMMAND_QMLINSTANTIATES
#define COMMAND_TYPEALIAS
#define COMMAND_CMAKEPACKAGE
#define COMMAND_QMLATTACHEDMETHOD
#define COMMAND_QMLATTACHEDSIGNAL
#define CONFIG_FILEEXTENSIONS
#define CONFIG_EXAMPLEDIRS
#define CONFIG_NOLINKERRORS
#define CONFIG_IMAGEEXTENSIONS
#define CONFIG_INCLUDEPATHS
static const QMap< QString, NodeTypeTestFunc > s_nodeTypeTestFuncMap
bool(Node::* NodeTypeTestFunc)() const
static void checkModuleInclusion(Node *n)
For each node that is part of C++ API and produces a documentation page, this function ensures that t...
QmlTypeNode * findOrCreateQmlType(const QString &moduleName, const QString &name, const Location &location)
Finds a QmlTypeNode name, under the specific moduleName, from the primary tree.
std::pair< QString, QString > ArgPair
This namespace holds QDoc-internal utility methods.
The Node class is the base class for all the nodes in QDoc's parse tree.
void markInternal()
Sets the node's access to Private and its status to Internal.
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.
void setAccess(Access t)
Sets the node's access type to t.
bool isNamespace() const
Returns true if the node type is Namespace.
bool isTypedef() const
Returns true if the node type is Typedef.
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
virtual bool isInternal() const
Returns true if the node's status is Internal, or if its parent is a class with Internal status.
NodeType nodeType() const override
Returns this node's type.
bool isStruct() const
Returns true if the node type is Struct.
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.
bool isVariable() const
Returns true if the node type is Variable.
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...
void setTemplateDecl(std::optional< RelaxedTemplateDeclaration > t)
virtual void markReadOnly(bool)
If this node is a QmlPropertyNode, then the property's read-only flag is set to flag.
void setComparisonCategory(const ComparisonCategory &category)
const Location & location() const
If this node's definition location is empty, this function returns this node's declaration location.
const std::optional< RelaxedTemplateDeclaration > & templateDecl() const
Access access() const
Returns the node's Access setting, which can be Public, Protected, or Private.
virtual void setWrapper()
If this node is a ClassNode or a QmlTypeNode, the node's wrapper flag data member is set to true.
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
virtual void markDefault()
If this node is a QmlPropertyNode, it is marked as the default property.
virtual bool isInAPI() const
Returns true if this node is considered to be part of the API as per the InclusionPolicy retrieved fr...
bool isProperty() const
Returns true if the node type is Property.
bool isTypeAlias() const
Returns true if the node type is Typedef.
bool isModule() const
Returns true if the node type is Module.
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 isPreliminary() const
Returns true if this node's status is Preliminary.
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
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 isUnion() const
Returns true if the node type is Union.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
Helper class for parsing QML property arguments.
static std::optional< QmlPropertyArguments > parse(const QString &arg, const Location &loc, ParsingOptions opts=ParsingOptions::None)
Parses a QML property from the input string str, with parsing options opts.
ParsingOptions
\value None No options specified.
friend ParsingOptions operator|(ParsingOptions lhs, ParsingOptions rhs)