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);
332 tied.emplace_back(TiedDocumentation{doc, qpn});
337 doc.startLocation().warning(
338 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
347 if (sharedNodes.size() > 1) {
351 if (
auto dot = (*firstTopicArgs).m_name.indexOf(
'.'_L1); dot != -1)
352 group = (*firstTopicArgs).m_name.left(dot);
358 for (
const auto n : sharedNodes)
367
368
369
370
371
372
378 QString arg = argPair.first;
394 static_cast<Aggregate *>(node)->setIncludeFile(arg);
402 u"Found \\%1 command outside of \\%2 context."_s
406
407
408
409
410
411 processOverloadCommand(node, doc);
415 auto *fn =
static_cast<FunctionNode *>(node);
422 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
424 QStringLiteral(
"The function either doesn't exist in any "
425 "base class with the same signature or it "
426 "exists but isn't virtual."));
431 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
440 doc
.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
444 CodeParser::setLink(node, Node::NextLink, arg);
446 CodeParser::setLink(node, Node::PreviousLink, arg);
448 CodeParser::setLink(node, Node::StartLink, arg);
450 if (node->name() == arg)
451 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
453 auto *qmlType =
static_cast<QmlTypeNode *>(node);
454 qmlType->setQmlBaseName(arg);
459 u"\\instantiates is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
461 processQmlNativeTypeCommand(node, command, arg, doc
.location());
464 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
466 }
else if (arg.isEmpty()) {
467 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
470 static_cast<QmlPropertyNode *>(node)->setDefaultValue(arg);
479 doc
.location().warning(
"Ignored '\\%1', applies only to '\\%2' and '\\%3'"_L1
483 if (!nativeEnum->resolve(argPair.first, argPair.second)) {
484 doc
.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
485 .arg(command, arg),
"Use \\value commands instead"_L1);
493 static_cast<QmlPropertyNode *>(node)->setRequired();
498 node->setDeprecated(argPair.second);
501 database->addToGroup(arg, node);
503 database->addToModule(arg, node);
525 if (!node->setSubtitle(arg))
528 node->setQtVariable(arg);
532 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
536 node->setCMakeComponent(arg);
539 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
543 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
546 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
550 node->setCMakePackage(arg);
553 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
557 node->setCMakeComponent(arg);
560 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
564 node->setCMakeTargetItem(arg);
567 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
573 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
576 static_cast<CollectionNode*>(node)->setState(arg);
582 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
585 static_cast<PageNode*>(node)->setNoAutoList(
true);
607 }
else {
static_cast<PageNode*>(node)->markAttribution(); }
612
613
614
615
616
617
618
622 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
627 if (
auto category = comparisonCategoryFromString(arg.toStdString());
628 category != ComparisonCategory::None) {
631 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
632 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
637
638
639
640
644 auto *fn =
static_cast<FunctionNode *>(node);
648 if (fn->sharedCommentNode())
652 const auto &overloadArgs = doc.overloadList();
653 if (!overloadArgs.isEmpty()
654 && overloadArgs.first().first ==
"__qdoc_primary_overload__"_L1) {
661 fn->setPrimaryOverloadFlag();
663 fn->setOverloadFlag();
665 fn->setOverloadFlag();
668 static_cast<SharedCommentNode *>(node)->setOverloadFlags();
675
676
677
678
679
682 std::vector<Node*> nodes_to_process{};
684 auto scn =
static_cast<SharedCommentNode*>(node);
686 nodes_to_process.reserve(scn->count() + 1);
687 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
700 nodes_to_process.push_back(node);
702 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
703 for (
const auto &command : metaCommandsUsed) {
704 const ArgList args = doc.metaCommandArgs(command);
705 for (
const auto &arg : args) {
706 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [doc, command, arg](
auto node){
707 processMetaCommand(doc, command, arg, node);
715 doc
.location().warning(QStringLiteral(
"Ignored '\\title'"));
722
723
724
725
726
727
729 const Location &location,
const QString &arg)
732 location.warning(u"Missing argument to \\%1 command."_s.arg(
COMMAND_QMLENUM));
743 auto *qmlType = findOrCreateQmlType((*parsedArgs).m_module, (*parsedArgs).m_qmltype, location);
745 auto *enumNode =
new QmlEnumNode(qmlType, (*parsedArgs).m_name);
746 enumNode->setLocation(location);
748 for (
const auto &item : enumItemNames)
749 enumNode->addItem(EnumItem(item, 0));
755
756
758 const QString &funcArg)
763 if (topic.contains(
"signal"_L1))
773 auto *aggregate = findOrCreateQmlType((*methodArgs).m_module,
774 (*methodArgs).m_qmltype, location);
777 bool attached = topic.contains(
"attached"_L1);
778 auto *fn =
new FunctionNode(metaness, aggregate, (*methodArgs).m_name, attached);
779 fn->setAccess(Access::Public);
780 fn->setLocation(location);
781 fn->setReturnType((*methodArgs).m_type);
782 fn->setParameters((*methodArgs).m_params);
787
788
789
790
791
796 QStringList leftParenSplit = macroArg.split(
'(');
797 if (leftParenSplit.isEmpty())
801 QStringList blankSplit = leftParenSplit[0].split(
' ');
802 if (!blankSplit.empty()) {
803 macroName = blankSplit.last();
804 oldMacroNode = database->findMacroNode(macroName);
807 if (blankSplit.size() > 1) {
808 blankSplit.removeLast();
809 returnType = blankSplit.join(
' ');
812 if (leftParenSplit.size() > 1) {
813 params = QString(
"");
814 const QString &afterParen = leftParenSplit.at(1);
815 qsizetype rightParen = afterParen.indexOf(
')');
817 params = afterParen.left(rightParen);
820 while (i < macroName.size() && !macroName.at(i).isLetter())
823 returnType += QChar(
' ') + macroName.left(i);
824 macroName = macroName.mid(i);
830 macro->setAccess(Access::Public);
831 macro->setLocation(location);
832 macro->setReturnType(returnType);
833 macro->setParameters(params);
834 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
835 && compare(macro, oldMacroNode) == 0) {
836 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
837 .arg(macroArg), QStringLiteral(
"also seen here: %1")
838 .arg(oldMacroNode
->doc().location().toString()));
845 Config &config = Config::instance();
846 QString fullPath = config.getExampleProjectFile(en->name());
847 if (fullPath.isEmpty()) {
848 QString details = QLatin1String(
"Example directories: ")
851 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
856 QDir exampleDir(QFileInfo(fullPath).dir());
860 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
863 QSet<QString> excludeDocDirs(excludeDirs);
864 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
865 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
867 if (!exampleFiles.isEmpty()) {
871 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
872 if (fileName.endsWith(
"/main.cpp")) {
873 if (mainCpp.isEmpty())
877 return Utilities::isGeneratedFile(fileName);
881 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
884 if (!mainCpp.isEmpty())
885 exampleFiles.append(mainCpp);
888 exampleFiles += Config::getFilesHere(exampleDir.path(),
889 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
893 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
894 for (
auto &file : exampleFiles)
895 file = file.mid(pathLen);
896 for (
auto &file : imageFiles)
897 file = file.mid(pathLen);
899 en->setFiles(exampleFiles, fullPath.mid(pathLen));
900 en->setImages(imageFiles);
904
905
906
914
915
916
922std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
923CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
925 const Doc &doc = untied.documentation;
927 if (doc.topicsUsed().isEmpty())
930 QDocDatabase *database = QDocDatabase::qdocDB();
932 const QString topic = doc.topicsUsed().first().m_topic;
934 std::vector<TiedDocumentation> tied{};
935 std::vector<FnMatchError> errors{};
937 if (isQMLPropertyTopic(topic)) {
938 auto tied_qml = processQmlProperties(untied);
939 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
941 ArgList args = doc.metaCommandArgs(topic);
942 Node *node =
nullptr;
943 if (args.size() == 1) {
945 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
946 if (
auto *error = std::get_if<FnMatchError>(&result)) {
947 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
948 if (!doc.isInternal() || InclusionFilter::processInternalDocs(policy))
949 errors.emplace_back(*error);
951 node = std::get<Node*>(result);
954 node = parseMacroArg(doc.location(), args[0].first);
955 }
else if (isQMLMethodTopic(topic)) {
956 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
958 database->primaryTree()->addToDontDocumentMap(args[0].first);
960 node = processTopicCommand(doc, topic, args[0]);
962 if (node !=
nullptr) {
963 tied.emplace_back(TiedDocumentation{doc, node});
965 }
else if (args.size() > 1) {
968 QList<SharedCommentNode *> sharedCommentNodes;
969 for (
const auto &arg : std::as_const(args)) {
972 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
973 if (
auto *error = std::get_if<FnMatchError>(&result)) {
974 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
975 if (!doc.isInternal() || InclusionFilter::processInternalDocs(policy))
976 errors.emplace_back(*error);
978 node = std::get<Node*>(result);
981 node = parseMacroArg(doc.location(), arg.first);
982 }
else if (isQMLMethodTopic(topic)) {
983 node = parseOtherFuncArg(topic, doc.location(), arg.first);
985 node = processTopicCommand(doc, topic, arg);
987 if (node !=
nullptr) {
989 for (SharedCommentNode *scn : sharedCommentNodes) {
990 if (scn->parent() == node->parent()) {
997 auto *scn =
new SharedCommentNode(node);
998 sharedCommentNodes.append(scn);
999 tied.emplace_back(TiedDocumentation{doc, scn});
1003 for (
auto *scn : sharedCommentNodes) {
1006 if (!scn->collective().isEmpty() && !scn->collective().first()->isFunction())
1011 return std::make_pair(tied, errors);
1015
1016
1017
1020 if (n->physicalModuleName().isEmpty()) {
1032 n->setPhysicalModuleName(Generator::defaultModuleName());
1035 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
1036 "using project name by default: %3")
1038 n->physicalModuleName()));
1045 for (
auto [doc, node] : tied) {
1047 processMetaCommands(doc, node);
1048 checkModuleInclusion(node);
1049 if (node->isAggregate()) {
1050 auto *aggregate =
static_cast<Aggregate *>(node);
1052 if (!aggregate->includeFile()) {
1053 const QString className = aggregate->name();
1059 QString includeFile = convenienceHeaderExists(className)
1061 : computeIncludeSpelling(aggregate->declLocation());
1063 if (includeFile.isEmpty() && !className.isEmpty())
1064 includeFile = className;
1066 if (!includeFile.isEmpty())
1067 aggregate->setIncludeFile(includeFile);
1073void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1078 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1083 auto qmlNode =
static_cast<QmlTypeNode *>(node);
1086 auto classNode = database->findClassNode(arg.split(u"::"_s));
1091 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1097 if (qmlNode->classNode()) {
1099 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1100 .arg(qmlNode->name(), qmlNode->classNode()->name(), arg));
1103 qmlNode->setClassNode(classNode);
1104 classNode->insertQmlNativeType(qmlNode);
1105 setQmlAttributesFromNativeType(qmlNode, classNode);
1111
1112
1113
1114QString stripIncludePrefix(
const QString &path)
1116 QString result = path.trimmed();
1118 static const QStringList prefixes = {
1119 "-I"_L1,
"-isystem"_L1,
"-iquote"_L1,
"-idirafter"_L1
1122 for (
const QString &prefix : prefixes) {
1123 if (result.startsWith(prefix)) {
1124 result = result.mid(prefix.size()).trimmed();
1125 return QDir::cleanPath(result);
1130 if (result.startsWith(u'-'))
1133 return QDir::cleanPath(result);
1139
1140
1141
1142const QStringList &
CppCodeParser::getCleanIncludePaths()
const
1144 if (!m_includePathsCached) {
1146 QStringList rawPaths = Config::instance().includePaths();
1147 rawPaths += Config::instance().getCanonicalPathList(
1150 for (
const QString &path : rawPaths) {
1151 QString clean = stripIncludePrefix(path);
1152 if (!clean.isEmpty() && !m_cleanIncludePaths.contains(clean))
1153 m_cleanIncludePaths.append(clean);
1155 m_includePathsCached =
true;
1157 return m_cleanIncludePaths;
1161
1162
1163
1164
1165
1166
1167bool CppCodeParser::convenienceHeaderExists(
const QString &className)
const
1169 if (className.isEmpty())
1172 auto it = m_convenienceHeaderCache.constFind(className);
1173 if (it != m_convenienceHeaderCache.constEnd())
1176 bool exists =
false;
1177 for (
const QString &includePath : getCleanIncludePaths()) {
1178 QFileInfo candidate(includePath + u'/' + className);
1179 if (candidate.exists() && candidate.isFile()) {
1185 m_convenienceHeaderCache.insert(className, exists);
1190
1191
1192
1193
1194
1195
1201 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.
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)