17#include <QtCore/qdebug.h>
18#include <QtCore/qregularexpression.h>
22using namespace Qt::StringLiterals;
25
26
33
34
35
38 QByteArray ext = extension.toLatin1();
39 return ext ==
"c" || ext ==
"c++" || ext ==
"qdoc" || ext ==
"qtt" || ext ==
"qtx"
40 || ext ==
"cc" || ext ==
"cpp" || ext ==
"cxx" || ext ==
"ch" || ext ==
"h"
41 || ext ==
"h++" || ext ==
"hh" || ext ==
"hpp" || ext ==
"hxx";
45
46
49 return lang == QLatin1String(
"C") || lang == QLatin1String(
"Cpp");
53
54
63 return addMarkUp(code, relative, location);
69 const int MaxEnumValues = 6;
76 name = taggedNode(node);
77 if (style != Section::Details)
78 name = linkTag(node, name);
79 name =
"<@name>" + name +
"</@name>";
84 name.prepend(taggedNode(node->parent()) +
"::");
94 synopsis += QLatin1Char(
' ') + name;
99 auto templateDecl = node->templateDecl();
101 synopsis = protect((*templateDecl).to_qstring()) + QLatin1Char(
' ');
103 if (style != Section::AllMembers && !func->returnType().isEmpty())
104 synopsis += typified(func->returnTypeString(),
true);
107 synopsis += QLatin1Char(
'(');
110 for (
int i = 0; i < parameters
.count(); ++i) {
113 QString name = parameters.at(i).name();
114 QString type = parameters.at(i).type();
115 QString value = parameters.at(i).defaultValue();
117 synopsis += typified(type, trailingSpace);
119 synopsis +=
"<@param>" + protect(name) +
"</@param>";
121 synopsis +=
" = " + protect(value);
124 synopsis += QLatin1Char(
')');
127 synopsis +=
" const";
131 synopsis.prepend(
"virtual ");
133 synopsis.append(
" final");
135 synopsis.append(
" override");
137 synopsis.append(
" = 0");
139 synopsis.append(
" &");
141 synopsis.append(
" &&");
143 if (!func->returnType().isEmpty() && func->returnType() !=
"void")
144 synopsis +=
" : " + typified(func->returnTypeString());
147 synopsis.append(
" &");
149 synopsis.append(
" &&");
153 enume =
static_cast<
const EnumNode *>(node);
156 synopsis +=
"class ";
161 QStringList documentedItems = enume->doc().enumItemNames();
162 if (documentedItems.isEmpty()) {
163 const auto &enumItems = enume->items();
164 for (
const auto &item : enumItems)
165 documentedItems << item.name();
167 const QStringList omitItems = enume->doc().omitEnumItemNames();
168 for (
const auto &item : omitItems)
169 documentedItems.removeAll(item);
171 if (documentedItems.size() > MaxEnumValues) {
173 const QString last = documentedItems.last();
174 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
175 documentedItems +=
"…";
176 documentedItems += last;
178 synopsis += documentedItems.join(QLatin1String(
", "));
180 if (!documentedItems.isEmpty())
181 synopsis += QLatin1Char(
' ');
182 synopsis += QLatin1Char(
'}');
187 auto templateDecl = node->templateDecl();
189 synopsis += protect((*templateDecl).to_qstring()) + QLatin1Char(
' ');
199 auto property =
static_cast<
const PropertyNode *>(node);
200 synopsis = name +
" : " + typified(property->qualifiedDataType());
205 synopsis = name +
" : " + typified(property->dataType());
211 synopsis = name +
" : " + typified(variable->dataType());
213 synopsis = typified(variable->leftType(),
true) + name + protect(variable->rightType());
220 QString extra = CodeMarker::extraSynopsis(node, style);
221 if (!extra.isEmpty()) {
222 extra.prepend(u"<@extra>"_s);
223 extra.append(u"</@extra> "_s);
226 return extra + synopsis;
230
233 QString name = taggedQmlNode(node);
237 name = linkTag(node, name);
241 name.prepend(pn->element() + QLatin1Char(
'.'));
243 name =
"<@name>" + name +
"</@name>";
246 synopsis = name +
" : " + typified(pn->dataType());
248 const auto *func =
static_cast<
const FunctionNode *>(node);
249 if (!func->returnType().isEmpty())
250 synopsis = typified(func->returnTypeString(),
true) + name;
253 synopsis += QLatin1Char(
'(');
256 for (
int i = 0; i < parameters
.count(); ++i) {
259 QString name = parameters.at(i).name();
260 QString type = parameters.at(i).type();
262 if (!name.isEmpty()) {
263 synopsis += typified(type,
true);
268 synopsis +=
"<@param>" + protect(paramName) +
"</@param>";
271 synopsis += QLatin1Char(
')');
276 QString extra = CodeMarker::extraSynopsis(node, summary ? Section::Summary : Section::Details);
277 if (!extra.isEmpty()) {
278 extra.prepend(u" <@extra>"_s);
279 extra.append(u"</@extra>"_s);
282 return synopsis + extra;
287 QString name = linkTag(node, taggedNode(node));
299 if (qpn->enumNode() && !enumValue.startsWith(
"%1."_L1.arg(qpn->enumPrefix())))
300 return "%1<@op>.</@op>%2"_L1.arg(qpn->enumPrefix(), enumValue);
309 parts.prepend(markedUpName(node));
315 parts.append(relative->name());
317 parts.append(enumValue);
318 return parts.join(QLatin1String(
"<@op>::</@op>"));
324 static QSet<QString> types{
325 QLatin1String(
"bool"), QLatin1String(
"char"), QLatin1String(
"double"),
326 QLatin1String(
"float"), QLatin1String(
"int"), QLatin1String(
"long"),
327 QLatin1String(
"short"), QLatin1String(
"signed"), QLatin1String(
"unsigned"),
328 QLatin1String(
"uint"), QLatin1String(
"ulong"), QLatin1String(
"ushort"),
329 QLatin1String(
"uchar"), QLatin1String(
"void"), QLatin1String(
"qlonglong"),
330 QLatin1String(
"qulonglong"), QLatin1String(
"qint"), QLatin1String(
"qint8"),
331 QLatin1String(
"qint16"), QLatin1String(
"qint32"), QLatin1String(
"qint64"),
332 QLatin1String(
"quint"), QLatin1String(
"quint8"), QLatin1String(
"quint16"),
333 QLatin1String(
"quint32"), QLatin1String(
"quint64"), QLatin1String(
"qreal"),
334 QLatin1String(
"cond")
337 static QSet<QString> keywords{
338 QLatin1String(
"and"), QLatin1String(
"and_eq"), QLatin1String(
"asm"), QLatin1String(
"auto"),
339 QLatin1String(
"bitand"), QLatin1String(
"bitor"), QLatin1String(
"break"),
340 QLatin1String(
"case"), QLatin1String(
"catch"), QLatin1String(
"class"),
341 QLatin1String(
"compl"), QLatin1String(
"const"), QLatin1String(
"const_cast"),
342 QLatin1String(
"continue"), QLatin1String(
"default"), QLatin1String(
"delete"),
343 QLatin1String(
"do"), QLatin1String(
"dynamic_cast"), QLatin1String(
"else"),
344 QLatin1String(
"enum"), QLatin1String(
"explicit"), QLatin1String(
"export"),
345 QLatin1String(
"extern"), QLatin1String(
"false"), QLatin1String(
"for"),
346 QLatin1String(
"friend"), QLatin1String(
"goto"), QLatin1String(
"if"),
347 QLatin1String(
"include"), QLatin1String(
"inline"), QLatin1String(
"monitor"),
348 QLatin1String(
"mutable"), QLatin1String(
"namespace"), QLatin1String(
"new"),
349 QLatin1String(
"not"), QLatin1String(
"not_eq"), QLatin1String(
"operator"),
350 QLatin1String(
"or"), QLatin1String(
"or_eq"), QLatin1String(
"private"),
351 QLatin1String(
"protected"), QLatin1String(
"public"), QLatin1String(
"register"),
352 QLatin1String(
"reinterpret_cast"), QLatin1String(
"return"), QLatin1String(
"sizeof"),
353 QLatin1String(
"static"), QLatin1String(
"static_cast"), QLatin1String(
"struct"),
354 QLatin1String(
"switch"), QLatin1String(
"template"), QLatin1String(
"this"),
355 QLatin1String(
"throw"), QLatin1String(
"true"), QLatin1String(
"try"),
356 QLatin1String(
"typedef"), QLatin1String(
"typeid"), QLatin1String(
"typename"),
357 QLatin1String(
"union"), QLatin1String(
"using"), QLatin1String(
"virtual"),
358 QLatin1String(
"volatile"), QLatin1String(
"wchar_t"), QLatin1String(
"while"),
359 QLatin1String(
"xor"), QLatin1String(
"xor_eq"), QLatin1String(
"synchronized"),
361 QLatin1String(
"signals"), QLatin1String(
"slots"), QLatin1String(
"emit")
373 static const QRegularExpression classRegExp(QRegularExpression::anchoredPattern(
"Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"));
374 static const QRegularExpression functionRegExp(QRegularExpression::anchoredPattern(
"q([A-Z][a-z]+)+"));
375 static const QRegularExpression findFunctionRegExp(QStringLiteral(
"^\\s*\\("));
378 auto readChar = [&]() {
390 if (ch.isLetter() || ch ==
'_') {
396 }
while (!atEOF && (ch.isLetterOrNumber() || ch ==
'_'));
398 if (classRegExp.match(ident).hasMatch()) {
399 tag = QStringLiteral(
"type");
400 }
else if (functionRegExp.match(ident).hasMatch()) {
401 tag = QStringLiteral(
"func");
403 }
else if (types.contains(ident)) {
404 tag = QStringLiteral(
"type");
405 }
else if (keywords.contains(ident)) {
406 tag = QStringLiteral(
"keyword");
407 }
else if (braceDepth == 0 && parenDepth == 0) {
408 if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
409 tag = QStringLiteral(
"func");
412 }
else if (ch.isDigit()) {
416 }
while (!atEOF && (ch.isLetterOrNumber() || ch ==
'.' || ch ==
'\''));
417 tag = QStringLiteral(
"number");
419 switch (ch.unicode()) {
439 tag = QStringLiteral(
"op");
445 while (!atEOF && ch !=
'"') {
452 tag = QStringLiteral(
"string");
457 while (!atEOF && ch !=
'\n') {
463 tag = QStringLiteral(
"preprocessor");
469 while (!atEOF && ch !=
'\'') {
476 tag = QStringLiteral(
"char");
491 if (!atEOF && ch ==
':') {
494 tag = QStringLiteral(
"op");
500 if (!atEOF && ch ==
'/') {
504 }
while (!atEOF && ch !=
'\n');
505 tag = QStringLiteral(
"comment");
506 }
else if (ch ==
'*') {
507 bool metAster =
false;
508 bool metAsterSlash =
false;
513 while (!metAsterSlash) {
518 else if (metAster && ch ==
'/')
519 metAsterSlash =
true;
525 tag = QStringLiteral(
"comment");
527 tag = QStringLiteral(
"op");
546 text = QStringView{code}.mid(start, finish - start);
549 if (!tag.isEmpty()) {
550 out += QStringLiteral(
"<@");
553 out += QStringLiteral(
" target=\"");
555 out += QStringLiteral(
"()\"");
557 out += QStringLiteral(
">");
560 appendProtectedString(&out, text);
562 if (!tag.isEmpty()) {
563 out += QStringLiteral(
"</@");
565 out += QStringLiteral(
">");
569 if (start < code.size()) {
570 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 isNonvirtual() const
bool isPureVirtual() const
The Location class provides a way to mark a location in a file.
bool isQmlNode() const
Returns true if this node's Genus value is QML.
bool isFunction(Genus g=DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
bool isHeader() const
Returns true if the node type is HeaderFile.
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.
NodeType nodeType() const
Returns this node's type.
bool isProxyNode() const
Returns true if the node type is Proxy.
bool isProperty() const
Returns true if the node type is Property.
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.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
A class for parsing and managing a function parameter list.
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
Combined button and popup list for selecting options.