23#include <QtCore/qdebug.h>
24#include <QtCore/qmap.h>
28using namespace Qt::Literals::StringLiterals;
33
34
35
36static const QMap<QString, Node::NodeType> s_nodeTypeMap{
56 Config &config = Config::instance();
61 if (!exampleFilePatterns.isEmpty())
62 m_exampleNameFilter = exampleFilePatterns.join(
' ');
64 m_exampleNameFilter =
"*.cpp *.h *.js *.xq *.svg *.xml *.ui";
70 if (!exampleImagePatterns.isEmpty())
71 m_exampleImageFilter = exampleImagePatterns.join(
' ');
73 m_exampleImageFilter =
"*.png";
79
80
88 }
else if (s_nodeTypeMap.contains(command)) {
90
91
92
93
94
95
96
98 QStringList words = arg.first.split(QLatin1Char(
' '));
101 Node *node =
nullptr;
104 idx = words.size() - 1;
105 path = words[idx].split(
"::");
107 node = database->findNodeByNameAndType(path, s_nodeTypeTestFuncMap[command]);
114 auto templateDecl = node->templateDecl();
121 if (node ==
nullptr) {
124 QStringLiteral(
"Cannot find '%1' specified with '\\%2' in any header file")
125 .arg(arg.first, command));
139 setExampleFileLists(en);
161 QStringList blankSplit = arg.first.split(QLatin1Char(
' '));
163 cn->setLogicalModuleInfo(blankSplit);
177 qmid = args.first().first;
178 auto *qcn = database->findQmlTypeInPrimaryTree(qmid, arg.first);
181 if (!qcn && !qmid.isEmpty())
182 qcn = database->findQmlTypeInPrimaryTree(QString(), arg.first);
183 if (!qcn || qcn->nodeType() != nodeType)
186 database->addToQmlModule(qmid, qcn);
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
216 QString &qmlTypeName, QString &name,
219 QStringList blankSplit = arg.split(QLatin1Char(
' '));
220 if (blankSplit.size() > 1) {
221 type = blankSplit[0];
222 QStringList colonSplit(blankSplit[1].split(
"::"));
223 if (colonSplit.size() == 3) {
224 module = colonSplit[0];
225 qmlTypeName = colonSplit[1];
226 name = colonSplit[2];
229 if (colonSplit.size() == 2) {
231 qmlTypeName = colonSplit[0];
232 name = colonSplit[1];
236 QStringLiteral(
"Unrecognizable QML module/component qualifier for %1").arg(arg));
238 location.warning(QStringLiteral(
"Missing property type for %1").arg(arg));
247 if (topics.isEmpty())
257 std::vector<TiedDocumentation> tied{};
259 Topic topic = topics.at(0);
262 qsizetype i = property.indexOf(
'.');
264 group = property.left(i);
270 QmlTypeNode *qmlType = database->findQmlTypeInPrimaryTree(qmlModule, qmlTypeName);
274 if (qmlType ==
nullptr) {
277 if (!qmlModule.isEmpty())
278 database->addToQmlModule(qmlModule, qmlType);
281 for (
const auto &topicCommand : topics) {
282 QString cmd = topicCommand.m_topic;
283 arg = topicCommand.m_args;
285 bool attached = cmd.contains(QLatin1String(
"attached"));
286 if (splitQmlPropertyArg(arg, type, qmlModule, qmlTypeName, property, doc.location())) {
287 if (qmlType != database->findQmlTypeInPrimaryTree(qmlModule, qmlTypeName)) {
288 doc.startLocation().warning(
290 "All properties in a group must belong to the same type: '%1'")
294 QmlPropertyNode *existingProperty = qmlType->hasQmlProperty(property, attached);
295 if (existingProperty) {
296 processMetaCommands(doc, existingProperty);
297 if (!doc.body().isEmpty()) {
298 doc.startLocation().warning(
299 QStringLiteral(
"QML property documented multiple times: '%1'")
300 .arg(arg), QStringLiteral(
"also seen here: %1")
301 .arg(existingProperty->location().toString()));
305 auto *qpn =
new QmlPropertyNode(qmlType, property, type, attached);
306 qpn->setLocation(doc.startLocation());
307 qpn->setGenus(Node::QML);
309 tied.emplace_back(TiedDocumentation{doc, qpn});
314 doc.startLocation().warning(
315 QStringLiteral(
"Command '\\%1'; not allowed with QML property commands")
324 if (sharedNodes.size() > 1) {
330 for (
const auto n : sharedNodes)
339
340
341
342
343
344
350 QString arg = argPair.first;
366 static_cast<
Aggregate *>(node)->setIncludeFile(arg);
372 if (!node->isClassNode())
373 doc.location().warning(
374 u"Found \\%1 command outside of \\%2 context."_s
378
379
380
381
382
399 QStringLiteral(
"Cannot find base function for '\\%1' in %2()")
401 QStringLiteral(
"The function either doesn't exist in any "
402 "base class with the same signature or it "
403 "exists but isn't virtual."));
408 QStringLiteral(
"Ignored '\\%1' in %2").arg(
COMMAND_REIMP, node->name()));
417 doc.location().warning(
"Invalid '\\%1' not allowed in '\\%2'"_L1
421 doc.location().warning(
"Invalid '\\%1' ('%2' must be global)"_L1
426 CodeParser::setLink(node, Node::NextLink, arg);
428 CodeParser::setLink(node, Node::PreviousLink, arg);
430 CodeParser::setLink(node, Node::StartLink, arg);
432 if (node->name() == arg)
433 doc
.location().warning(QStringLiteral(
"%1 tries to inherit itself").arg(arg));
436 qmlType->setQmlBaseName(arg);
440 doc.location().report(
441 u"\\nativetype is deprecated and will be removed in a future version. Use \\nativetype instead."_s);
443 processQmlNativeTypeCommand(node, command, arg, doc
.location());
446 doc
.location().warning(QStringLiteral(
"Ignored '\\%1', applies only to '\\%2'")
448 }
else if (arg.isEmpty()) {
449 doc
.location().warning(QStringLiteral(
"Expected an argument for '\\%1' (maybe you meant '\\%2'?)")
458 doc.location().warning(
"Ignored '\\%1', applies only to '\\%2'"_L1
460 }
else if (!
static_cast<
QmlPropertyNode*>(node)->setEnumNode(argPair.first, argPair.second)) {
461 doc.location().warning(
"Failed to find C++ enumeration '%2' passed to \\%1"_L1
462 .arg(command, arg),
"Use \\value commands instead"_L1);
475 node->setDeprecated(argPair.second);
478 database->addToGroup(arg, node);
480 database->addToModule(arg, node);
492 if (!Config::instance().showInternal())
503 if (!node->setTitle(arg))
508 if (!node->setSubtitle(arg))
511 node->setQtVariable(arg);
515 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
519 node->setCMakeComponent(arg);
522 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
526 node->setCMakeTargetItem(QLatin1String(
"Qt6::") + arg);
529 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
533 node->setCMakePackage(arg);
536 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
540 node->setCMakeComponent(arg);
543 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
547 node->setCMakeTargetItem(arg);
550 QStringLiteral(
"Command '\\%1' is only meaningful in '\\module'.")
556 "Command '\\%1' is only meaningful in '\\module' and '\\qmlmodule'.")
565 "Command '\\%1' is only meaningful in '\\module', '\\qmlmodule', `\\group` and `\\example`.")
595
596
597
598
599
600
601
605 loc.warning(u"Found \\%1 command outside of \\%2 context."_s.arg(
COMMAND_COMPARES,
610 if (
auto category = comparisonCategoryFromString(arg.toStdString());
611 category != ComparisonCategory::None) {
614 loc.warning(u"Invalid argument to \\%1 command: `%2`"_s.arg(
COMMAND_COMPARES, arg),
615 u"Valid arguments are `strong`, `weak`, `partial`, or `equality`."_s);
620
621
622
623
624
627 std::vector<Node*> nodes_to_process{};
631 nodes_to_process.reserve(scn->count() + 1);
632 std::copy(scn->collective().cbegin(), scn->collective().cend(),
std::back_inserter(nodes_to_process));
645 nodes_to_process.push_back(node);
647 const QStringList metaCommandsUsed = doc.metaCommandsUsed().values();
648 for (
const auto &command : metaCommandsUsed) {
649 const ArgList args = doc.metaCommandArgs(command);
650 for (
const auto &arg : args) {
651 std::for_each(nodes_to_process.cbegin(), nodes_to_process.cend(), [
this, doc, command, arg](
auto node){
652 processMetaCommand(doc, command, arg, node);
659
660
662 const QString &funcArg)
667 qsizetype leftParen = funcArg.indexOf(QChar(
'('));
669 funcName = funcArg.left(leftParen);
672 qsizetype firstBlank = funcName.indexOf(QChar(
' '));
673 if (firstBlank > 0) {
674 returnType = funcName.left(firstBlank);
675 funcName = funcName.right(funcName.size() - firstBlank - 1);
678 QStringList colonSplit(funcName.split(
"::"));
679 if (colonSplit.size() < 2) {
680 QString msg =
"Unrecognizable QML module/component qualifier for " + funcArg;
681 location.warning(msg.toLatin1().data());
686 if (colonSplit.size() > 2) {
687 moduleName = colonSplit[0];
688 elementName = colonSplit[1];
690 elementName = colonSplit[0];
692 funcName = colonSplit.last();
696 auto *aggregate = database->findQmlTypeInPrimaryTree(moduleName, elementName);
702 aggregate->setLocation(location);
703 if (!moduleName.isEmpty())
704 database->addToQmlModule(moduleName, aggregate);
708 QStringList leftParenSplit = funcArg.split(
'(');
709 if (leftParenSplit.size() > 1) {
710 QStringList rightParenSplit = leftParenSplit[1].split(
')');
711 if (!rightParenSplit.empty())
712 params = rightParenSplit[0];
716 bool attached = topic.contains(QLatin1String(
"attached"));
717 auto *fn =
new FunctionNode(metaness, aggregate, funcName, attached);
718 fn->setAccess(Access::Public);
719 fn->setLocation(location);
720 fn->setReturnType(returnType);
721 fn->setParameters(params);
726
727
728
729
730
735 QStringList leftParenSplit = macroArg.split(
'(');
736 if (leftParenSplit.isEmpty())
740 QStringList blankSplit = leftParenSplit[0].split(
' ');
741 if (!blankSplit.empty()) {
742 macroName = blankSplit.last();
743 oldMacroNode = database->findMacroNode(macroName);
746 if (blankSplit.size() > 1) {
747 blankSplit.removeLast();
748 returnType = blankSplit.join(
' ');
751 if (leftParenSplit.size() > 1) {
752 const QString &afterParen = leftParenSplit.at(1);
753 qsizetype rightParen = afterParen.indexOf(
')');
755 params = afterParen.left(rightParen);
758 while (i < macroName.size() && !macroName.at(i).isLetter())
761 returnType += QChar(
' ') + macroName.left(i);
762 macroName = macroName.mid(i);
765 if (params.isEmpty())
768 macro->setAccess(Access::Public);
769 macro->setLocation(location);
770 macro->setReturnType(returnType);
771 macro->setParameters(params);
772 if (oldMacroNode && macro->parent() == oldMacroNode
->parent()
773 && compare(macro, oldMacroNode) == 0) {
774 location.warning(QStringLiteral(
"\\macro %1 documented more than once")
775 .arg(macroArg), QStringLiteral(
"also seen here: %1")
776 .arg(oldMacroNode
->doc().location().toString()));
783 Config &config = Config::instance();
784 QString fullPath = config.getExampleProjectFile(en->name());
785 if (fullPath.isEmpty()) {
786 QString details = QLatin1String(
"Example directories: ")
789 QStringLiteral(
"Cannot find project file for example '%1'").arg(en->name()),
794 QDir exampleDir(QFileInfo(fullPath).dir());
798 QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), m_exampleNameFilter,
799 Location(), excludeDirs, excludeFiles);
801 QSet<QString> excludeDocDirs(excludeDirs);
802 excludeDocDirs.insert(exampleDir.path() + QLatin1String(
"/doc/images"));
803 QStringList imageFiles = Config::getFilesHere(exampleDir.path(), m_exampleImageFilter,
804 Location(), excludeDocDirs, excludeFiles);
805 if (!exampleFiles.isEmpty()) {
809 const auto isGeneratedOrMainCpp = [&mainCpp](
const QString &fileName) {
810 if (fileName.endsWith(
"/main.cpp")) {
811 if (mainCpp.isEmpty())
815 return fileName.contains(
"/qrc_") || fileName.contains(
"/moc_")
816 || fileName.contains(
"/ui_");
820 std::remove_if(exampleFiles.begin(), exampleFiles.end(), isGeneratedOrMainCpp),
823 if (!mainCpp.isEmpty())
824 exampleFiles.append(mainCpp);
827 exampleFiles += Config::getFilesHere(exampleDir.path(),
828 QLatin1String(
"*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"),
832 const qsizetype pathLen = exampleDir.path().size() - en->name().size();
833 for (
auto &file : exampleFiles)
834 file = file.mid(pathLen);
835 for (
auto &file : imageFiles)
836 file = file.mid(pathLen);
838 en->setFiles(exampleFiles, fullPath.mid(pathLen));
839 en->setImages(imageFiles);
843
844
845
853
854
855
861std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
862CppCodeParser::processTopicArgs(
const UntiedDocumentation &untied)
864 const Doc &doc = untied.documentation;
866 if (doc.topicsUsed().isEmpty())
869 QDocDatabase *database = QDocDatabase::qdocDB();
871 const QString topic = doc.topicsUsed().first().m_topic;
873 std::vector<TiedDocumentation> tied{};
874 std::vector<FnMatchError> errors{};
876 if (isQMLPropertyTopic(topic)) {
877 auto tied_qml = processQmlProperties(untied);
878 tied.insert(tied.end(), tied_qml.begin(), tied_qml.end());
880 ArgList args = doc.metaCommandArgs(topic);
881 Node *node =
nullptr;
882 if (args.size() == 1) {
884 if (Config::instance().showInternal() || !doc.isInternal()) {
885 auto result = fn_parser(doc.location(), args[0].first, args[0].second, untied.context);
886 if (
auto *error = std::get_if<FnMatchError>(&result))
887 errors.emplace_back(*error);
889 node = std::get<Node*>(result);
892 node = parseMacroArg(doc.location(), args[0].first);
893 }
else if (isQMLMethodTopic(topic)) {
894 node = parseOtherFuncArg(topic, doc.location(), args[0].first);
896 database->primaryTree()->addToDontDocumentMap(args[0].first);
898 node = processTopicCommand(doc, topic, args[0]);
900 if (node !=
nullptr) {
901 tied.emplace_back(TiedDocumentation{doc, node});
903 }
else if (args.size() > 1) {
904 QList<SharedCommentNode *> sharedCommentNodes;
905 for (
const auto &arg : std::as_const(args)) {
908 if (Config::instance().showInternal() || !doc.isInternal()) {
909 auto result = fn_parser(doc.location(), arg.first, arg.second, untied.context);
910 if (
auto *error = std::get_if<FnMatchError>(&result))
911 errors.emplace_back(*error);
913 node = std::get<Node*>(result);
916 node = parseMacroArg(doc.location(), arg.first);
917 }
else if (isQMLMethodTopic(topic)) {
918 node = parseOtherFuncArg(topic, doc.location(), arg.first);
920 node = processTopicCommand(doc, topic, arg);
922 if (node !=
nullptr) {
924 for (SharedCommentNode *scn : sharedCommentNodes) {
925 if (scn->parent() == node->parent()) {
932 auto *scn =
new SharedCommentNode(node);
933 sharedCommentNodes.append(scn);
934 tied.emplace_back(TiedDocumentation{doc, scn});
938 for (
auto *scn : sharedCommentNodes)
942 return std::make_pair(tied, errors);
946
947
948
951 if (n->physicalModuleName().isEmpty()) {
963 n->setPhysicalModuleName(Generator::defaultModuleName());
966 QStringLiteral(
"Documentation for %1 '%2' has no \\inmodule command; "
967 "using project name by default: %3")
969 n->physicalModuleName()));
976 for (
auto [doc, node] : tied) {
977 processMetaCommands(doc, node);
979 checkModuleInclusion(node);
980 if (node->isAggregate()) {
981 auto *aggregate =
static_cast<Aggregate *>(node);
983 if (!aggregate->includeFile()) {
984 Aggregate *parent = aggregate;
985 while (parent->physicalModuleName().isEmpty() && (parent->parent() !=
nullptr))
986 parent = parent->parent();
988 if (parent == aggregate)
1001 aggregate->setIncludeFile(aggregate->name());
1002 else if (aggregate->includeFile())
1003 aggregate->setIncludeFile(*parent->includeFile());
1009void CppCodeParser::processQmlNativeTypeCommand(
Node *node,
const QString &cmd,
const QString &arg,
const Location &location)
1014 QStringLiteral(
"Command '\\%1' is only meaningful in '\\%2'")
1022 auto classNode = database->findClassNode(arg.split(u"::"_s));
1025 if (m_showLinkErrors) {
1027 QStringLiteral(
"C++ class %2 not found: \\%1 %2")
1035 QStringLiteral(
"QML type %1 documented with %2 as its native type. Replacing %2 with %3")
1040 classNode->insertQmlNativeType(qmlNode);
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)
bool splitQmlPropertyArg(const QString &arg, QString &type, QString &module, QString &element, QString &name, const Location &location)
A QML property argument has the form...
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.
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.
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.
bool isInternal() const
Returns true if the set of metacommands used in the doc comment contains {internal}...
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.
void setReimpFlag()
Sets the function node's reimp flag to true, which means the {\reimp} command was used in the qdoc co...
const QString & overridesThis() const
The Location class provides a way to mark a location in a file.
Location()
Constructs an empty location.
This class represents a C++ namespace.
Tree * tree() const override
Returns a pointer to the Tree that contains this NamespaceNode.
void markSeen()
Sets the data member that indicates that the {\namespace} command this NamespaceNode represents has b...
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.
NodeType
An unsigned char value that identifies an object as a particular subclass of Node.
bool isFunction(Genus g=DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
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.
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.
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...
NodeType nodeType() const
Returns this node's type.
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.
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.
virtual void markDefault()
If this node is a QmlPropertyNode, it is marked as the default 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.
LinkType
An unsigned char value that probably should be moved out of the Node base class.
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
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 isQmlProperty() const
Returns true if the node type is QmlProperty.
A PageNode is a Node that generates a documentation page.
void setNoAutoList(bool b)
Sets the no auto-list flag to b.
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.
ClassNode * classNode() override
If this is a QmlTypeNode, this function returns the pointer to the C++ ClassNode that this QML type r...
void setClassNode(ClassNode *cn) override
If this is a QmlTypeNode, this function sets the C++ class node to cn.
const QString & camelCaseModuleName() const
#define COMMAND_HEADERFILE
#define COMMAND_EXTERNALPAGE
#define COMMAND_QMLINHERITS
#define COMMAND_MODULESTATE
#define COMMAND_NONREENTRANT
#define COMMAND_QMLSIGNAL
#define COMMAND_DEPRECATED
#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
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...
std::pair< QString, QString > ArgPair