diff options
author | Liang Qi <liang.qi@qt.io> | 2019-10-14 13:55:50 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-14 14:48:20 +0200 |
commit | 1c1b386a41d00e9b0f386667737ee8e2b8affe97 (patch) | |
tree | 237b466d13ea2bac49b04bd3ee8b26f21af7a717 | |
parent | e4177a8db1144f52d71df7ebab2e6755ae21fb01 (diff) | |
parent | 8ed4ee82552ec61f657b2b681002c5d7813e6e76 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
src/linguist/lupdate/cpp_clang.cpp
src/linguist/lupdate/cpp_clang.h
src/linguist/lupdate/main.cpp
src/qdoc/qdoc.pro
src/windeployqt/main.cpp
Change-Id: I467e502a6186d9e6b7fc92b652de89f296740e5d
60 files changed, 1079 insertions, 618 deletions
diff --git a/dist/changes-5.12.5 b/dist/changes-5.12.5 new file mode 100644 index 000000000..379f39064 --- /dev/null +++ b/dist/changes-5.12.5 @@ -0,0 +1,37 @@ +Qt 5.12.5 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.4. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* distancefieldgenerator * +**************************************************************************** + + - [QTBUG-76188] Fixed bug where the tool would fail for valid fonts with + the message "end of cmap table reached when parsing subtable". + - [QTBUG-76528] Fixed a bug where the generated textures might exceed the + maximum height. + - [QTBUG-76188][QTBUG-76528] Fixed possible crash when generating large + number of glyphs with a small texture size. + - [QTBUG-77501] Fixed broken text rendering when generating large glyph + sets. + +**************************************************************************** +* Qt Help * +**************************************************************************** + + - [QDS-779] Fixed possible application freeze when using QtHelp module. diff --git a/dist/changes-5.13.1 b/dist/changes-5.13.1 new file mode 100644 index 000000000..557d7021f --- /dev/null +++ b/dist/changes-5.13.1 @@ -0,0 +1,29 @@ +Qt 5.13.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* distancefieldgenerator * +**************************************************************************** + + - [QTBUG-76188] Fixed bug where the tool would fail for valid fonts with + the message "end of cmap table reached when parsing subtable". + - [QTBUG-76528] Fixed a bug where the generated textures might exceed the + maximum height. + - [QTBUG-76188][QTBUG-76528] Fixed possible crash when generating large + number of glyphs with a small texture size. diff --git a/src/assistant/assistant/aboutdialog.cpp b/src/assistant/assistant/aboutdialog.cpp index f5a38101d..774b6fd4b 100644 --- a/src/assistant/assistant/aboutdialog.cpp +++ b/src/assistant/assistant/aboutdialog.cpp @@ -37,7 +37,6 @@ #include <QtWidgets/QPushButton> #include <QtWidgets/QLayout> #include <QtWidgets/QApplication> -#include <QtWidgets/QDesktopWidget> #include <QtWidgets/QMessageBox> #include <QtGui/QDesktopServices> #include <QtGui/QScreen> diff --git a/src/assistant/assistant/mainwindow.cpp b/src/assistant/assistant/mainwindow.cpp index fc5fe5b3f..a6b257eb7 100644 --- a/src/assistant/assistant/mainwindow.cpp +++ b/src/assistant/assistant/mainwindow.cpp @@ -60,7 +60,6 @@ #include <QtWidgets/QAction> #include <QtWidgets/QComboBox> -#include <QtWidgets/QDesktopWidget> #include <QtWidgets/QDockWidget> #include <QtGui/QFontDatabase> #include <QtGui/QImageReader> diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp index 464d7f618..cc0f78e38 100644 --- a/src/designer/src/components/formeditor/formwindow.cpp +++ b/src/designer/src/components/formeditor/formwindow.cpp @@ -684,6 +684,7 @@ bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e) const bool blocked = blockSelectionChanged(true); QWidgetList sel = selectedWidgets(); + const QWidgetList originalSelection = sel; simplifySelection(&sel); QSet<QWidget*> widget_set; @@ -733,6 +734,11 @@ bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e) } } + // In case when we have reduced the selection (by calling simplifySelection() + // beforehand) we still need to hide selection handles for children widgets + for (auto *widget : originalSelection) + m_selection->hide(widget); + blockSelectionChanged(blocked); if (!sel.empty()) // reshow selection? diff --git a/src/designer/src/components/formeditor/formwindowmanager.cpp b/src/designer/src/components/formeditor/formwindowmanager.cpp index d1edb231c..73b315889 100644 --- a/src/designer/src/components/formeditor/formwindowmanager.cpp +++ b/src/designer/src/components/formeditor/formwindowmanager.cpp @@ -71,7 +71,6 @@ #endif #include <QtWidgets/qmdiarea.h> #include <QtWidgets/qmdisubwindow.h> -#include <QtWidgets/qdesktopwidget.h> #include <QtWidgets/qmessagebox.h> #include <QtCore/qdebug.h> diff --git a/src/designer/src/designer/qdesigner_settings.cpp b/src/designer/src/designer/qdesigner_settings.cpp index 8ac61c52a..e8ac4be54 100644 --- a/src/designer/src/designer/qdesigner_settings.cpp +++ b/src/designer/src/designer/qdesigner_settings.cpp @@ -40,7 +40,6 @@ #include <QtCore/qvariant.h> #include <QtCore/qdir.h> -#include <QtWidgets/qdesktopwidget.h> #include <QtWidgets/qstyle.h> #include <QtWidgets/qlistview.h> diff --git a/src/designer/src/designer/qdesigner_workbench.cpp b/src/designer/src/designer/qdesigner_workbench.cpp index f2a8b5d1c..498b0a7d7 100644 --- a/src/designer/src/designer/qdesigner_workbench.cpp +++ b/src/designer/src/designer/qdesigner_workbench.cpp @@ -58,7 +58,6 @@ #include <QtWidgets/qactiongroup.h> #include <QtGui/qevent.h> #include <QtGui/qscreen.h> -#include <QtWidgets/qdesktopwidget.h> #include <QtWidgets/qdockwidget.h> #include <QtWidgets/qmenu.h> #include <QtWidgets/qmenubar.h> @@ -569,9 +568,9 @@ QRect QDesignerWorkbench::desktopGeometry() const case NeutralMode: break; } - const int screenNumber = widget ? QApplication::desktop()->screenNumber(widget) : 0; - auto screen = QGuiApplication::screens().value(screenNumber, QGuiApplication::primaryScreen()); - return screen->availableGeometry(); + const auto screen = widget ? widget->screen() : QGuiApplication::primaryScreen(); + return screen ? screen->availableGeometry() + : QGuiApplication::primaryScreen()->availableGeometry(); } QRect QDesignerWorkbench::availableGeometry() const @@ -579,9 +578,8 @@ QRect QDesignerWorkbench::availableGeometry() const if (m_mode == DockedMode) return m_dockedMainWindow->mdiArea()->geometry(); - const int screenNumber = QApplication::desktop()->screenNumber(widgetBoxToolWindow()); - auto screen = QGuiApplication::screens().value(screenNumber, QGuiApplication::primaryScreen()); - return screen->availableGeometry(); + const auto screen = widgetBoxToolWindow()->screen(); + return screen ? screen->availableGeometry() : QGuiApplication::primaryScreen()->availableGeometry() ; } int QDesignerWorkbench::marginHint() const diff --git a/src/designer/src/lib/sdk/abstractnewformwidget.h b/src/designer/src/lib/sdk/abstractnewformwidget.h index 35d8efe00..8805097bb 100644 --- a/src/designer/src/lib/sdk/abstractnewformwidget.h +++ b/src/designer/src/lib/sdk/abstractnewformwidget.h @@ -39,7 +39,7 @@ class QDesignerFormEditorInterface; class QDESIGNER_SDK_EXPORT QDesignerNewFormWidgetInterface : public QWidget { - Q_DISABLE_COPY_MOVE(QDesignerNewFormWidgetInterface) + Q_DISABLE_COPY(QDesignerNewFormWidgetInterface) Q_OBJECT public: explicit QDesignerNewFormWidgetInterface(QWidget *parent = nullptr); diff --git a/src/designer/src/lib/sdk/propertysheet.qdoc b/src/designer/src/lib/sdk/propertysheet.qdoc index 4e0ccddf2..e5ab420f4 100644 --- a/src/designer/src/lib/sdk/propertysheet.qdoc +++ b/src/designer/src/lib/sdk/propertysheet.qdoc @@ -68,17 +68,24 @@ also provides an interface for creating custom property sheet extensions. - \warning \QD uses the QDesignerPropertySheetExtension to feed its - property editor. Whenever a widget is selected in its workspace, - \QD will query for the widget's property sheet extension. If the - selected widget has an implemented property sheet extension, this - extension will override the default property sheet. - - \warning The data types used by the property sheet for some properties - are opaque custom QVariant types containing additional information - instead of plain Qt data types. - For example, this is the case for enumerations, flags, - icons, pixmaps and strings. + Keep the following limitations in mind: + + \list + \li \QD uses the QDesignerPropertySheetExtension to feed its + property editor. Whenever a widget is selected in its workspace, + \QD will query for the widget's property sheet extension. If the + selected widget has an implemented property sheet extension, this + extension will override the default property sheet. + + \li The data types used by the property sheet for some properties + are opaque custom QVariant types containing additional information + instead of plain Qt data types. For example, this is the case for + enumerations, flags, icons, pixmaps and strings. + + \li \QD's property editor has no implementation for handling + Q_PROPERTY types for custom types that have been declared + with Q_DECLARE_METATYPE(). + \endlist To create a property sheet extension, your extension class must inherit from both QObject and diff --git a/src/designer/src/lib/shared/widgetdatabase.cpp b/src/designer/src/lib/shared/widgetdatabase.cpp index 1a9297e73..5fecd4c98 100644 --- a/src/designer/src/lib/shared/widgetdatabase.cpp +++ b/src/designer/src/lib/shared/widgetdatabase.cpp @@ -601,22 +601,22 @@ static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const // Generate default standard ui new form xml based on the class passed on as similarClassName. static QString generateNewFormXML(const QString &className, const QString &similarClassName, const QString &name) { - QString rc; { - QTextStream str(&rc); - str << QStringLiteral("<ui version=\"4.0\" >\n<class>") << name << QStringLiteral("</class>\n") - << QStringLiteral("<widget class=\"") << className << QStringLiteral("\" name=\"") << name << QStringLiteral("\" >\n") - << QStringLiteral("<property name=\"geometry\" >\n<rect><x>0</x><y>0</y><width>") - << NewFormWidth << QStringLiteral("</width><height>") << NewFormHeight << QStringLiteral("</height></rect>\n</property>\n"); - str << QStringLiteral("<property name=\"windowTitle\" >\n<string>") << name << QStringLiteral("</string>\n</property>\n"); - - if (similarClassName == QStringLiteral("QMainWindow")) { - str << QStringLiteral("<widget class=\"QWidget\" name=\"centralwidget\" />\n"); - } else { - if (similarClassName == QStringLiteral("QWizard")) - str << QStringLiteral("<widget class=\"QWizardPage\" name=\"wizardPage1\" /><widget class=\"QWizardPage\" name=\"wizardPage2\" />\n"); - } - str << QStringLiteral("</widget>\n</ui>\n"); + QString rc; + QTextStream str(&rc); + str << R"(<ui version="4.0"><class>)" << name << "</class>" + << R"(<widget class=")" << className << R"(" name=")" << name << R"(">)" + << R"(<property name="geometry" ><rect><x>0</x><y>0</y><width>)" + << NewFormWidth << "</width><height>" << NewFormHeight << "</height></rect></property>" + << R"(<property name="windowTitle"><string>)" << name << "</string></property>\n"; + + if (similarClassName == QLatin1String("QMainWindow")) { + str << R"(<widget class="QWidget" name="centralwidget"/>)"; + } else if (similarClassName == QLatin1String("QWizard")) { + str << R"(<widget class="QWizardPage" name="wizardPage1"/><widget class="QWizardPage" name="wizardPage2"/>)"; + } else if (similarClassName == QLatin1String("QDockWidget")) { + str << R"(<widget class="QWidget" name="dockWidgetContents"/>)"; } + str << "</widget></ui>\n"; return rc; } diff --git a/src/distancefieldgenerator/mainwindow.cpp b/src/distancefieldgenerator/mainwindow.cpp index ee4475ada..6bc793ede 100644 --- a/src/distancefieldgenerator/mainwindow.cpp +++ b/src/distancefieldgenerator/mainwindow.cpp @@ -693,18 +693,25 @@ void MainWindow::updateUnicodeRanges() this, &MainWindow::updateSelection); + QItemSelection selectedItems; + for (int i = 0; i < ui->lwUnicodeRanges->count(); ++i) { QListWidgetItem *item = ui->lwUnicodeRanges->item(i); - DistanceFieldModel::UnicodeRange unicodeRange = item->data(Qt::UserRole).value<DistanceFieldModel::UnicodeRange>(); - QList<glyph_t> glyphIndexes = m_model->glyphIndexesForUnicodeRange(unicodeRange); - for (glyph_t glyphIndex : glyphIndexes) { - QModelIndex index = m_model->index(glyphIndex); - ui->lvGlyphs->selectionModel()->select(index, item->isSelected() - ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect); + if (item->isSelected()) { + DistanceFieldModel::UnicodeRange unicodeRange = item->data(Qt::UserRole).value<DistanceFieldModel::UnicodeRange>(); + QList<glyph_t> glyphIndexes = m_model->glyphIndexesForUnicodeRange(unicodeRange); + + for (glyph_t glyphIndex : glyphIndexes) { + QModelIndex index = m_model->index(glyphIndex); + selectedItems.select(index, index); + } } } + ui->lvGlyphs->selectionModel()->clearSelection(); + if (!selectedItems.isEmpty()) + ui->lvGlyphs->selectionModel()->select(selectedItems, QItemSelectionModel::Select); + connect(ui->lvGlyphs->selectionModel(), &QItemSelectionModel::selectionChanged, this, diff --git a/src/linguist/linguist/main.cpp b/src/linguist/linguist/main.cpp index 0b549b6e0..8f8bdb134 100644 --- a/src/linguist/linguist/main.cpp +++ b/src/linguist/linguist/main.cpp @@ -32,13 +32,10 @@ #include <QtCore/QFile> #include <QtCore/QLibraryInfo> #include <QtCore/QLocale> -#include <QtCore/QSettings> #include <QtCore/QTranslator> #include <QtWidgets/QApplication> -#include <QtWidgets/QDesktopWidget> #include <QtGui/QPixmap> -#include <QtWidgets/QSplashScreen> #ifdef Q_OS_MAC #include <QtCore/QUrl> @@ -134,28 +131,11 @@ int main(int argc, char **argv) app.setOrganizationName(QLatin1String("QtProject")); app.setApplicationName(QLatin1String("Linguist")); - QSettings config; - - QWidget tmp; - tmp.restoreGeometry(config.value(settingPath("Geometry/WindowGeometry")).toByteArray()); - - QSplashScreen *splash = 0; - int screenId = QApplication::desktop()->screenNumber(tmp.geometry().center()); - splash = new QSplashScreen(QApplication::desktop()->screen(screenId), - QPixmap(QLatin1String(":/images/icons/linguist-128-32.png"))); - if (QApplication::desktop()->isVirtualDesktop()) { - QRect srect(0, 0, splash->width(), splash->height()); - splash->move(QApplication::desktop()->availableGeometry(screenId).center() - srect.center()); - } - splash->setAttribute(Qt::WA_DeleteOnClose); - splash->show(); - MainWindow mw; #ifdef Q_OS_MAC eventFilter.setMainWindow(&mw); #endif // Q_OS_MAC mw.show(); - splash->finish(&mw); QApplication::restoreOverrideCursor(); mw.openFiles(files, true); diff --git a/src/linguist/lupdate/lupdate.pro b/src/linguist/lupdate/lupdate.pro index fcbb65d64..8f1826eee 100644 --- a/src/linguist/lupdate/lupdate.pro +++ b/src/linguist/lupdate/lupdate.pro @@ -45,7 +45,6 @@ qtHaveModule(qmldevtools-private): SOURCES += qdeclarative.cpp HEADERS += \ lupdate.h \ cpp.h \ - cpp_clang.h \ ../shared/projectdescriptionreader.h \ ../shared/qrcreader.h \ ../shared/runqttool.h \ diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp index 0c33308ef..6c4e3db9c 100644 --- a/src/linguist/lupdate/main.cpp +++ b/src/linguist/lupdate/main.cpp @@ -282,7 +282,6 @@ static void printUsage() " Specify the output file(s). This will override the TRANSLATIONS.\n" " -version\n" " Display the version of lupdate and exit.\n" -#if QT_CONFIG(clangcpp) " -clang-parser \n" " Use clang to parse cpp files. Otherwise a custom parser is used.\n" " Need a compile_commands.json for the files that needs to be parsed.\n" @@ -290,7 +289,6 @@ static void printUsage() " under LUPDATE_COMPILE_COMMANDS_PATH.\n" " If no path is given search for compile_commands.json will be attempted\n" " through all parent paths of the first input file.\n" -#endif " @lst-file\n" " Read additional file names (one per line) or includepaths (one per\n" " line, and prefixed with -I) from lst-file.\n" diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp index 216bc8329..7a453aa32 100644 --- a/src/linguist/lupdate/qdeclarative.cpp +++ b/src/linguist/lupdate/qdeclarative.cpp @@ -108,6 +108,10 @@ protected: yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); return; } + if (AST::cast<AST::TemplateLiteral *>(node->arguments->expression)) { + yyMsg(identLineNo) << qPrintable(LU::tr("%1() cannot be used with template literals. Ignoring\n").arg(name)); + return; + } QString source; if (!createString(node->arguments->expression, &source)) diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp index aebe13df1..adcfb6a38 100644 --- a/src/pixeltool/qpixeltool.cpp +++ b/src/pixeltool/qpixeltool.cpp @@ -538,7 +538,7 @@ void QPixelTool::grabScreen() const QBrush darkBrush = palette().color(QPalette::Dark); const QDesktopWidget *desktopWidget = QApplication::desktop(); - if (QScreen *screen = QGuiApplication::screens().value(desktopWidget->screenNumber(this), nullptr)) { + if (QScreen *screen = this->screen()) { m_buffer = screen->grabWindow(desktopWidget->winId(), x, y, w, h); } else { m_buffer = QPixmap(w, h); diff --git a/src/qdoc/atom.cpp b/src/qdoc/atom.cpp index a739b0b69..dff90b299 100644 --- a/src/qdoc/atom.cpp +++ b/src/qdoc/atom.cpp @@ -399,28 +399,28 @@ void LinkAtom::resolveSquareBracketParams() { if (resolved_) return; - QStringList params = squareBracketParams_.toLower().split(QLatin1Char(' ')); - foreach (const QString &p, params) { + const QStringList params = squareBracketParams_.toLower().split(QLatin1Char(' ')); + for (const auto ¶m : params) { if (!domain_) { - domain_ = QDocDatabase::qdocDB()->findTree(p); + domain_ = QDocDatabase::qdocDB()->findTree(param); if (domain_) { continue; } } if (goal_ == Node::NoType) { - goal_ = Node::goal(p); + goal_ = Node::goal(param); if (goal_ != Node::NoType) continue; } - if (p == "qml") { + if (param == "qml") { genus_ = Node::QML; continue; } - if (p == "cpp") { + if (param == "cpp") { genus_ = Node::CPP; continue; } - if (p == "doc") { + if (param == "doc") { genus_ = Node::DOC; continue; } diff --git a/src/qdoc/codemarker.cpp b/src/qdoc/codemarker.cpp index 2579c94e1..7c8843c65 100644 --- a/src/qdoc/codemarker.cpp +++ b/src/qdoc/codemarker.cpp @@ -369,10 +369,11 @@ QStringList CodeMarker::macRefsForNode(Node *node) { QStringList stringList; stringList << encode(result + QLatin1String("tag/") + macName(node)); - foreach (const QString &enumName, node->doc().enumItemNames()) { + const auto enumItemNames = node->doc().enumItemNames(); + for (const auto &name : enumItemNames) { // ### Write a plainEnumValue() and use it here stringList << encode(result + QLatin1String("econst/") + - macName(node->parent(), enumName)); + macName(node->parent(), name)); } return stringList; } @@ -412,9 +413,9 @@ QStringList CodeMarker::macRefsForNode(Node *node) break; case Node::Property: { - NodeList list = static_cast<const PropertyNode *>(node)->functions(); + const NodeList list = static_cast<const PropertyNode *>(node)->functions(); QStringList stringList; - foreach (Node *node, list) { + for (auto *node : list) { stringList += macRefsForNode(node); } return stringList; diff --git a/src/qdoc/codeparser.cpp b/src/qdoc/codeparser.cpp index a3c93ca4c..99bd5b1c8 100644 --- a/src/qdoc/codeparser.cpp +++ b/src/qdoc/codeparser.cpp @@ -98,11 +98,8 @@ void CodeParser::parseHeaderFile(const Location &location, const QString &filePa */ void CodeParser::initialize(const Config &config) { - QList<CodeParser *>::ConstIterator p = parsers.constBegin(); - while (p != parsers.constEnd()) { - (*p)->initializeParser(config); - ++p; - } + for (const auto &parser : qAsConst(parsers)) + parser->initializeParser(config); } /*! @@ -110,20 +107,15 @@ void CodeParser::initialize(const Config &config) */ void CodeParser::terminate() { - QList<CodeParser *>::ConstIterator p = parsers.constBegin(); - while (p != parsers.constEnd()) { - (*p)->terminateParser(); - ++p; - } + for (const auto parser : parsers) + parser->terminateParser(); } CodeParser *CodeParser::parserForLanguage(const QString &language) { - QList<CodeParser *>::ConstIterator p = parsers.constBegin(); - while (p != parsers.constEnd()) { - if ((*p)->language() == language) - return *p; - ++p; + for (const auto parser : qAsConst(parsers)) { + if (parser->language() == language) + return parser; } return nullptr; } @@ -132,16 +124,13 @@ CodeParser *CodeParser::parserForHeaderFile(const QString &filePath) { QString fileName = QFileInfo(filePath).fileName(); - QList<CodeParser *>::ConstIterator p = parsers.constBegin(); - while (p != parsers.constEnd()) { - - QStringList headerPatterns = (*p)->headerFileNameFilter(); - foreach (const QString &pattern, headerPatterns) { + for (const auto &parser : qAsConst(parsers)) { + const QStringList headerPatterns = parser->headerFileNameFilter(); + for (const auto &pattern : headerPatterns) { QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard); if (re.exactMatch(fileName)) - return *p; + return parser; } - ++p; } return nullptr; } @@ -150,16 +139,13 @@ CodeParser *CodeParser::parserForSourceFile(const QString &filePath) { QString fileName = QFileInfo(filePath).fileName(); - QList<CodeParser *>::ConstIterator p = parsers.constBegin(); - while (p != parsers.constEnd()) { - - QStringList sourcePatterns = (*p)->sourceFileNameFilter(); - foreach (const QString &pattern, sourcePatterns) { + for (const auto &parser : parsers) { + const QStringList sourcePatterns = parser->sourceFileNameFilter(); + for (const QString &pattern : sourcePatterns) { QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard); if (re.exactMatch(fileName)) - return *p; + return parser; } - ++p; } return nullptr; } diff --git a/src/qdoc/config.cpp b/src/qdoc/config.cpp index 0d3a5e945..7b96ebdd7 100644 --- a/src/qdoc/config.cpp +++ b/src/qdoc/config.cpp @@ -266,13 +266,33 @@ QMap<QString, QStringList> Config::includeFilesMap_; Config::Config(const QString &programName) : prog(programName) { - loc = Location::null; - lastLocation_ = Location::null; - configVars_.clear(); numInstances++; + reset(); +} + +Config::~Config() +{ + clear(); +} + +/*! + Clears the location and internal maps for config variables. + */ +void Config::clear() +{ + loc = lastLocation_ = Location::null; + configVars_.clear(); includeFilesMap_.clear(); +} - // Default values: +/*! + Resets the Config instance - used by load() + */ +void Config::reset() +{ + clear(); + + // Default values setStringList(CONFIG_CODEINDENT, QStringList("0")); setStringList(CONFIG_FALSEHOODS, QStringList("0")); setStringList(CONFIG_FILEEXTENSIONS, QStringList("*.cpp *.h *.qdoc *.qml")); @@ -282,24 +302,17 @@ Config::Config(const QString &programName) } /*! - The destructor has nothing special to do. - */ -Config::~Config() -{ - includeFilesMap_.clear(); -} - -/*! Loads and parses the qdoc configuration file \a fileName. - This function calls the other load() function, which does - the loading, parsing, and processing of the configuration - file. + This function first resets the Config instance, then + calls the other load() function, which does the loading, + parsing, and processing of the configuration file. Intializes the location variables returned by location() and lastLocation(). */ void Config::load(const QString &fileName) { + reset(); load(Location::null, fileName); if (loc.isEmpty()) loc = Location(fileName); @@ -309,16 +322,35 @@ void Config::load(const QString &fileName) } /*! - Joins all the strings in \a values into a single string with the - individual \a values separated by ' '. Then it inserts the result - into the string list map with \a var as the key. - - It also inserts the \a values string list into a separate map, - also with \a var as the key. + Sets the \a values of a configuration variable \a var from a string list. */ void Config::setStringList(const QString &var, const QStringList &values) { - configVars_.insert(var,ConfigVar(var, values, QDir::currentPath())); + configVars_.replace(var, ConfigVar(var, values, QDir::currentPath())); +} + +/*! + Adds the \a values from a string list to the configuration variable \a var. + Existing value(s) are kept. +*/ +void Config::insertStringList(const QString &var, const QStringList &values) +{ + configVars_.insert(var, ConfigVar(var, values, QDir::currentPath())); +} + +/*! + Set configuration options from \a qdocGlobals. + */ +void Config::setOptions(const QDocGlobals &qdocGlobals) +{ + setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(qdocGlobals.highlighting() ? "true" : "false")); + setStringList(CONFIG_SHOWINTERNAL, QStringList(qdocGlobals.showInternal() ? "true" : "false")); + setStringList(CONFIG_SINGLEEXEC, QStringList(qdocGlobals.singleExec() ? "true" : "false")); + setStringList(CONFIG_WRITEQAPAGES, QStringList(qdocGlobals.writeQaPages() ? "true" : "false")); + setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(qdocGlobals.redirectDocumentationToDevNull() ? "true" : "false")); + setStringList(CONFIG_NOLINKERRORS, QStringList(qdocGlobals.noLinkErrors() ? "true" : "false")); + setStringList(CONFIG_AUTOLINKERRORS, QStringList(qdocGlobals.autolinkErrors() ? "true" : "false")); + setStringList(CONFIG_OBSOLETELINKS, QStringList(qdocGlobals.obsoleteLinks() ? "true" : "false")); } /*! diff --git a/src/qdoc/config.h b/src/qdoc/config.h index e01e1fa6c..615387f73 100644 --- a/src/qdoc/config.h +++ b/src/qdoc/config.h @@ -35,6 +35,7 @@ #include "location.h" #include "qdoccommandlineparser.h" +#include "qdocglobals.h" #include <QtCore/qmap.h> #include <QtCore/qpair.h> @@ -79,9 +80,13 @@ public: bool getDebug() const { return debug_; } + void clear(); + void reset(); void load(const QString &fileName); void setStringList(const QString &var, const QStringList &values); + void insertStringList(const QString &var, const QStringList &values); + void setOptions(const QDocGlobals &qdocGlobals); void setOptions(const QDocCommandLineParser &parser); const QString &programName() const { return prog; } const Location &location() const { return loc; } diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp index 325130399..a59654cfa 100644 --- a/src/qdoc/cppcodemarker.cpp +++ b/src/qdoc/cppcodemarker.cpp @@ -133,8 +133,13 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, name = "<@name>" + name + "</@name>"; if (style == Section::Details) { - if (!node->parent()->name().isEmpty() && !node->parent()->isHeader() && - !node->isProperty() && !node->isQmlNode() && !node->isJsNode()) + if (!node->isRelatedNonmember() && + !node->isProxyNode() && + !node->parent()->name().isEmpty() && + !node->parent()->isHeader() && + !node->isProperty() && + !node->isQmlNode() && + !node->isJsNode()) name.prepend(taggedNode(node->parent()) + "::"); } @@ -240,11 +245,12 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, QStringList documentedItems = enume->doc().enumItemNames(); if (documentedItems.isEmpty()) { - foreach (const EnumItem &item, enume->items()) + const auto enumItems = enume->items(); + for (const auto &item : enumItems) documentedItems << item.name(); } - QStringList omitItems = enume->doc().omitEnumItemNames(); - foreach (const QString &item, omitItems) + const QStringList omitItems = enume->doc().omitEnumItemNames(); + for (const auto &item : omitItems) documentedItems.removeAll(item); if (documentedItems.size() <= MaxEnumValues) { diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp index af0d9bd9b..47f3f52a6 100644 --- a/src/qdoc/cppcodeparser.cpp +++ b/src/qdoc/cppcodeparser.cpp @@ -911,12 +911,10 @@ void CppCodeParser::setExampleFileLists(PageNode *pn) exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro *.qmlproject qmldir"); } - int i = 0; - foreach (const QString &exampleFile, exampleFiles) - exampleFiles[i++] = exampleFile.mid(sizeOfBoringPartOfName); - i = 0; - foreach (const QString &imageFile, imageFiles) - imageFiles[i++] = imageFile.mid(sizeOfBoringPartOfName); + for (auto &file : exampleFiles) + file = file.mid(sizeOfBoringPartOfName); + for (auto &file : imageFiles) + file = file.mid(sizeOfBoringPartOfName); ExampleNode *en = static_cast<ExampleNode *>(pn); en->setFiles(exampleFiles); en->setImages(imageFiles); diff --git a/src/qdoc/doc.cpp b/src/qdoc/doc.cpp index 536fe8764..90799bd8c 100644 --- a/src/qdoc/doc.cpp +++ b/src/qdoc/doc.cpp @@ -381,9 +381,7 @@ DocPrivate::DocPrivate(const Location &start, DocPrivate::~DocPrivate() { delete extra; - foreach (DitaRef *t, ditamap_) { - delete t; - } + qDeleteAll(ditamap_); } void DocPrivate::addAlso(const Text &also) @@ -2861,9 +2859,9 @@ Doc::Doc(const Location &start_loc, const QSet<QString> &metaCommandSet, const QSet<QString> &topics) { - priv = new DocPrivate(start_loc,end_loc,source); + priv = new DocPrivate(start_loc, end_loc, source); DocParser parser; - parser.parse(source,priv,metaCommandSet,topics); + parser.parse(source, priv, metaCommandSet, topics); } Doc::Doc(const Doc &doc) @@ -3416,9 +3414,7 @@ void Doc::detach() */ TopicRef::~TopicRef() { - foreach (DitaRef *t, subrefs_) { - delete t; - } + qDeleteAll(subrefs_); } /*! diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp index 3a2fc802d..e7088c610 100644 --- a/src/qdoc/generator.cpp +++ b/src/qdoc/generator.cpp @@ -205,10 +205,8 @@ int Generator::appendSortedNames(Text &text, const ClassNode *cn, const QList<Re ++r; } - QStringList classNames = classMap.keys(); - classNames.sort(); - - foreach (const QString &className, classNames) { + const QStringList classNames = classMap.keys(); + for (const auto &className : classNames) { text << classMap[className]; text << comma(index++, classNames.count()); } @@ -229,10 +227,8 @@ int Generator::appendSortedQmlNames(Text &text, const Node *base, const NodeList } } - QStringList names = classMap.keys(); - names.sort(); - - foreach (const QString &name, names) { + const QStringList names = classMap.keys(); + for (const auto &name : names) { text << classMap[name]; text << comma(index++, names.count()); } @@ -248,7 +244,8 @@ void Generator::writeOutFileNames() if (!files.open(QFile::WriteOnly)) return; QTextStream filesout(&files); - foreach (const QString &file, outFileNames_) { + const auto names = outFileNames_; + for (const auto &file : names) { filesout << file << "\n"; } } @@ -428,9 +425,13 @@ QString Generator::fileBase(const Node *node) const /*! Constructs an href link from an example file name, which - is a path to the example file. + is a path to the example file. If \a fileExtension is + empty (default value), retrieve the file extension from + the generator. */ -QString Generator::linkForExampleFile(const QString &path, const Node *parent) +QString Generator::linkForExampleFile(const QString &path, + const Node *parent, + const QString &fileExt) { QString link = path; QString modPrefix(parent->physicalModuleName()); @@ -441,11 +442,31 @@ QString Generator::linkForExampleFile(const QString &path, const Node *parent) QString res; transmogrify(link, res); res.append(QLatin1Char('.')); - res.append(fileExtension()); + res.append(fileExt); + if (fileExt.isEmpty()) + res.append(fileExtension()); return res; } /*! + Helper function to construct a title for a file or image page + included in an example. +*/ +QString Generator::exampleFileTitle(const ExampleNode *relative, + const QString &fileName) +{ + QString suffix; + if (relative->files().contains(fileName)) + suffix = QLatin1String(" Example File"); + else if (relative->images().contains(fileName)) + suffix = QLatin1String(" Image File"); + else + return suffix; + + return fileName.mid(fileName.lastIndexOf(QLatin1Char('/')) + 1) + suffix; +} + +/*! If the \a node has a URL, return the URL as the file name. Otherwise, construct the file name from the fileBase() and either the provided \a extension or fileExtension(), and @@ -483,7 +504,7 @@ QString Generator::cleanRef(const QString &ref) clean += QLatin1Char('A'); } - for (int i = 1; i < (int) ref.length(); i++) { + for (int i = 1; i < ref.length(); i++) { const QChar c = ref[i]; const uint u = c.unicode(); if ((u >= 'a' && u <= 'z') || @@ -507,7 +528,7 @@ QString Generator::cleanRef(const QString &ref) clean += QLatin1Char('#'); } else { clean += QLatin1Char('-'); - clean += QString::number((int)u, 16); + clean += QString::number(static_cast<int>(u), 16); } } return clean; @@ -658,6 +679,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir) case Node::QmlType: case Node::Page: case Node::Group: + case Node::HeaderFile: case Node::Module: case Node::JsModule: case Node::QmlModule: @@ -842,7 +864,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } if (node->isEnumType()) { - const EnumNode *enume = (const EnumNode *) node; + const EnumNode *enume = static_cast<const EnumNode *>(node); QSet<QString> definedItems; QList<EnumItem>::ConstIterator it = enume->items().constBegin(); @@ -920,62 +942,75 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } } } + generateRequiredLinks(node, marker); +} - // For examples, generate either a link to the project directory - // (if url.examples is defined), or a list of files/images. - if (node->isExample()) { - const ExampleNode *en = static_cast<const ExampleNode *>(node); - QString exampleUrl = config()->getString(CONFIG_URL + Config::dot + CONFIG_EXAMPLES); - if (!exampleUrl.isEmpty()) { - generateLinkToExample(en, marker, exampleUrl); - } else if (!en->noAutoList()) { - generateFileList(en, marker, false); - generateFileList(en, marker, true); +/*! + Generates either a link to the project folder for example \a node, or a list + of links files/images if 'url.examples config' variable is not defined. + + Does nothing for non-example nodes. +*/ +void Generator::generateRequiredLinks(const Node *node, CodeMarker *marker) +{ + if (!node->isExample()) + return; + + const ExampleNode *en = static_cast<const ExampleNode *>(node); + QString exampleUrl = config()->getString(CONFIG_URL + Config::dot + CONFIG_EXAMPLES); + + if (exampleUrl.isEmpty()) { + if (!en->noAutoList()) { + generateFileList(en, marker, false); // files + generateFileList(en, marker, true); // images } + } else { + generateLinkToExample(en, marker, exampleUrl); } } /*! - Generates a link to the project folder for example node \a en. - \a baseUrl is the base URL - path information is available in - the example node's name() and 'examplesinstallpath' configuration - variable. + Generates an external link to the project folder for example \a node. + The path to the example is appended to \a baseUrl string, or to a + specific location within the string marked with the placeholder '\1' + character. */ void Generator::generateLinkToExample(const ExampleNode *en, CodeMarker *marker, const QString &baseUrl) { - Text text; - QString exampleUrl(baseUrl); - - if (!exampleUrl.contains("\1")) { - if (!exampleUrl.endsWith("/")) - exampleUrl += "/"; - exampleUrl += "\1"; - } - - // Name of the example node is the path, relative to install path - QStringList path = QStringList() - << config()->getString(CONFIG_EXAMPLESINSTALLPATH) - << en->name(); - path.removeAll({}); - - QString link; + QString exampleUrl(baseUrl); + QString link; #ifndef QT_BOOTSTRAPPED - link = QUrl(baseUrl).host(); + link = QUrl(exampleUrl).host(); #endif - if (!link.isEmpty()) - link.prepend(" @ "); - link.prepend("Example project"); + if (!link.isEmpty()) + link.prepend(" @ "); + link.prepend("Example project"); + + const QLatin1Char separator('/'); + const QLatin1Char placeholder('\1'); + if (!exampleUrl.contains(placeholder)) { + if (!exampleUrl.endsWith(separator)) + exampleUrl += separator; + exampleUrl += placeholder; + } - text << Atom::ParaLeft - << Atom(Atom::Link, exampleUrl.replace("\1", path.join("/"))) - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, link) - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) - << Atom::ParaRight; + // Construct a path to the example; <install path>/<example name> + QStringList path = QStringList() + << config()->getString(CONFIG_EXAMPLESINSTALLPATH) + << en->name(); + path.removeAll({}); + + Text text; + text << Atom::ParaLeft + << Atom(Atom::Link, exampleUrl.replace(placeholder, path.join(separator))) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, link) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) + << Atom::ParaRight; - generateText(text, 0, marker); + generateText(text, nullptr, marker); } /*! @@ -1007,7 +1042,7 @@ void Generator::generateFileList(const ExampleNode *en, CodeMarker *marker, bool text << Atom(Atom::ListLeft, openedList.styleString()); QString path; - foreach (QString file, paths) { + for (const auto &file : qAsConst(paths)) { if (images) { if (!file.isEmpty()) { QDir dirInfo; @@ -1188,9 +1223,9 @@ void Generator::generateDocumentation(Node *node) if (node->isAggregate()) { Aggregate *aggregate = static_cast<Aggregate *>(node); const NodeList &children = aggregate->childNodes(); - foreach (Node *n, children) { - if (n->isPageNode() && !n->isPrivate()) - generateDocumentation(n); + for (auto *node : children) { + if (node->isPageNode() && !node->isPrivate()) + generateDocumentation(node); } } } @@ -1449,21 +1484,21 @@ static bool hasExceptions(const Node *node, bool result = false; Node::ThreadSafeness ts = node->threadSafeness(); const NodeList &children = static_cast<const Aggregate *>(node)->childNodes(); - foreach (Node *n, children) { - if (!n->isObsolete()){ - switch (n->threadSafeness()) { + for (auto *node : children) { + if (!node->isObsolete()){ + switch (node->threadSafeness()) { case Node::Reentrant: - reentrant.append(n); + reentrant.append(node); if (ts == Node::ThreadSafe) result = true; break; case Node::ThreadSafe: - threadsafe.append(n); + threadsafe.append(node); if (ts == Node::Reentrant) result = true; break; case Node::NonReentrant: - nonreentrant.append(n); + nonreentrant.append(node); result = true; break; default: @@ -1746,7 +1781,7 @@ QString Generator::indent(int level, const QString &markedCode) int column = 0; int i = 0; - while (i < (int) markedCode.length()) { + while (i < markedCode.length()) { if (markedCode.at(i) == QLatin1Char('\n')) { column = 0; } @@ -2008,8 +2043,6 @@ bool Generator::parseArg(const QString &src, //SKIP_CHAR('@'); if (tag != QStringRef(&src, i, tag.length())) { - if (0 && debug) - qDebug() << "tag " << tag << " not found at " << i; return false; } diff --git a/src/qdoc/generator.h b/src/qdoc/generator.h index 05d54fa66..f9bb4d53b 100644 --- a/src/qdoc/generator.h +++ b/src/qdoc/generator.h @@ -68,8 +68,11 @@ public: QString fullDocumentLocation(const Node *node, bool useSubdir = false); const Config *config() { return config_; } - QString linkForExampleFile(const QString &path, const Node *parent); - + QString linkForExampleFile(const QString &path, + const Node *parent, + const QString &fileExt = QString()); + static QString exampleFileTitle(const ExampleNode *relative, + const QString &fileName); static Generator *currentGenerator() { return currentGenerator_; } static Generator *generatorForFormat(const QString &format); static void initialize(const Config &config); @@ -150,10 +153,9 @@ protected: CodeMarker *marker, bool generate, int &numGeneratedAtoms); - void generateLinkToExample(const ExampleNode *en, - CodeMarker *marker, - const QString &baseUrl); - void generateFileList(const ExampleNode *en, CodeMarker *marker, bool images); + void generateRequiredLinks(const Node *node, CodeMarker *marker); + void generateLinkToExample(const ExampleNode *en, CodeMarker *marker, const QString &exampleUrl); + virtual void generateFileList(const ExampleNode *en, CodeMarker *marker, bool images); void generateSince(const Node *node, CodeMarker *marker); void generateStatus(const Node *node, CodeMarker *marker); void generatePrivateSignalNote(const Node *node, CodeMarker *marker); diff --git a/src/qdoc/helpprojectwriter.cpp b/src/qdoc/helpprojectwriter.cpp index 4a07f023f..3d45b60a4 100644 --- a/src/qdoc/helpprojectwriter.cpp +++ b/src/qdoc/helpprojectwriter.cpp @@ -65,9 +65,9 @@ void HelpProjectWriter::reset(const Config &config, // generator. outputDir = config.getOutputDir(); - QStringList names = config.getStringList(CONFIG_QHP + Config::dot + "projects"); + const QStringList names = config.getStringList(CONFIG_QHP + Config::dot + "projects"); - foreach (const QString &projectName, names) { + for (const auto &projectName : names) { HelpProject project; project.name = projectName; @@ -85,18 +85,20 @@ void HelpProjectWriter::reset(const Config &config, const auto &filterAttributes = config.getStringList(prefix + "filterAttributes"); project.filterAttributes = QSet<QString>(filterAttributes.cbegin(), filterAttributes.cend()); project.includeIndexNodes = config.getBool(prefix + "includeIndexNodes"); - QSet<QString> customFilterNames = config.subVars(prefix + "customFilters"); - foreach (const QString &filterName, customFilterNames) { + const QSet<QString> customFilterNames = config.subVars(prefix + "customFilters"); + for (const auto &filterName : customFilterNames) { QString name = config.getString(prefix + "customFilters" + Config::dot + filterName + Config::dot + "name"); const auto &filters = config.getStringList(prefix + "customFilters" + Config::dot + filterName + Config::dot + "filterAttributes"); project.customFilters[name] = QSet<QString>(filters.cbegin(), filters.cend()); } //customFilters = config.defs. - foreach (QString name, config.getStringSet(prefix + "excluded")) + const auto excludedPrefixes = config.getStringSet(prefix + "excluded"); + for (auto name : excludedPrefixes) project.excluded.insert(name.replace(QLatin1Char('\\'), QLatin1Char('/'))); - foreach (const QString &name, config.getStringList(prefix + "subprojects")) { + const auto subprojectPrefixes = config.getStringList(prefix + "subprojects"); + for (const auto &name : subprojectPrefixes) { SubProject subproject; QString subprefix = prefix + "subprojects" + Config::dot + name + Config::dot; subproject.title = config.getString(subprefix + "title"); @@ -158,7 +160,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList for (auto it = pageTypeHash.cbegin(), end = pageTypeHash.cend(); it != end; ++it) fullSubset.insert(it.value()); - foreach (const QString &selector, selectors) { + for (const QString &selector : selectors) { QStringList pieces = selector.split(QLatin1Char(':')); if (pieces.size() == 1) { QString lower = selector.toLower(); @@ -217,7 +219,10 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const else details << node->name(); // "id" - details << node->parent()->name()+"::"+node->name(); + if (!node->isRelatedNonmember()) + details << node->parent()->name()+"::"+node->name(); + else + details << node->name(); } else if (node->isQmlType() || node->isQmlBasicType()) { details << node->name(); @@ -272,7 +277,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project, if (node->isGroup() || node->isModule() || node->isQmlModule()) { if (project.subprojects[i].groups.contains(node->name().toLower())) { const CollectionNode *cn = static_cast<const CollectionNode *>(node); - foreach (const Node *m, cn->members()) { + const auto members = cn->members(); + for (const Node *m : members) { QString memberName = m->isTextPageNode() ? m->fullTitle() : m->fullDocumentName(); project.subprojects[i].nodes[memberName] = m; @@ -306,7 +312,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project, case Node::JsType: case Node::JsBasicType: if (node->doc().hasKeywords()) { - foreach (const Atom *keyword, node->doc().keywords()) { + const auto keywords = node->doc().keywords(); + for (const Atom *keyword : keywords) { if (!keyword->string().isEmpty()) { QStringList details; details << keyword->string() @@ -329,7 +336,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project, project.keywords.append(keywordDetails(node)); { const EnumNode *enumNode = static_cast<const EnumNode *>(node); - foreach (const EnumItem &item, enumNode->items()) { + const auto items = enumNode->items(); + for (const auto &item : items) { QStringList details; if (enumNode->itemAccess(item.name()) == Node::Private) @@ -356,7 +364,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project, const CollectionNode *cn = static_cast<const CollectionNode *>(node); if (!cn->fullTitle().isEmpty()) { if (cn->doc().hasKeywords()) { - foreach (const Atom *keyword, cn->doc().keywords()) { + const auto keywords = cn->doc().keywords(); + for (const Atom *keyword : keywords) { if (!keyword->string().isEmpty()) { QStringList details; details << keyword->string() @@ -439,7 +448,8 @@ bool HelpProjectWriter::generateSection(HelpProject &project, const PageNode *pn = static_cast<const PageNode *>(node); if (!pn->fullTitle().isEmpty()) { if (pn->doc().hasKeywords()) { - foreach (const Atom *keyword, pn->doc().keywords()) { + const auto keywords = pn->doc().keywords(); + for (const Atom *keyword : keywords) { if (!keyword->string().isEmpty()) { QStringList details; details << keyword->string() @@ -491,7 +501,10 @@ void HelpProjectWriter::generateSections(HelpProject &project, QXmlStreamWriter // Ensure that we don't visit nodes more than once. QSet<const Node *> childSet; const NodeList &children = aggregate->childNodes(); - foreach (const Node *child, children) { + for (const auto *child : children) { + // Skip related non-members adopted by some other aggregate + if (child->parent() != aggregate) + continue; if (child->isIndexNode() || child->isPrivate()) continue; if (child->isTextPageNode()) { @@ -504,7 +517,7 @@ void HelpProjectWriter::generateSections(HelpProject &project, QXmlStreamWriter childSet << child; } } - foreach (const Node *child, childSet) + for (const auto *child : qAsConst(childSet)) generateSections(project, writer, child); } } @@ -682,7 +695,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) writer.writeAttribute("name", it.key()); QStringList sortedAttributes = it.value().values(); sortedAttributes.sort(); - foreach (const QString &filter, sortedAttributes) + for (const auto &filter : qAsConst(sortedAttributes)) writer.writeTextElement("filterAttribute", filter); writer.writeEndElement(); // customFilter } @@ -693,7 +706,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) // Write filterAttribute elements. QStringList sortedFilterAttributes = project.filterAttributes.values(); sortedFilterAttributes.sort(); - foreach (const QString &filterName, sortedFilterAttributes) + for (const auto &filterName : qAsConst(sortedFilterAttributes)) writer.writeTextElement("filterAttribute", filterName); writer.writeStartElement("toc"); @@ -780,14 +793,14 @@ void HelpProjectWriter::generateProject(HelpProject &project) if (subproject.sortPages) { QStringList titles = subproject.nodes.keys(); titles.sort(); - foreach (const QString &title, titles) { + for (const auto &title : qAsConst(titles)) { writeNode(project, writer, subproject.nodes[title]); } } else { // Find a contents node and navigate from there, using the NextLink values. QSet<QString> visited; bool contentsFound = false; - foreach (const Node *node, subproject.nodes) { + for (const auto *node : qAsConst(subproject.nodes)) { QString nextTitle = node->links().value(Node::NextLink).first; if (!nextTitle.isEmpty() && node->links().value(Node::ContentsLink).first.isEmpty()) { @@ -815,7 +828,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) std::sort(subnodes.begin(), subnodes.end(), Node::nodeNameLessThan); - foreach (const Node *node, subnodes) + for (const auto *node : qAsConst(subnodes)) writeNode(project, writer, node); } } @@ -832,7 +845,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) writer.writeStartElement("keywords"); std::sort(project.keywords.begin(), project.keywords.end()); - foreach (const QStringList &details, project.keywords) { + for (const QStringList &details : qAsConst(project.keywords)) { writer.writeStartElement("keyword"); writer.writeAttribute("name", details[0]); writer.writeAttribute("id", details[1]); @@ -850,7 +863,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) files.unite(project.extraFiles); QStringList sortedFiles = files.values(); sortedFiles.sort(); - foreach (const QString &usedFile, sortedFiles) { + for (const auto &usedFile : qAsConst(sortedFiles)) { if (!usedFile.isEmpty()) writer.writeTextElement("file", usedFile); } diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp index 1be3d17fe..7810e7793 100644 --- a/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/htmlgenerator.cpp @@ -450,10 +450,10 @@ QString HtmlGenerator::generateLinksToLinksPage(const QString &module, CodeMarke out() << "Click on a link to go to the location of the link. The link is marked "; out() << "with red asterisks. "; out() << "Click on the marked link to see if it goes to the right place.</p>\n"; - TargetList* tlist = qdb_->getTargetList(module); + const TargetList *tlist = qdb_->getTargetList(module); if (tlist) { out() << "<table class=\"valuelist\"><tr valign=\"top\" class=\"odd\"><th class=\"tblConst\">Link to link...</th><th class=\"tblval\">In file...</th><th class=\"tbldscr\">Somewhere after line number...</th></tr>\n"; - foreach (TargetLoc* t, *tlist) { + for (const TargetLoc *t : *tlist) { // e.g.: <a name="link-8421"></a><a href="layout.html">Layout Management</a> out() << "<tr><td class=\"topAlign\">"; out() << "<a href=\"" << t->fileName_ << "#" << t->target_ << "\">"; @@ -483,7 +483,7 @@ QString HtmlGenerator::generateLinksToBrokenLinksPage(CodeMarker *marker, int &c { QString fileName; NamespaceNode *node = qdb_->primaryTreeRoot(); - TargetList* tlist = qdb_->getTargetList("broken"); + const TargetList *tlist = qdb_->getTargetList("broken"); if (tlist && !tlist->isEmpty()) { count = tlist->size(); fileName = "aaa-links-to-broken-links.html"; @@ -495,7 +495,7 @@ QString HtmlGenerator::generateLinksToBrokenLinksPage(CodeMarker *marker, int &c out() << "Click on a link to go to the broken link. "; out() << "The link's target could not be found.</p>\n"; out() << "<table class=\"valuelist\"><tr valign=\"top\" class=\"odd\"><th class=\"tblConst\">Link to broken link...</th><th class=\"tblval\">In file...</th><th class=\"tbldscr\">Somewhere after line number...</th></tr>\n"; - foreach (TargetLoc* t, *tlist) { + for (const TargetLoc *t : *tlist) { // e.g.: <a name="link-8421"></a><a href="layout.html">Layout Management</a> out() << "<tr><td class=\"topAlign\">"; out() << "<a href=\"" << t->fileName_ << "#" << t->target_ << "\">"; @@ -2893,7 +2893,8 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, NodeMap &classM stack.top().erase(stack.top().begin()); NodeMap newTop; - foreach (const RelatedClass &d, child->derivedClasses()) { + const auto derivedClasses = child->derivedClasses(); + for (const RelatedClass &d : derivedClasses) { if (d.node_ && d.node_->isInAPI()) newTop.insert(d.node_->name(), d.node_); } @@ -2926,7 +2927,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, { NodeMultiMap nmm; bool allInternal = true; - foreach (Node *node, unsortedNodes) { + for (auto *node : unsortedNodes) { if (!node->isInternal() && !node->isObsolete()) { allInternal = false; nmm.insert(node->fullName(relative), node); @@ -2939,7 +2940,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, NodeList nodes = nmm.values(); std::sort(nodes.begin(), nodes.end(), Node::nodeNameLessThan); - foreach (const Node *node, nodes) { + for (const auto *node : qAsConst(nodes)) { if (++row % 2 == 1) out() << "<tr class=\"odd topAlign\">"; else @@ -2983,7 +2984,8 @@ void HtmlGenerator::generateAnnotatedLists(const Node *relative, CodeMarker *marker, const NodeMultiMap &nmm) { - foreach (const QString &name, nmm.uniqueKeys()) { + const auto &uniqueKeys = nmm.uniqueKeys(); + for (const QString &name : uniqueKeys) { if (!name.isEmpty()) { out() << "<h2 id=\"" << registerRef(name.toLower()) << "\">" << protectEnc(name) << "</h2>\n"; @@ -3276,7 +3278,8 @@ bool HtmlGenerator::generateGroupList(CollectionNode *cn) if (cn->members().isEmpty()) return false; out() << "<ul>\n"; - foreach (const Node *node, cn->members()) { + const auto members = cn->members(); + for (const auto *node : members) { out() << "<li>" << "<a href=\"#" << Doc::canonicalTitle(node->title()) @@ -3301,12 +3304,13 @@ void HtmlGenerator::generateList(const Node *relative, CodeMarker *marker, const else if (selector == QLatin1String("js-modules")) type = Node::JsModule; if (type != Node::NoType) { - NodeList nl; + NodeList nodeList; qdb_->mergeCollections(type, cnm, relative); - CollectionList cl = cnm.values(); - foreach (CollectionNode *cn, cl) - nl.append(cn); - generateAnnotatedList(relative, marker, nl); + const CollectionList collectionList = cnm.values(); + nodeList.reserve(collectionList.size()); + for (auto *collectionNode : collectionList) + nodeList.append(collectionNode); + generateAnnotatedList(relative, marker, nodeList); } else { /* @@ -3965,7 +3969,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) } QString link = fn; - if ((!node->isAggregate() && !node->isCollectionNode()) || node->isPropertyGroup()) { + if (!node->isPageNode() || node->isPropertyGroup()) { QString ref = refForNode(node); if (relative && fn == fileName(relative) && ref == refForNode(relative)) return QString(); @@ -4021,12 +4025,12 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const QVector<Node *> &collective = scn->collective(); if (collective.size() > 1) out() << "<div class=\"fngroup\">\n"; - foreach (const Node *n, collective) { - if (n->isFunction()) { - nodeRef = refForNode(n); + for (const auto *node : collective) { + if (node->isFunction()) { + nodeRef = refForNode(node); out() << "<h3 class=\"fn fngroupitem\" id=\"" << nodeRef << "\">"; out() << "<a name=\"" + nodeRef + "\"></a>"; - generateSynopsis(n, relative, marker, Section::Details); + generateSynopsis(node, relative, marker, Section::Details); out() << "</h3>"; } } @@ -4163,8 +4167,8 @@ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) if (!pleaseGenerateMacRef || marker == 0) return; - QStringList macRefs = marker->macRefsForNode(node); - foreach (const QString &macRef, macRefs) + const QStringList macRefs = marker->macRefsForNode(node); + for (const auto &macRef : macRefs) out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n"; } #endif @@ -4470,7 +4474,7 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType out() << "-prop"; const PropertyNode *prop = static_cast<const PropertyNode *>(node); const NodeList &list = prop->functions(); - foreach (const Node *propFuncNode, list) { + for (const auto *propFuncNode : list) { if (propFuncNode->isFunction()) { const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode); out() << "$$$" + func->name() + func->parameters().rawSignature().remove(' '); @@ -4478,7 +4482,8 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType } } else if (node->isEnumType()) { const EnumNode *enumNode = static_cast<const EnumNode *>(node); - foreach (const EnumItem &item, enumNode->items()) + const auto items = enumNode->items(); + for (const auto &item : items) out() << "$$$" + item.name(); } } else if (markType == BriefMark) { @@ -4570,7 +4575,8 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString docUrl = manifestDir + fileBase(en) + ".html"; writer.writeAttribute("docUrl", docUrl); QStringList proFiles; - foreach (const QString file, en->files()) { + const auto exampleFiles = en->files(); + for (const QString &file : exampleFiles) { if (file.endsWith(".pro") || file.endsWith(".qmlproject") || file.endsWith(".pyproject")) proFiles << file; } @@ -4603,7 +4609,8 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString fullName = project + QLatin1Char('/') + en->title(); QSet<QString> tags; for (int idx=0; idx < manifestMetaContent.size(); ++idx) { - foreach (const QString &name, manifestMetaContent[idx].names) { + const auto names = manifestMetaContent[idx].names; + for (const QString &name : names) { bool match = false; int wildcard = name.indexOf(QChar('*')); switch (wildcard) { @@ -4618,7 +4625,8 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString } if (match) { tags += manifestMetaContent[idx].tags; - foreach (const QString &attr, manifestMetaContent[idx].attributes) { + const auto attributes = manifestMetaContent[idx].attributes; + for (const QString &attr : attributes) { QLatin1Char div(':'); QStringList attrList = attr.split(div); if (attrList.count() == 1) @@ -4694,7 +4702,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString bool wrote_one = false; QStringList sortedTags = tags.values(); sortedTags.sort(); - foreach (const QString &tag, sortedTags) { + for (const auto &tag : qAsConst(sortedTags)) { if (wrote_one) writer.writeCharacters(","); writer.writeCharacters(tag); @@ -4705,7 +4713,8 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString ename = en->name().mid(en->name().lastIndexOf('/')+1); QMap<int, QString> filesToOpen; - foreach (QString file, en->files()) { + const auto files = en->files(); + for (const QString &file : files) { QFileInfo fileInfo(file); QString fileName = fileInfo.fileName().toLower(); // open .qml, .cpp and .h files with a @@ -4759,9 +4768,10 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString */ void HtmlGenerator::readManifestMetaContent(const Config &config) { - QStringList names = config.getStringList(CONFIG_MANIFESTMETA + Config::dot + QStringLiteral("filters")); + const QStringList names = + config.getStringList(CONFIG_MANIFESTMETA + Config::dot + QStringLiteral("filters")); - foreach (const QString &manifest, names) { + for (const auto &manifest : names) { ManifestMetaFilter filter; QString prefix = CONFIG_MANIFESTMETA + Config::dot + manifest + Config::dot; filter.names = config.getStringSet(prefix + QStringLiteral("names")); @@ -4783,7 +4793,7 @@ void HtmlGenerator::reportOrphans(const Aggregate *parent) return; QString message = "has documentation but no \\relates command"; - foreach (Node *child, children) { + for (const auto *child : children) { if (!child || child->isInternal() || child->doc().isEmpty() || !child->isRelatedNonmember()) continue; switch (child->nodeType()) { @@ -4862,9 +4872,9 @@ void HtmlGenerator::generateAssociatedPropertyNotes(FunctionNode *fn) out() << "<p><b>Note:</b> "; NodeList &nodes = fn->associatedProperties(); std::sort(nodes.begin(), nodes.end(), Node::nodeNameLessThan); - foreach (const Node *n, nodes) { + for (const auto *node : qAsConst(nodes)) { QString msg; - const PropertyNode *pn = static_cast<const PropertyNode *>(n); + const PropertyNode *pn = static_cast<const PropertyNode *>(node); switch (pn->role(fn)) { case PropertyNode::Getter: msg = QStringLiteral("Getter function "); diff --git a/src/qdoc/main.cpp b/src/qdoc/main.cpp index 39ad0c9a2..c85ddb44d 100644 --- a/src/qdoc/main.cpp +++ b/src/qdoc/main.cpp @@ -94,8 +94,8 @@ static void loadIndexFiles(Config &config, const QSet<QString> &formats) { QDocDatabase *qdb = QDocDatabase::qdocDB(); QStringList indexFiles; - QStringList configIndexes = config.getStringList(CONFIG_INDEXES); - foreach (const QString &index, configIndexes) { + const QStringList configIndexes = config.getStringList(CONFIG_INDEXES); + for (const auto &index : configIndexes) { QFileInfo fi(index); if (fi.exists() && fi.isFile()) indexFiles << index; @@ -205,15 +205,6 @@ static void loadIndexFiles(Config &config, const QSet<QString> &formats) */ static void processQdocconfFile(const QString &fileName, Config &config) { - config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(qdocGlobals.highlighting() ? "true" : "false")); - config.setStringList(CONFIG_SHOWINTERNAL, QStringList(qdocGlobals.showInternal() ? "true" : "false")); - config.setStringList(CONFIG_SINGLEEXEC, QStringList(qdocGlobals.singleExec() ? "true" : "false")); - config.setStringList(CONFIG_WRITEQAPAGES, QStringList(qdocGlobals.writeQaPages() ? "true" : "false")); - config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(qdocGlobals.redirectDocumentationToDevNull() ? "true" : "false")); - config.setStringList(CONFIG_NOLINKERRORS, QStringList(qdocGlobals.noLinkErrors() ? "true" : "false")); - config.setStringList(CONFIG_AUTOLINKERRORS, QStringList(qdocGlobals.autolinkErrors() ? "true" : "false")); - config.setStringList(CONFIG_OBSOLETELINKS, QStringList(qdocGlobals.obsoleteLinks() ? "true" : "false")); - qdocGlobals.setPreviousCurrentDir(QDir::currentPath()); /* @@ -228,18 +219,15 @@ static void processQdocconfFile(const QString &fileName, Config &config) Location::initialize(config); config.load(fileName); QString project = config.getString(CONFIG_PROJECT); - QString moduleHeader = config.getString(CONFIG_MODULEHEADER); if (project.isEmpty()) { Location::logToStdErrAlways(QLatin1String("qdoc can't run; no project set in qdocconf file")); exit(1); } /* - Add the defines to the configuration variables. + Add the defines and includepaths to their respective configuration variables. */ - QStringList defs = qdocGlobals.defines() + config.getStringList(CONFIG_DEFINES); - config.setStringList(CONFIG_DEFINES,defs); - QStringList incs = qdocGlobals.includesPaths() + config.getStringList(CONFIG_INCLUDEPATHS); - config.setStringList(CONFIG_INCLUDEPATHS, incs); + config.insertStringList(CONFIG_DEFINES, qdocGlobals.defines()); + config.insertStringList(CONFIG_INCLUDEPATHS, qdocGlobals.includesPaths()); Location::terminate(); qdocGlobals.setCurrentDir(QFileInfo(fileName).path()); @@ -308,8 +296,6 @@ static void processQdocconfFile(const QString &fileName, Config &config) } #endif - //QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES); - /* Get the source language (Cpp) from the configuration and the location in the configuration file where the @@ -350,6 +336,8 @@ static void processQdocconfFile(const QString &fileName, Config &config) qdb->newPrimaryTree(project); else qdb->setPrimaryTree(project); + + const QString moduleHeader = config.getString(CONFIG_MODULEHEADER); if (!moduleHeader.isNull()) clangParser_->setModuleHeader(moduleHeader); else @@ -585,6 +573,7 @@ int main(int argc, char **argv) qdocGlobals.setOptions(parser); config.setOptions(parser); postProcess(parser); + config.setOptions(qdocGlobals); // Get the list of files to act on: QStringList qdocFiles = parser.positionalArguments(); diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp index 5cf323e1c..06f2d6bd6 100644 --- a/src/qdoc/node.cpp +++ b/src/qdoc/node.cpp @@ -1334,11 +1334,11 @@ QString Node::fullDocumentName() const if (n->isTextPageNode()) break; - // Examine the parent node if one exists. - if (n->parent()) - n = n->parent(); - else + // Examine the parent if the node is a member + if (!n->parent() || n->isRelatedNonmember()) break; + + n = n->parent(); } while (true); // Create a name based on the type of the ancestor node. @@ -2184,7 +2184,7 @@ QStringList Aggregate::primaryKeys() */ void Aggregate::markUndocumentedChildrenInternal() { - foreach (Node *child, children_) { + for (auto *child : qAsConst(children_)) { if (!child->isSharingComment() && !child->hasDoc() && !child->isDontDocument()) { if (!child->docMustBeGenerated()) { if (child->isFunction()) { @@ -2258,9 +2258,9 @@ void Aggregate::normalizeOverloads() /* Recursive part. */ - foreach (Node *n, children_) { - if (n->isAggregate()) - static_cast<Aggregate *>(n)->normalizeOverloads(); + for (auto *node : qAsConst(children_)) { + if (node->isAggregate()) + static_cast<Aggregate *>(node)->normalizeOverloads(); } } @@ -2291,7 +2291,7 @@ const NodeList &Aggregate::nonfunctionList() */ const EnumNode *Aggregate::findEnumNodeForValue(const QString &enumValue) const { - foreach (const Node *node, enumChildren_) { + for (const auto *node : enumChildren_) { const EnumNode *en = static_cast<const EnumNode *>(node); if (en->hasItem(enumValue)) return en; @@ -2503,8 +2503,8 @@ void Aggregate::adoptChild(Node *child) void Aggregate::setOutputSubdirectory(const QString &t) { Node::setOutputSubdirectory(t); - foreach (Node *n, children_) - n->setOutputSubdirectory(t); + for (auto *node : qAsConst(children_)) + node->setOutputSubdirectory(t); } /*! @@ -2516,7 +2516,7 @@ QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n) const NodeType goal = Node::QmlProperty; if (isJsNode()) goal = Node::JsProperty; - foreach (Node *child, children_) { + for (auto *child : qAsConst(children_)) { if (child->nodeType() == goal) { if (child->name() == n) return static_cast<QmlPropertyNode *>(child); @@ -2535,7 +2535,7 @@ QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n, bool attached) cons NodeType goal = Node::QmlProperty; if (isJsNode()) goal = Node::JsProperty; - foreach (Node *child, children_) { + for (auto *child : qAsConst(children_)) { if (child->nodeType() == goal) { if (child->name() == n && child->isAttached() == attached) return static_cast<QmlPropertyNode *>(child); @@ -2664,9 +2664,9 @@ void Aggregate::findAllFunctions(NodeMapMap &functionIndex) fn = fn->nextOverload(); } } - foreach (Node *n, children_) { - if (n->isAggregate() && !n->isPrivate()) - static_cast<Aggregate *>(n)->findAllFunctions(functionIndex); + for (Node *node : qAsConst(children_)) { + if (node->isAggregate() && !node->isPrivate()) + static_cast<Aggregate *>(node)->findAllFunctions(functionIndex); } } @@ -2686,11 +2686,11 @@ void Aggregate::findAllFunctions(NodeMapMap &functionIndex) */ void Aggregate::findAllNamespaces(NodeMultiMap &namespaces) { - foreach (Node *n, children_) { - if (n->isAggregate() && !n->isPrivate()) { - if (n->isNamespace() && !n->name().isEmpty()) - namespaces.insert(n->name(), n); - static_cast<Aggregate *>(n)->findAllNamespaces(namespaces); + for (auto *node : qAsConst(children_)) { + if (node->isAggregate() && !node->isPrivate()) { + if (node->isNamespace() && !node->name().isEmpty()) + namespaces.insert(node->name(), node); + static_cast<Aggregate *>(node)->findAllNamespaces(namespaces); } } } @@ -2699,13 +2699,13 @@ void Aggregate::findAllNamespaces(NodeMultiMap &namespaces) Returns true if this aggregate contains at least one child that is marked obsolete. Otherwise returns false. */ -bool Aggregate::hasObsoleteMembers() +bool Aggregate::hasObsoleteMembers() const { - foreach (Node *n, children_) { - if (!n->isPrivate() && n->isObsolete()) { - if (n->isFunction() || n->isProperty() || n->isEnumType() || - n->isTypedef() || n->isTypeAlias() || n->isVariable() || - n->isQmlProperty() || n->isJsProperty()) + for (const auto *node : children_) { + if (!node->isPrivate() && node->isObsolete()) { + if (node->isFunction() || node->isProperty() || node->isEnumType() || + node->isTypedef() || node->isTypeAlias() || node->isVariable() || + node->isQmlProperty() || node->isJsProperty()) return true; } } @@ -2720,26 +2720,24 @@ bool Aggregate::hasObsoleteMembers() */ void Aggregate::findAllObsoleteThings() { - foreach (Node *n, children_) { - if (!n->isPrivate()) { - QString name = n->name(); - if (n->isObsolete()) { - if (n->isClassNode()) - QDocDatabase::obsoleteClasses().insert(n->qualifyCppName(), n); - else if (n->isQmlType() || n->isJsType()) - QDocDatabase::obsoleteQmlTypes().insert(n->qualifyQmlName(), n); - } else if (n->isClassNode()) { - Aggregate *a = static_cast<Aggregate *>(n); + for (auto *node : qAsConst(children_)) { + if (!node->isPrivate()) { + QString name = node->name(); + if (node->isObsolete()) { + if (node->isClassNode()) + QDocDatabase::obsoleteClasses().insert(node->qualifyCppName(), node); + else if (node->isQmlType() || node->isJsType()) + QDocDatabase::obsoleteQmlTypes().insert(node->qualifyQmlName(), node); + } else if (node->isClassNode()) { + Aggregate *a = static_cast<Aggregate *>(node); if (a->hasObsoleteMembers()) - QDocDatabase::classesWithObsoleteMembers().insert(n->qualifyCppName(), n); - } - else if (n->isQmlType() || n->isJsType()) { - Aggregate *a = static_cast<Aggregate *>(n); + QDocDatabase::classesWithObsoleteMembers().insert(node->qualifyCppName(), node); + } else if (node->isQmlType() || node->isJsType()) { + Aggregate *a = static_cast<Aggregate *>(node); if (a->hasObsoleteMembers()) - QDocDatabase::qmlTypesWithObsoleteMembers().insert(n->qualifyQmlName(), n); - } - else if (n->isAggregate()) { - static_cast<Aggregate *>(n)->findAllObsoleteThings(); + QDocDatabase::qmlTypesWithObsoleteMembers().insert(node->qualifyQmlName(), node); + } else if (node->isAggregate()) { + static_cast<Aggregate *>(node)->findAllObsoleteThings(); } } } @@ -2752,24 +2750,24 @@ void Aggregate::findAllObsoleteThings() */ void Aggregate::findAllClasses() { - foreach (Node *n, children_) { - if (!n->isPrivate() && !n->isInternal() && - n->tree()->camelCaseModuleName() != QString("QDoc")) { - if (n->isClassNode()) { - QDocDatabase::cppClasses().insert(n->qualifyCppName().toLower(), n); - } else if (n->isQmlType() || n->isQmlBasicType() || n->isJsType() || n->isJsBasicType()) { - QString name = n->unqualifyQmlName(); - QDocDatabase::qmlTypes().insert(name, n); + for (auto *node : qAsConst(children_)) { + if (!node->isPrivate() && !node->isInternal() && + node->tree()->camelCaseModuleName() != QString("QDoc")) { + if (node->isClassNode()) { + QDocDatabase::cppClasses().insert(node->qualifyCppName().toLower(), node); + } else if (node->isQmlType() || node->isQmlBasicType() || node->isJsType() || node->isJsBasicType()) { + QString name = node->unqualifyQmlName(); + QDocDatabase::qmlTypes().insert(name, node); //also add to the QML basic type map - if (n->isQmlBasicType() || n->isJsBasicType()) - QDocDatabase::qmlBasicTypes().insert(name, n); - } else if (n->isExample()) { + if (node->isQmlBasicType() || node->isJsBasicType()) + QDocDatabase::qmlBasicTypes().insert(name, node); + } else if (node->isExample()) { // use the module index title as key for the example map - QString title = n->tree()->indexTitle(); - if (!QDocDatabase::examples().contains(title, n)) - QDocDatabase::examples().insert(title, n); - } else if (n->isAggregate()) { - static_cast<Aggregate *>(n)->findAllClasses(); + QString title = node->tree()->indexTitle(); + if (!QDocDatabase::examples().contains(title, node)) + QDocDatabase::examples().insert(title, node); + } else if (node->isAggregate()) { + static_cast<Aggregate *>(node)->findAllClasses(); } } } @@ -2781,12 +2779,12 @@ void Aggregate::findAllClasses() */ void Aggregate::findAllAttributions(NodeMultiMap &attributions) { - foreach (Node *n, children_) { - if (!n->isPrivate()) { - if (n->pageType() == Node::AttributionPage) - attributions.insertMulti(n->tree()->indexTitle(), n); - else if (n->isAggregate()) - static_cast<Aggregate *>(n)->findAllAttributions(attributions); + for (auto *node : qAsConst(children_)) { + if (!node->isPrivate()) { + if (node->pageType() == Node::AttributionPage) + attributions.insertMulti(node->tree()->indexTitle(), node); + else if (node->isAggregate()) + static_cast<Aggregate *>(node)->findAllAttributions(attributions); } } } @@ -2801,10 +2799,10 @@ void Aggregate::findAllAttributions(NodeMultiMap &attributions) */ void Aggregate::findAllSince() { - foreach (Node *n, children_) { - QString sinceString = n->since(); + for (auto *node : qAsConst(children_)) { + QString sinceString = node->since(); // Insert a new entry into each map for each new since string found. - if (!n->isPrivate() && !sinceString.isEmpty()) { + if (!node->isPrivate() && !sinceString.isEmpty()) { NodeMultiMapMap::iterator nsmap = QDocDatabase::newSinceMaps().find(sinceString); if (nsmap == QDocDatabase::newSinceMaps().end()) nsmap = QDocDatabase::newSinceMaps().insert(sinceString, NodeMultiMap()); @@ -2817,34 +2815,34 @@ void Aggregate::findAllSince() if (nqcmap == QDocDatabase::newQmlTypeMaps().end()) nqcmap = QDocDatabase::newQmlTypeMaps().insert(sinceString, NodeMap()); - if (n->isFunction()) { + if (node->isFunction()) { // Insert functions into the general since map. - FunctionNode *fn = static_cast<FunctionNode *>(n); + FunctionNode *fn = static_cast<FunctionNode *>(node); if (!fn->isObsolete() && !fn->isSomeCtor() && !fn->isDtor()) nsmap.value().insert(fn->name(), fn); } - else if (n->isClassNode()) { + else if (node->isClassNode()) { // Insert classes into the since and class maps. - QString name = n->qualifyWithParentName(); - nsmap.value().insert(name, n); - ncmap.value().insert(name, n); - } else if (n->isQmlType() || n->isJsType()) { + QString name = node->qualifyWithParentName(); + nsmap.value().insert(name, node); + ncmap.value().insert(name, node); + } else if (node->isQmlType() || node->isJsType()) { // Insert QML elements into the since and element maps. - QString name = n->qualifyWithParentName(); - nsmap.value().insert(name, n); - nqcmap.value().insert(name, n); - } else if (n->isQmlProperty() || n->isJsProperty()) { + QString name = node->qualifyWithParentName(); + nsmap.value().insert(name, node); + nqcmap.value().insert(name, node); + } else if (node->isQmlProperty() || node->isJsProperty()) { // Insert QML properties into the since map. - nsmap.value().insert(n->name(), n); + nsmap.value().insert(node->name(), node); } else { // Insert external documents into the general since map. - QString name = n->qualifyWithParentName(); - nsmap.value().insert(name, n); + QString name = node->qualifyWithParentName(); + nsmap.value().insert(name, node); } } // Recursively find child nodes with since commands. - if (n->isAggregate()) - static_cast<Aggregate *>(n)->findAllSince(); + if (node->isAggregate()) + static_cast<Aggregate *>(node)->findAllSince(); } } @@ -2859,7 +2857,7 @@ void Aggregate::resolveQmlInheritance() { NodeMap previousSearches; // Do we need recursion? - foreach (Node *child, children_) { + for (auto *child : qAsConst(children_)) { if (!child->isQmlType() && !child->isJsType()) continue; QmlTypeNode *type = static_cast<QmlTypeNode *>(child); @@ -3119,8 +3117,8 @@ bool NamespaceNode::isDocumentedHere() const */ bool NamespaceNode::hasDocumentedChildren() const { - foreach (Node *n, children_) { - if (n->isInAPI()) + for (const auto *node : qAsConst(children_)) { + if (node->isInAPI()) return true; } return false; @@ -3133,15 +3131,15 @@ bool NamespaceNode::hasDocumentedChildren() const */ void NamespaceNode::reportDocumentedChildrenInUndocumentedNamespace() const { - foreach (Node *n, children_) { - if (n->isInAPI()) { - QString msg1 = n->name(); - if (n->isFunction()) + for (const auto *node : qAsConst(children_)) { + if (node->isInAPI()) { + QString msg1 = node->name(); + if (node->isFunction()) msg1 += "()"; msg1 += tr(" is documented, but namespace %1 is not documented in any module.").arg(name()); QString msg2 = tr("Add /*! '\\%1 %2' ... */ or remove the qdoc comment marker (!) at that line number.").arg(COMMAND_NAMESPACE).arg(name()); - n->doc().location().warning(msg1, msg2); + node->doc().location().warning(msg1, msg2); } } } @@ -3590,8 +3588,8 @@ bool HeaderNode::docMustBeGenerated() const */ bool HeaderNode::hasDocumentedChildren() const { - foreach (Node *n, children_) { - if (n->isInAPI()) + for (const auto *node : qAsConst(children_)) { + if (node->isInAPI()) return true; } return false; @@ -3794,7 +3792,7 @@ Node::Access EnumNode::itemAccess(const QString &name) const */ QString EnumNode::itemValue(const QString &name) const { - foreach (const EnumItem &item, items_) { + for (const auto &item : qAsConst(items_)) { if (item.name() == name) return item.value(); } @@ -4297,8 +4295,8 @@ bool FunctionNode::hasActiveAssociatedProperty() const { if (associatedProperties_.isEmpty()) return false; - foreach (const Node *p, associatedProperties_) { - if (!p->isObsolete()) + for (const auto *property : qAsConst(associatedProperties_)) { + if (!property->isObsolete()) return true; } return false; diff --git a/src/qdoc/node.h b/src/qdoc/node.h index 5530e1088..71a603146 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -485,7 +485,7 @@ public: void findAllFunctions(NodeMapMap &functionIndex); void findAllNamespaces(NodeMultiMap &namespaces); void findAllAttributions(NodeMultiMap &attributions); - bool hasObsoleteMembers(); + bool hasObsoleteMembers() const; void findAllObsoleteThings(); void findAllClasses(); void findAllSince(); diff --git a/src/qdoc/parameters.cpp b/src/qdoc/parameters.cpp index c723fe9cc..44178c9d9 100644 --- a/src/qdoc/parameters.cpp +++ b/src/qdoc/parameters.cpp @@ -456,7 +456,8 @@ QString Parameters::signature(bool includeValues) const QString Parameters::rawSignature(bool names, bool values) const { QString raw; - foreach (const Parameter ¶meter, parameters_) { + const auto params = parameters_; + for (const auto ¶meter : params) { raw += parameter.type(); if (names) raw += parameter.name(); @@ -508,7 +509,8 @@ void Parameters::set(const QString &signature) */ void Parameters::getNames(QSet<QString> &names) const { - foreach (const Parameter ¶meter, parameters_) { + const auto params = parameters_; + for (const auto ¶meter : params) { if (!parameter.name().isEmpty()) names.insert(parameter.name()); } diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro index f9aa52225..234ebddbe 100644 --- a/src/qdoc/qdoc.pro +++ b/src/qdoc/qdoc.pro @@ -11,6 +11,8 @@ qtHaveModule(qmldevtools-private) { DEFINES += QT_NO_DECLARATIVE } +DEFINES += QT_NO_FOREACH + include($$OUT_PWD/../global/qttools-config.pri) LIBS += $$CLANG_LIBS diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp index 2ad906bd6..311b19db7 100644 --- a/src/qdoc/qdocdatabase.cpp +++ b/src/qdoc/qdocdatabase.cpp @@ -169,7 +169,7 @@ void QDocForest::setPrimaryTree(const QString &t) If the search order array is empty, create the search order. If the search order array is not empty, do nothing. */ -void QDocForest::setSearchOrder(QStringList &t) +void QDocForest::setSearchOrder(const QStringList &t) { if (!searchOrder_.isEmpty()) return; @@ -187,7 +187,7 @@ void QDocForest::setSearchOrder(QStringList &t) forest_.remove(primaryName); QMap<QString, Tree *>::iterator i; - foreach (const QString &m, t) { + for (const QString &m : t) { if (primaryName != m) { i = forest_.find(m); if (i != forest_.end()) { @@ -326,8 +326,8 @@ const Node *QDocForest::findNodeForTarget(QStringList &targetPath, if (!targetPath.isEmpty()) target = targetPath.takeFirst(); - foreach (Tree *t, searchOrder()) { - const Node *n = t->findNodeForTarget(entityPath, target, relative, flags, genus, ref); + for (const auto *tree : searchOrder()) { + const Node *n = tree->findNodeForTarget(entityPath, target, relative, flags, genus, ref); if (n) return n; relative = nullptr; @@ -343,9 +343,9 @@ void QDocForest::printLinkCounts(const QString &project) { Location::null.report(QString("%1: Link Counts").arg(project)); QMultiMap<int, QString> m; - foreach (Tree *t, searchOrder()) { - if (t->linkCount() < 0) - m.insert(t->linkCount(), t->physicalModuleName()); + for (const auto *tree : searchOrder()) { + if (tree->linkCount() < 0) + m.insert(tree->linkCount(), tree->physicalModuleName()); } QString depends = "depends +="; QString module = project.toLower(); @@ -372,9 +372,9 @@ void QDocForest::printLinkCounts(const QString &project) QString QDocForest::getLinkCounts(QStringList &strings, QVector<int> &counts) { QMultiMap<int, QString> m; - foreach (Tree *t, searchOrder()) { - if (t->linkCount() < 0) - m.insert(t->linkCount(), t->physicalModuleName()); + for (const auto *tree : searchOrder()) { + if (tree->linkCount() < 0) + m.insert(tree->linkCount(), tree->physicalModuleName()); } QString depends = "depends +="; QString module = Generator::defaultModuleName().toLower(); @@ -405,8 +405,8 @@ const FunctionNode *QDocForest::findFunctionNode(const QStringList &path, const Node *relative, Node::Genus genus) { - foreach (Tree *t, searchOrder()) { - const FunctionNode *fn = t->findFunctionNode(path, parameters, relative, genus); + for (const auto *tree : searchOrder()) { + const FunctionNode *fn = tree->findFunctionNode(path, parameters, relative, genus); if (fn) return fn; relative = nullptr; @@ -1181,15 +1181,15 @@ void QDocDatabase::resolveNamespaces() t->root()->findAllNamespaces(namespaceMultimap); t = forest_.nextTree(); } - QList<QString> keys = namespaceMultimap.uniqueKeys(); - foreach (const QString &s, keys) { + const QList<QString> keys = namespaceMultimap.uniqueKeys(); + for (const QString &key : keys) { NamespaceNode *ns = nullptr; NamespaceNode *somewhere = nullptr; - NodeList namespaces = namespaceMultimap.values(s); - int count = namespaceMultimap.remove(s); + const NodeList namespaces = namespaceMultimap.values(key); + int count = namespaceMultimap.remove(key); if (count > 0) { - foreach (Node *n, namespaces) { - ns = static_cast<NamespaceNode *>(n); + for (auto *node : namespaces) { + ns = static_cast<NamespaceNode *>(node); if (ns->isDocumentedHere()) break; else if (ns->hadDoc()) @@ -1197,8 +1197,8 @@ void QDocDatabase::resolveNamespaces() ns = nullptr; } if (ns) { - foreach (Node *n, namespaces) { - NamespaceNode *NS = static_cast<NamespaceNode *>(n); + for (auto *node : namespaces) { + NamespaceNode *NS = static_cast<NamespaceNode *>(node); if (NS->hadDoc() && NS != ns) { ns->doc().location().warning(tr("Namespace %1 documented more than once") .arg(NS->name())); @@ -1207,14 +1207,14 @@ void QDocDatabase::resolveNamespaces() } } else if (somewhere == nullptr) { - foreach (Node *n, namespaces) { - NamespaceNode *NS = static_cast<NamespaceNode *>(n); + for (auto *node : namespaces) { + NamespaceNode *NS = static_cast<NamespaceNode *>(node); NS->reportDocumentedChildrenInUndocumentedNamespace(); } } if (somewhere) { - foreach (Node *n, namespaces) { - NamespaceNode *NS = static_cast<NamespaceNode *>(n); + for (auto *node : namespaces) { + NamespaceNode *NS = static_cast<NamespaceNode *>(node); if (NS != somewhere) NS->setDocNode(somewhere); } @@ -1229,11 +1229,11 @@ void QDocDatabase::resolveNamespaces() the namespace. */ if (ns && count > 1) { - foreach (Node *n, namespaces) { - NamespaceNode *NS = static_cast<NamespaceNode *>(n); - if (NS != ns) { - NodeList::ConstIterator c = NS->constBegin(); - while (c != NS->constEnd()) { + for (auto *node : namespaces) { + auto *nameSpaceNode = static_cast<NamespaceNode *>(node); + if (nameSpaceNode != ns) { + NodeList::ConstIterator c = nameSpaceNode->constBegin(); + while (c != nameSpaceNode->constEnd()) { Node *N = *c; if (N && N->isPublic() && !N->isInternal()) ns->includeChild(N); @@ -1265,10 +1265,10 @@ void QDocDatabase::resolveProxies() Tree *t = forest_.firstTree(); t = forest_.nextTree(); while (t) { - NodeList &proxies = t->proxies(); + const NodeList &proxies = t->proxies(); if (!proxies.isEmpty()) { - foreach (Node *n, proxies) { - ProxyNode *pn = static_cast<ProxyNode *>(n); + for (auto *node : proxies) { + ProxyNode *pn = static_cast<ProxyNode *>(node); if (pn->count() > 0) { Aggregate *aggregate = primaryTree()->findAggregate(pn->name()); if (aggregate != nullptr) @@ -1349,8 +1349,8 @@ const Node *QDocDatabase::findNodeForTarget(const QString &target, const Node *r else { QStringList path = target.split("::"); int flags = SearchBaseClasses | SearchEnumValues; - foreach (Tree *t, searchOrder()) { - const Node *n = t->findNode(path, relative, flags, Node::DontCare); + for (const auto *tree : searchOrder()) { + const Node *n = tree->findNode(path, relative, flags, Node::DontCare); if (n) return n; relative = nullptr; @@ -1372,19 +1372,19 @@ void QDocDatabase::generateTagFile(const QString &name, Generator *g) } /*! - Reads and parses the qdoc index files listed in \a t. + Reads and parses the qdoc index files listed in \a indexFiles. */ -void QDocDatabase::readIndexes(const QStringList &t) +void QDocDatabase::readIndexes(const QStringList &indexFiles) { - QStringList indexFiles; - foreach (const QString &f, t) { - QString fn = f.mid(f.lastIndexOf(QChar('/'))+1); + QStringList filesToRead; + for (const QString &file : indexFiles) { + QString fn = file.mid(file.lastIndexOf(QChar('/'))+1); if (!isLoaded(fn)) - indexFiles << f; + filesToRead << file; else - qDebug() << "This index file is already in memory:" << f; + qDebug() << "This index file is already in memory:" << file; } - QDocIndexFiles::qdocIndexFiles()->readIndexes(indexFiles); + QDocIndexFiles::qdocIndexFiles()->readIndexes(filesToRead); } /*! @@ -1416,7 +1416,8 @@ Node *QDocDatabase::findNodeInOpenNamespace(QStringList &path, bool (Node::*isMa return nullptr; Node *n = nullptr; if (!openNamespaces_.isEmpty()) { - foreach (const QString &t, openNamespaces_) { + const auto &openNamespaces = openNamespaces_; + for (const QString &t : openNamespaces) { QStringList p; if (t != path[0]) p = t.split("::") + path; @@ -1441,8 +1442,8 @@ void QDocDatabase::mergeCollections(Node::NodeType type, CNMap &cnm, const Node { cnm.clear(); CNMultiMap cnmm; - foreach (Tree *t, searchOrder()) { - CNMap *m = t->getCollectionMap(type); + for (auto *tree : searchOrder()) { + CNMap *m = tree->getCollectionMap(type); if (m && !m->isEmpty()) { CNMap::const_iterator i = m->cbegin(); while (i != m->cend()) { @@ -1455,28 +1456,28 @@ void QDocDatabase::mergeCollections(Node::NodeType type, CNMap &cnm, const Node if (cnmm.isEmpty()) return; QRegExp singleDigit("\\b([0-9])\\b"); - QStringList keys = cnmm.uniqueKeys(); - foreach (const QString &key, keys) { - QList<CollectionNode *> values = cnmm.values(key); + const QStringList keys = cnmm.uniqueKeys(); + for (const auto &key : keys) { + const QList<CollectionNode *> values = cnmm.values(key); CollectionNode *n = nullptr; - foreach (CollectionNode *v, values) { - if (v && v->wasSeen() && (v != relative)) { - n = v; + for (auto *value : values) { + if (value && value->wasSeen() && value != relative) { + n = value; break; } } if (n) { if (values.size() > 1) { - foreach (CollectionNode *v, values) { - if (v != n) { + for (CollectionNode *value : values) { + if (value != n) { // Allow multiple (major) versions of QML/JS modules if ((n->isQmlModule() || n->isJsModule()) && - n->logicalModuleIdentifier() != v->logicalModuleIdentifier()) { - if (v->wasSeen() && v != relative && !v->members().isEmpty()) - cnm.insert(v->fullTitle().toLower(), v); + n->logicalModuleIdentifier() != value->logicalModuleIdentifier()) { + if (value->wasSeen() && value != relative && !value->members().isEmpty()) + cnm.insert(value->fullTitle().toLower(), value); continue; } - foreach (Node *t, v->members()) + for (Node *t : value->members()) n->addMember(t); } } @@ -1503,14 +1504,14 @@ void QDocDatabase::mergeCollections(Node::NodeType type, CNMap &cnm, const Node */ void QDocDatabase::mergeCollections(CollectionNode *c) { - foreach (Tree *t, searchOrder()) { - CollectionNode *cn = t->getCollection(c->name(), c->nodeType()); + for (auto *tree : searchOrder()) { + CollectionNode *cn = tree->getCollection(c->name(), c->nodeType()); if (cn && cn != c) { if ((cn->isQmlModule() || cn->isJsModule()) && cn->logicalModuleIdentifier() != c->logicalModuleIdentifier()) continue; - foreach (Node *n, cn->members()) - c->addMember(n); + for (auto *node : cn->members()) + c->addMember(node); } } } diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h index 4093dbac5..28b1cea83 100644 --- a/src/qdoc/qdocdatabase.h +++ b/src/qdoc/qdocdatabase.h @@ -74,10 +74,10 @@ class QDocForest bool done() { return (currentIndex_ >= searchOrder().size()); } const QVector<Tree *> &searchOrder(); const QVector<Tree *> &indexSearchOrder(); - void setSearchOrder(QStringList &t); + void setSearchOrder(const QStringList &t); bool isLoaded(const QString &fn) { - foreach (Tree *t, searchOrder()) { - if (fn == t->indexFileName()) + for (const auto *tree : searchOrder()) { + if (fn == tree->indexFileName()) return true; } return false; @@ -87,8 +87,8 @@ class QDocForest const Node *relative, int findFlags, Node::Genus genus) { - foreach (Tree *t, searchOrder()) { - const Node *n = t->findNode(path, relative, findFlags, genus); + for (const auto *tree : searchOrder()) { + const Node *n = tree->findNode(path, relative, findFlags, genus); if (n) return n; relative = nullptr; @@ -97,8 +97,8 @@ class QDocForest } Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch) () const) { - foreach (Tree *t, searchOrder()) { - Node *n = t->findNodeByNameAndType(path, isMatch); + for (const auto *tree : searchOrder()) { + Node *n = tree->findNodeByNameAndType(path, isMatch); if (n) return n; } @@ -106,8 +106,8 @@ class QDocForest } ClassNode *findClassNode(const QStringList &path) { - foreach (Tree *t, searchOrder()) { - ClassNode *n = t->findClassNode(path); + for (const auto *tree : searchOrder()) { + ClassNode *n = tree->findClassNode(path); if (n) return n; } @@ -115,8 +115,8 @@ class QDocForest } Node *findNodeForInclude(const QStringList &path) { - foreach (Tree *t, searchOrder()) { - Node *n = t->findNodeForInclude(path); + for (const auto *tree : searchOrder()) { + Node *n = tree->findNodeForInclude(path); if (n) return n; } @@ -137,8 +137,8 @@ class QDocForest int flags = SearchBaseClasses | SearchEnumValues | TypesOnly; if (relative && genus == Node::DontCare && relative->genus() != Node::DOC) genus = relative->genus(); - foreach (Tree *t, searchOrder()) { - const Node *n = t->findNode(path, relative, flags, genus); + for (const auto *tree : searchOrder()) { + const Node *n = tree->findNode(path, relative, flags, genus); if (n) return n; relative = nullptr; @@ -148,8 +148,8 @@ class QDocForest const PageNode *findPageNodeByTitle(const QString &title) { - foreach (Tree *t, searchOrder()) { - const PageNode *n = t->findPageNodeByTitle(title); + for (const auto *tree : searchOrder()) { + const PageNode *n = tree->findPageNodeByTitle(title); if (n) return n; } @@ -158,8 +158,8 @@ class QDocForest const CollectionNode *getCollectionNode(const QString &name, Node::NodeType type) { - foreach (Tree *t, searchOrder()) { - const CollectionNode *cn = t->getCollection(name, type); + for (auto *tree : searchOrder()) { + const CollectionNode *cn = tree->getCollection(name, type); if (cn) return cn; } @@ -168,8 +168,8 @@ class QDocForest QmlTypeNode *lookupQmlType(const QString &name) { - foreach (Tree *t, searchOrder()) { - QmlTypeNode *qcn = t->lookupQmlType(name); + for (const auto *tree : searchOrder()) { + QmlTypeNode *qcn = tree->lookupQmlType(name); if (qcn) return qcn; } @@ -178,8 +178,8 @@ class QDocForest Aggregate *lookupQmlBasicType(const QString &name) { - foreach (Tree *t, searchOrder()) { - Aggregate *a = t->lookupQmlBasicType(name); + for (const auto *tree : searchOrder()) { + Aggregate *a = tree->lookupQmlBasicType(name); if (a) return a; } @@ -188,8 +188,8 @@ class QDocForest void clearSearchOrder() { searchOrder_.clear(); } void clearLinkCounts() { - foreach (Tree *t, searchOrder()) - t->clearLinkCount(); + for (auto *tree : searchOrder()) + tree->clearLinkCount(); } void printLinkCounts(const QString &project); QString getLinkCounts(QStringList &strings, QVector<int> &counts); diff --git a/src/qdoc/qdocglobals.cpp b/src/qdoc/qdocglobals.cpp index 22e9beb70..05fa3a96f 100644 --- a/src/qdoc/qdocglobals.cpp +++ b/src/qdoc/qdocglobals.cpp @@ -33,7 +33,7 @@ #include <QtCore/qdir.h> #include <QtCore/qfile.h> -bool QDocGlobals::highlighting() +bool QDocGlobals::highlighting() const { return m_highlighting; } @@ -43,7 +43,7 @@ void QDocGlobals::enableHighlighting(bool value) m_highlighting = value; } -bool QDocGlobals::showInternal() +bool QDocGlobals::showInternal() const { return m_showInternal; } @@ -53,7 +53,7 @@ void QDocGlobals::setShowInternal(bool value) m_showInternal = value; } -bool QDocGlobals::singleExec() +bool QDocGlobals::singleExec() const { return m_singleExec; } @@ -62,7 +62,7 @@ void QDocGlobals::setSingleExec(bool value) m_singleExec = value; } -bool QDocGlobals::writeQaPages() +bool QDocGlobals::writeQaPages() const { return m_writeQaPages; } @@ -71,7 +71,7 @@ void QDocGlobals::setWriteQaPages(bool value) m_writeQaPages = value; } -bool QDocGlobals::redirectDocumentationToDevNull() +bool QDocGlobals::redirectDocumentationToDevNull() const { return m_redirectDocumentationToDevNull; } @@ -81,7 +81,7 @@ void QDocGlobals::setRedirectDocumentationToDevNull(bool value) m_redirectDocumentationToDevNull = value; } -bool QDocGlobals::noLinkErrors() +bool QDocGlobals::noLinkErrors() const { return m_noLinkErrors; } @@ -91,7 +91,7 @@ void QDocGlobals::setNoLinkErrors(bool value) m_noLinkErrors = value; } -bool QDocGlobals::autolinkErrors() +bool QDocGlobals::autolinkErrors() const { return m_autolinkErrors; } @@ -101,7 +101,7 @@ void QDocGlobals::setAutolinkErrors(bool value) m_autolinkErrors = value; } -bool QDocGlobals::obsoleteLinks() +bool QDocGlobals::obsoleteLinks() const { return m_obsoleteLinks; } @@ -111,7 +111,7 @@ void QDocGlobals::setObsoleteLinks(bool value) m_obsoleteLinks = value; } -QStringList QDocGlobals::defines() +QStringList QDocGlobals::defines() const { return m_defines; } @@ -121,7 +121,7 @@ void QDocGlobals::addDefine(const QStringList &valueList) m_defines += valueList; } -QStringList QDocGlobals::includesPaths() +QStringList QDocGlobals::includesPaths() const { return m_includesPaths; } @@ -137,7 +137,7 @@ QStringList &QDocGlobals::dependModules() return m_dependModules; } -QStringList QDocGlobals::indexDirs() +QStringList QDocGlobals::indexDirs() const { return m_indexDirs; } @@ -147,7 +147,7 @@ void QDocGlobals::appendToIndexDirs(const QString &path) m_indexDirs += path; } -QString QDocGlobals::currentDir() +QString QDocGlobals::currentDir() const { return m_currentDir; } @@ -157,7 +157,7 @@ void QDocGlobals::setCurrentDir(const QString &path) m_currentDir = path; } -QString QDocGlobals::previousCurrentDir() +QString QDocGlobals::previousCurrentDir() const { return m_previousCurrentDir; } diff --git a/src/qdoc/qdocglobals.h b/src/qdoc/qdocglobals.h index d1198db37..640dd6bf6 100644 --- a/src/qdoc/qdocglobals.h +++ b/src/qdoc/qdocglobals.h @@ -40,45 +40,45 @@ struct QDocCommandLineParser; class QDocGlobals { public: - bool highlighting(); + bool highlighting() const; void enableHighlighting(bool value); - bool showInternal(); + bool showInternal() const; void setShowInternal(bool value); - bool singleExec(); + bool singleExec() const; void setSingleExec(bool value); - bool writeQaPages(); + bool writeQaPages() const; void setWriteQaPages(bool value); - bool redirectDocumentationToDevNull(); + bool redirectDocumentationToDevNull() const; void setRedirectDocumentationToDevNull(bool value); - bool noLinkErrors(); + bool noLinkErrors() const; void setNoLinkErrors(bool value); - bool autolinkErrors(); + bool autolinkErrors() const; void setAutolinkErrors(bool value); - bool obsoleteLinks(); + bool obsoleteLinks() const; void setObsoleteLinks(bool value); - QStringList defines(); + QStringList defines() const; void addDefine(const QStringList &valueList); - QStringList includesPaths(); + QStringList includesPaths() const; void addIncludePath(const QString &flag, const QString &path); QStringList &dependModules(); - QStringList indexDirs(); + QStringList indexDirs() const; void appendToIndexDirs(const QString &path); - QString currentDir(); + QString currentDir() const; void setCurrentDir(const QString &path); - QString previousCurrentDir(); + QString previousCurrentDir() const; void setPreviousCurrentDir(const QString &path); void setOptions(const QDocCommandLineParser &parser); diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp index a41904a8f..9ea7d9f86 100644 --- a/src/qdoc/qdocindexfiles.cpp +++ b/src/qdoc/qdocindexfiles.cpp @@ -108,10 +108,10 @@ void QDocIndexFiles::destroyQDocIndexFiles() */ void QDocIndexFiles::readIndexes(const QStringList &indexFiles) { - foreach (const QString &indexFile, indexFiles) { - QString msg = "Loading index file: " + indexFile; + for (const QString &file : indexFiles) { + QString msg = "Loading index file: " + file; Location::logToStdErr(msg); - readIndexFile(indexFile); + readIndexFile(file); } } @@ -608,8 +608,8 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, QString groupsAttr = attributes.value(QLatin1String("groups")).toString(); if (!groupsAttr.isEmpty()) { - QStringList groupNames = groupsAttr.split(QLatin1Char(',')); - foreach (const QString &name, groupNames) { + const QStringList groupNames = groupsAttr.split(QLatin1Char(',')); + for (const auto &name : groupNames) { qdb_->addToGroup(name, node); } } @@ -691,9 +691,9 @@ void QDocIndexFiles::insertTarget(TargetRec::TargetType type, void QDocIndexFiles::resolveIndex() { QPair<ClassNode *, QString> pair; - foreach (pair, basesList_) { - QStringList bases = pair.second.split(QLatin1Char(',')); - foreach (const QString &base, bases) { + for (const auto &pair : qAsConst(basesList_)) { + const QStringList bases = pair.second.split(QLatin1Char(',')); + for (const auto &base : bases) { QStringList basePath = base.split(QString("::")); Node *n = qdb_->findClassNode(basePath); if (n) @@ -950,9 +950,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, { // Classes contain information about their base classes. const ClassNode *classNode = static_cast<const ClassNode *>(node); - QList<RelatedClass> bases = classNode->baseClasses(); + const QList<RelatedClass> bases = classNode->baseClasses(); QSet<QString> baseStrings; - foreach (const RelatedClass &related, bases) { + for (const auto &related : bases) { ClassNode *n = related.node_; if (n) baseStrings.insert(n->fullName()); @@ -1067,7 +1067,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, */ if (!cn->members().isEmpty()) { QStringList names; - foreach (const Node *member, cn->members()) + const auto &members = cn->members(); + for (const Node *member : members) names.append(member->name()); writer.writeAttribute("members", names.join(QLatin1Char(','))); } @@ -1092,7 +1093,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, */ if (!cn->members().isEmpty()) { QStringList names; - foreach (const Node *member, cn->members()) + const auto &members = cn->members(); + for (const Node *member : members) names.append(member->name()); writer.writeAttribute("members", names.join(QLatin1Char(','))); } @@ -1118,7 +1120,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, */ if (!cn->members().isEmpty()) { QStringList names; - foreach (const Node *member, cn->members()) + const auto &members = cn->members(); + for (const Node *member : members) names.append(member->name()); writer.writeAttribute("members", names.join(QLatin1Char(','))); } @@ -1143,7 +1146,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeAttribute("type", propertyNode->dataType()); if (!brief.isEmpty()) writer.writeAttribute("brief", brief); - foreach (const Node *fnNode, propertyNode->getters()) { + const auto &getters = propertyNode->getters(); + for (const auto *fnNode : getters) { if (fnNode) { const FunctionNode *functionNode = static_cast<const FunctionNode *>(fnNode); writer.writeStartElement("getter"); @@ -1151,7 +1155,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeEndElement(); // getter } } - foreach (const Node *fnNode, propertyNode->setters()) { + const auto &setters = propertyNode->setters(); + for (const auto *fnNode : setters) { if (fnNode) { const FunctionNode *functionNode = static_cast<const FunctionNode *>(fnNode); writer.writeStartElement("setter"); @@ -1159,7 +1164,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeEndElement(); // setter } } - foreach (const Node *fnNode, propertyNode->resetters()) { + const auto &resetters = propertyNode->resetters(); + for (const auto *fnNode : resetters) { if (fnNode) { const FunctionNode *functionNode = static_cast<const FunctionNode *>(fnNode); writer.writeStartElement("resetter"); @@ -1167,7 +1173,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeEndElement(); // resetter } } - foreach (const Node *fnNode, propertyNode->notifiers()) { + const auto ¬ifiers = propertyNode->notifiers(); + for (const auto *fnNode : notifiers) { if (fnNode) { const FunctionNode *functionNode = static_cast<const FunctionNode *>(fnNode); writer.writeStartElement("notifier"); @@ -1191,7 +1198,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, const EnumNode *enumNode = static_cast<const EnumNode *>(node); if (enumNode->flagsType()) writer.writeAttribute("typedef",enumNode->flagsType()->fullDocumentName()); - foreach (const EnumItem &item, enumNode->items()) { + const auto &items = enumNode->items(); + for (const auto &item : items) { writer.writeStartElement("value"); writer.writeAttribute("name", item.name()); writer.writeAttribute("value", item.value()); @@ -1227,7 +1235,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, bool external = false; if (node->isExternalPage()) external = true; - foreach (const Atom *target, node->doc().targets()) { + const auto &targets = node->doc().targets(); + for (const Atom *target : targets) { QString title = target->string(); QString name = Doc::canonicalTitle(title); writer.writeStartElement("target"); @@ -1241,7 +1250,8 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, } } if (node->doc().hasKeywords()) { - foreach (const Atom *keyword, node->doc().keywords()) { + const auto &keywords = node->doc().keywords(); + for (const Atom *keyword : keywords) { QString title = keyword->string(); QString name = Doc::canonicalTitle(title); writer.writeStartElement("keyword"); @@ -1273,9 +1283,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, } } } - if (node->isExample()) { + // WebXMLGenerator - skip the nested <page> elements for example + // files/images, as the generator produces them separately + if (node->isExample() && gen_->format() != QLatin1String("WebXML")) { const ExampleNode *en = static_cast<const ExampleNode *>(node); - foreach (const QString &file, en->files()) { + const auto &files = en->files(); + for (const QString &file : files) { writer.writeStartElement("page"); writer.writeAttribute("name", file); QString href = gen_->linkForExampleFile(file, en); @@ -1283,11 +1296,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeAttribute("status", "active"); writer.writeAttribute("subtype", "file"); writer.writeAttribute("title", ""); - writer.writeAttribute("fulltitle", file.mid(file.lastIndexOf('/') + 1) + " Example File"); + writer.writeAttribute("fulltitle", Generator::exampleFileTitle(en, file)); writer.writeAttribute("subtitle", file); writer.writeEndElement(); // page } - foreach (const QString &file, en->images()) { + const auto &images = en->images(); + for (const QString &file : images) { writer.writeStartElement("page"); writer.writeAttribute("name", file); QString href = gen_->linkForExampleFile(file, en); @@ -1295,7 +1309,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter &writer, Node *node, writer.writeAttribute("status", "active"); writer.writeAttribute("subtype", "image"); writer.writeAttribute("title", ""); - writer.writeAttribute("fulltitle", file.mid(file.lastIndexOf('/') + 1) + " Image File"); + writer.writeAttribute("fulltitle", Generator::exampleFileTitle(en, file)); writer.writeAttribute("subtitle", file); writer.writeEndElement(); // page } @@ -1368,8 +1382,8 @@ void QDocIndexFiles::generateFunctionSection(QXmlStreamWriter &writer, FunctionN writer.writeAttribute("refness", QString::number(2)); if (fn->hasAssociatedProperties()) { QStringList associatedProperties; - foreach (Node *n, fn->associatedProperties()) { - associatedProperties << n->name(); + for (const auto *node : qAsConst(fn->associatedProperties())) { + associatedProperties << node->name(); } associatedProperties.sort(); writer.writeAttribute("associated-property", associatedProperties.join(QLatin1Char(','))); @@ -1462,8 +1476,9 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter &writer, Node *node, Aggregate *aggregate = static_cast<Aggregate *>(node); // First write the function children, then write the nonfunction children. generateFunctionSections(writer, aggregate); - foreach (Node *n, aggregate->nonfunctionList()) - generateIndexSections(writer, n, post); + const auto &nonFunctionList = aggregate->nonfunctionList(); + for (auto *node : nonFunctionList) + generateIndexSections(writer, node, post); } if (node == root_) { diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp index 41d485444..bdf001469 100644 --- a/src/qdoc/qdoctagfiles.cpp +++ b/src/qdoc/qdoctagfiles.cpp @@ -96,7 +96,8 @@ void QDocTagFiles::destroyQDocTagFiles() */ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter &writer, const Aggregate *parent) { - foreach (const Node *node, const_cast<Aggregate *>(parent)->nonfunctionList()) { + const auto &nonFunctionList = const_cast<Aggregate *>(parent)->nonfunctionList(); + for (const auto *node : nonFunctionList) { if (!node->url().isEmpty() || node->isPrivate()) continue; @@ -137,8 +138,8 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter &writer, const Aggr // Classes contain information about their base classes. const ClassNode *classNode = static_cast<const ClassNode *>(node); - QList<RelatedClass> bases = classNode->baseClasses(); - foreach (const RelatedClass& related, bases) { + const QList<RelatedClass> bases = classNode->baseClasses(); + for (const auto &related : bases) { ClassNode *n = related.node_; if (n) writer.writeTextElement("base", n->name()); @@ -170,7 +171,8 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter &writer, const Aggr */ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter &writer, const Aggregate *parent) { - foreach (const Node *node, parent->childNodes()) { + const auto &childNodes = parent->childNodes(); + for (const auto *node : childNodes) { if (!node->url().isEmpty()) continue; diff --git a/src/qdoc/qmlcodeparser.cpp b/src/qdoc/qmlcodeparser.cpp index 8b0b4dcaa..1b8688f00 100644 --- a/src/qdoc/qmlcodeparser.cpp +++ b/src/qdoc/qmlcodeparser.cpp @@ -147,7 +147,8 @@ void QmlCodeParser::parseSourceFile(const Location &location, const QString &fil << "The output is incomplete."; } } - foreach (const QQmlJS::DiagnosticMessage &msg, parser->diagnosticMessages()) { + const auto &messages = parser->diagnosticMessages(); + for (const auto &msg : messages) { qDebug().nospace() << qPrintable(filePath) << ':' #if Q_QML_PRIVATE_API_VERSION < 5 << msg.loc.startLine << ": QML syntax error at col " diff --git a/src/qdoc/qmlmarkupvisitor.cpp b/src/qdoc/qmlmarkupvisitor.cpp index 37a23c072..e032e8884 100644 --- a/src/qdoc/qmlmarkupvisitor.cpp +++ b/src/qdoc/qmlmarkupvisitor.cpp @@ -192,7 +192,7 @@ void QmlMarkupVisitor::addMarkedUpToken( return; output += QString(QLatin1String("<@%1")).arg(tagName); - foreach (const QString &key, attributes) + for (const auto &key : attributes) output += QString(QLatin1String(" %1=\"%2\"")).arg(key).arg(attributes[key]); output += QString(QLatin1String(">%2</@%3>")).arg(protect(sourceText(location)), tagName); cursor += location.length; @@ -236,7 +236,8 @@ bool QmlMarkupVisitor::visit(QQmlJS::AST::UiImport *uiimport) void QmlMarkupVisitor::endVisit(QQmlJS::AST::UiImport *uiimport) { - addVerbatim(uiimport->versionToken); + if (uiimport->version) + addVerbatim(uiimport->version->firstSourceLocation(), uiimport->version->lastSourceLocation()); addVerbatim(uiimport->asToken); addMarkedUpToken(uiimport->importIdToken, QLatin1String("headerfile")); addVerbatim(uiimport->semicolonToken); diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp index c7be4b1cf..1195234c2 100644 --- a/src/qdoc/qmlvisitor.cpp +++ b/src/qdoc/qmlvisitor.cpp @@ -584,10 +584,14 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiImport *import) QString name = document.mid(import->fileNameToken.offset, import->fileNameToken.length); if (name[0] == '\"') name = name.mid(1, name.length()-2); - QString version = document.mid(import->versionToken.offset, import->versionToken.length); + QString version; + if (import->version) { + const auto start = import->version->firstSourceLocation().begin(); + const auto end = import->version->lastSourceLocation().end(); + version = document.mid(start, end - start); + } QString importId = document.mid(import->importIdToken.offset, import->importIdToken.length); QString importUri = getFullyQualifiedId(import->importUri); - QString reconstructed = importUri + QLatin1Char(' ') + version; importList.append(ImportRec(name, version, importId, importUri)); return true; diff --git a/src/qdoc/tokenizer.cpp b/src/qdoc/tokenizer.cpp index ddfe61002..45c33fa7c 100644 --- a/src/qdoc/tokenizer.cpp +++ b/src/qdoc/tokenizer.cpp @@ -518,17 +518,18 @@ void Tokenizer::initialize(const Config &config) ignoredTokensAndDirectives = new QHash<QByteArray, bool>; - QStringList tokens = config.getStringList(LANGUAGE_CPP + Config::dot + CONFIG_IGNORETOKENS); - foreach (const QString &t, tokens) { - const QByteArray tb = t.toLatin1(); + const QStringList tokens = + config.getStringList(LANGUAGE_CPP + Config::dot + CONFIG_IGNORETOKENS); + for (const auto &token : tokens) { + const QByteArray tb = token.toLatin1(); ignoredTokensAndDirectives->insert(tb, false); insertKwordIntoHash(tb.data(), -1); } - QStringList directives = config.getStringList(LANGUAGE_CPP + Config::dot + const QStringList directives = config.getStringList(LANGUAGE_CPP + Config::dot + CONFIG_IGNOREDIRECTIVES); - foreach (const QString &d, directives) { - const QByteArray db = d.toLatin1(); + for (const auto &directive : directives) { + const QByteArray db = directive.toLatin1(); ignoredTokensAndDirectives->insert(db, true); insertKwordIntoHash(db.data(), -1); } diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp index d29d41503..1ae07c52b 100644 --- a/src/qdoc/tree.cpp +++ b/src/qdoc/tree.cpp @@ -112,8 +112,8 @@ Tree::~Tree() while (i != targetListMap_->end()) { TargetList *tlist = i.value(); if (tlist) { - foreach (TargetLoc *tloc, *tlist) - delete tloc; + for (auto *location : qAsConst(*tlist)) + delete location; } delete tlist; ++i; @@ -364,7 +364,7 @@ void Tree::resolveCppToQmlLinks() { const NodeList &children = root_.childNodes(); - foreach (Node *child, children) { + for (auto *child : children) { if (child->isQmlType() || child->isJsType()) { QmlTypeNode *qcn = static_cast<QmlTypeNode *>(child); ClassNode *cn = const_cast<ClassNode *>(qcn->classNode()); @@ -381,7 +381,7 @@ void Tree::resolveCppToQmlLinks() void Tree::resolveUsingClauses() { const NodeList &children = root_.childNodes(); - foreach (Node *child, children) { + for (auto *child : children) { if (child->isClassNode()) { ClassNode *cn = static_cast<ClassNode *>(child); QList<UsingClause> &usingClauses = cn->usingClauses(); @@ -427,10 +427,11 @@ void Tree::removePrivateAndInternalBases(NamespaceNode *rootNode) ClassList Tree::allBaseClasses(const ClassNode *classNode) const { ClassList result; - foreach (const RelatedClass &r, classNode->baseClasses()) { - if (r.node_ != nullptr) { - result += r.node_; - result += allBaseClasses(r.node_); + const auto &baseClasses = classNode->baseClasses(); + for (const auto &relatedClass : baseClasses) { + if (relatedClass.node_ != nullptr) { + result += relatedClass.node_; + result += allBaseClasses(relatedClass.node_); } } return result; @@ -477,19 +478,19 @@ Node *Tree::findNodeRecursive(const QStringList &path, Aggregate *current = static_cast<Aggregate *>(node); const NodeList &children = current->childNodes(); const QString &name = path.at(pathIndex); - foreach (Node *n, children) { - if (n == nullptr) + for (auto *node : children) { + if (node == nullptr) continue; - if (n->name() == name) { + if (node->name() == name) { if (pathIndex+1 >= path.size()) { - if ((n->*(isMatch))()) - return n; + if ((node->*(isMatch))()) + return node; continue; } else { // Search the children of n for the next name in the path. - n = findNodeRecursive(path, pathIndex+1, n, isMatch); - if (n != nullptr) - return n; + node = findNodeRecursive(path, pathIndex+1, node, isMatch); + if (node != nullptr) + return node; } } } @@ -633,10 +634,10 @@ const Node *Tree::matchPathAndTarget(const QStringList &path, if (node->isAggregate()) { NodeVector nodes; static_cast<const Aggregate *>(node)->findChildren(name, nodes); - foreach (const Node *n, nodes) { - if (genus != Node::DontCare && n->genus() != genus) + for (const auto *node : qAsConst(nodes)) { + if (genus != Node::DontCare && node->genus() != genus) continue; - const Node *t = matchPathAndTarget(path, idx + 1, target, n, flags, genus, ref); + const Node *t = matchPathAndTarget(path, idx + 1, target, node, flags, genus, ref); if (t && !t->isPrivate()) return t; } @@ -650,8 +651,8 @@ const Node *Tree::matchPathAndTarget(const QStringList &path, } if (((genus == Node::CPP) || (genus == Node::DontCare)) && node->isClassNode() && (flags & SearchBaseClasses)) { - ClassList bases = allBaseClasses(static_cast<const ClassNode *>(node)); - foreach (const ClassNode *base, bases) { + const ClassList bases = allBaseClasses(static_cast<const ClassNode *>(node)); + for (const auto *base : bases) { const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref); if (t && ! t->isPrivate()) return t; @@ -720,8 +721,8 @@ const Node *Tree::findNode(const QStringList &path, } if ((next == nullptr) && ((genus == Node::CPP) || (genus == Node::DontCare)) && node->isClassNode() && (flags & SearchBaseClasses)) { - ClassList bases = allBaseClasses(static_cast<const ClassNode *>(node)); - foreach (const ClassNode *base, bases) { + const ClassList bases = allBaseClasses(static_cast<const ClassNode *>(node)); + for (const auto *base : bases) { next = base->findChildNode(path.at(i), genus, tmpFlags); if ((next == nullptr) && (flags & SearchEnumValues) && i == path.size() - 1) next = base->findEnumNodeForValue(path.at(i)); @@ -788,7 +789,7 @@ void Tree::insertTarget(const QString &name, */ void Tree::resolveTargets(Aggregate *root) { - foreach (Node *child, root->childNodes()) { + for (auto *child : root->childNodes()) { if (child->isTextPageNode()) { PageNode *node = static_cast<PageNode *>(child); QString key = node->title(); @@ -1284,8 +1285,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, next = aggregate->findChildNode(path.at(i), genus); if ((next == nullptr) && aggregate->isClassNode()) { - ClassList bases = allBaseClasses(static_cast<const ClassNode *>(aggregate)); - foreach (ClassNode *base, bases) { + const ClassList bases = allBaseClasses(static_cast<const ClassNode *>(aggregate)); + for (auto *base : bases) { if (i == path.size() - 1) next = base->findFunctionChild(path.at(i), parameters); else diff --git a/src/qdoc/webxmlgenerator.cpp b/src/qdoc/webxmlgenerator.cpp index a4a14f7b7..ba1ad8389 100644 --- a/src/qdoc/webxmlgenerator.cpp +++ b/src/qdoc/webxmlgenerator.cpp @@ -32,6 +32,7 @@ #include "node.h" #include "qdocdatabase.h" #include "separator.h" +#include "quoter.h" #include "tree.h" #include <QtCore/qxmlstream.h> @@ -65,10 +66,17 @@ QString WebXMLGenerator::fileExtension() const return "html"; } -int WebXMLGenerator::generateAtom(const Atom * /* atom, */, - const Node * /* relative */, - CodeMarker * /* marker */) +/*! + Most of the output is generated by QDocIndexFiles and the append() callback. + Some pages produce supplementary output while being generated, and that's + handled here. +*/ +int WebXMLGenerator::generateAtom(const Atom *atom, + const Node *relative, + CodeMarker *marker) { + if (supplement && currentWriter) + addAtomElements(*currentWriter.data(), atom, relative, marker); return 0; } @@ -95,27 +103,73 @@ void WebXMLGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker void WebXMLGenerator::generatePageNode(PageNode *pn, CodeMarker * /* marker */) { QByteArray data; + currentWriter.reset(new QXmlStreamWriter(&data)); + currentWriter->setAutoFormatting(true); + beginSubPage(pn, Generator::fileName(pn, "webxml")); + currentWriter->writeStartDocument(); + currentWriter->writeStartElement("WebXML"); + currentWriter->writeStartElement("document"); + + generateIndexSections(*currentWriter.data(), pn); + + currentWriter->writeEndElement(); // document + currentWriter->writeEndElement(); // WebXML + currentWriter->writeEndDocument(); + + out() << data; + endSubPage(); +} + +void WebXMLGenerator::generateExampleFilePage(const Node *en, + const QString &file, + CodeMarker * /* marker */) +{ + QByteArray data; QXmlStreamWriter writer(&data); writer.setAutoFormatting(true); - beginSubPage(pn, Generator::fileName(pn, "webxml")); + beginFilePage(en, linkForExampleFile(file, en, "webxml")); writer.writeStartDocument(); writer.writeStartElement("WebXML"); writer.writeStartElement("document"); + writer.writeStartElement("page"); + writer.writeAttribute("name", file); + writer.writeAttribute("href", linkForExampleFile(file, en)); + QString title = exampleFileTitle(static_cast<const ExampleNode *>(en), file); + writer.writeAttribute("title", title); + writer.writeAttribute("fulltitle", title); + writer.writeAttribute("subtitle", file); + writer.writeStartElement("description"); + QString userFriendlyFilePath; // unused + writer.writeAttribute("path", Doc::resolveFile(en->doc().location(), + file, + &userFriendlyFilePath)); + writer.writeAttribute("line", "0"); + writer.writeAttribute("column", "0"); + + Quoter quoter; + Doc::quoteFromFile(en->doc().location(), quoter, file); + QString code = quoter.quoteTo(en->location(), QString(), QString()); + writer.writeTextElement("code", trimmedTrailing(code, QString(), QString())); - generateIndexSections(writer, pn); + writer.writeEndElement(); // description + writer.writeEndElement(); // page writer.writeEndElement(); // document writer.writeEndElement(); // WebXML writer.writeEndDocument(); + out() << data; - endSubPage(); + endFilePage(); } void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer, Node *node) { marker_ = CodeMarker::markerForFileName(node->location().filePath()); QDocIndexFiles::qdocIndexFiles()->generateIndexSections(writer, node, this); + // generateIndexSections does nothing for groups, so handle them explicitly + if (node->isGroup()) + QDocIndexFiles::qdocIndexFiles()->generateIndexSection(writer, node, this); } // Handles callbacks from QDocIndexFiles to add documentation to node @@ -180,6 +234,17 @@ void WebXMLGenerator::append(QXmlStreamWriter &writer, Node *node) } writer.writeEndElement(); // see-also } + + if (node->isExample()) { + supplement = true; + generateRequiredLinks(node, marker_); + supplement = false; + } else if (node->isGroup()) { + CollectionNode *cn = static_cast<CollectionNode *>(node); + if (!cn->noAutoList()) + generateAnnotatedList(writer, node, cn->members()); + } + writer.writeEndElement(); // description } @@ -225,6 +290,13 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, bool keepQuoting = false; switch (atom->type()) { + case Atom::AnnotatedList: + { + const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::Group); + if (cn) + generateAnnotatedList(writer, relative, cn->members()); + } + break; case Atom::AutoLink: if (!inLink && !inSectionHeading) { const Node *node = nullptr; @@ -349,6 +421,26 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, } break; + case Atom::ExampleFileLink: + { + if (!inLink) { + QString link = linkForExampleFile(atom->string(), relative); + if (!link.isEmpty()) + startLink(writer, atom, relative, link); + } + } + break; + + case Atom::ExampleImageLink: + { + if (!inLink) { + QString link = atom->string(); + if (!link.isEmpty()) + startLink(writer, atom, nullptr, "images/used-in-examples/" + link); + } + } + break; + case Atom::FootnoteLeft: writer.writeStartElement("footnote"); break; @@ -453,7 +545,7 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, if (!inLink) { const Node *node = nullptr; QString link = getLink(atom, relative, &node); - if (node) + if (!link.isEmpty()) startLink(writer, atom, node, link); } break; @@ -668,27 +760,41 @@ const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom, const Node *node, const QString &link) { - QString fullName = node->fullName(); + QString fullName = link; + if (node) + fullName = node->fullName(); if (!fullName.isEmpty() && !link.isEmpty()) { writer.writeStartElement("link"); writer.writeAttribute("raw", atom->string()); writer.writeAttribute("href", link); writer.writeAttribute("type", targetType(node)); - switch (node->nodeType()) { - case Node::Enum: - writer.writeAttribute("enum", fullName); - break; - case Node::Page: - writer.writeAttribute("page", fullName); - break; - case Node::Property: - { - const PropertyNode *propertyNode = static_cast<const PropertyNode *>(node); - if (propertyNode->getters().size() > 0) - writer.writeAttribute("getter", propertyNode->getters().at(0)->fullName()); - } - default: - ; + if (node) { + switch (node->nodeType()) { + case Node::Enum: + writer.writeAttribute("enum", fullName); + break; + case Node::Example: + { + const ExampleNode *en = static_cast<const ExampleNode *>(node); + QString fileTitle = exampleFileTitle(en, atom->string()); + if (!fileTitle.isEmpty()) { + writer.writeAttribute("page", fileTitle); + break; + } + } + // fall through + case Node::Page: + writer.writeAttribute("page", fullName); + break; + case Node::Property: + { + const PropertyNode *propertyNode = static_cast<const PropertyNode *>(node); + if (propertyNode->getters().size() > 0) + writer.writeAttribute("getter", propertyNode->getters().at(0)->fullName()); + } + default: + ; + } } inLink = true; } @@ -696,6 +802,9 @@ void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom, QString WebXMLGenerator::targetType(const Node *node) { + if (!node) + return "external"; + switch (node->nodeType()) { case Node::Namespace: return "namespace"; @@ -704,6 +813,7 @@ QString WebXMLGenerator::targetType(const Node *node) case Node::Union: return "class"; case Node::Page: + case Node::Example: return "page"; case Node::Enum: return "enum"; @@ -771,13 +881,16 @@ void WebXMLGenerator::generateRelations(QXmlStreamWriter &writer, const Node *no void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer, const Node *relative, const NodeMap &nodeMap) { + generateAnnotatedList(writer, relative, nodeMap.values()); +} + +void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer, + const Node *relative, const NodeList &nodeList) +{ writer.writeStartElement("table"); writer.writeAttribute("width", "100%"); - for (NodeMap::const_iterator it = nodeMap.cbegin(), - end = nodeMap.cend(); it != end; ++it) { - const Node *node = it.value(); - + for (const auto *node : nodeList) { writer.writeStartElement("row"); writer.writeStartElement("heading"); generateFullName(writer, node, relative); @@ -794,10 +907,14 @@ void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer, void WebXMLGenerator::generateFullName(QXmlStreamWriter &writer, const Node *node, const Node *relative) { + QString type = targetType(node); + QString name = node->fullName(relative); writer.writeStartElement("link"); writer.writeAttribute("href", fullDocumentLocation(node)); - writer.writeAttribute("type", targetType(node)); - writer.writeCharacters(node->fullName(relative)); + writer.writeAttribute("type", type); + if (type == QLatin1String("page")) + writer.writeAttribute("page", name); + writer.writeCharacters(name); writer.writeEndElement(); // link } diff --git a/src/qdoc/webxmlgenerator.h b/src/qdoc/webxmlgenerator.h index b52ffb398..5e3e0e9e2 100644 --- a/src/qdoc/webxmlgenerator.h +++ b/src/qdoc/webxmlgenerator.h @@ -34,6 +34,7 @@ #include "htmlgenerator.h" #include "qdocindexfiles.h" +#include <QtCore/qscopedpointer.h> #include <QtCore/qxmlstream.h> QT_BEGIN_NAMESPACE @@ -54,6 +55,7 @@ protected: void generateCppReferencePage(Aggregate *aggregate, CodeMarker *marker) override; void generatePageNode(PageNode *pn, CodeMarker *marker) override; void generateDocumentation(Node *node) override; + void generateExampleFilePage(const Node *en, const QString &file, CodeMarker *marker) override; QString fileExtension() const override; virtual const Atom *addAtomElements(QXmlStreamWriter &writer, const Atom *atom, @@ -64,6 +66,7 @@ protected: private: const QPair<QString,QString> anchorForNode(const Node *node); void generateAnnotatedList(QXmlStreamWriter &writer, const Node *relative, const NodeMap &nodeMap); + void generateAnnotatedList(QXmlStreamWriter &writer, const Node *relative, const NodeList &nodeList); void generateFullName(QXmlStreamWriter &writer, const Node *node, const Node *relative); void generateRelations(QXmlStreamWriter &writer, const Node *node); @@ -77,6 +80,8 @@ private: bool hasQuotingInformation; int numTableRows; QString quoteCommand; + QScopedPointer<QXmlStreamWriter> currentWriter; + bool supplement = false; }; QT_END_NAMESPACE diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp index 38869b282..48b28f3ee 100644 --- a/src/windeployqt/main.cpp +++ b/src/windeployqt/main.cpp @@ -1493,11 +1493,12 @@ static DeployResult deploy(const Options &options, if (options.patchQt && !options.dryRun && !options.isWinRt()) { const QString qt6CoreName = QFileInfo(libraryPath(libraryLocation, "Qt6Core", qtLibInfix, options.platform, isDebug)).fileName(); - +#ifndef QT_RELOCATABLE if (!patchQtCore(targetPath + QLatin1Char('/') + qt6CoreName, errorMessage)) { std::wcerr << "Warning: " << *errorMessage << '\n'; errorMessage->clear(); } +#endif } } // optLibraries diff --git a/src/windeployqt/windeployqt.pro b/src/windeployqt/windeployqt.pro index fb12a12f3..cd09c238f 100644 --- a/src/windeployqt/windeployqt.pro +++ b/src/windeployqt/windeployqt.pro @@ -10,4 +10,7 @@ CONFIG += force_bootstrap win32: LIBS += -lshlwapi QMAKE_TARGET_DESCRIPTION = "Qt Windows Deployment Tool" + +qtConfig(relocatable): DEFINES += QT_RELOCATABLE + load(qt_tool) diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html new file mode 100644 index 000000000..da5398612 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput-linking.html @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<!-- qdoctests-outputfromqdocfiles.qdoc --> + <title>Testing QDoc's link command | Test</title> +</head> +<body> +<div class="sidebar"> +<div class="toc"> +<h3><a name="toc">Contents</a></h3> +<ul> +<li class="level1"><a href="#link-targets">Link targets</a></li> +</ul> +</div> +<div class="sidebar-content" id="sidebar-content"></div></div> +<h1 class="title">Testing QDoc's link command</h1> +<span class="subtitle"></span> +<!-- $$$qdoctests-qdocfileoutput-linking.html-description --> +<div class="descr"> <a name="details"></a> +<a name="link-test-target"></a><a name="link-targets"></a> +<h2 id="link-targets">Link targets</h2> +<p>Valid parameters for the link command (<code>\l</code>) are page and section titles, targets defined with \target or \keyword commands, and API reference keywords (types, methods, namespaces, and so on).</p> +</div> +<!-- @@@qdoctests-qdocfileoutput-linking.html --> +</body> +</html> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html index 199d63ef1..6f444482d 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/qdoctests-qdocfileoutput.html @@ -13,6 +13,7 @@ <ul> <li class="level1"><a href="#supported-file-types">Supported file types</a></li> <li class="level1"><a href="#further-information">Further information</a></li> +<li class="level1"><a href="#linking">Linking</a></li> </ul> </div> <div class="sidebar-content" id="sidebar-content"></div></div> @@ -38,6 +39,15 @@ <li><code>\li</code></li> <li><code>\endlist</code></li> </ul> +<a name="linking"></a> +<h2 id="linking">Linking</h2> +<p>There are multiple ways to create hyperlinks to other topics:</p> +<ul> +<li><a href="qdoctests-qdocfileoutput-linking.html">Linking to a page title</a></li> +<li><a href="qdoctests-qdocfileoutput-linking.html#link-targets">Linking to a section title</a></li> +<li><a href="qdoctests-qdocfileoutput-linking.html#link-test-target">Linking using a \target string</a></li> +<li><a href="qdoctests-qdocfileoutput-linking.html">Linking using a \keyword string</a></li> +</ul> </div> <!-- @@@qdoctests-qdocfileoutput.html --> </body> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-members.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-members.html index caa002a7d..2c0b9b24f 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-members.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-members.html @@ -14,6 +14,7 @@ <ul> <li class="fn"><span class="name"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b></span>()</li> <li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b></span>(int ) : int</li> +<li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b></span>(int , bool )</li> </ul> </body> </html> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-obsolete.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-obsolete.html new file mode 100644 index 000000000..732300dd3 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test-obsolete.html @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<!-- testcpp.cpp --> + <title>Obsolete Members for Test | TestCPP</title> +</head> +<body> +<li>Test</li> +<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div> +<h1 class="title">Obsolete Members for Test</h1> +<p><b>The following members of class <a href="testqdoc-test.html">Test</a> are obsolete.</b> They are provided to keep old source code working. We strongly advise against using them in new code.</p> +<h2>Public Functions</h2> +<div class="table"><table class="alignedsummary"> +<tr><td class="memItemLeft topAlign rightAlign"> <code>(obsolete) </code>void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test-obsolete.html#anotherObsoleteMember">anotherObsoleteMember</a></b>()</td></tr> +<tr><td class="memItemLeft topAlign rightAlign"> <code>(obsolete) </code>void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test-obsolete.html#deprecatedMember">deprecatedMember</a></b>()</td></tr> +<tr><td class="memItemLeft topAlign rightAlign"> <code>(obsolete) </code>void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test-obsolete.html#obsoleteMember">obsoleteMember</a></b>()</td></tr> +</table></div> +<h2>Member Function Documentation</h2> +<!-- $$$anotherObsoleteMember[overload1]$$$anotherObsoleteMember --> +<h3 class="fn" id="anotherObsoleteMember"><a name="anotherObsoleteMember"></a><span class="type">void</span> Test::<span class="name">anotherObsoleteMember</span>()</h3> +<p>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</p> +<p>Use <a href="testqdoc-test-obsolete.html#obsoleteMember">obsoleteMember</a>() instead.</p> +<!-- @@@anotherObsoleteMember --> +<!-- $$$deprecatedMember[overload1]$$$deprecatedMember --> +<h3 class="fn" id="deprecatedMember"><a name="deprecatedMember"></a><span class="type">void</span> Test::<span class="name">deprecatedMember</span>()</h3> +<p>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</p> +<p>Use <a href="testqdoc-test.html#someFunction">someFunction</a>() instead.</p> +<!-- @@@deprecatedMember --> +<!-- $$$obsoleteMember[overload1]$$$obsoleteMember --> +<h3 class="fn" id="obsoleteMember"><a name="obsoleteMember"></a><span class="type">void</span> Test::<span class="name">obsoleteMember</span>()</h3> +<p>This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.</p> +<p>Use <a href="testqdoc-test.html#someFunction">someFunction</a>() instead.</p> +<!-- @@@obsoleteMember --> +</body> +</html> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html index f0ef69491..bf7ba3307 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-test.html @@ -13,6 +13,7 @@ <h3><a name="toc">Contents</a></h3> <ul> <li class="level1"><a href="#public-functions">Public Functions</a></li> +<li class="level1"><a href="#macros">Macros</a></li> <li class="level1"><a href="#details">Detailed Description</a></li> </ul> </div> @@ -24,14 +25,21 @@ <!-- @@@Test --> <div class="table"><table class="alignedsummary"> <tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include <Test></span> -</td></tr></table></div><ul> +</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul> <li><a href="testqdoc-test-members.html">List of all members, including inherited members</a></li> +<li><a href="testqdoc-test-obsolete.html">Obsolete members</a></li> </ul> <a name="public-functions"></a> <h2 id="public-functions">Public Functions</h2> <div class="table"><table class="alignedsummary"> <tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b>()</td></tr> <tr><td class="memItemLeft rightAlign topAlign"> int </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b>(int <i>v</i>)</td></tr> +<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b>(int <i>i</i>, bool <i>b</i> = false)</td></tr> +</table></div> +<a name="macros"></a> +<h2 id="macros">Macros</h2> +<div class="table"><table class="alignedsummary"> +<tr><td class="memItemLeft rightAlign topAlign"> </td><td class="memItemRight bottomAlign"><b><a href="testqdoc-test.html#QDOCTEST_MACRO2">QDOCTEST_MACRO2</a></b>(<i>x</i>)</td></tr> </table></div> <a name="details"></a> <!-- $$$Test-description --> @@ -49,6 +57,18 @@ <h3 class="fn" id="someFunction"><a name="someFunction"></a><span class="type">int</span> Test::<span class="name">someFunction</span>(<span class="type">int</span> <i>v</i>)</h3> <p>Function that takes a parameter <i>v</i>. Also returns the value of <i>v</i>.</p> <!-- @@@someFunction --> +<!-- $$$someFunctionDefaultArg[overload1]$$$someFunctionDefaultArgintbool --> +<h3 class="fn" id="someFunctionDefaultArg"><a name="someFunctionDefaultArg"></a><span class="type">void</span> Test::<span class="name">someFunctionDefaultArg</span>(<span class="type">int</span> <i>i</i>, <span class="type">bool</span> <i>b</i> = false)</h3> +<p>Function that takes a parameter <i>i</i> and <i>b</i>.</p> +<!-- @@@someFunctionDefaultArg --> +</div> +<div class="macros"> +<h2>Macro Documentation</h2> +<!-- $$$QDOCTEST_MACRO2[overload1]$$$QDOCTEST_MACRO2 --> +<h3 class="fn" id="QDOCTEST_MACRO2"><a name="QDOCTEST_MACRO2"></a><span class="name">QDOCTEST_MACRO2</span>(<i>x</i>)</h3> +<p>A macro with argument <i>x</i>.</p> +<p>This function was introduced in Test 1.1.</p> +<!-- @@@QDOCTEST_MACRO2 --> </div> </body> </html> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc.html index d46a4f5c8..baa0d9a65 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc.html @@ -23,8 +23,8 @@ <p>A namespace. <a href="#details">More...</a></p> <!-- @@@TestQDoc --> <div class="table"><table class="alignedsummary"> -<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include <TestQDoc></span> -</td></tr></table></div><ul> +<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include <TestCPP></span> +</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr></table></div><ul> </ul> <a name="classes"></a> <h2 id="classes">Classes</h2> @@ -54,7 +54,7 @@ <div class="macros"> <h2>Macro Documentation</h2> <!-- $$$QDOCTEST_MACRO[overload1]$$$QDOCTEST_MACRO --> -<h3 class="fn" id="QDOCTEST_MACRO"><a name="QDOCTEST_MACRO"></a>TestQDoc::<span class="name">QDOCTEST_MACRO</span></h3> +<h3 class="fn" id="QDOCTEST_MACRO"><a name="QDOCTEST_MACRO"></a><span class="name">QDOCTEST_MACRO</span></h3> <!-- @@@QDOCTEST_MACRO --> </div> </body> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/uicomponents-qmlmodule.html b/tests/auto/qdoc/generatedoutput/expected_output/uicomponents-qmlmodule.html index 87a0d45b5..8c577ab7f 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/uicomponents-qmlmodule.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/uicomponents-qmlmodule.html @@ -13,7 +13,7 @@ <!-- $$$UIComponents-description --> <div class="descr"> <a name="details"></a> <p>This is a listing of a list of UI components implemented by QML types. These files are available for general import and they are based on the Qt Quick Code Samples.</p> -<p>This module is part of the <a href="test-componentset-example.html#">UIComponents</a> example.</p> +<p>This module is part of the <a href="test-componentset-example.html">UIComponents</a> example.</p> </div> <!-- @@@UIComponents --> </body> diff --git a/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc b/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc index fc3a5d870..e56c447c4 100644 --- a/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc +++ b/tests/auto/qdoc/generatedoutput/qdoctests-outputfromqdocfiles.qdoc @@ -55,4 +55,29 @@ \li \c {\li} \li \c {\endlist} \endlist + + \section1 Linking + + There are multiple ways to create hyperlinks to other topics: + + \list + \li \l {Testing QDoc's link command}{Linking to a page title} + \li \l {Link targets}{Linking to a section title} + \li \l {link-test-target}{Linking using a \\target string} + \li \l {QDoc Linking Test}{Linking using a \\keyword string} + \endlist +*/ + +/*! + \keyword QDoc Linking Test + \page qdoctests-qdocfileoutput-linking.html + \title Testing QDoc's link command + \brief This is a page for testing QDoc's link command. + + \target link-test-target + \section1 Link targets + + Valid parameters for the link command (\c {\l}) are page and section + titles, targets defined with \\target or \\keyword commands, and API + reference keywords (types, methods, namespaces, and so on). */ diff --git a/tests/auto/qdoc/generatedoutput/testcpp.cpp b/tests/auto/qdoc/generatedoutput/testcpp.cpp index 12698c9d6..3ed4dc0bd 100644 --- a/tests/auto/qdoc/generatedoutput/testcpp.cpp +++ b/tests/auto/qdoc/generatedoutput/testcpp.cpp @@ -31,12 +31,14 @@ namespace TestQDoc { /*! \module TestCPP + \qtvariable testcpp \title QDoc Test C++ Classes \brief A test module page. */ /*! \namespace TestQDoc + \inheaderfile TestCPP \inmodule TestCPP \brief A namespace. @@ -56,6 +58,51 @@ namespace TestQDoc { */ /*! + \macro QDOCTEST_MACRO2(x) + \relates TestQDoc::Test + \since Test 1.1 + \brief A macro with argument \a x. +*/ + +/*! + \deprecated + + Use someFunction() instead. +*/ +void Test::deprecatedMember() +{ + return; +} + +/*! + \obsolete + + Use someFunction() instead. +*/ +void Test::obsoleteMember() +{ + return; +} + +/*! + \obsolete + + Use obsoleteMember() instead. +*/ +void Test::anotherObsoleteMember() +{ + return; +} + +/*! + Function that takes a parameter \a i and \a b. +*/ +void Test::someFunctionDefaultArg(int i, bool b = false) +{ + return; +} + +/*! Function that takes a parameter \a v. Also returns the value of \a v. */ diff --git a/tests/auto/qdoc/generatedoutput/testcpp.h b/tests/auto/qdoc/generatedoutput/testcpp.h index 46355711c..f39b6d284 100644 --- a/tests/auto/qdoc/generatedoutput/testcpp.h +++ b/tests/auto/qdoc/generatedoutput/testcpp.h @@ -27,12 +27,17 @@ ****************************************************************************/ #pragma once #define QDOCTEST_MACRO test +#define QDOCTEST_MACRO2(x) (x) < 0 ? 0 : (x)) namespace TestQDoc { class Test { public: int someFunction(int v); + void someFunctionDefaultArg(int i, bool b); + void obsoleteMember(); + void anotherObsoleteMember(); + void deprecatedMember(); inline void inlineFunction() {}; }; diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp index 103198d42..09709ac6c 100644 --- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp +++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp @@ -109,10 +109,11 @@ void tst_generatedOutput::compareLineByLine(const QStringList &expectedFiles) QFAIL("Cannot open actual data file!"); QTextStream actualIn(&actualFile); + const QLatin1String delim(": "); int lineNumber = 0; while (!expectedIn.atEnd() && !actualIn.atEnd()) { lineNumber++; - QString prefix = QString::number(lineNumber) + QLatin1String(": "); + QString prefix = file + delim + QString::number(lineNumber) + delim; QString expectedLine = prefix + expectedIn.readLine(); QString actualLine = prefix + actualIn.readLine(); QCOMPARE(actualLine, expectedLine); @@ -136,7 +137,8 @@ void tst_generatedOutput::testAndCompare(const char *input, void tst_generatedOutput::htmlFromQDocFile() { testAndCompare("test.qdocconf", - "qdoctests-qdocfileoutput.html"); + "qdoctests-qdocfileoutput.html " + "qdoctests-qdocfileoutput-linking.html"); } void tst_generatedOutput::htmlFromCpp() |