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);
171 cn->setTitle(arg.first);
176 QStringList blankSplit = arg.first.split(QLatin1Char(
' '));
178 cn->setLogicalModuleInfo(blankSplit);
194 qmid = args.first().first;
195 auto *qcn = database->findQmlTypeInPrimaryTree(qmid, arg.first);
198 if (!qcn && !qmid.isEmpty()) {
199 qcn = database->findQmlTypeInPrimaryTree(QString(), arg.first);
200 if (qcn && !qcn->logicalModuleName().isEmpty())
203 if (!qcn || qcn->nodeType() != nodeType)
206 database->addToQmlModule(qmid, qcn);
211 qcn->setUncreatable();
212 else if (command ==
COMMAND_QMLTYPE && !qcn->isSingleton() && !qcn->isUncreatable()) {
215 if (
auto classNode = database->findClassNode(arg.first.split(u"::"_s))) {
216 if (classNode->isQmlSingleton())
218 else if (classNode->isQmlUncreatable())
219 qcn->setUncreatable();
224 return processQmlEnumTopic(doc.enumItemNames(), doc.location(), arg.first);
234
235
236
237
238
242 auto *aggregate = database->findQmlTypeInPrimaryTree(moduleName, name);
247 aggregate =
new QmlTypeNode(database->primaryTreeRoot(), name, NodeType::QmlType);
249 if (!moduleName.isEmpty())
250 database->addToQmlModule(moduleName, aggregate);
259 if (topics.isEmpty())
262 std::vector<TiedDocumentation> tied{};
264 auto firstTopicArgs =
271 auto *qmlType = findOrCreateQmlType((*firstTopicArgs).m_module, (*firstTopicArgs).m_qmltype, doc
.startLocation());
273 for (
const auto &topicCommand : topics) {
274 QString cmd = topicCommand.m_topic;
276 bool attached = cmd.contains(QLatin1String(
"attached"));
277 if (
auto qpa = QmlPropertyArguments::parse(topicCommand.m_args, doc.location(),
278 QmlPropertyArguments::ParsingOptions::RequireQualifiedPath)) {
279 if (qmlType != QDocDatabase::qdocDB()->findQmlTypeInPrimaryTree(qpa->m_module, qpa->m_qmltype)) {
280 doc.startLocation().warning(
282 "All properties in a group must belong to the same type: '%1'")
283 .arg(topicCommand.m_args));
286 Aggregate::PropertySearchType searchType = attached ? Aggregate::AttachedProperties
287 : Aggregate::UnattachedProperties;
288 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(qpa->m_name, searchType);
289 if (existingProperty) {
290 processMetaCommands(doc, existingProperty);
291 if (!doc.body().isEmpty()) {
292 doc.startLocation().warning(
293 QStringLiteral(
"QML property documented multiple times: '%1'")
294 .arg(topicCommand.m_args), QStringLiteral(
"also seen here: %1")
295 .arg(existingProperty->location().toString()));
299 auto *qpn =
new QmlPropertyNode(qmlType, qpa->m_name, qpa->m_type, attached);
300 qpn->setIsList(qpa->m_isList);
301 qpn->setLocation(doc.startLocation());
302 qpn->setGenus(Genus::QML);
304 tied.emplace_back(TiedDocumentation{doc, qpn});
309 doc.startLocation().warning(
310 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
319 if (sharedNodes.size() > 1) {
323 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
324 group = (*firstTopicArgs).m_name.left(dot);
330 for (
const auto n : sharedNodes)
339
340
341
342
343
344
350 QString arg = argPair.first;
366 static_cast<Aggregate *>(node)->setIncludeFile(arg);
374 u"Found \\%1 command outside of \\%2 context."_s
378
379
380
381
382
383 processOverloadCommand(node, doc);
387 auto *fn =
static_cast<FunctionNode *>(node);
394 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
396 QStringLiteral(
"The function either doesn't exist in any "
397 "base class with the same signature or it "
398 "exists but isn't virtual."));
403 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
412 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
416 CodeParser::setLink(node, Node::NextLink, arg);
418 CodeParser::setLink(node, Node::PreviousLink, arg);
420 CodeParser::setLink(node, Node::StartLink, arg);
422 if (node->name() == arg)
423 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
425 auto *qmlType =
static_cast<QmlTypeNode *>(node);
426 qmlType->setQmlBaseName(arg);
431 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
433 processQmlNativeTypeCommand(node, command, arg, doc
.location());
436 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
438 }
else if (arg.isEmpty()) {
439 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
442 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
451 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
455 if (!nativeEnum->resolve(argPair.first, argPair.second)) {
456 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
457 .arg(command, arg),
"Use \\value commands instead"_L1);
465 static_cast<QmlPropertyNode *>(node)->setRequired();
470 node->setDeprecated(argPair.second);
473 database->addToGroup(arg, node);
475 database->addToModule(arg, node);
497 if (!node->setSubtitle(arg))
500 node->setQtVariable(arg);
504 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
508 node->setCMakeComponent(arg);
511 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
515 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
518 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
522 node->setCMakePackage(arg);
525 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
529 node->setCMakeComponent(arg);
532 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
536 node->setCMakeTargetItem(arg);
539 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
545 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
548 static_cast<CollectionNode*>(node)->setState(arg);
554 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
557 static_cast<PageNode*>(node)->setNoAutoList(
true);
579 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
584
585
586
587
588
589
590
594 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
599 if (
auto category = comparisonCategoryFromString(arg.toStdString());
600 category != ComparisonCategory::None) {
603 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
604 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
609
610
611
612
616 auto *fn =
static_cast<FunctionNode *>(node);
620 if (fn->sharedCommentNode())
624 const auto &overloadArgs = doc.overloadList();
625 if (!overloadArgs.isEmpty()
626 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
633 fn->setPrimaryOverloadFlag();
635 fn->setOverloadFlag();
637 fn->setOverloadFlag();
640 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
647
648
649
650
651
654 std::vector<Node*> nodes_to_process{};
656 auto scn =
static_cast<SharedCommentNode*>(node);
658 nodes_to_process.reserve(scn->count() + 1);
659 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
672 nodes_to_process.push_back(node);
674 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
675 for (
const auto &command : metaCommandsUsed) {
676 const ArgList args = doc.metaCommandArgs(command);
677 for (
const auto &arg : args) {
678 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [doc, command, arg](
auto node){
679 processMetaCommand(doc, command, arg, node);
687 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
694
695
696
697
698
699
701 const Location &location,
const QString &arg)
704 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
715 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
717 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
718 enumNode->setLocation(location);
720 for (
const auto &item : enumItemNames)
721 enumNode->addItem(EnumItem(item, 0));
727
728
730 const QString &funcArg)
735 if (topic.contains(
"signal"_L1))
745 auto *aggregate = findOrCreateQmlType((*methodArgs).m_module,
746 (*methodArgs).m_qmltype, location);
749 bool attached = topic.contains(
"attached"_L1);
750 auto *fn =
new FunctionNode(metaness, aggregate, (*methodArgs).m_name, attached);
751 fn->setAccess(Access::Public);
752 fn->setLocation(location);
753 fn->setReturnType((*methodArgs).m_type);
754 fn->setParameters((*methodArgs).m_params);
759
760
761
762
763
768 QStringList leftParenSplit = macroArg.split(
'(');
769 if (leftParenSplit.isEmpty())
773 QStringList blankSplit = leftParenSplit[0].split(
' ');
774 if (!blankSplit.empty()) {
775 macroName = blankSplit.last();
776 oldMacroNode = database->findMacroNode(macroName);
779 if (blankSplit.size() > 1) {
780 blankSplit.removeLast();
781 returnType = blankSplit.join(
' ');
784 if (leftParenSplit.size() > 1) {
785 params = QString(
"");
786 const QString &afterParen = leftParenSplit.at(1);
787 qsizetype rightParen = afterParen.indexOf(
')');
789 params = afterParen.left(rightParen);
792 while (i < macroName.size() && !macroName.at(i).isLetter())
795 returnType += QChar(
' ') + macroName.left(i);
796 macroName = macroName.mid(i);
802 macro->setAccess(Access::Public);
803 macro->setLocation(location);
804 macro->setReturnType(returnType);
805 macro->setParameters(params);
806 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
807 && compare(macro, oldMacroNode) == 0) {
808 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
809 .arg(macroArg), QStringLiteral(
"also seen here: %1")
810 .arg(oldMacroNode
->doc().location().toString()));
817 Config &config = Config::instance();
818 QString fullPath = config.getExampleProjectFile(en->name());
819 if (fullPath.isEmpty()) {
820 QString details = QLatin1String(
"Example directories: ")
823 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
828 QDir exampleDir(QFileInfo(fullPath).dir());
832 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
835 QSet<QString> excludeDocDirs(excludeDirs);
836 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
837 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
839 if (!exampleFiles.isEmpty()) {
843 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
844 if (fileName.endsWith(
"/main.cpp")) {
845 if (mainCpp.isEmpty())
849 return Utilities::isGeneratedFile(fileName);
853 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
856 if (!mainCpp.isEmpty())
857 exampleFiles.append(mainCpp);
860 exampleFiles += Config::getFilesHere(exampleDir.path(),
861 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
865 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
866 for (
auto &file : exampleFiles)
867 file = file.mid(pathLen);
868 for (
auto &file : imageFiles)
869 file = file.mid(pathLen);
871 en->setFiles(exampleFiles, fullPath.mid(pathLen));
872 en->setImages(imageFiles);
876
877
878
886
887
888
894std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
895CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
897 const Doc &doc = untied.documentation;
899 if (doc.topicsUsed().isEmpty())
902 QDocDatabase *database = QDocDatabase::qdocDB();
904 const QString topic = doc.topicsUsed().first().m_topic;
906 std::vector<TiedDocumentation> tied{};
907 std::vector<FnMatchError> errors{};
909 if (isQMLPropertyTopic(topic)) {
910 auto tied_qml = processQmlProperties(untied);
911 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
913 ArgList args = doc.metaCommandArgs(topic);
914 Node *node =
nullptr;
915 if (args.size() == 1) {
917 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
918 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
919 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
920 if (
auto *error = std::get_if<FnMatchError>(&result))
921 errors.emplace_back(*error);
923 node = std::get<Node*>(result);
926 node = parseMacroArg(doc.location(), args[0].first);
927 }
else if (isQMLMethodTopic(topic)) {
928 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
930 database->primaryTree()->addToDontDocumentMap(args[0].first);
932 node = processTopicCommand(doc, topic, args[0]);
934 if (node !=
nullptr) {
935 tied.emplace_back(TiedDocumentation{doc, node});
937 }
else if (args.size() > 1) {
940 QList<SharedCommentNode *> sharedCommentNodes;
941 for (
const auto &arg : std::as_const(args)) {
944 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
945 if (InclusionFilter::processInternalDocs(policy) || !doc.isInternal()) {
946 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
947 if (
auto *error = std::get_if<FnMatchError>(&result))
948 errors.emplace_back(*error);
950 node = std::get<Node*>(result);
953 node = parseMacroArg(doc.location(), arg.first);
954 }
else if (isQMLMethodTopic(topic)) {
955 node = parseOtherFuncArg(topic, doc.location(), arg.first);
957 node = processTopicCommand(doc, topic, arg);
959 if (node !=
nullptr) {
961 for (SharedCommentNode *scn : sharedCommentNodes) {
962 if (scn->parent() == node->parent()) {
969 auto *scn =
new SharedCommentNode(node);
970 sharedCommentNodes.append(scn);
971 tied.emplace_back(TiedDocumentation{doc, scn});
975 for (
auto *scn : sharedCommentNodes) {
978 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
983 return std::make_pair(tied, errors);
987
988
989
992 if (n->physicalModuleName().isEmpty()) {
1004 n->setPhysicalModuleName(Generator::defaultModuleName());
1007 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
1008 "using project name by default: %3")
1010 n->physicalModuleName()));
1017 for (
auto [doc, node] : tied) {
1019 processMetaCommands(doc, node);
1020 checkModuleInclusion(node);
1021 if (node->isAggregate()) {
1022 auto *aggregate =
static_cast<Aggregate *>(node);
1024 if (!aggregate->includeFile()) {
1025 const QString className = aggregate->name();
1031 QString includeFile = convenienceHeaderExists(className)
1033 : computeIncludeSpelling(aggregate->declLocation());
1035 if (includeFile.isEmpty() && !className.isEmpty())
1036 includeFile = className;
1038 if (!includeFile.isEmpty())
1039 aggregate->setIncludeFile(includeFile);
1045void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1050 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1055 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1058 auto classNode = database->findClassNode(arg.split(u"::"_s));
1063 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1069 if (qmlNode->classNode()) {
1071 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1072 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1075 qmlNode->setClassNode(classNode);
1076 classNode->insertQmlNativeType(qmlNode);
1082
1083
1084
1085QString stripIncludePrefix(
const QString &path)
1087 QString result = path.trimmed();
1089 static const QStringList prefixes = {
1090 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1093 for (
const QString &prefix : prefixes) {
1094 if (result.startsWith(prefix)) {
1095 result = result.mid(prefix.size()).trimmed();
1096 return QDir::cleanPath(result);
1101 if (result.startsWith(u'-'))
1104 return QDir::cleanPath(result);
1110
1111
1112
1113const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1115 if (!m_includePathsCached) {
1117 QStringList rawPaths = Config::instance().includePaths();
1118 rawPaths += Config::instance().getCanonicalPathList(
1121 for (
const QString &path : rawPaths) {
1122 QString clean = stripIncludePrefix(path);
1123 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1124 m_cleanIncludePaths.append(clean);
1126 m_includePathsCached =
true;
1128 return m_cleanIncludePaths;
1132
1133
1134
1135
1136
1137
1138bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1140 if (className.isEmpty())
1143 auto it = m_convenienceHeaderCache.constFind(className);
1144 if (it != m_convenienceHeaderCache.constEnd())
1147 bool exists =
false;
1148 for (
const QString &includePath : getCleanIncludePaths()) {
1149 QFileInfo candidate(includePath + u'/' + className);
1150 if (candidate.exists() && candidate.isFile()) {
1156 m_convenienceHeaderCache.insert(className, exists);
1161
1162
1163
1164
1165
1166
1172 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)