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 Aggregate::PropertySearchType searchType = attached ? Aggregate::AttachedProperties
269 : Aggregate::UnattachedProperties;
270 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(qpa->m_name, searchType);
271 if (existingProperty) {
272 processMetaCommands(doc, existingProperty);
273 if (!doc.body().isEmpty()) {
274 doc.startLocation().warning(
275 QStringLiteral(
"QML property documented multiple times: '%1'")
276 .arg(topicCommand.m_args), QStringLiteral(
"also seen here: %1")
277 .arg(existingProperty->location().toString()));
281 auto *qpn =
new QmlPropertyNode(qmlType, qpa->m_name, qpa->m_type, attached);
282 qpn->setIsList(qpa->m_isList);
283 qpn->setLocation(doc.startLocation());
284 qpn->setGenus(Genus::QML);
286 tied.emplace_back(TiedDocumentation{doc, qpn});
291 doc.startLocation().warning(
292 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
301 if (sharedNodes.size() > 1) {
305 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
306 group = (*firstTopicArgs).m_name.left(dot);
312 for (
const auto n : sharedNodes)
321
322
323
324
325
326
332 QString arg = argPair.first;
348 static_cast<Aggregate *>(node)->setIncludeFile(arg);
356 u"Found \\%1 command outside of \\%2 context."_s
360
361
362
363
364
365 processOverloadCommand(node, doc);
369 auto *fn =
static_cast<FunctionNode *>(node);
376 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
378 QStringLiteral(
"The function either doesn't exist in any "
379 "base class with the same signature or it "
380 "exists but isn't virtual."));
385 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
394 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
398 CodeParser::setLink(node, Node::NextLink, arg);
400 CodeParser::setLink(node, Node::PreviousLink, arg);
402 CodeParser::setLink(node, Node::StartLink, arg);
404 if (node->name() == arg)
405 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
407 auto *qmlType =
static_cast<QmlTypeNode *>(node);
408 qmlType->setQmlBaseName(arg);
413 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
415 processQmlNativeTypeCommand(node, command, arg, doc
.location());
418 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
420 }
else if (arg.isEmpty()) {
421 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
424 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
433 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
437 if (!nativeEnum->resolve(argPair.first, argPair.second)) {
438 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
439 .arg(command, arg),
"Use \\value commands instead"_L1);
447 static_cast<QmlPropertyNode *>(node)->setRequired();
452 node->setDeprecated(argPair.second);
455 database->addToGroup(arg, node);
457 database->addToModule(arg, node);
479 if (!node->setSubtitle(arg))
482 node->setQtVariable(arg);
486 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
490 node->setCMakeComponent(arg);
493 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
497 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
500 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
504 node->setCMakePackage(arg);
507 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
511 node->setCMakeComponent(arg);
514 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
518 node->setCMakeTargetItem(arg);
521 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
527 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
530 static_cast<CollectionNode*>(node)->setState(arg);
536 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
539 static_cast<PageNode*>(node)->setNoAutoList(
true);
561 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
566
567
568
569
570
571
572
576 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
581 if (
auto category = comparisonCategoryFromString(arg.toStdString());
582 category != ComparisonCategory::None) {
585 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
586 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
591
592
593
594
598 auto *fn =
static_cast<FunctionNode *>(node);
602 if (fn->sharedCommentNode())
606 const auto &overloadArgs = doc.overloadList();
607 if (!overloadArgs.isEmpty()
608 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
615 fn->setPrimaryOverloadFlag();
617 fn->setOverloadFlag();
619 fn->setOverloadFlag();
622 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
629
630
631
632
633
636 std::vector<Node*> nodes_to_process{};
638 auto scn =
static_cast<SharedCommentNode*>(node);
640 nodes_to_process.reserve(scn->count() + 1);
641 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
654 nodes_to_process.push_back(node);
656 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
657 for (
const auto &command : metaCommandsUsed) {
658 const ArgList args = doc.metaCommandArgs(command);
659 for (
const auto &arg : args) {
660 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [doc, command, arg](
auto node){
661 processMetaCommand(doc, command, arg, node);
669 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
676
677
678
679
680
681
683 const Location &location,
const QString &arg)
686 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
697 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
699 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
700 enumNode->setLocation(location);
702 for (
const auto &item : enumItemNames)
703 enumNode->addItem(EnumItem(item, 0));
709
710
712 const QString &funcArg)
717 if (topic.contains(
"signal"_L1))
727 auto *aggregate = findOrCreateQmlType((*methodArgs).m_module,
728 (*methodArgs).m_qmltype, location);
731 bool attached = topic.contains(
"attached"_L1);
732 auto *fn =
new FunctionNode(metaness, aggregate, (*methodArgs).m_name, attached);
734 fn->setLocation(location);
735 fn->setReturnType((*methodArgs).m_type);
736 fn->setParameters((*methodArgs).m_params);
741
742
743
744
745
750 QStringList leftParenSplit = macroArg.split(
'(');
751 if (leftParenSplit.isEmpty())
755 QStringList blankSplit = leftParenSplit[0].split(
' ');
756 if (!blankSplit.empty()) {
757 macroName = blankSplit.last();
758 oldMacroNode = database->findMacroNode(macroName);
761 if (blankSplit.size() > 1) {
762 blankSplit.removeLast();
763 returnType = blankSplit.join(
' ');
766 if (leftParenSplit.size() > 1) {
767 params = QString(
"");
768 const QString &afterParen = leftParenSplit.at(1);
769 qsizetype rightParen = afterParen.indexOf(
')');
771 params = afterParen.left(rightParen);
774 while (i < macroName.size() && !macroName.at(i).isLetter())
777 returnType += QChar(
' ') + macroName.left(i);
778 macroName = macroName.mid(i);
785 macro->setLocation(location);
786 macro->setReturnType(returnType);
787 macro->setParameters(params);
788 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
789 && compare(macro, oldMacroNode) == 0) {
790 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
791 .arg(macroArg), QStringLiteral(
"also seen here: %1")
792 .arg(oldMacroNode
->doc().location().toString()));
799 Config &config = Config::instance();
800 QString fullPath = config.getExampleProjectFile(en->name());
801 if (fullPath.isEmpty()) {
802 QString details = QLatin1String(
"Example directories: ")
805 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
810 QDir exampleDir(QFileInfo(fullPath).dir());
814 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
817 QSet<QString> excludeDocDirs(excludeDirs);
818 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
819 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
821 if (!exampleFiles.isEmpty()) {
825 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
826 if (fileName.endsWith(
"/main.cpp")) {
827 if (mainCpp.isEmpty())
831 return Utilities::isGeneratedFile(fileName);
835 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
838 if (!mainCpp.isEmpty())
839 exampleFiles.append(mainCpp);
842 exampleFiles += Config::getFilesHere(exampleDir.path(),
843 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
847 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
848 for (
auto &file : exampleFiles)
849 file = file.mid(pathLen);
850 for (
auto &file : imageFiles)
851 file = file.mid(pathLen);
853 en->setFiles(exampleFiles, fullPath.mid(pathLen));
854 en->setImages(imageFiles);
858
859
860
868
869
870
876std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
877CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
879 const Doc &doc = untied.documentation;
881 if (doc.topicsUsed().isEmpty())
884 QDocDatabase *database = QDocDatabase::qdocDB();
886 const QString topic = doc.topicsUsed().first().m_topic;
888 std::vector<TiedDocumentation> tied{};
889 std::vector<FnMatchError> errors{};
891 if (isQMLPropertyTopic(topic)) {
892 auto tied_qml = processQmlProperties(untied);
893 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
895 ArgList args = doc.metaCommandArgs(topic);
896 Node *node =
nullptr;
897 if (args.size() == 1) {
899 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
900 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
901 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
902 if (
auto *error = std::get_if<FnMatchError>(&result))
903 errors.emplace_back(*error);
905 node = std::get<Node*>(result);
908 node = parseMacroArg(doc.location(), args[0].first);
909 }
else if (isQMLMethodTopic(topic)) {
910 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
912 database->primaryTree()->addToDontDocumentMap(args[0].first);
914 node = processTopicCommand(doc, topic, args[0]);
916 if (node !=
nullptr) {
917 tied.emplace_back(TiedDocumentation{doc, node});
919 }
else if (args.size() > 1) {
922 QList<SharedCommentNode *> sharedCommentNodes;
923 for (
const auto &arg : std::as_const(args)) {
926 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
927 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
928 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
929 if (
auto *error = std::get_if<FnMatchError>(&result))
930 errors.emplace_back(*error);
932 node = std::get<Node*>(result);
935 node = parseMacroArg(doc.location(), arg.first);
936 }
else if (isQMLMethodTopic(topic)) {
937 node = parseOtherFuncArg(topic, doc.location(), arg.first);
939 node = processTopicCommand(doc, topic, arg);
941 if (node !=
nullptr) {
943 for (SharedCommentNode *scn : sharedCommentNodes) {
944 if (scn->parent() == node->parent()) {
951 auto *scn =
new SharedCommentNode(node);
952 sharedCommentNodes.append(scn);
953 tied.emplace_back(TiedDocumentation{doc, scn});
957 for (
auto *scn : sharedCommentNodes) {
960 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
965 return std::make_pair(tied, errors);
969
970
971
974 if (n->physicalModuleName().isEmpty()) {
986 n->setPhysicalModuleName(Generator::defaultModuleName());
989 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
990 "using project name by default: %3")
992 n->physicalModuleName()));
999 for (
auto [doc, node] : tied) {
1001 processMetaCommands(doc, node);
1002 checkModuleInclusion(node);
1003 if (node->isAggregate()) {
1004 auto *aggregate =
static_cast<Aggregate *>(node);
1006 if (!aggregate->includeFile()) {
1007 const QString className = aggregate->name();
1013 QString includeFile = convenienceHeaderExists(className)
1015 : computeIncludeSpelling(aggregate->declLocation());
1017 if (includeFile.isEmpty() && !className.isEmpty())
1018 includeFile = className;
1020 if (!includeFile.isEmpty())
1021 aggregate->setIncludeFile(includeFile);
1027void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1032 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1037 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1040 auto classNode = database->findClassNode(arg.split(u"::"_s));
1045 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1051 if (qmlNode->classNode()) {
1053 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1054 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1057 qmlNode->setClassNode(classNode);
1058 classNode->insertQmlNativeType(qmlNode);
1060 if (classNode->isQmlSingleton())
1061 qmlNode->setSingleton(
true);
1067
1068
1069
1070QString stripIncludePrefix(
const QString &path)
1072 QString result = path.trimmed();
1074 static const QStringList prefixes = {
1075 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1078 for (
const QString &prefix : prefixes) {
1079 if (result.startsWith(prefix)) {
1080 result = result.mid(prefix.size()).trimmed();
1081 return QDir::cleanPath(result);
1086 if (result.startsWith(u'-'))
1089 return QDir::cleanPath(result);
1095
1096
1097
1098const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1100 if (!m_includePathsCached) {
1102 QStringList rawPaths = Config::instance().includePaths();
1103 rawPaths += Config::instance().getCanonicalPathList(
1106 for (
const QString &path : rawPaths) {
1107 QString clean = stripIncludePrefix(path);
1108 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1109 m_cleanIncludePaths.append(clean);
1111 m_includePathsCached =
true;
1113 return m_cleanIncludePaths;
1117
1118
1119
1120
1121
1122
1123bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1125 if (className.isEmpty())
1128 auto it = m_convenienceHeaderCache.constFind(className);
1129 if (it != m_convenienceHeaderCache.constEnd())
1132 bool exists =
false;
1133 for (
const QString &includePath : getCleanIncludePaths()) {
1134 QFileInfo candidate(includePath + u'/' + className);
1135 if (candidate.exists() && candidate.isFile()) {
1141 m_convenienceHeaderCache.insert(className, exists);
1146
1147
1148
1149
1150
1151
1157 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_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.
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)