18#include <QtCore/qdebug.h>
19#include <QtCore/qregularexpression.h>
23using namespace Qt::StringLiterals;
26
27
34
35
36
39 QByteArray ext = extension.toLatin1();
40 return ext ==
"c" || ext ==
"c++" || ext ==
"qdoc" || ext ==
"qtt" || ext ==
"qtx"
41 || ext ==
"cc" || ext ==
"cpp" || ext ==
"cxx" || ext ==
"ch" || ext ==
"h"
42 || ext ==
"h++" || ext ==
"hh" || ext ==
"hpp" || ext ==
"hxx";
46
47
50 return lang == QLatin1String(
"C") || lang == QLatin1String(
"Cpp");
54
55
64 return addMarkUp(code, relative, location);
70 const int MaxEnumValues = 6;
77 name = taggedNode(node);
78 if (style != Section::Details)
79 name = linkTag(node, name);
80 name =
"<@name>" + name +
"</@name>";
85 name.prepend(taggedNode(node->parent()) +
"::");
95 synopsis += QLatin1Char(
' ') + name;
100 auto templateDecl = node->templateDecl();
102 synopsis = protect((*templateDecl).to_qstring()) + QLatin1Char(
' ');
104 if (style != Section::AllMembers && !func->returnType().isEmpty())
105 synopsis += typified(func->returnTypeString(),
true);
108 synopsis += QLatin1Char(
'(');
111 for (
int i = 0; i < parameters
.count(); ++i) {
114 QString name = parameters
.at(i
).name();
115 QString type = parameters
.at(i
).type();
116 QString value = parameters
.at(i
).defaultValue();
118 synopsis += typified(type, trailingSpace);
120 synopsis +=
"<@param>" + protect(name) +
"</@param>";
122 synopsis +=
" = " + protect(value);
125 synopsis += QLatin1Char(
')');
128 synopsis +=
" const";
132 synopsis.prepend(
"virtual ");
134 synopsis.append(
" final");
136 synopsis.append(
" override");
138 synopsis.append(
" = 0");
140 synopsis.append(
" &");
142 synopsis.append(
" &&");
144 if (!func->returnType().isEmpty() && func->returnType() !=
"void")
145 synopsis +=
" : " + typified(func->returnTypeString());
148 synopsis.append(
" &");
150 synopsis.append(
" &&");
154 enume =
static_cast<
const EnumNode *>(node);
157 synopsis +=
" class";
158 if (!enume->isAnonymous())
159 synopsis +=
" %1"_L1.arg(name);
160 else if (style != Section::Details)
161 synopsis = linkTag(node, synopsis);
165 QStringList documentedItems = enume
->doc().enumItemNames();
166 if (documentedItems.isEmpty()) {
167 const auto &enumItems = enume->items();
168 for (
const auto &item : enumItems)
169 documentedItems << item.name();
171 const QStringList omitItems = enume
->doc().omitEnumItemNames();
172 for (
const auto &item : omitItems)
173 documentedItems.removeAll(item);
175 if (documentedItems.size() > MaxEnumValues) {
177 const QString last = documentedItems.last();
178 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
179 documentedItems +=
"…";
180 documentedItems += last;
182 synopsis += documentedItems.join(QLatin1String(
", "));
184 if (!documentedItems.isEmpty())
185 synopsis += QLatin1Char(
' ');
186 synopsis += QLatin1Char(
'}');
191 auto templateDecl = node->templateDecl();
193 synopsis += protect((*templateDecl).to_qstring()) + QLatin1Char(
' ');
203 auto property =
static_cast<
const PropertyNode *>(node);
204 synopsis = name +
" : " + typified(property->qualifiedDataType());
209 synopsis = name +
" : " + typified(property->dataType());
215 synopsis = name +
" : " + typified(variable->dataType());
217 synopsis = typified(variable->leftType(),
true) + name + protect(variable->rightType());
221 synopsis =
std::move(name);
224 QString extra = CodeMarker::extraSynopsis(node, style);
225 if (!extra.isEmpty()) {
226 extra.prepend(u"<@extra>"_s);
227 extra.append(u"</@extra> "_s);
230 return extra + synopsis;
234
237 QString name = taggedQmlNode(node);
241 name = linkTag(node, name);
245 name.prepend(pn->element() + QLatin1Char(
'.'));
247 name =
"<@name>" + name +
"</@name>";
250 synopsis = name +
" : " + typified(pn->dataType());
252 const auto *func =
static_cast<
const FunctionNode *>(node);
253 if (!func->returnType().isEmpty())
254 synopsis = typified(func->returnTypeString(),
true) + name;
257 synopsis += QLatin1Char(
'(');
260 for (
int i = 0; i < parameters
.count(); ++i) {
263 QString name = parameters
.at(i
).name();
264 QString type = parameters
.at(i
).type();
266 if (!name.isEmpty()) {
267 synopsis += typified(type,
true);
268 paramName =
std::move(name);
270 paramName =
std::move(type);
272 synopsis +=
"<@param>" + protect(paramName) +
"</@param>";
275 synopsis += QLatin1Char(
')');
277 synopsis =
std::move(name);
281 if (!extra.isEmpty()) {
282 extra.prepend(u" <@extra>"_s);
283 extra.append(u"</@extra>"_s);
286 return synopsis + extra;
291 QString name = linkTag(node, taggedNode(node));
305 if (nativeEnum && nativeEnum->enumNode()
306 && !enumValue.startsWith(
"%1."_L1.arg(nativeEnum->prefix())))
307 return "%1<@op>.</@op>%2"_L1.arg(nativeEnum->prefix(), enumValue);
315 parts.prepend(markedUpName(node));
321 parts.append(relative->name());
323 parts.append(enumValue);
324 const auto &delim = (relative->genus() == Genus::QML) ?
"."_L1 :
"::"_L1;
325 return parts.join(
"<@op>%1</@op>"_L1.arg(delim));
331 static QSet<QString> types{
332 QLatin1String(
"bool"), QLatin1String(
"char"), QLatin1String(
"double"),
333 QLatin1String(
"float"), QLatin1String(
"int"), QLatin1String(
"long"),
334 QLatin1String(
"short"), QLatin1String(
"signed"), QLatin1String(
"unsigned"),
335 QLatin1String(
"uint"), QLatin1String(
"ulong"), QLatin1String(
"ushort"),
336 QLatin1String(
"uchar"), QLatin1String(
"void"), QLatin1String(
"qlonglong"),
337 QLatin1String(
"qulonglong"), QLatin1String(
"qint"), QLatin1String(
"qint8"),
338 QLatin1String(
"qint16"), QLatin1String(
"qint32"), QLatin1String(
"qint64"),
339 QLatin1String(
"quint"), QLatin1String(
"quint8"), QLatin1String(
"quint16"),
340 QLatin1String(
"quint32"), QLatin1String(
"quint64"), QLatin1String(
"qreal"),
341 QLatin1String(
"cond")
344 static QSet<QString> keywords{
345 QLatin1String(
"and"), QLatin1String(
"and_eq"), QLatin1String(
"asm"), QLatin1String(
"auto"),
346 QLatin1String(
"bitand"), QLatin1String(
"bitor"), QLatin1String(
"break"),
347 QLatin1String(
"case"), QLatin1String(
"catch"), QLatin1String(
"class"),
348 QLatin1String(
"compl"), QLatin1String(
"const"), QLatin1String(
"const_cast"),
349 QLatin1String(
"continue"), QLatin1String(
"default"), QLatin1String(
"delete"),
350 QLatin1String(
"do"), QLatin1String(
"dynamic_cast"), QLatin1String(
"else"),
351 QLatin1String(
"enum"), QLatin1String(
"explicit"), QLatin1String(
"export"),
352 QLatin1String(
"extern"), QLatin1String(
"false"), QLatin1String(
"for"),
353 QLatin1String(
"friend"), QLatin1String(
"goto"), QLatin1String(
"if"),
354 QLatin1String(
"include"), QLatin1String(
"inline"), QLatin1String(
"monitor"),
355 QLatin1String(
"mutable"), QLatin1String(
"namespace"), QLatin1String(
"new"),
356 QLatin1String(
"not"), QLatin1String(
"not_eq"), QLatin1String(
"operator"),
357 QLatin1String(
"or"), QLatin1String(
"or_eq"), QLatin1String(
"private"),
358 QLatin1String(
"protected"), QLatin1String(
"public"), QLatin1String(
"register"),
359 QLatin1String(
"reinterpret_cast"), QLatin1String(
"return"), QLatin1String(
"sizeof"),
360 QLatin1String(
"static"), QLatin1String(
"static_cast"), QLatin1String(
"struct"),
361 QLatin1String(
"switch"), QLatin1String(
"template"), QLatin1String(
"this"),
362 QLatin1String(
"throw"), QLatin1String(
"true"), QLatin1String(
"try"),
363 QLatin1String(
"typedef"), QLatin1String(
"typeid"), QLatin1String(
"typename"),
364 QLatin1String(
"union"), QLatin1String(
"using"), QLatin1String(
"virtual"),
365 QLatin1String(
"volatile"), QLatin1String(
"wchar_t"), QLatin1String(
"while"),
366 QLatin1String(
"xor"), QLatin1String(
"xor_eq"), QLatin1String(
"synchronized"),
368 QLatin1String(
"signals"), QLatin1String(
"slots"), QLatin1String(
"emit")
380 static const QRegularExpression classRegExp(QRegularExpression::anchoredPattern(
"Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"));
381 static const QRegularExpression functionRegExp(QRegularExpression::anchoredPattern(
"q([A-Z][a-z]+)+"));
382 static const QRegularExpression findFunctionRegExp(QStringLiteral(
"^\\s*\\("));
385 auto readChar = [&]() {
397 if (ch.isLetter() || ch ==
'_') {
403 }
while (!atEOF && (ch.isLetterOrNumber() || ch ==
'_'));
405 if (classRegExp.match(ident).hasMatch()) {
406 tag = QStringLiteral(
"type");
407 }
else if (functionRegExp.match(ident).hasMatch()) {
408 tag = QStringLiteral(
"func");
410 }
else if (types.contains(ident)) {
411 tag = QStringLiteral(
"type");
412 }
else if (keywords.contains(ident)) {
413 tag = QStringLiteral(
"keyword");
414 }
else if (braceDepth == 0 && parenDepth == 0) {
415 if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
416 tag = QStringLiteral(
"func");
419 }
else if (ch.isDigit()) {
423 }
while (!atEOF && (ch.isLetterOrNumber() || ch ==
'.' || ch ==
'\''));
424 tag = QStringLiteral(
"number");
426 switch (ch.unicode()) {
446 tag = QStringLiteral(
"op");
452 while (!atEOF && ch !=
'"') {
459 tag = QStringLiteral(
"string");
464 while (!atEOF && ch !=
'\n') {
470 tag = QStringLiteral(
"preprocessor");
476 while (!atEOF && ch !=
'\'') {
483 tag = QStringLiteral(
"char");
498 if (!atEOF && ch ==
':') {
501 tag = QStringLiteral(
"op");
507 if (!atEOF && ch ==
'/') {
511 }
while (!atEOF && ch !=
'\n');
512 tag = QStringLiteral(
"comment");
513 }
else if (ch ==
'*') {
514 bool metAster =
false;
515 bool metAsterSlash =
false;
520 while (!metAsterSlash) {
525 else if (metAster && ch ==
'/')
526 metAsterSlash =
true;
532 tag = QStringLiteral(
"comment");
534 tag = QStringLiteral(
"op");
553 text = QStringView{code}.mid(start, finish - start);
556 if (!tag.isEmpty()) {
557 out += QStringLiteral(
"<@");
560 out += QStringLiteral(
" target=\"");
562 out += QStringLiteral(
"()\"");
564 out += QStringLiteral(
">");
567 appendProtectedString(&out, text);
569 if (!tag.isEmpty()) {
570 out += QStringLiteral(
"</@");
572 out += QStringLiteral(
">");
576 if (start < code.size()) {
577 appendProtectedString(&out, QStringView{code}.mid(start));
The Atom class is the fundamental unit for representing documents internally.
AtomType
\value AnnotatedList \value AutoLink \value BaseName \value BriefLeft \value BriefRight \value C \val...
QString markedUpQmlItem(const Node *node, bool summary) override
bool recognizeExtension(const QString &ext) override
Returns true if ext is any of a list of file extensions for the C++ language.
QString markedUpName(const Node *node) override
QString markedUpEnumValue(const QString &enumValue, const Node *relative) override
Atom::AtomType atomType() const override
Returns the type of atom used to represent C++ code in the documentation.
bool recognizeLanguage(const QString &lang) override
Returns true if lang is either "C" or "Cpp".
QString markedUpSynopsis(const Node *node, const Node *relative, Section::Style style) override
QString markedUpCode(const QString &code, const Node *relative, const Location &location) override
bool recognizeCode(const QString &code) override
Returns true.
This node is used to represent any kind of function being documented.
bool isMacroWithoutParams() const
const Parameters & parameters() const
bool isPureVirtual() const override
bool isNonvirtual() const
The Location class provides a way to mark a location in a file.
Interface implemented by Node subclasses that can refer to a C++ enum.
virtual const NativeEnum * nativeEnum() const =0
Encapsulates information about native (C++) enum values.
This class describes one instance of using the Q_PROPERTY macro.
bool isAttached() const override
Returns true if the QML property or QML method node is marked as attached.
A class for containing the elements of one documentation section.
const EnumNode * associatedEnum() const
The Node class is the base class for all the nodes in QDoc's parse tree.
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.
bool isHeader() const
Returns true if the node type is HeaderFile.
NodeType nodeType() const override
Returns this node's type.
virtual bool isMacro() const
returns true if either FunctionNode::isMacroWithParams() or FunctionNode::isMacroWithoutParams() retu...
bool isEnumType() const
Returns true if the node type is Enum.
Aggregate * parent() const
Returns the node's parent pointer.
bool isProxyNode() const
Returns true if the node type is Proxy.
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
bool isProperty() const
Returns true if the node type is Property.
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
A class for parsing and managing a function parameter list.
const Parameter & at(int i) const