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);
185 qmid = args.first().first;
186 auto *qcn = database->findQmlTypeInPrimaryTree(qmid, arg.first);
189 if (!qcn && !qmid.isEmpty()) {
190 qcn = database->findQmlTypeInPrimaryTree(QString(), arg.first);
191 if (qcn && !qcn->logicalModuleName().isEmpty())
194 if (!qcn || qcn->nodeType() != nodeType)
197 database->addToQmlModule(qmid, qcn);
202 qcn->setUncreatable();
203 else if (command ==
COMMAND_QMLTYPE && !qcn->isSingleton() && !qcn->isUncreatable()) {
206 if (
auto classNode = database->findClassNode(arg.first.split(u"::"_s))) {
207 if (classNode->isQmlSingleton())
209 else if (classNode->isQmlUncreatable())
210 qcn->setUncreatable();
215 return processQmlEnumTopic(doc.enumItemNames(), doc.location(), arg.first);
225
226
227
228
229
233 auto *aggregate = database->findQmlTypeInPrimaryTree(moduleName, name);
238 aggregate =
new QmlTypeNode(database->primaryTreeRoot(), name, NodeType::QmlType);
240 if (!moduleName.isEmpty())
241 database->addToQmlModule(moduleName, aggregate);
250 if (topics.isEmpty())
253 std::vector<TiedDocumentation> tied{};
255 auto firstTopicArgs =
262 auto *qmlType = findOrCreateQmlType((*firstTopicArgs).m_module, (*firstTopicArgs).m_qmltype, doc
.startLocation());
264 for (
const auto &topicCommand : topics) {
265 QString cmd = topicCommand.m_topic;
267 bool attached = cmd.contains(QLatin1String(
"attached"));
268 if (
auto qpa = QmlPropertyArguments::parse(topicCommand.m_args, doc.location(),
269 QmlPropertyArguments::ParsingOptions::RequireQualifiedPath)) {
270 if (qmlType != QDocDatabase::qdocDB()->findQmlTypeInPrimaryTree(qpa->m_module, qpa->m_qmltype)) {
271 doc.startLocation().warning(
273 "All properties in a group must belong to the same type: '%1'")
274 .arg(topicCommand.m_args));
277 Aggregate::PropertySearchType searchType = attached ? Aggregate::AttachedProperties
278 : Aggregate::UnattachedProperties;
279 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(qpa->m_name, searchType);
280 if (existingProperty) {
281 processMetaCommands(doc, existingProperty);
282 if (!doc.body().isEmpty()) {
283 doc.startLocation().warning(
284 QStringLiteral(
"QML property documented multiple times: '%1'")
285 .arg(topicCommand.m_args), QStringLiteral(
"also seen here: %1")
286 .arg(existingProperty->location().toString()));
290 auto *qpn =
new QmlPropertyNode(qmlType, qpa->m_name, qpa->m_type, attached);
291 qpn->setIsList(qpa->m_isList);
292 qpn->setLocation(doc.startLocation());
293 qpn->setGenus(Genus::QML);
295 tied.emplace_back(TiedDocumentation{doc, qpn});
300 doc.startLocation().warning(
301 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
310 if (sharedNodes.size() > 1) {
314 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
315 group = (*firstTopicArgs).m_name.left(dot);
321 for (
const auto n : sharedNodes)
330
331
332
333
334
335
341 QString arg = argPair.first;
357 static_cast<Aggregate *>(node)->setIncludeFile(arg);
365 u"Found \\%1 command outside of \\%2 context."_s
369
370
371
372
373
374 processOverloadCommand(node, doc);
378 auto *fn =
static_cast<FunctionNode *>(node);
385 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
387 QStringLiteral(
"The function either doesn't exist in any "
388 "base class with the same signature or it "
389 "exists but isn't virtual."));
394 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
403 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
407 CodeParser::setLink(node, Node::NextLink, arg);
409 CodeParser::setLink(node, Node::PreviousLink, arg);
411 CodeParser::setLink(node, Node::StartLink, arg);
413 if (node->name() == arg)
414 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
416 auto *qmlType =
static_cast<QmlTypeNode *>(node);
417 qmlType->setQmlBaseName(arg);
422 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
424 processQmlNativeTypeCommand(node, command, arg, doc
.location());
427 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
429 }
else if (arg.isEmpty()) {
430 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
433 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
442 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
446 if (!nativeEnum->resolve(argPair.first, argPair.second)) {
447 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
448 .arg(command, arg),
"Use \\value commands instead"_L1);
456 static_cast<QmlPropertyNode *>(node)->setRequired();
461 node->setDeprecated(argPair.second);
464 database->addToGroup(arg, node);
466 database->addToModule(arg, node);
488 if (!node->setSubtitle(arg))
491 node->setQtVariable(arg);
495 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
499 node->setCMakeComponent(arg);
502 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
506 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
509 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
513 node->setCMakePackage(arg);
516 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
520 node->setCMakeComponent(arg);
523 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
527 node->setCMakeTargetItem(arg);
530 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
536 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
539 static_cast<CollectionNode*>(node)->setState(arg);
545 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
548 static_cast<PageNode*>(node)->setNoAutoList(
true);
570 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
575
576
577
578
579
580
581
585 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
590 if (
auto category = comparisonCategoryFromString(arg.toStdString());
591 category != ComparisonCategory::None) {
594 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
595 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
600
601
602
603
607 auto *fn =
static_cast<FunctionNode *>(node);
611 if (fn->sharedCommentNode())
615 const auto &overloadArgs = doc.overloadList();
616 if (!overloadArgs.isEmpty()
617 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
624 fn->setPrimaryOverloadFlag();
626 fn->setOverloadFlag();
628 fn->setOverloadFlag();
631 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
638
639
640
641
642
645 std::vector<Node*> nodes_to_process{};
647 auto scn =
static_cast<SharedCommentNode*>(node);
649 nodes_to_process.reserve(scn->count() + 1);
650 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
663 nodes_to_process.push_back(node);
665 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
666 for (
const auto &command : metaCommandsUsed) {
667 const ArgList args = doc.metaCommandArgs(command);
668 for (
const auto &arg : args) {
669 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [doc, command, arg](
auto node){
670 processMetaCommand(doc, command, arg, node);
678 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
685
686
687
688
689
690
692 const Location &location,
const QString &arg)
695 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
706 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
708 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
709 enumNode->setLocation(location);
711 for (
const auto &item : enumItemNames)
712 enumNode->addItem(EnumItem(item, 0));
718
719
721 const QString &funcArg)
726 if (topic.contains(
"signal"_L1))
736 auto *aggregate = findOrCreateQmlType((*methodArgs).m_module,
737 (*methodArgs).m_qmltype, location);
740 bool attached = topic.contains(
"attached"_L1);
741 auto *fn =
new FunctionNode(metaness, aggregate, (*methodArgs).m_name, attached);
742 fn->setAccess(Access::Public);
743 fn->setLocation(location);
744 fn->setReturnType((*methodArgs).m_type);
745 fn->setParameters((*methodArgs).m_params);
750
751
752
753
754
759 QStringList leftParenSplit = macroArg.split(
'(');
760 if (leftParenSplit.isEmpty())
764 QStringList blankSplit = leftParenSplit[0].split(
' ');
765 if (!blankSplit.empty()) {
766 macroName = blankSplit.last();
767 oldMacroNode = database->findMacroNode(macroName);
770 if (blankSplit.size() > 1) {
771 blankSplit.removeLast();
772 returnType = blankSplit.join(
' ');
775 if (leftParenSplit.size() > 1) {
776 params = QString(
"");
777 const QString &afterParen = leftParenSplit.at(1);
778 qsizetype rightParen = afterParen.indexOf(
')');
780 params = afterParen.left(rightParen);
783 while (i < macroName.size() && !macroName.at(i).isLetter())
786 returnType += QChar(
' ') + macroName.left(i);
787 macroName = macroName.mid(i);
793 macro->setAccess(Access::Public);
794 macro->setLocation(location);
795 macro->setReturnType(returnType);
796 macro->setParameters(params);
797 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
798 && compare(macro, oldMacroNode) == 0) {
799 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
800 .arg(macroArg), QStringLiteral(
"also seen here: %1")
801 .arg(oldMacroNode
->doc().location().toString()));
808 Config &config = Config::instance();
809 QString fullPath = config.getExampleProjectFile(en->name());
810 if (fullPath.isEmpty()) {
811 QString details = QLatin1String(
"Example directories: ")
814 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
819 QDir exampleDir(QFileInfo(fullPath).dir());
823 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
826 QSet<QString> excludeDocDirs(excludeDirs);
827 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
828 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
830 if (!exampleFiles.isEmpty()) {
834 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
835 if (fileName.endsWith(
"/main.cpp")) {
836 if (mainCpp.isEmpty())
840 return Utilities::isGeneratedFile(fileName);
844 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
847 if (!mainCpp.isEmpty())
848 exampleFiles.append(mainCpp);
851 exampleFiles += Config::getFilesHere(exampleDir.path(),
852 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
856 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
857 for (
auto &file : exampleFiles)
858 file = file.mid(pathLen);
859 for (
auto &file : imageFiles)
860 file = file.mid(pathLen);
862 en->setFiles(exampleFiles, fullPath.mid(pathLen));
863 en->setImages(imageFiles);
867
868
869
877
878
879
885std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
886CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
888 const Doc &doc = untied.documentation;
890 if (doc.topicsUsed().isEmpty())
893 QDocDatabase *database = QDocDatabase::qdocDB();
895 const QString topic = doc.topicsUsed().first().m_topic;
897 std::vector<TiedDocumentation> tied{};
898 std::vector<FnMatchError> errors{};
900 if (isQMLPropertyTopic(topic)) {
901 auto tied_qml = processQmlProperties(untied);
902 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
904 ArgList args = doc.metaCommandArgs(topic);
905 Node *node =
nullptr;
906 if (args.size() == 1) {
908 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
909 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
910 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
911 if (
auto *error = std::get_if<FnMatchError>(&result))
912 errors.emplace_back(*error);
914 node = std::get<Node*>(result);
917 node = parseMacroArg(doc.location(), args[0].first);
918 }
else if (isQMLMethodTopic(topic)) {
919 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
921 database->primaryTree()->addToDontDocumentMap(args[0].first);
923 node = processTopicCommand(doc, topic, args[0]);
925 if (node !=
nullptr) {
926 tied.emplace_back(TiedDocumentation{doc, node});
928 }
else if (args.size() > 1) {
931 QList<SharedCommentNode *> sharedCommentNodes;
932 for (
const auto &arg : std::as_const(args)) {
935 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
936 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
937 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
938 if (
auto *error = std::get_if<FnMatchError>(&result))
939 errors.emplace_back(*error);
941 node = std::get<Node*>(result);
944 node = parseMacroArg(doc.location(), arg.first);
945 }
else if (isQMLMethodTopic(topic)) {
946 node = parseOtherFuncArg(topic, doc.location(), arg.first);
948 node = processTopicCommand(doc, topic, arg);
950 if (node !=
nullptr) {
952 for (SharedCommentNode *scn : sharedCommentNodes) {
953 if (scn->parent() == node->parent()) {
960 auto *scn =
new SharedCommentNode(node);
961 sharedCommentNodes.append(scn);
962 tied.emplace_back(TiedDocumentation{doc, scn});
966 for (
auto *scn : sharedCommentNodes) {
969 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
974 return std::make_pair(tied, errors);
978
979
980
983 if (n->physicalModuleName().isEmpty()) {
995 n->setPhysicalModuleName(Generator::defaultModuleName());
998 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
999 "using project name by default: %3")
1001 n->physicalModuleName()));
1008 for (
auto [doc, node] : tied) {
1010 processMetaCommands(doc, node);
1011 checkModuleInclusion(node);
1012 if (node->isAggregate()) {
1013 auto *aggregate =
static_cast<Aggregate *>(node);
1015 if (!aggregate->includeFile()) {
1016 const QString className = aggregate->name();
1022 QString includeFile = convenienceHeaderExists(className)
1024 : computeIncludeSpelling(aggregate->declLocation());
1026 if (includeFile.isEmpty() && !className.isEmpty())
1027 includeFile = className;
1029 if (!includeFile.isEmpty())
1030 aggregate->setIncludeFile(includeFile);
1036void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1041 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1046 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1049 auto classNode = database->findClassNode(arg.split(u"::"_s));
1054 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1060 if (qmlNode->classNode()) {
1062 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1063 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1066 qmlNode->setClassNode(classNode);
1067 classNode->insertQmlNativeType(qmlNode);
1073
1074
1075
1076QString stripIncludePrefix(
const QString &path)
1078 QString result = path.trimmed();
1080 static const QStringList prefixes = {
1081 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1084 for (
const QString &prefix : prefixes) {
1085 if (result.startsWith(prefix)) {
1086 result = result.mid(prefix.size()).trimmed();
1087 return QDir::cleanPath(result);
1092 if (result.startsWith(u'-'))
1095 return QDir::cleanPath(result);
1101
1102
1103
1104const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1106 if (!m_includePathsCached) {
1108 QStringList rawPaths = Config::instance().includePaths();
1109 rawPaths += Config::instance().getCanonicalPathList(
1112 for (
const QString &path : rawPaths) {
1113 QString clean = stripIncludePrefix(path);
1114 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1115 m_cleanIncludePaths.append(clean);
1117 m_includePathsCached =
true;
1119 return m_cleanIncludePaths;
1123
1124
1125
1126
1127
1128
1129bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1131 if (className.isEmpty())
1134 auto it = m_convenienceHeaderCache.constFind(className);
1135 if (it != m_convenienceHeaderCache.constEnd())
1138 bool exists =
false;
1139 for (
const QString &includePath : getCleanIncludePaths()) {
1140 QFileInfo candidate(includePath + u'/' + className);
1141 if (candidate.exists() && candidate.isFile()) {
1147 m_convenienceHeaderCache.insert(className, exists);
1152
1153
1154
1155
1156
1157
1163 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.
static 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.
static 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.
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_QMLUNCREATABLETYPE
#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
Metaness
Specifies the kind of function a FunctionNode represents.
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.
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 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 and QML method 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)