summaryrefslogtreecommitdiff
path: root/src/qdoc/cppcodemarker.cpp
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2023-04-11 14:38:38 +0200
committerLuca Di Sera <luca.disera@qt.io>2023-04-12 15:06:56 +0200
commit846c860b89ee5fbef4f1db583bd951f8a33e196a (patch)
treef29b0f8ae9c1ab4d796e11e7b72cc56347e8a5e5 /src/qdoc/cppcodemarker.cpp
parent2ba87cd00e6527dbd64f5884f29081bd535605bb (diff)
downloadqttools-846c860b89ee5fbef4f1db583bd951f8a33e196a.tar.gz
QDoc: Move QDoc source files under a further "qdoc" directory
QDoc development under the "qttools" repository is currently performed under the "src/qdoc" directory, which contains all source files and directories relevant to QDoc as direct children. Due to a slow restructuring of how QDoc works, what its dependencies are and certain possible architectural changes, the infrastructure that is expected to be required for the development of QDoc might increase. Some of that infrastructure, which might require some custom effort, is expected to be developed as "independent" "library-like" sub-projects, which QDoc depends on. Albeit developed "independently", such infrastructure would be developed specifically for QDoc and thus should live "adjacent" to it. To allow such a structure a new "qdoc" directory was added under the "src/qdoc" directory. All source files and directory that were previously children of the "src/qdoc" directory were moved under the new "qdoc" directory. This preserves the space for QDoc-related elements and the relative project structure while allowing some space for "adjacent" projects that are intended for QDoc specifically. To support the change, a new "CMakeLists.txt" file was introduced under "src/qdoc", which dispatches to the "CMakeLists.txt" file in the new "src/qdoc/qdoc" directory. QDoc is only built when certain dependencies are found. This is supported through the use of Qt features at the CMake level. The "CMakeLists.txt" file in "src", thus dispatched to the "src/qdoc" directory only when the required features were found. As "independent", "library-like", entities might not have the same requirements as QDoc, the "CMakeLists.txt" file in "src" was modified to always dispatch to the "src/qdoc" directory while the features-check was moved to the new "CMakeLists.txt" files in "src/qdoc", so as to allow non-QDoc but QDoc-specific project to have an independent configuration for building. Certain test projects in "test/auto/qdoc/" depends on QDoc-specific source-files to generate their CMake targets. Those dependencies were generally specified as relative paths. The additional level in the directory structure invalidated the paths and, hence, the relevant "CMakeLists.txt" files for those projects were modified to correctly refer to the new directory structure. Change-Id: I50c7106614428753544eaba5091e1e44d48fd31d Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'src/qdoc/cppcodemarker.cpp')
-rw-r--r--src/qdoc/cppcodemarker.cpp593
1 files changed, 0 insertions, 593 deletions
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
deleted file mode 100644
index 32b14d24b..000000000
--- a/src/qdoc/cppcodemarker.cpp
+++ /dev/null
@@ -1,593 +0,0 @@
-// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "cppcodemarker.h"
-
-#include "access.h"
-#include "enumnode.h"
-#include "functionnode.h"
-#include "namespacenode.h"
-#include "propertynode.h"
-#include "qmlpropertynode.h"
-#include "text.h"
-#include "tree.h"
-#include "typedefnode.h"
-#include "variablenode.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qregularexpression.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- Returns \c true.
- */
-bool CppCodeMarker::recognizeCode(const QString & /* code */)
-{
- return true;
-}
-
-/*!
- Returns \c true if \a ext is any of a list of file extensions
- for the C++ language.
- */
-bool CppCodeMarker::recognizeExtension(const QString &extension)
-{
- QByteArray ext = extension.toLatin1();
- return ext == "c" || ext == "c++" || ext == "qdoc" || ext == "qtt" || ext == "qtx"
- || ext == "cc" || ext == "cpp" || ext == "cxx" || ext == "ch" || ext == "h"
- || ext == "h++" || ext == "hh" || ext == "hpp" || ext == "hxx";
-}
-
-/*!
- Returns \c true if \a lang is either "C" or "Cpp".
- */
-bool CppCodeMarker::recognizeLanguage(const QString &lang)
-{
- return lang == QLatin1String("C") || lang == QLatin1String("Cpp");
-}
-
-/*!
- Returns the type of atom used to represent C++ code in the documentation.
-*/
-Atom::AtomType CppCodeMarker::atomType() const
-{
- return Atom::Code;
-}
-
-QString CppCodeMarker::markedUpCode(const QString &code, const Node *relative,
- const Location &location)
-{
- return addMarkUp(code, relative, location);
-}
-
-QString CppCodeMarker::markedUpSynopsis(const Node *node, const Node * /* relative */,
- Section::Style style)
-{
- const int MaxEnumValues = 6;
- const FunctionNode *func;
- const VariableNode *variable;
- const EnumNode *enume;
- QString synopsis;
- QString name;
-
- name = taggedNode(node);
- if (style != Section::Details)
- name = linkTag(node, name);
- name = "<@name>" + name + "</@name>";
-
- if (style == Section::Details) {
- if (!node->isRelatedNonmember() && !node->isProxyNode() && !node->parent()->name().isEmpty()
- && !node->parent()->isHeader() && !node->isProperty() && !node->isQmlNode()) {
- name.prepend(taggedNode(node->parent()) + "::");
- }
- }
-
- switch (node->nodeType()) {
- case Node::Namespace:
- case Node::Class:
- case Node::Struct:
- case Node::Union:
- synopsis = Node::nodeTypeString(node->nodeType());
- synopsis += QLatin1Char(' ') + name;
- break;
- case Node::Function:
- func = (const FunctionNode *)node;
- if (style == Section::Details) {
- const QString &templateDecl = node->templateDecl();
- if (!templateDecl.isEmpty())
- synopsis = templateDecl + QLatin1Char(' ');
- }
- if (style != Section::AllMembers && !func->returnType().isEmpty())
- synopsis += typified(func->returnType(), true);
- synopsis += name;
- if (!func->isMacroWithoutParams()) {
- synopsis += QLatin1Char('(');
- if (!func->parameters().isEmpty()) {
- const Parameters &parameters = func->parameters();
- for (int i = 0; i < parameters.count(); ++i) {
- if (i > 0)
- synopsis += ", ";
- QString name = parameters.at(i).name();
- QString type = parameters.at(i).type();
- QString value = parameters.at(i).defaultValue();
- bool trailingSpace = style != Section::AllMembers && !name.isEmpty();
- synopsis += typified(type, trailingSpace);
- if (style != Section::AllMembers && !name.isEmpty())
- synopsis += "<@param>" + protect(name) + "</@param>";
- if (style != Section::AllMembers && !value.isEmpty())
- synopsis += " = " + protect(value);
- }
- }
- synopsis += QLatin1Char(')');
- }
- if (func->isConst())
- synopsis += " const";
-
- if (style == Section::Summary || style == Section::Accessors) {
- if (!func->isNonvirtual())
- synopsis.prepend("virtual ");
- if (func->isFinal())
- synopsis.append(" final");
- if (func->isOverride())
- synopsis.append(" override");
- if (func->isPureVirtual())
- synopsis.append(" = 0");
- if (func->isRef())
- synopsis.append(" &");
- else if (func->isRefRef())
- synopsis.append(" &&");
- } else if (style == Section::AllMembers) {
- if (!func->returnType().isEmpty() && func->returnType() != "void")
- synopsis += " : " + typified(func->returnType());
- } else {
- if (func->isRef())
- synopsis.append(" &");
- else if (func->isRefRef())
- synopsis.append(" &&");
- }
- break;
- case Node::Enum:
- enume = static_cast<const EnumNode *>(node);
- synopsis = "enum ";
- if (enume->isScoped())
- synopsis += "class ";
- synopsis += name;
- if (style == Section::Summary) {
- synopsis += " { ";
-
- QStringList documentedItems = enume->doc().enumItemNames();
- if (documentedItems.isEmpty()) {
- const auto &enumItems = enume->items();
- for (const auto &item : enumItems)
- documentedItems << item.name();
- }
- const QStringList omitItems = enume->doc().omitEnumItemNames();
- for (const auto &item : omitItems)
- documentedItems.removeAll(item);
-
- if (documentedItems.size() > MaxEnumValues) {
- // Take the last element and keep it safe, then elide the surplus.
- const QString last = documentedItems.last();
- documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
- documentedItems += "&hellip;";
- documentedItems += last;
- }
- synopsis += documentedItems.join(QLatin1String(", "));
-
- if (!documentedItems.isEmpty())
- synopsis += QLatin1Char(' ');
- synopsis += QLatin1Char('}');
- }
- break;
- case Node::TypeAlias:
- if (style == Section::Details) {
- const QString &templateDecl = node->templateDecl();
- if (!templateDecl.isEmpty())
- synopsis += templateDecl + QLatin1Char(' ');
- }
- synopsis += name;
- break;
- case Node::Typedef:
- if (static_cast<const TypedefNode *>(node)->associatedEnum())
- synopsis = "flags ";
- synopsis += name;
- break;
- case Node::Property: {
- auto property = static_cast<const PropertyNode *>(node);
- synopsis = name + " : " + typified(property->qualifiedDataType());
- break;
- }
- case Node::QmlProperty: {
- auto property = static_cast<const QmlPropertyNode *>(node);
- synopsis = name + " : " + typified(property->dataType());
- break;
- }
- case Node::Variable:
- variable = static_cast<const VariableNode *>(node);
- if (style == Section::AllMembers) {
- synopsis = name + " : " + typified(variable->dataType());
- } else {
- synopsis = typified(variable->leftType(), true) + name + protect(variable->rightType());
- }
- break;
- default:
- synopsis = name;
- }
-
- QString extra = CodeMarker::extraSynopsis(node, style);
- if (!extra.isEmpty()) {
- extra.prepend("<@extra>");
- extra.append("</@extra>");
- }
-
- return extra + synopsis;
-}
-
-/*!
- */
-QString CppCodeMarker::markedUpQmlItem(const Node *node, bool summary)
-{
- QString name = taggedQmlNode(node);
- if (summary) {
- name = linkTag(node, name);
- } else if (node->isQmlProperty()) {
- const auto *pn = static_cast<const QmlPropertyNode *>(node);
- if (pn->isAttached())
- name.prepend(pn->element() + QLatin1Char('.'));
- }
- name = "<@name>" + name + "</@name>";
- QString synopsis;
- if (node->isQmlProperty()) {
- const auto *pn = static_cast<const QmlPropertyNode *>(node);
- synopsis = name + " : " + typified(pn->dataType());
- } else if (node->isFunction(Node::QML)) {
- const auto *func = static_cast<const FunctionNode *>(node);
- if (!func->returnType().isEmpty())
- synopsis = typified(func->returnType(), true) + name;
- else
- synopsis = name;
- synopsis += QLatin1Char('(');
- if (!func->parameters().isEmpty()) {
- const Parameters &parameters = func->parameters();
- for (int i = 0; i < parameters.count(); ++i) {
- if (i > 0)
- synopsis += ", ";
- QString name = parameters.at(i).name();
- QString type = parameters.at(i).type();
- QString paramName;
- if (!name.isEmpty()) {
- synopsis += typified(type, true);
- paramName = name;
- } else {
- paramName = type;
- }
- synopsis += "<@param>" + protect(paramName) + "</@param>";
- }
- }
- synopsis += QLatin1Char(')');
- } else {
- synopsis = name;
- }
-
- QString extra;
- if (summary) {
- if (node->isPreliminary())
- extra += " (preliminary)";
- else if (node->isDeprecated()) {
- if (const QString &version = node->deprecatedSince(); !version.isEmpty())
- extra += " (deprecated since " + version + ")";
- else
- extra += " (deprecated)";
- }
- }
-
- if (!extra.isEmpty()) {
- extra.prepend("<@extra>");
- extra.append("</@extra>");
- }
- return synopsis + extra;
-}
-
-QString CppCodeMarker::markedUpName(const Node *node)
-{
- QString name = linkTag(node, taggedNode(node));
- if (node->isFunction() && !node->isMacro())
- name += "()";
- return name;
-}
-
-QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative)
-{
- if (!relative->isEnumType())
- return enumValue;
-
- const Node *node = relative->parent();
- QStringList parts;
- while (!node->isHeader() && node->parent()) {
- parts.prepend(markedUpName(node));
- if (node->parent() == relative || node->parent()->name().isEmpty())
- break;
- node = node->parent();
- }
- if (static_cast<const EnumNode *>(relative)->isScoped())
- parts.append(relative->name());
-
- parts.append(enumValue);
- return parts.join(QLatin1String("<@op>::</@op>"));
-}
-
-QString CppCodeMarker::markedUpInclude(const QString &include)
-{
- return "<@preprocessor>#include &lt;<@headerfile>" + include + "</@headerfile>&gt;</@preprocessor>";
-}
-
-/*
- @char
- @class
- @comment
- @function
- @keyword
- @number
- @op
- @preprocessor
- @string
- @type
-*/
-
-QString CppCodeMarker::addMarkUp(const QString &in, const Node * /* relative */,
- const Location & /* location */)
-{
- static QSet<QString> types{
- QLatin1String("bool"), QLatin1String("char"), QLatin1String("double"),
- QLatin1String("float"), QLatin1String("int"), QLatin1String("long"),
- QLatin1String("short"), QLatin1String("signed"), QLatin1String("unsigned"),
- QLatin1String("uint"), QLatin1String("ulong"), QLatin1String("ushort"),
- QLatin1String("uchar"), QLatin1String("void"), QLatin1String("qlonglong"),
- QLatin1String("qulonglong"), QLatin1String("qint"), QLatin1String("qint8"),
- QLatin1String("qint16"), QLatin1String("qint32"), QLatin1String("qint64"),
- QLatin1String("quint"), QLatin1String("quint8"), QLatin1String("quint16"),
- QLatin1String("quint32"), QLatin1String("quint64"), QLatin1String("qreal"),
- QLatin1String("cond")
- };
-
- static QSet<QString> keywords{
- QLatin1String("and"), QLatin1String("and_eq"), QLatin1String("asm"), QLatin1String("auto"),
- QLatin1String("bitand"), QLatin1String("bitor"), QLatin1String("break"),
- QLatin1String("case"), QLatin1String("catch"), QLatin1String("class"),
- QLatin1String("compl"), QLatin1String("const"), QLatin1String("const_cast"),
- QLatin1String("continue"), QLatin1String("default"), QLatin1String("delete"),
- QLatin1String("do"), QLatin1String("dynamic_cast"), QLatin1String("else"),
- QLatin1String("enum"), QLatin1String("explicit"), QLatin1String("export"),
- QLatin1String("extern"), QLatin1String("false"), QLatin1String("for"),
- QLatin1String("friend"), QLatin1String("goto"), QLatin1String("if"),
- QLatin1String("include"), QLatin1String("inline"), QLatin1String("monitor"),
- QLatin1String("mutable"), QLatin1String("namespace"), QLatin1String("new"),
- QLatin1String("not"), QLatin1String("not_eq"), QLatin1String("operator"),
- QLatin1String("or"), QLatin1String("or_eq"), QLatin1String("private"),
- QLatin1String("protected"), QLatin1String("public"), QLatin1String("register"),
- QLatin1String("reinterpret_cast"), QLatin1String("return"), QLatin1String("sizeof"),
- QLatin1String("static"), QLatin1String("static_cast"), QLatin1String("struct"),
- QLatin1String("switch"), QLatin1String("template"), QLatin1String("this"),
- QLatin1String("throw"), QLatin1String("true"), QLatin1String("try"),
- QLatin1String("typedef"), QLatin1String("typeid"), QLatin1String("typename"),
- QLatin1String("union"), QLatin1String("using"), QLatin1String("virtual"),
- QLatin1String("volatile"), QLatin1String("wchar_t"), QLatin1String("while"),
- QLatin1String("xor"), QLatin1String("xor_eq"), QLatin1String("synchronized"),
- // Qt specific
- QLatin1String("signals"), QLatin1String("slots"), QLatin1String("emit")
- };
-
- QString code = in;
- QString out;
- QStringView text;
- int braceDepth = 0;
- int parenDepth = 0;
- int i = 0;
- int start = 0;
- int finish = 0;
- QChar ch;
- static const QRegularExpression classRegExp(QRegularExpression::anchoredPattern("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"));
- static const QRegularExpression functionRegExp(QRegularExpression::anchoredPattern("q([A-Z][a-z]+)+"));
- static const QRegularExpression findFunctionRegExp(QStringLiteral("^\\s*\\("));
- bool atEOF = false;
-
- auto readChar = [&]() {
- if (i < code.size())
- ch = code[i++];
- else
- atEOF = true;
- };
-
- readChar();
- while (!atEOF) {
- QString tag;
- bool target = false;
-
- if (ch.isLetter() || ch == '_') {
- QString ident;
- do {
- ident += ch;
- finish = i;
- readChar();
- } while (!atEOF && (ch.isLetterOrNumber() || ch == '_'));
-
- if (classRegExp.match(ident).hasMatch()) {
- tag = QStringLiteral("type");
- } else if (functionRegExp.match(ident).hasMatch()) {
- tag = QStringLiteral("func");
- target = true;
- } else if (types.contains(ident)) {
- tag = QStringLiteral("type");
- } else if (keywords.contains(ident)) {
- tag = QStringLiteral("keyword");
- } else if (braceDepth == 0 && parenDepth == 0) {
- if (code.indexOf(findFunctionRegExp, i - 1) == i - 1)
- tag = QStringLiteral("func");
- target = true;
- }
- } else if (ch.isDigit()) {
- do {
- finish = i;
- readChar();
- } while (!atEOF && (ch.isLetterOrNumber() || ch == '.' || ch == '\''));
- tag = QStringLiteral("number");
- } else {
- switch (ch.unicode()) {
- case '+':
- case '-':
- case '!':
- case '%':
- case '^':
- case '&':
- case '*':
- case ',':
- case '.':
- case '<':
- case '=':
- case '>':
- case '?':
- case '[':
- case ']':
- case '|':
- case '~':
- finish = i;
- readChar();
- tag = QStringLiteral("op");
- break;
- case '"':
- finish = i;
- readChar();
-
- while (!atEOF && ch != '"') {
- if (ch == '\\')
- readChar();
- readChar();
- }
- finish = i;
- readChar();
- tag = QStringLiteral("string");
- break;
- case '#':
- finish = i;
- readChar();
- while (!atEOF && ch != '\n') {
- if (ch == '\\')
- readChar();
- finish = i;
- readChar();
- }
- tag = QStringLiteral("preprocessor");
- break;
- case '\'':
- finish = i;
- readChar();
-
- while (!atEOF && ch != '\'') {
- if (ch == '\\')
- readChar();
- readChar();
- }
- finish = i;
- readChar();
- tag = QStringLiteral("char");
- break;
- case '(':
- finish = i;
- readChar();
- ++parenDepth;
- break;
- case ')':
- finish = i;
- readChar();
- --parenDepth;
- break;
- case ':':
- finish = i;
- readChar();
- if (!atEOF && ch == ':') {
- finish = i;
- readChar();
- tag = QStringLiteral("op");
- }
- break;
- case '/':
- finish = i;
- readChar();
- if (!atEOF && ch == '/') {
- do {
- finish = i;
- readChar();
- } while (!atEOF && ch != '\n');
- tag = QStringLiteral("comment");
- } else if (ch == '*') {
- bool metAster = false;
- bool metAsterSlash = false;
-
- finish = i;
- readChar();
-
- while (!metAsterSlash) {
- if (atEOF)
- break;
- if (ch == '*')
- metAster = true;
- else if (metAster && ch == '/')
- metAsterSlash = true;
- else
- metAster = false;
- finish = i;
- readChar();
- }
- tag = QStringLiteral("comment");
- } else {
- tag = QStringLiteral("op");
- }
- break;
- case '{':
- finish = i;
- readChar();
- braceDepth++;
- break;
- case '}':
- finish = i;
- readChar();
- braceDepth--;
- break;
- default:
- finish = i;
- readChar();
- }
- }
-
- text = QStringView{code}.mid(start, finish - start);
- start = finish;
-
- if (!tag.isEmpty()) {
- out += QStringLiteral("<@");
- out += tag;
- if (target) {
- out += QStringLiteral(" target=\"");
- out += text;
- out += QStringLiteral("()\"");
- }
- out += QStringLiteral(">");
- }
-
- appendProtectedString(&out, text);
-
- if (!tag.isEmpty()) {
- out += QStringLiteral("</@");
- out += tag;
- out += QStringLiteral(">");
- }
- }
-
- if (start < code.size()) {
- appendProtectedString(&out, QStringView{code}.mid(start));
- }
-
- return out;
-}
-
-QT_END_NAMESPACE