1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef CPPCODEPARSER_H
5#define CPPCODEPARSER_H
6
7#include "clangcodeparser.h"
8#include "codeparser.h"
9#include "parsererror.h"
10#include "utilities.h"
11
12QT_BEGIN_NAMESPACE
13
14class ClassNode;
15class EnumNode;
16class ExampleNode;
17class FunctionNode;
18class Aggregate;
19
20class CppCodeParser
21{
22public:
23 static inline const QSet<QString> topic_commands{
24 COMMAND_CLASS, COMMAND_DONTDOCUMENT, COMMAND_ENUM, COMMAND_EXAMPLE,
25 COMMAND_EXTERNALPAGE, COMMAND_FN, COMMAND_GROUP, COMMAND_HEADERFILE,
26 COMMAND_MACRO, COMMAND_MODULE, COMMAND_NAMESPACE, COMMAND_PAGE,
27 COMMAND_PROPERTY, COMMAND_TYPEALIAS, COMMAND_TYPEDEF, COMMAND_VARIABLE,
28 COMMAND_QMLTYPE, COMMAND_QMLPROPERTY, COMMAND_QMLPROPERTYGROUP,
29 COMMAND_QMLATTACHEDPROPERTY, COMMAND_QMLENUM, COMMAND_QMLSIGNAL, COMMAND_QMLATTACHEDSIGNAL,
30 COMMAND_QMLMETHOD, COMMAND_QMLATTACHEDMETHOD, COMMAND_QMLVALUETYPE, COMMAND_QMLBASICTYPE,
31 COMMAND_QMLMODULE, COMMAND_STRUCT, COMMAND_UNION,
32 };
33
34 static inline const QSet<QString> meta_commands = QSet<QString>(CodeParser::common_meta_commands)
35 << COMMAND_COMPARES << COMMAND_COMPARESWITH << COMMAND_INHEADERFILE
36 << COMMAND_NEXTPAGE << COMMAND_OVERLOAD << COMMAND_PREVIOUSPAGE
37 << COMMAND_QMLINSTANTIATES << COMMAND_QMLNATIVETYPE << COMMAND_REIMP << COMMAND_RELATES;
38
39public:
40 explicit CppCodeParser(FnCommandParser&& parser);
41
42 FunctionNode *parseMacroArg(const Location &location, const QString &macroArg);
43 FunctionNode *parseOtherFuncArg(const QString &topic, const Location &location,
44 const QString &funcArg);
45 static bool isQMLMethodTopic(const QString &t);
46 static bool isQMLPropertyTopic(const QString &t);
47
48 std::pair<std::vector<TiedDocumentation>, std::vector<FnMatchError>>
49 processTopicArgs(const UntiedDocumentation &untied);
50
51 void processMetaCommand(const Doc &doc, const QString &command, const ArgPair &argLocPair,
52 Node *node);
53 void processMetaCommands(const Doc &doc, Node *node);
54 void processMetaCommands(const std::vector<TiedDocumentation> &tied);
55
56protected:
57 virtual Node *processTopicCommand(const Doc &doc, const QString &command,
58 const ArgPair &arg);
59 std::vector<TiedDocumentation> processQmlProperties(const UntiedDocumentation& untied);
60
61private:
62 void setExampleFileLists(ExampleNode *en);
63 static void processComparesCommand(Node *node, const QString &arg, const Location &loc);
64 void processQmlNativeTypeCommand(Node *node, const QString &cmd,
65 const QString &arg, const Location &loc);
66 EnumNode *processQmlEnumTopic(const QStringList &enumItemNames, const Location &location,
67 const QString &arg);
68
69private:
70 FnCommandParser fn_parser;
71 QString m_exampleNameFilter;
72 QString m_exampleImageFilter;
73 bool m_showLinkErrors { false };
74};
75
76/*!
77 * \internal
78 * \brief Checks if there are too many topic commands in \a doc.
79 *
80 * This method compares the commands used in \a doc with the set of topic
81 * commands. If zero or one topic command is found, or if all found topic
82 * commands are {\\qml*}-commands, the method returns \c false.
83 *
84 * If more than one topic command is found, QDoc issues a warning and the list
85 * of topic commands used in \a doc, and the method returns \c true.
86 */
87[[nodiscard]] inline bool hasTooManyTopics(const Doc &doc)
88{
89 const QSet<QString> topicCommandsUsed = CppCodeParser::topic_commands & doc.metaCommandsUsed();
90
91 if (topicCommandsUsed.empty() || topicCommandsUsed.size() == 1)
92 return false;
93 if (std::all_of(first: topicCommandsUsed.cbegin(), last: topicCommandsUsed.cend(),
94 pred: [](const auto &cmd) { return cmd.startsWith(QLatin1String("qml")); }))
95 return false;
96
97 const QStringList commands = topicCommandsUsed.values();
98 const QString topicCommands{ std::accumulate(
99 first: commands.cbegin(), last: commands.cend(), init: QString{},
100 binary_op: [index = qsizetype{ 0 }, numberOfCommands = commands.size()](
101 const QString &accumulator, const QString &topic) mutable -> QString {
102 return accumulator + QLatin1String("\\") + topic
103 + Utilities::separator(wordPosition: index++, numberOfWords: numberOfCommands);
104 }) };
105
106 doc.location().warning(
107 QStringLiteral("Multiple topic commands found in comment: %1").arg(a: topicCommands));
108 return true;
109}
110
111QT_END_NAMESPACE
112
113#endif
114

source code of qttools/src/qdoc/qdoc/src/qdoc/cppcodeparser.h