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 | #include "codeparser.h" |
5 | |
6 | #include "config.h" |
7 | #include "generator.h" |
8 | #include "node.h" |
9 | #include "qdocdatabase.h" |
10 | |
11 | #include <QtCore/qregularexpression.h> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | QList<CodeParser *> CodeParser::s_parsers; |
16 | |
17 | /*! |
18 | The constructor adds this code parser to the static |
19 | list of code parsers. |
20 | */ |
21 | CodeParser::CodeParser() |
22 | { |
23 | m_qdb = QDocDatabase::qdocDB(); |
24 | s_parsers.prepend(t: this); |
25 | } |
26 | |
27 | /*! |
28 | The destructor removes this code parser from the static |
29 | list of code parsers. |
30 | */ |
31 | CodeParser::~CodeParser() |
32 | { |
33 | s_parsers.removeAll(t: this); |
34 | } |
35 | |
36 | /*! |
37 | Terminating a code parser is trivial. |
38 | */ |
39 | void CodeParser::terminateParser() |
40 | { |
41 | // nothing. |
42 | } |
43 | |
44 | /*! |
45 | All the code parsers in the static list are initialized here, |
46 | after the qdoc configuration variables have been set. |
47 | */ |
48 | void CodeParser::initialize() |
49 | { |
50 | for (const auto &parser : std::as_const(t&: s_parsers)) |
51 | parser->initializeParser(); |
52 | } |
53 | |
54 | /*! |
55 | All the code parsers in the static list are terminated here. |
56 | */ |
57 | void CodeParser::terminate() |
58 | { |
59 | for (const auto parser : s_parsers) |
60 | parser->terminateParser(); |
61 | } |
62 | |
63 | CodeParser *CodeParser::parserForLanguage(const QString &language) |
64 | { |
65 | for (const auto parser : std::as_const(t&: s_parsers)) { |
66 | if (parser->language() == language) |
67 | return parser; |
68 | } |
69 | return nullptr; |
70 | } |
71 | |
72 | CodeParser *CodeParser::parserForSourceFile(const QString &filePath) |
73 | { |
74 | QString fileName = QFileInfo(filePath).fileName(); |
75 | |
76 | for (const auto &parser : s_parsers) { |
77 | const QStringList sourcePatterns = parser->sourceFileNameFilter(); |
78 | for (const QString &pattern : sourcePatterns) { |
79 | auto re = QRegularExpression::fromWildcard(pattern, cs: Qt::CaseInsensitive); |
80 | if (re.match(subject: fileName).hasMatch()) |
81 | return parser; |
82 | } |
83 | } |
84 | return nullptr; |
85 | } |
86 | |
87 | /*! |
88 | \internal |
89 | */ |
90 | void CodeParser::extractPageLinkAndDesc(QStringView arg, QString *link, QString *desc) |
91 | { |
92 | static const QRegularExpression bracedRegExp( |
93 | QRegularExpression::anchoredPattern(expression: QLatin1String(R"(\{([^{}]*)\}(?:\{([^{}]*)\})?)" ))); |
94 | auto match = bracedRegExp.matchView(subjectView: arg); |
95 | if (match.hasMatch()) { |
96 | *link = match.captured(nth: 1); |
97 | *desc = match.captured(nth: 2); |
98 | if (desc->isEmpty()) |
99 | *desc = *link; |
100 | } else { |
101 | qsizetype spaceAt = arg.indexOf(c: QLatin1Char(' ')); |
102 | if (arg.contains(s: QLatin1String(".html" )) && spaceAt != -1) { |
103 | *link = arg.left(n: spaceAt).trimmed().toString(); |
104 | *desc = arg.mid(pos: spaceAt).trimmed().toString(); |
105 | } else { |
106 | *link = arg.toString(); |
107 | *desc = *link; |
108 | } |
109 | } |
110 | } |
111 | |
112 | /*! |
113 | \internal |
114 | */ |
115 | void CodeParser::setLink(Node *node, Node::LinkType linkType, const QString &arg) |
116 | { |
117 | QString link; |
118 | QString desc; |
119 | extractPageLinkAndDesc(arg, link: &link, desc: &desc); |
120 | node->setLink(linkType, link, desc); |
121 | } |
122 | |
123 | /*! |
124 | \brief Test for whether a doc comment warrants warnings. |
125 | |
126 | Returns true if qdoc should report that it has found something |
127 | wrong with the qdoc comment in \a doc. Sometimes, qdoc should |
128 | not report the warning, for example, when the comment contains |
129 | the \c internal command, which normally means qdoc will not use |
130 | the comment in the documentation anyway, so there is no point |
131 | in reporting warnings about it. |
132 | */ |
133 | bool CodeParser::isWorthWarningAbout(const Doc &doc) |
134 | { |
135 | return (Config::instance().showInternal() |
136 | || !doc.metaCommandsUsed().contains(QStringLiteral("internal" ))); |
137 | } |
138 | |
139 | QT_END_NAMESPACE |
140 | |