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
87
88
101
102
103
106 const QSet<QString> metaCommands = doc.metaCommandsUsed();
112
113
121 }
else if (s_nodeTypeMap.contains(command)) {
123
124
125
126
127
128
129
130 NodeType type = s_nodeTypeMap[command];
131 QStringList words = arg.first.split(QLatin1Char(
' '));
134 Node *node =
nullptr;
137 idx = words.size() - 1;
138 path = words[idx].split(
"::");
140 node = database->findNodeByNameAndType(path, s_nodeTypeTestFuncMap[command]);
154 if (node ==
nullptr) {
157 QStringLiteral(
"Cannot find '%1' specified with '\\%2' in any header file")
158 .arg(arg.first, command));
162 auto *ns =
static_cast<NamespaceNode *>(node);
164 ns->setWhereDocumented(ns->tree()->camelCaseModuleName());
172 setExampleFileLists(en);
198 cn->setTitle(arg.first);
203 QStringList blankSplit = arg.first.split(QLatin1Char(
' '));
205 cn->setLogicalModuleInfo(blankSplit);
221 qmid = args.first().first;
222 auto *qcn = database->findQmlTypeInPrimaryTree(qmid, arg.first);
225 if (!qcn && !qmid.isEmpty()) {
226 qcn = database->findQmlTypeInPrimaryTree(QString(), arg.first);
227 if (qcn && !qcn->logicalModuleName().isEmpty())
230 if (!qcn || qcn->nodeType() != nodeType)
233 database->addToQmlModule(qmid, qcn);
238 qcn->setUncreatable();
247 if (
auto classNode = database->findClassNode(arg.first.split(u"::"_s)))
248 setQmlAttributesFromNativeType(qcn, classNode);
252 return processQmlEnumTopic(doc.enumItemNames(), doc.location(), arg.first);
262
263
264
265
266
270 auto *aggregate = database->findQmlTypeInPrimaryTree(moduleName, name);
275 aggregate =
new QmlTypeNode(database->primaryTreeRoot(), name, NodeType::QmlType);
277 if (!moduleName.isEmpty())
278 database->addToQmlModule(moduleName, aggregate);
287 if (topics.isEmpty())
290 std::vector<TiedDocumentation> tied{};
292 auto firstTopicArgs =
299 auto *qmlType = findOrCreateQmlType((*firstTopicArgs).m_module, (*firstTopicArgs).m_qmltype, doc
.startLocation());
301 for (
const auto &topicCommand : topics) {
302 QString cmd = topicCommand.m_topic;
304 bool attached = cmd.contains(QLatin1String(
"attached"));
305 if (
auto qpa = QmlPropertyArguments::parse(topicCommand.m_args, doc.location(),
306 QmlPropertyArguments::ParsingOptions::RequireQualifiedPath)) {
307 if (qmlType != QDocDatabase::qdocDB()->findQmlTypeInPrimaryTree(qpa->m_module, qpa->m_qmltype)) {
308 doc.startLocation().warning(
310 "All properties in a group must belong to the same type: '%1'")
311 .arg(topicCommand.m_args));
314 Aggregate::PropertySearchType searchType = attached ? Aggregate::AttachedProperties
315 : Aggregate::UnattachedProperties;
316 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(qpa->m_name, searchType);
317 if (existingProperty) {
318 processMetaCommands(doc, existingProperty);
319 if (!doc.body().isEmpty()) {
320 doc.startLocation().warning(
321 QStringLiteral(
"QML property documented multiple times: '%1'")
322 .arg(topicCommand.m_args), QStringLiteral(
"also seen here: %1")
323 .arg(existingProperty->location().toString()));
327 auto *qpn =
new QmlPropertyNode(qmlType, qpa->m_name, qpa->m_type, attached);
328 qpn->setIsList(qpa->m_isList);
329 qpn->setLocation(doc.startLocation());
330 qpn->setGenus(Genus::QML);
335 doc.startLocation().warning(
336 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
345 if (sharedNodes.size() > 1) {
349 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
350 group = (*firstTopicArgs).m_name.left(dot);
356 for (
const auto n : sharedNodes) {
361 }
else if (!sharedNodes.isEmpty()) {
369
370
371
372
373
374
380 QString arg = argPair.first;
396 static_cast<Aggregate *>(node)->setIncludeFile(arg);
404 u"Found \\%1 command outside of \\%2 context."_s
408
409
410
411
412
413 processOverloadCommand(node, doc);
417 auto *fn =
static_cast<FunctionNode *>(node);
424 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
426 QStringLiteral(
"The function either doesn't exist in any "
427 "base class with the same signature or it "
428 "exists but isn't virtual."));
433 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
442 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
446 CodeParser::setLink(node, Node::NextLink, arg);
448 CodeParser::setLink(node, Node::PreviousLink, arg);
450 CodeParser::setLink(node, Node::StartLink, arg);
452 if (node->name() == arg)
453 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
455 auto *qmlType =
static_cast<QmlTypeNode *>(node);
456 qmlType->setQmlBaseName(arg);
461 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
463 processQmlNativeTypeCommand(node, command, arg, doc
.location());
466 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
468 }
else if (arg.isEmpty()) {
469 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
472 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
481 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
485 if (!nativeEnum->resolve(argPair.first, argPair.second)) {
486 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
487 .arg(command, arg),
"Use \\value commands instead"_L1);
495 static_cast<QmlPropertyNode *>(node)->setRequired();
500 node->setDeprecated(argPair.second);
503 database->addToGroup(arg, node);
505 database->addToModule(arg, node);
527 if (!node->setSubtitle(arg))
530 node->setQtVariable(arg);
534 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
538 node->setCMakeComponent(arg);
541 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
545 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
548 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
552 node->setCMakePackage(arg);
555 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
559 node->setCMakeComponent(arg);
562 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
566 node->setCMakeTargetItem(arg);
569 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
575 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
578 static_cast<CollectionNode*>(node)->setState(arg);
584 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
587 static_cast<PageNode*>(node)->setNoAutoList(
true);
609 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
614
615
616
617
618
619
620
624 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
629 if (
auto category = comparisonCategoryFromString(arg.toStdString());
630 category != ComparisonCategory::None) {
633 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
634 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
639
640
641
642
646 auto *fn =
static_cast<FunctionNode *>(node);
650 if (fn->sharedCommentNode())
654 const auto &overloadArgs = doc.overloadList();
655 if (!overloadArgs.isEmpty()
656 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
663 fn->setPrimaryOverloadFlag();
665 fn->setOverloadFlag();
667 fn->setOverloadFlag();
670 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
677
678
679
680
681
684 std::vector<Node*> nodes_to_process{};
686 auto scn =
static_cast<SharedCommentNode*>(node);
688 nodes_to_process.reserve(scn->count() + 1);
689 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
702 nodes_to_process.push_back(node);
704 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
705 for (
const auto &command : metaCommandsUsed) {
706 const ArgList args = doc.metaCommandArgs(command);
707 for (
const auto &arg : args) {
708 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [doc, command, arg](
auto node){
709 processMetaCommand(doc, command, arg, node);
717 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
724
725
726
727
728
729
731 const Location &location,
const QString &arg)
734 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
745 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
747 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
748 enumNode->setLocation(location);
750 for (
const auto &item : enumItemNames)
751 enumNode->addItem(EnumItem(item, 0));
757
758
760 const QString &funcArg)
765 if (topic.contains(
"signal"_L1))
775 auto *aggregate = findOrCreateQmlType((*methodArgs).m_module,
776 (*methodArgs).m_qmltype, location);
779 bool attached = topic.contains(
"attached"_L1);
780 auto *fn =
new FunctionNode(metaness, aggregate, (*methodArgs).m_name, attached);
781 fn->setAccess(Access::Public);
782 fn->setLocation(location);
783 fn->setReturnType((*methodArgs).m_type);
784 fn->setParameters((*methodArgs).m_params);
789
790
791
792
793
798 QStringList leftParenSplit = macroArg.split(
'(');
799 if (leftParenSplit.isEmpty())
803 QStringList blankSplit = leftParenSplit[0].split(
' ');
804 if (!blankSplit.empty()) {
805 macroName = blankSplit.last();
806 oldMacroNode = database->findMacroNode(macroName);
809 if (blankSplit.size() > 1) {
810 blankSplit.removeLast();
811 returnType = blankSplit.join(
' ');
814 if (leftParenSplit.size() > 1) {
815 params = QString(
"");
816 const QString &afterParen = leftParenSplit.at(1);
817 qsizetype rightParen = afterParen.indexOf(
')');
819 params = afterParen.left(rightParen);
822 while (i < macroName.size() && !macroName.at(i).isLetter())
825 returnType += QChar(
' ') + macroName.left(i);
826 macroName = macroName.mid(i);
832 macro->setAccess(Access::Public);
833 macro->setLocation(location);
834 macro->setReturnType(returnType);
835 macro->setParameters(params);
836 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
837 && compare(macro, oldMacroNode) == 0) {
838 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
839 .arg(macroArg), QStringLiteral(
"also seen here: %1")
840 .arg(oldMacroNode
->doc().location().toString()));
847 Config &config = Config::instance();
848 QString fullPath = config.getExampleProjectFile(en->name());
849 if (fullPath.isEmpty()) {
850 QString details = QLatin1String(
"Example directories: ")
853 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
858 QDir exampleDir(QFileInfo(fullPath).dir());
862 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
865 QSet<QString> excludeDocDirs(excludeDirs);
866 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
867 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
869 if (!exampleFiles.isEmpty()) {
873 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
874 if (fileName.endsWith(
"/main.cpp")) {
875 if (mainCpp.isEmpty())
879 return Utilities::isGeneratedFile(fileName);
883 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
886 if (!mainCpp.isEmpty())
887 exampleFiles.append(mainCpp);
890 exampleFiles += Config::getFilesHere(exampleDir.path(),
891 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
895 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
896 for (
auto &file : exampleFiles)
897 file = file.mid(pathLen);
898 for (
auto &file : imageFiles)
899 file = file.mid(pathLen);
901 en->setFiles(exampleFiles, fullPath.mid(pathLen));
902 en->setImages(imageFiles);
906
907
908
916
917
918
924std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
925CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
927 const Doc &doc = untied.documentation;
929 if (doc.topicsUsed().isEmpty())
932 QDocDatabase *database = QDocDatabase::qdocDB();
934 const QString topic = doc.topicsUsed().first().m_topic;
936 std::vector<TiedDocumentation> tied{};
937 std::vector<FnMatchError> errors{};
939 if (isQMLPropertyTopic(topic)) {
940 auto tied_qml = processQmlProperties(untied);
941 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
943 ArgList args = doc.metaCommandArgs(topic);
944 Node *node =
nullptr;
945 if (args.size() == 1) {
947 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
948 if (
auto *error = std::get_if<FnMatchError>(&result)) {
949 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
950 if (!doc.isInternal() || InclusionFilter::processInternalDocs(policy))
951 errors.emplace_back(*error);
953 node = std::get<Node*>(result);
956 node = parseMacroArg(doc.location(), args[0].first);
957 }
else if (isQMLMethodTopic(topic)) {
958 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
960 database->primaryTree()->addToDontDocumentMap(args[0].first);
962 node = processTopicCommand(doc, topic, args[0]);
964 if (node !=
nullptr) {
965 tied.emplace_back(TiedDocumentation{doc, node});
967 }
else if (args.size() > 1) {
970 QList<SharedCommentNode *> sharedCommentNodes;
971 for (
const auto &arg : std::as_const(args)) {
974 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
975 if (
auto *error = std::get_if<FnMatchError>(&result)) {
976 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
977 if (!doc.isInternal() || InclusionFilter::processInternalDocs(policy))
978 errors.emplace_back(*error);
980 node = std::get<Node*>(result);
983 node = parseMacroArg(doc.location(), arg.first);
984 }
else if (isQMLMethodTopic(topic)) {
985 node = parseOtherFuncArg(topic, doc.location(), arg.first);
987 node = processTopicCommand(doc, topic, arg);
989 if (node !=
nullptr) {
991 for (SharedCommentNode *scn : sharedCommentNodes) {
992 if (scn->parent() == node->parent()) {
999 auto *scn =
new SharedCommentNode(node);
1000 sharedCommentNodes.append(scn);
1001 tied.emplace_back(TiedDocumentation{doc, scn});
1005 for (
auto *scn : sharedCommentNodes) {
1008 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
1013 return std::make_pair(tied, errors);
1017
1018
1019
1022 if (n->physicalModuleName().isEmpty()) {
1034 n->setPhysicalModuleName(Generator::defaultModuleName());
1037 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
1038 "using project name by default: %3")
1040 n->physicalModuleName()));
1047 for (
auto [doc, node] : tied) {
1049 processMetaCommands(doc, node);
1050 checkModuleInclusion(node);
1051 if (node->isAggregate()) {
1052 auto *aggregate =
static_cast<Aggregate *>(node);
1054 if (!aggregate->includeFile()) {
1055 const QString className = aggregate->name();
1061 QString includeFile = convenienceHeaderExists(className)
1063 : computeIncludeSpelling(aggregate->declLocation());
1065 if (includeFile.isEmpty() && !className.isEmpty())
1066 includeFile = className;
1068 if (!includeFile.isEmpty())
1069 aggregate->setIncludeFile(includeFile);
1075void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1080 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1085 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1088 auto classNode = database->findClassNode(arg.split(u"::"_s));
1093 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1099 if (qmlNode->classNode()) {
1101 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1102 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1105 qmlNode->setClassNode(classNode);
1106 classNode->insertQmlNativeType(qmlNode);
1107 setQmlAttributesFromNativeType(qmlNode, classNode);
1113
1114
1115
1116QString stripIncludePrefix(
const QString &path)
1118 QString result = path.trimmed();
1120 static const QStringList prefixes = {
1121 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1124 for (
const QString &prefix : prefixes) {
1125 if (result.startsWith(prefix)) {
1126 result = result.mid(prefix.size()).trimmed();
1127 return QDir::cleanPath(result);
1132 if (result.startsWith(u'-'))
1135 return QDir::cleanPath(result);
1141
1142
1143
1144const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1146 if (!m_includePathsCached) {
1148 QStringList rawPaths = Config::instance().includePaths();
1149 rawPaths += Config::instance().getCanonicalPathList(
1152 for (
const QString &path : rawPaths) {
1153 QString clean = stripIncludePrefix(path);
1154 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1155 m_cleanIncludePaths.append(clean);
1157 m_includePathsCached =
true;
1159 return m_cleanIncludePaths;
1163
1164
1165
1166
1167
1168
1169bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1171 if (className.isEmpty())
1174 auto it = m_convenienceHeaderCache.constFind(className);
1175 if (it != m_convenienceHeaderCache.constEnd())
1178 bool exists =
false;
1179 for (
const QString &includePath : getCleanIncludePaths()) {
1180 QFileInfo candidate(includePath + u'/' + className);
1181 if (candidate.exists() && candidate.isFile()) {
1187 m_convenienceHeaderCache.insert(className, exists);
1192
1193
1194
1195
1196
1197
1203 return loc.fileName();
The ClassNode represents a C++ class.
bool isQmlSingleton() const
bool isQmlUncreatable() const
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.
bool isUncreatable() const
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
static bool hasNativeTypeCommand(const Doc &doc)
Returns true if doc names the native type of a QML type explicitly, using either \nativetype or the d...
bool(Node::* NodeTypeTestFunc)() const
static void setQmlAttributesFromNativeType(QmlTypeNode *qmlType, const ClassNode *classNode)
Takes the singleton or uncreatable attribute of qmlType from its native type classNode.
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, that is, the aggregate under which the node is documented.
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)