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
13QT_BEGIN_NAMESPACE
14
15QList<CodeParser *> CodeParser::s_parsers;
16
17/*!
18 The constructor adds this code parser to the static
19 list of code parsers.
20 */
21CodeParser::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 */
31CodeParser::~CodeParser()
32{
33 s_parsers.removeAll(t: this);
34}
35
36/*!
37 Terminating a code parser is trivial.
38 */
39void 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 */
48void 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 */
57void CodeParser::terminate()
58{
59 for (const auto parser : s_parsers)
60 parser->terminateParser();
61}
62
63CodeParser *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
72CodeParser *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 */
90void 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 */
115void 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 */
133bool CodeParser::isWorthWarningAbout(const Doc &doc)
134{
135 return (Config::instance().showInternal()
136 || !doc.metaCommandsUsed().contains(QStringLiteral("internal")));
137}
138
139QT_END_NAMESPACE
140

source code of qttools/src/qdoc/qdoc/codeparser.cpp