From 06ff4c6c05ebaf8adb275292f6f0b8a639e74df3 Mon Sep 17 00:00:00 2001 From: Raoul Hecky Date: Fri, 30 Nov 2018 11:43:27 +0100 Subject: [PATCH 01/44] Fix include paths with subfolder When an autotools project is using SUBDIRS it starts a new parser. The new parser object was not propagating includes/defines/flags to the main parser object, and thus the code model did miss those. This commit fixes that. Task-number: QTCREATORBUG-21618 Change-Id: I19ed4dd3820257378e888f3c4935ebd30e958828 Reviewed-by: Eike Ziller --- .../makefileparser.cpp | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.cpp b/src/plugins/autotoolsprojectmanager/makefileparser.cpp index 9c3e32216b6..f56d58422af 100644 --- a/src/plugins/autotoolsprojectmanager/makefileparser.cpp +++ b/src/plugins/autotoolsprojectmanager/makefileparser.cpp @@ -291,12 +291,27 @@ void MakefileParser::parseSubDirs() foreach (const QString& source, parser.sources()) m_sources.append(subDir + slash + source); - // Duplicates might be possible in combination with several - // "..._SUBDIRS" targets - m_makefiles.removeDuplicates(); - m_sources.removeDuplicates(); + // Append the include paths of the sub directory + m_includePaths.append(parser.includePaths()); + + // Append the flags of the sub directory + m_cflags.append(parser.cflags()); + m_cxxflags.append(parser.cxxflags()); + + // Append the macros of the sub directory + foreach (const auto& m, parser.macros()) + { + if (!m_macros.contains(m)) + m_macros.append(m); + } + } + // Duplicates might be possible in combination with several + // "..._SUBDIRS" targets + m_makefiles.removeDuplicates(); + m_sources.removeDuplicates(); + if (subDirs.isEmpty()) m_success = false; } From 03f76770e174dcf78a372b73c9342c190a014799 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 4 Feb 2019 16:35:26 +0100 Subject: [PATCH 02/44] ProjectExplorer: Allow to close all files in a project [ChangeLog] Users can now close all open files of a specific project Fixes: QTCREATORBUG-15593 Change-Id: Icb755511ae682042433030c33671a214c448b8be Reviewed-by: David Schulz --- .../projectexplorer/projectexplorer.cpp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 82d458ffa08..04bbef8bb0f 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -110,6 +110,7 @@ #include #include #include +#include #include #include #include @@ -360,6 +361,7 @@ public: void handleRenameFile(); void handleSetStartupProject(); void setStartupProject(ProjectExplorer::Project *project); + void closeAllFilesInProject(const Project *project); void updateRecentProjectMenu(); void clearRecentProjects(); @@ -441,6 +443,8 @@ public: QAction *m_openFileAction; QAction *m_projectTreeCollapseAllAction; QAction *m_projectTreeExpandAllAction; + Utils::ParameterAction *m_closeProjectFilesActionFileMenu; + Utils::ParameterAction *m_closeProjectFilesActionContextMenu; QAction *m_searchOnFileSystem; QAction *m_showInGraphicalShell; QAction *m_openTerminalHere; @@ -933,6 +937,15 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er cmd->setDescription(dd->m_unloadAction->text()); mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT); + dd->m_closeProjectFilesActionFileMenu = new Utils::ParameterAction( + tr("Close All Files in Project"), tr("Close All Files in Project \"%1\""), + Utils::ParameterAction::AlwaysEnabled, this); + cmd = ActionManager::registerAction(dd->m_closeProjectFilesActionFileMenu, + "ProjectExplorer.CloseProjectFilesFileMenu"); + cmd->setAttribute(Command::CA_UpdateText); + cmd->setDescription(dd->m_closeProjectFilesActionFileMenu->text()); + mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT); + ActionContainer *munload = ActionManager::createMenu(Constants::M_UNLOADPROJECTS); munload->menu()->setTitle(tr("Close Pro&ject")); @@ -1140,6 +1153,15 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er cmd->setDescription(dd->m_unloadActionContextMenu->text()); mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_LAST); + dd->m_closeProjectFilesActionContextMenu = new Utils::ParameterAction( + tr("Close All Files"), tr("Close All Files in Project \"%1\""), + Utils::ParameterAction::EnabledWithParameter, this); + cmd = ActionManager::registerAction(dd->m_closeProjectFilesActionContextMenu, + "ProjectExplorer.CloseAllFilesInProjectContextMenu"); + cmd->setAttribute(Command::CA_UpdateText); + cmd->setDescription(dd->m_closeProjectFilesActionContextMenu->text()); + mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_LAST); + // file properties action dd->m_filePropertiesAction = new QAction(tr("Properties..."), this); cmd = ActionManager::registerAction(dd->m_filePropertiesAction, Constants::FILEPROPERTIES, @@ -1442,6 +1464,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er dd, &ProjectExplorerPluginPrivate::handleRenameFile); connect(dd->m_setStartupProjectAction, &QAction::triggered, dd, &ProjectExplorerPluginPrivate::handleSetStartupProject); + connect(dd->m_closeProjectFilesActionFileMenu, &QAction::triggered, + dd, [] { dd->closeAllFilesInProject(SessionManager::projects().first()); }); + connect(dd->m_closeProjectFilesActionContextMenu, &QAction::triggered, + dd, [] { dd->closeAllFilesInProject(ProjectTree::currentProject()); }); connect(dd->m_projectTreeCollapseAllAction, &QAction::triggered, ProjectTree::instance(), &ProjectTree::collapseAll); connect(dd->m_projectTreeExpandAllAction, &QAction::triggered, @@ -1824,6 +1850,26 @@ void ProjectExplorerPluginPrivate::setStartupProject(Project *project) updateActions(); } +void ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project) +{ + QTC_ASSERT(project, return); + const Utils::FileNameList filesInProject = project->files(Project::AllFiles); + QList openFiles = DocumentModel::openedDocuments(); + Utils::erase(openFiles, [filesInProject](const IDocument *doc) { + return !filesInProject.contains(doc->filePath()); + }); + for (const Project * const otherProject : SessionManager::projects()) { + if (otherProject == project) + continue; + const Utils::FileNameList filesInOtherProject + = otherProject->files(Project::AllFiles); + Utils::erase(openFiles, [filesInOtherProject](const IDocument *doc) { + return filesInOtherProject.contains(doc->filePath()); + }); + } + EditorManager::closeDocuments(openFiles); +} + void ProjectExplorerPluginPrivate::savePersistentSettings() { if (dd->m_shuttingDown) @@ -2332,6 +2378,8 @@ void ProjectExplorerPluginPrivate::updateActions() m_unloadAction->setParameter(projectName); m_unloadActionContextMenu->setParameter(projectNameContextMenu); + m_closeProjectFilesActionFileMenu->setParameter(projectName); + m_closeProjectFilesActionContextMenu->setParameter(projectNameContextMenu); // mode bar build action QAction * const buildAction = ActionManager::command(Constants::BUILD)->action(); @@ -2390,6 +2438,9 @@ void ProjectExplorerPluginPrivate::updateActions() m_unloadAction->setVisible(SessionManager::projects().size() <= 1); m_unloadAction->setEnabled(SessionManager::projects().size() == 1); m_unloadActionContextMenu->setEnabled(SessionManager::hasProjects()); + m_closeProjectFilesActionFileMenu->setVisible(SessionManager::projects().size() <= 1); + m_closeProjectFilesActionFileMenu->setEnabled(SessionManager::projects().size() == 1); + m_closeProjectFilesActionContextMenu->setEnabled(SessionManager::hasProjects()); ActionContainer *aci = ActionManager::actionContainer(Constants::M_UNLOADPROJECTS); From 3f10e77b4cff55dc0daaaa1386dc5479886ea903 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 5 Feb 2019 13:32:52 +0100 Subject: [PATCH 03/44] ProjectExplorer: Close open files along with project Fixes: QTCREATORBUG-15721 Change-Id: Ifb67b7c228facfce52a2fe7ad29a4ecc199d91f4 Reviewed-by: David Schulz --- src/plugins/projectexplorer/projectexplorer.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 04bbef8bb0f..47164b48821 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -361,7 +361,7 @@ public: void handleRenameFile(); void handleSetStartupProject(); void setStartupProject(ProjectExplorer::Project *project); - void closeAllFilesInProject(const Project *project); + bool closeAllFilesInProject(const Project *project); void updateRecentProjectMenu(); void clearRecentProjects(); @@ -1700,6 +1700,9 @@ void ProjectExplorerPlugin::unloadProject(Project *project) if (!DocumentManager::saveModifiedDocumentSilently(document)) return; + if (!dd->closeAllFilesInProject(project)) + return; + dd->addToRecentProjects(document->filePath().toString(), project->displayName()); SessionManager::removeProject(project); @@ -1850,9 +1853,9 @@ void ProjectExplorerPluginPrivate::setStartupProject(Project *project) updateActions(); } -void ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project) +bool ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project) { - QTC_ASSERT(project, return); + QTC_ASSERT(project, return false); const Utils::FileNameList filesInProject = project->files(Project::AllFiles); QList openFiles = DocumentModel::openedDocuments(); Utils::erase(openFiles, [filesInProject](const IDocument *doc) { @@ -1867,7 +1870,7 @@ void ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project return filesInOtherProject.contains(doc->filePath()); }); } - EditorManager::closeDocuments(openFiles); + return EditorManager::closeDocuments(openFiles); } void ProjectExplorerPluginPrivate::savePersistentSettings() From 8d4e550551bcb1305e0a392bf7545e977d8a9cc2 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Tue, 5 Feb 2019 14:48:25 +0100 Subject: [PATCH 04/44] ClangTools: Do not format code after fix-its without ClangFormat plugin Applying analyser fix-its triggers formatting after each fix-it. In case of no ClangFormat plugin this instead lead to indentation call. Do not trigger anything instead when ClangFormat is not enabled. Task-number: QTCREATORBUG-21880 Change-Id: I2f9e6e69be0366d2bb0701228bb5d562ef0095f2 Reviewed-by: Nikolai Kosjar --- src/plugins/texteditor/indenter.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h index 2907ea783ce..8a663be9037 100644 --- a/src/plugins/texteditor/indenter.h +++ b/src/plugins/texteditor/indenter.h @@ -91,11 +91,10 @@ public: } // By default just calls indent with default settings. - virtual Replacements format(const QTextCursor &cursor, - const TabSettings &tabSettings, - int cursorPositionInEditor = -1) + virtual Replacements format(const QTextCursor &/*cursor*/, + const TabSettings &/*tabSettings*/, + int /*cursorPositionInEditor*/ = -1) { - indent(cursor, QChar::Null, tabSettings, cursorPositionInEditor); return Replacements(); } From 8bc7e040121d0d47a39c0bc286625afce7a4f64d Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 12:32:46 +0100 Subject: [PATCH 05/44] ProjectExplorer: Fix build directory expansion QDir::cleanPath() must be called on the expanded path, otherwise it messes with the data. For instance, QDir::cleanPath("%{a:b}/..") yields ".". Change-Id: If55b9c7a733097cb36f62fbdae49fe03b542fcdf Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/buildconfiguration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 5297ec7c84d..7973ed4c056 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -86,7 +86,7 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id) Utils::FileName BuildConfiguration::buildDirectory() const { - const QString path = macroExpander()->expand(QDir::cleanPath(environment().expandVariables(m_buildDirectory.toString()))); + const QString path = QDir::cleanPath(macroExpander()->expand(environment().expandVariables(m_buildDirectory.toString()))); return Utils::FileName::fromString(QDir::cleanPath(QDir(target()->project()->projectDirectory().toString()).absoluteFilePath(path))); } From e25be3d5ee762093da01119d3a2f19fc0815d2e8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 28 Jan 2019 10:05:38 +0100 Subject: [PATCH 06/44] PerfProfiler: Allow creating trace points without valid project We can still create trace points on the desktop device then. Change-Id: I123bece2d11a6405883e0bcec9b066cec4e017b9 Reviewed-by: Christian Kandeler --- .../perfprofiler/perftracepointdialog.cpp | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/plugins/perfprofiler/perftracepointdialog.cpp b/src/plugins/perfprofiler/perftracepointdialog.cpp index b821924f832..f42ec8a9a7a 100644 --- a/src/plugins/perfprofiler/perftracepointdialog.cpp +++ b/src/plugins/perfprofiler/perftracepointdialog.cpp @@ -26,6 +26,7 @@ #include "perftracepointdialog.h" #include "ui_perftracepointdialog.h" +#include #include #include #include @@ -46,17 +47,26 @@ PerfTracePointDialog::PerfTracePointDialog() : { m_ui->setupUi(this); - Project *currentProject = SessionManager::startupProject(); - QTC_ASSERT(currentProject, return); + if (Project *currentProject = SessionManager::startupProject()) { + if (const Target *target = currentProject->activeTarget()) { + const Kit *kit = target->kit(); + QTC_ASSERT(kit, return); - const Target *target = currentProject->activeTarget(); - QTC_ASSERT(target, return); + m_device = DeviceKitInformation::device(kit); + if (!m_device) { + m_ui->textEdit->setPlainText(tr("Error: No device available for active target.")); + return; + } + } + } - const Kit *kit = target->kit(); - QTC_ASSERT(kit, return); + if (!m_device) { + const DeviceManager *deviceManager = DeviceManager::instance(); - m_device = DeviceKitInformation::device(kit); - QTC_ASSERT(m_device, return); + // There should at least be a desktop device. + m_device = deviceManager->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); + QTC_ASSERT(m_device, return); + } QFile file(":/perfprofiler/tracepoints.sh"); if (file.open(QIODevice::ReadOnly)) { From 9cfc4a68db9e5a16b33f48ef5811fdb410d40cda Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 6 Feb 2019 14:22:09 +0100 Subject: [PATCH 07/44] ClangTools: Hide file path items without diagnostics ...in case diagnostics are filtered out. Change-Id: I8a78f8873577ca80fe5a3d4123f64a9432c0fb7f Reviewed-by: Ivan Donchevskii --- src/plugins/clangtools/clangtidyclazytool.cpp | 7 ++++++ src/plugins/clangtools/clangtidyclazytool.h | 2 ++ src/plugins/clangtools/clangtool.h | 2 +- .../clangtools/clangtoolsdiagnosticmodel.cpp | 24 ++++++++++++++++--- .../clangtools/clangtoolsdiagnosticmodel.h | 2 ++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp index 233f6d87eba..aa9853825cf 100644 --- a/src/plugins/clangtools/clangtidyclazytool.cpp +++ b/src/plugins/clangtools/clangtidyclazytool.cpp @@ -471,6 +471,13 @@ QList ClangTidyClazyTool::read(const QString &filePath, return readSerializedDiagnostics(filePath, projectRootDir, logFilePath, errorMessage); } +void ClangTidyClazyTool::onNewDiagnosticsAvailable(const QList &diagnostics) +{ + ClangTool::onNewDiagnosticsAvailable(diagnostics); + if (!m_diagnosticFilterModel->filterRegExp().pattern().isEmpty()) + m_diagnosticFilterModel->invalidateFilter(); +} + } // namespace Internal } // namespace ClangTools diff --git a/src/plugins/clangtools/clangtidyclazytool.h b/src/plugins/clangtools/clangtidyclazytool.h index 7cde29f89d7..24aac6673bf 100644 --- a/src/plugins/clangtools/clangtidyclazytool.h +++ b/src/plugins/clangtools/clangtidyclazytool.h @@ -58,6 +58,8 @@ public: const QString &logFilePath, QString *errorMessage) const final; + void onNewDiagnosticsAvailable(const QList &diagnostics) override; + private: void handleStateUpdate() final; diff --git a/src/plugins/clangtools/clangtool.h b/src/plugins/clangtools/clangtool.h index de4d08ceb9d..65dde580095 100644 --- a/src/plugins/clangtools/clangtool.h +++ b/src/plugins/clangtools/clangtool.h @@ -62,7 +62,7 @@ public: const QString &name() const; - void onNewDiagnosticsAvailable(const QList &diagnostics); + virtual void onNewDiagnosticsAvailable(const QList &diagnostics); signals: void finished(bool success); // For testing. diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index 00bf9112b95..5b824f22508 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -584,14 +584,32 @@ void DiagnosticFilterModel::addSuppressedDiagnostic( invalidate(); } +void DiagnosticFilterModel::invalidateFilter() +{ + QSortFilterProxyModel::invalidateFilter(); +} + bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { auto model = static_cast(sourceModel()); - Utils::TreeItem *item = model->itemForIndex(sourceParent); + + // FilePathItem - hide if no diagnostics match + if (!sourceParent.isValid()) { + const QModelIndex filePathIndex = model->index(sourceRow, 0); + const int rowCount = model->rowCount(filePathIndex); + if (rowCount == 0) + return true; // Children not yet added. + for (int row = 0; row < rowCount; ++row) { + if (filterAcceptsRow(row, filePathIndex)) + return true; + } + return false; + } // DiagnosticItem - if (auto filePathItem = dynamic_cast(item)) { + Utils::TreeItem *parentItem = model->itemForIndex(sourceParent); + if (auto filePathItem = dynamic_cast(parentItem)) { auto diagnosticItem = dynamic_cast(filePathItem->childAt(sourceRow)); QTC_ASSERT(diagnosticItem, return false); @@ -612,7 +630,7 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, return diag.description.contains(filterRegExp()); } - return true; + return true; // ExplainingStepItem } bool DiagnosticFilterModel::lessThan(const QModelIndex &l, const QModelIndex &r) const diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h index 8a69e9def76..22d06992018 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h @@ -146,6 +146,8 @@ public: void addSuppressedDiagnostic(const SuppressedDiagnostic &diag); ProjectExplorer::Project *project() const { return m_project; } + void invalidateFilter(); + private: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan(const QModelIndex &l, const QModelIndex &r) const override; From 8d9d24bc65f2bf94feb2b1ce05ffd2d33c797896 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 6 Feb 2019 14:47:22 +0100 Subject: [PATCH 08/44] ClangTools: Fix copy action * Location of the main diagnostic was not included. * No actual message/text of an ExplainingStepItem ended up in the tooltip. * Copy file path for FilePathItem * Copy location and text for ExplainingStepItem Change-Id: I47b890f77f5ff680ce82a75b51b598681a481385 Reviewed-by: Ivan Donchevskii --- .../clangtools/clangtoolsdiagnosticmodel.cpp | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index 5b824f22508..657ffe36d24 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -57,6 +57,8 @@ QVariant FilePathItem::data(int column, int role) const return m_filePath; case Qt::DecorationRole: return Core::FileIconProvider::icon(m_filePath); + case Debugger::DetailedErrorView::FullTextRole: + return m_filePath; default: return QVariant(); } @@ -295,15 +297,24 @@ static QString createExplainingStepString(const ExplainingStep &explainingStep, { return createExplainingStepNumberString(number) + QLatin1Char(' ') - + explainingStep.extendedMessage + + explainingStep.message + QLatin1Char(' ') + createLocationString(explainingStep.location); } + +static QString lineColumnString(const Debugger::DiagnosticLocation &location) +{ + return QString("%1:%2").arg(QString::number(location.line), QString::number(location.column)); +} + static QString fullText(const Diagnostic &diagnostic) { - // Summary. - QString text = diagnostic.category + QLatin1String(": ") + diagnostic.type; + QString text = diagnostic.location.filePath + QLatin1Char(':'); + text += lineColumnString(diagnostic.location) + QLatin1String(": "); + if (!diagnostic.category.isEmpty()) + text += diagnostic.category + QLatin1String(": "); + text += diagnostic.type; if (diagnostic.type != diagnostic.description) text += QLatin1String(": ") + diagnostic.description; text += QLatin1Char('\n'); @@ -380,11 +391,6 @@ static QVariant iconData(const QString &type) return QVariant(); } -static QString lineColumnString(const Debugger::DiagnosticLocation &location) -{ - return QString("%1:%2").arg(QString::number(location.line), QString::number(location.column)); -} - QVariant DiagnosticItem::data(int column, int role) const { if (column == DiagnosticView::FixItColumn) { @@ -509,8 +515,10 @@ QVariant ExplainingStepItem::data(int column, int role) const switch (role) { case Debugger::DetailedErrorView::LocationRole: return QVariant::fromValue(m_step.location); - case Debugger::DetailedErrorView::FullTextRole: - return fullText(static_cast(parent())->diagnostic()); + case Debugger::DetailedErrorView::FullTextRole: { + return QString("%1:%2: %3") + .arg(m_step.location.filePath, lineColumnString(m_step.location), m_step.message); + } case ClangToolsDiagnosticModel::TextRole: return m_step.message; case ClangToolsDiagnosticModel::DiagnosticRole: From f5867d0fff5a963e2a32e6a562b6da0cae5f91fb Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 6 Feb 2019 15:18:28 +0100 Subject: [PATCH 09/44] ClangTools: Fix showing location for ExplainingStepItem In case the ExplainingStepItem refers to another file than the main diagnostic, display the file name too. Change-Id: I1df2781766dc0c7a58b451e3c96b78574d574e54 Reviewed-by: Ivan Donchevskii --- .../clangtools/clangtoolsdiagnosticmodel.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index 657ffe36d24..7a2d78ed3a3 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -524,21 +524,28 @@ QVariant ExplainingStepItem::data(int column, int role) const case ClangToolsDiagnosticModel::DiagnosticRole: return QVariant::fromValue(static_cast(parent())->diagnostic()); case Qt::DisplayRole: { + const QString mainFilePath = static_cast(parent())->diagnostic().location.filePath; + const QString locationString + = m_step.location.filePath == mainFilePath + ? lineColumnString(m_step.location) + : QString("%1:%2").arg(QFileInfo(m_step.location.filePath).fileName(), + lineColumnString(m_step.location)); + if (m_step.isFixIt) { if (m_step.ranges[0] == m_step.ranges[1]) { return QString("%1: Insertion of \"%2\".") - .arg(lineColumnString(m_step.location), m_step.message); + .arg(locationString, m_step.message); } if (m_step.message.isEmpty()) { return QString("%1: Removal of %2.") - .arg(lineColumnString(m_step.location), rangeString(m_step.ranges)); + .arg(locationString, rangeString(m_step.ranges)); } return QString("%1: Replacement of %2 with: \"%3\".") - .arg(lineColumnString(m_step.location), + .arg(locationString, rangeString(m_step.ranges), m_step.message); } - return QString("%1: %2").arg(lineColumnString(m_step.location), m_step.message); + return QString("%1: %2").arg(locationString, m_step.message); } case Qt::ToolTipRole: return createExplainingStepToolTipString(m_step); From aaec90c6bc1f8ceb605007dd3f747fdfaf993b54 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 09:43:51 +0100 Subject: [PATCH 10/44] Core: add combo info to info bar entry This allows user to show a combo box for a stringlist. Every time the user changes the selection a callback is called. Change-Id: I27e16843465e6006cccdc3502e76be852b584dfa Reviewed-by: Eike Ziller --- src/plugins/coreplugin/infobar.cpp | 19 ++++++++++++++++++- src/plugins/coreplugin/infobar.h | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/infobar.cpp b/src/plugins/coreplugin/infobar.cpp index 827f1e8337a..a81a8834d50 100644 --- a/src/plugins/coreplugin/infobar.cpp +++ b/src/plugins/coreplugin/infobar.cpp @@ -36,6 +36,7 @@ #include #include #include +#include static const char C_SUPPRESSED_WARNINGS[] = "SuppressedWarnings"; @@ -73,6 +74,12 @@ void InfoBarEntry::setCancelButtonInfo(const QString &_cancelButtonText, CallBac m_cancelButtonCallBack = callBack; } +void InfoBarEntry::setComboInfo(const QStringList &list, InfoBarEntry::ComboCallBack callBack) +{ + m_comboCallBack = callBack; + m_comboInfo = list; +} + void InfoBarEntry::removeCancelButton() { m_useCancelButton = false; @@ -242,7 +249,7 @@ void InfoBarDisplay::update() QLabel *infoWidgetLabel = new QLabel(info.m_infoText); infoWidgetLabel->setWordWrap(true); - hbox->addWidget(infoWidgetLabel); + hbox->addWidget(infoWidgetLabel, 1); if (info.m_detailsWidgetCreator) { if (m_isShowingDetailsWidget) { @@ -270,6 +277,16 @@ void InfoBarDisplay::update() m_isShowingDetailsWidget = false; } + if (!info.m_comboInfo.isEmpty()) { + auto cb = new QComboBox(); + cb->addItems(info.m_comboInfo); + connect(cb, &QComboBox::currentTextChanged, [info](const QString &text) { + info.m_comboCallBack(text); + }); + + hbox->addWidget(cb); + } + if (!info.m_buttonText.isEmpty()) { auto infoWidgetButton = new QToolButton; infoWidgetButton->setText(info.m_buttonText); diff --git a/src/plugins/coreplugin/infobar.h b/src/plugins/coreplugin/infobar.h index ccd235cedc9..b65a821bcf1 100644 --- a/src/plugins/coreplugin/infobar.h +++ b/src/plugins/coreplugin/infobar.h @@ -61,6 +61,8 @@ public: void setCustomButtonInfo(const QString &_buttonText, CallBack callBack); void setCancelButtonInfo(CallBack callBack); void setCancelButtonInfo(const QString &_cancelButtonText, CallBack callBack); + using ComboCallBack = std::function; + void setComboInfo(const QStringList &list, ComboCallBack callBack); void removeCancelButton(); using DetailsWidgetCreator = std::function; @@ -76,6 +78,8 @@ private: GlobalSuppressionMode m_globalSuppression; DetailsWidgetCreator m_detailsWidgetCreator; bool m_useCancelButton = true; + ComboCallBack m_comboCallBack; + QStringList m_comboInfo; friend class InfoBar; friend class InfoBarDisplay; }; From 4da11c355f6cc7c1b3903c91fda22aef3d7b7830 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 4 Feb 2019 18:14:44 +0100 Subject: [PATCH 11/44] ClangPchManager: Don't generate a PCH header file any more We used an extra process to generate the PCH but now we use clang tooling so we can utilize the in memory file system. Task-number: QTCREATORBUG-21933 Change-Id: I1c1d39248e9513c87269d854c35d38b373b0f515 Reviewed-by: Ivan Donchevskii --- .../source/pchcreator.cpp | 33 ++------- .../source/pchcreator.h | 3 - tests/unit/unittest/pchcreator-test.cpp | 15 ---- tests/unit/unittest/pchtaskgenerator-test.cpp | 72 +++++++++---------- 4 files changed, 38 insertions(+), 85 deletions(-) diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 935e446f53c..777252dece5 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -82,15 +82,6 @@ bool PchCreator::generatePch() return tool.run(action.get()) != 1; } -FilePath PchCreator::generatePchHeaderFilePath() const -{ - std::uniform_int_distribution distribution; - - return FilePathView{Utils::PathString{Utils::SmallString(m_environment.pchBuildDirectory()), - "/", - std::to_string(distribution(randomNumberGenator)), - ".h"}}; -} FilePath PchCreator::generatePchFilePath() const { @@ -121,15 +112,12 @@ void PchCreator::generatePch(PchTask &&pchTask) { long long lastModified = QDateTime::currentSecsSinceEpoch(); auto content = generatePchIncludeFileContent(pchTask.includes); - auto pchSourceFilePath = generatePchHeaderFilePath(); auto pchOutputPath = generatePchFilePath(); - generateFileWithContent(pchSourceFilePath, content); - m_clangTool.addFile( - pchSourceFilePath.directory(), - pchSourceFilePath.name(), - "", - generateClangCompilerArguments(pchTask, pchSourceFilePath, pchOutputPath)); + m_clangTool.addFile(m_environment.pchBuildDirectory().toStdString(), + "dummy.h", + Utils::SmallStringView(content), + generateClangCompilerArguments(pchTask, "dummy.h", pchOutputPath)); bool success = generatePch(); @@ -179,17 +167,4 @@ const FilePathCaching &PchCreator::filePathCache() return m_filePathCache; } -std::unique_ptr PchCreator::generateFileWithContent(const Utils::SmallString &filePath, - const Utils::SmallString &content) -{ - std::unique_ptr precompiledIncludeFile(new QFile(QString(filePath))); - - precompiledIncludeFile->open(QIODevice::WriteOnly); - - precompiledIncludeFile->write(content.data(), qint64(content.size())); - precompiledIncludeFile->close(); - - return precompiledIncludeFile; -} - } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 0d55adbcdd4..1e36e18b6e1 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -83,13 +83,10 @@ public: Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const; bool generatePch(); - FilePath generatePchHeaderFilePath() const; FilePath generatePchFilePath() const; static std::vector generateClangCompilerArguments(const PchTask &pchTask, FilePathView includePchHeaderPath, FilePathView pchPath); - static std::unique_ptr generateFileWithContent(const Utils::SmallString &filePath, - const Utils::SmallString &content); const ClangTool &clangTool() const { diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 26ca9965c2f..a75ff4267ab 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -130,21 +130,6 @@ TEST_F(PchCreator, CreateProjectPartPchFileContent) HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n"))); } -TEST_F(PchCreator, CreatePchIncludeFile) -{ - auto content = creator.generatePchIncludeFileContent(pchTask1.includes); - auto pchIncludeFilePath = creator.generatePchHeaderFilePath(); - auto file = creator.generateFileWithContent(pchIncludeFilePath, content); - file->open(QIODevice::ReadOnly); - - auto fileContent = file->readAll(); - - ASSERT_THAT(fileContent.toStdString(), - AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external1.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n"))); -} - TEST_F(PchCreator, CreateProjectPartClangCompilerArguments) { auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1), diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp index a3ebb3c17be..08a0079ad84 100644 --- a/tests/unit/unittest/pchtaskgenerator-test.cpp +++ b/tests/unit/unittest/pchtaskgenerator-test.cpp @@ -91,46 +91,42 @@ TEST_F(PchTaskGenerator, AddProjectParts) mockPchTaskMerger, mergeTasks( ElementsAre(AllOf( - Field( - &PchTaskSet::system, - AllOf( - Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")), - Field(&PchTask::includes, ElementsAre(5)), - Field(&PchTask::allIncludes, IsEmpty()), - Field(&PchTask::compilerMacros, - ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})), - Field(&PchTask::systemIncludeSearchPaths, - ElementsAre( - IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System}, - IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn}, - IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})), - Field(&PchTask::projectIncludeSearchPaths, - ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User}, - IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})), - Field(&PchTask::toolChainArguments, ElementsAre("--yi")), - Field(&PchTask::language, Eq(Utils::Language::Cxx)), - Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)), - Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All)))), + Field(&PchTaskSet::system, + AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")), + Field(&PchTask::includes, ElementsAre(5)), + Field(&PchTask::allIncludes, IsEmpty()), + Field(&PchTask::compilerMacros, + ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})), + Field(&PchTask::systemIncludeSearchPaths, + ElementsAre( + IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System}, + IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn}, + IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})), + Field(&PchTask::projectIncludeSearchPaths, IsEmpty()), + Field(&PchTask::toolChainArguments, ElementsAre("--yi")), + Field(&PchTask::language, Eq(Utils::Language::Cxx)), + Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)), + Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All)))), AllOf(Field( &PchTaskSet::project, - AllOf( - Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")), - Field(&PchTask::includes, ElementsAre(3)), - Field(&PchTask::allIncludes, ElementsAre(1, 2, 3, 4, 5)), - Field(&PchTask::compilerMacros, - ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})), - Field(&PchTask::systemIncludeSearchPaths, - ElementsAre( - IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System}, - IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn}, - IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})), - Field(&PchTask::projectIncludeSearchPaths, - ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User}, - IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})), - Field(&PchTask::toolChainArguments, ElementsAre("--yi")), - Field(&PchTask::language, Eq(Utils::Language::Cxx)), - Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)), - Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All))))))), + AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")), + Field(&PchTask::includes, ElementsAre(3)), + Field(&PchTask::allIncludes, ElementsAre(1, 2, 3, 4, 5)), + Field(&PchTask::compilerMacros, + ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})), + Field(&PchTask::systemIncludeSearchPaths, + ElementsAre( + IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System}, + IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn}, + IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})), + Field(&PchTask::projectIncludeSearchPaths, + ElementsAre( + IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User}, + IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})), + Field(&PchTask::toolChainArguments, ElementsAre("--yi")), + Field(&PchTask::language, Eq(Utils::Language::Cxx)), + Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)), + Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All))))))), ElementsAre(Eq("ToolChainArgument")))); generator.addProjectParts({projectPart1}, {"ToolChainArgument"}); From bf6dfa0db9c41f5a9f3d9f170f7517522ce8560b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 10:01:09 +0100 Subject: [PATCH 12/44] TextEditor: remove senseless function call updating the info bar only makes sense after trying to set a generic highlighter, otherwise the member capturing the information whether a highlight definition for the current file is available might be uninitialized. Change-Id: I5cce70ecf1df0ba34f43eeb01743c1fae729cc6b Reviewed-by: Christian Stenger --- src/plugins/texteditor/texteditor.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index d8e994b749b..409fc6dc24d 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -8574,8 +8574,6 @@ void TextEditorWidget::setupGenericHighlighter() connect(textDocument(), &IDocument::filePathChanged, d, &TextEditorWidgetPrivate::reconfigure); - - updateEditorInfoBar(this); } // From 1dd462ac4d7f356052f5daf9110e548941ab2e65 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 10:21:26 +0100 Subject: [PATCH 13/44] TextEditor: update the infobar after setting up the highlighter removes the need of public function and member carrying the information whether a highlight definition was found. Change-Id: I8a0f24c9b376c01246116b502f5bbc06b3c65d21 Reviewed-by: Christian Stenger --- src/plugins/texteditor/texteditor.cpp | 68 +++++++++++---------------- src/plugins/texteditor/texteditor.h | 1 - 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 409fc6dc24d..7a301e38998 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -611,6 +611,7 @@ public: void updateCodeFoldingVisible(); void reconfigure(); + void updateSyntaxInfoBar(bool showInfo); public: TextEditorWidget *q; @@ -768,8 +769,6 @@ public: QScopedPointer m_clipboardAssistProvider; - bool m_isMissingSyntaxDefinition = false; - QScopedPointer m_autoCompleter; CommentDefinition m_commentDefinition; @@ -904,33 +903,6 @@ void TextEditorWidgetPrivate::showTextMarksToolTip(const QPoint &pos, } // namespace Internal -/*! - * Test if syntax highlighter is available (or unneeded) for \a widget. - * If not found, show a warning with a link to the relevant settings page. - */ -static void updateEditorInfoBar(TextEditorWidget *widget) -{ - Id id(Constants::INFO_SYNTAX_DEFINITION); - InfoBar *infoBar = widget->textDocument()->infoBar(); - if (!widget->isMissingSyntaxDefinition()) { - infoBar->removeInfo(id); - } else if (infoBar->canInfoBeAdded(id)) { - InfoBarEntry info(id, - BaseTextEditor::tr("A highlight definition was not found for this file. " - "Would you like to update highlight definition files?"), - InfoBarEntry::GlobalSuppressionEnabled); - info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [id, widget]() { - widget->textDocument()->infoBar()->removeInfo(id); - Highlighter::updateDefinitions([widget = QPointer(widget)]() { - if (widget) - widget->configureGenericHighlighter(); - }); - }); - - infoBar->addInfo(info); - } -} - QString TextEditorWidget::plainTextFromSelection(const QTextCursor &cursor) const { // Copy the selected text as plain text @@ -3301,6 +3273,30 @@ void TextEditorWidgetPrivate::reconfigure() q->configureGenericHighlighter(); } +void TextEditorWidgetPrivate::updateSyntaxInfoBar(bool showInfo) +{ + Id id(Constants::INFO_SYNTAX_DEFINITION); + InfoBar *infoBar = m_document->infoBar(); + + if (showInfo) { + InfoBarEntry info(id, + BaseTextEditor::tr( + "A highlight definition was not found for this file. " + "Would you like to update highlight definition files?"), + InfoBarEntry::GlobalSuppressionEnabled); + info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [&]() { + m_document->infoBar()->removeInfo(id); + Highlighter::updateDefinitions([widget = QPointer(q)]() { + if (widget) + widget->configureGenericHighlighter(); + }); + }); + infoBar->addInfo(info); + } else { + infoBar->removeInfo(id); + } +} + bool TextEditorWidget::codeFoldingVisible() const { return d->m_codeFoldingVisible; @@ -8514,20 +8510,17 @@ void TextEditorWidget::configureGenericHighlighter() if (definition.isValid()) { highlighter->setDefinition(definition); - d->m_isMissingSyntaxDefinition = false; d->m_commentDefinition.singleLine = definition.singleLineCommentMarker(); d->m_commentDefinition.multiLineStart = definition.multiLineCommentMarker().first; d->m_commentDefinition.multiLineEnd = definition.multiLineCommentMarker().second; setCodeFoldingSupported(true); - } else { - d->m_isMissingSyntaxDefinition = - !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName); } - textDocument()->setFontSettings(TextEditorSettings::fontSettings()); + d->updateSyntaxInfoBar(!definition.isValid() + && !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName)); - updateEditorInfoBar(this); + textDocument()->setFontSettings(TextEditorSettings::fontSettings()); } int TextEditorWidget::blockNumberForVisibleRow(int row) const @@ -8562,11 +8555,6 @@ HighlightScrollBarController *TextEditorWidget::highlightScrollBarController() c return d->m_highlightScrollBarController; } -bool TextEditorWidget::isMissingSyntaxDefinition() const -{ - return d->m_isMissingSyntaxDefinition; -} - // The remnants of PlainTextEditor. void TextEditorWidget::setupGenericHighlighter() { diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 5cf1ecbd1a3..d792a1b12c7 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -332,7 +332,6 @@ public: // the blocks list must be sorted void setIfdefedOutBlocks(const QList &blocks); - bool isMissingSyntaxDefinition() const; enum Side { Left, Right }; QAction *insertExtraToolBarWidget(Side side, QWidget *widget); From f4a45884ca722e346d16eae3a6b10213ba2cf487 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 10:43:34 +0100 Subject: [PATCH 14/44] TextEditor: add convenient definition for document function Change-Id: I8bbaec71a4682e36d3919924932b410e2e9d74a9 Reviewed-by: Christian Stenger --- src/plugins/texteditor/highlighter.cpp | 12 ++++++++++++ src/plugins/texteditor/highlighter.h | 2 ++ src/plugins/texteditor/texteditor.cpp | 13 ++++--------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index 170ec12bc8b..2471fd17a14 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -99,6 +100,17 @@ Highlighter::Highlighter() &categoryForTextStyle); } +KSyntaxHighlighting::Definition Highlighter::definitionForDocument(const TextDocument *document) +{ + const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType()); + KSyntaxHighlighting::Definition definition; + if (mimeType.isValid()) + definition = Highlighter::definitionForMimeType(mimeType.name()); + if (!definition.isValid()) + definition = Highlighter::definitionForFileName(document->filePath().fileName()); + return definition; +} + KSyntaxHighlighting::Definition Highlighter::definitionForMimeType(const QString &mimeType) { return highlightRepository()->definitionForMimeType(mimeType); diff --git a/src/plugins/texteditor/highlighter.h b/src/plugins/texteditor/highlighter.h index 90ab31332ac..f29da279e31 100644 --- a/src/plugins/texteditor/highlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -34,12 +34,14 @@ namespace TextEditor { class FontSettings; +class TextDocument; class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter { public: Highlighter(); + static KSyntaxHighlighting::Definition definitionForDocument(const TextDocument *document); static KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType); static KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 7a301e38998..8e5aaacbad3 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -8499,14 +8499,8 @@ void TextEditorWidget::configureGenericHighlighter() setCodeFoldingSupported(false); - const QString type = textDocument()->mimeType(); - const MimeType mimeType = Utils::mimeTypeForName(type); - const QString fileName = textDocument()->filePath().fileName(); - KSyntaxHighlighting::Definition definition; - if (mimeType.isValid()) - definition = Highlighter::definitionForMimeType(mimeType.name()); - if (!definition.isValid()) - definition = Highlighter::definitionForFileName(fileName); + const KSyntaxHighlighting::Definition definition = + Highlighter::definitionForDocument(textDocument()); if (definition.isValid()) { highlighter->setDefinition(definition); @@ -8518,7 +8512,8 @@ void TextEditorWidget::configureGenericHighlighter() } d->updateSyntaxInfoBar(!definition.isValid() - && !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName)); + && !TextEditorSettings::highlighterSettings().isIgnoredFilePattern( + textDocument()->filePath().fileName())); textDocument()->setFontSettings(TextEditorSettings::fontSettings()); } From f75934f2979b4d6da5031068e42dad48c1cfbee2 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 10:51:37 +0100 Subject: [PATCH 15/44] TextEditor: shorten namespace noise Change-Id: I16bc218ccefb7234cb9c1299ee3022549b178600 Reviewed-by: Christian Stenger --- src/plugins/texteditor/highlighter.cpp | 8 ++++---- src/plugins/texteditor/highlighter.h | 7 ++++--- src/plugins/texteditor/texteditor.cpp | 3 +-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index 2471fd17a14..5c88110b8a6 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -100,10 +100,10 @@ Highlighter::Highlighter() &categoryForTextStyle); } -KSyntaxHighlighting::Definition Highlighter::definitionForDocument(const TextDocument *document) +Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *document) { const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType()); - KSyntaxHighlighting::Definition definition; + Definition definition; if (mimeType.isValid()) definition = Highlighter::definitionForMimeType(mimeType.name()); if (!definition.isValid()) @@ -111,12 +111,12 @@ KSyntaxHighlighting::Definition Highlighter::definitionForDocument(const TextDoc return definition; } -KSyntaxHighlighting::Definition Highlighter::definitionForMimeType(const QString &mimeType) +Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType) { return highlightRepository()->definitionForMimeType(mimeType); } -KSyntaxHighlighting::Definition Highlighter::definitionForFileName(const QString &fileName) +Highlighter::Definition Highlighter::definitionForFileName(const QString &fileName) { return highlightRepository()->definitionForFileName(fileName); } diff --git a/src/plugins/texteditor/highlighter.h b/src/plugins/texteditor/highlighter.h index f29da279e31..22fd23b26fe 100644 --- a/src/plugins/texteditor/highlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -39,11 +39,12 @@ class TextDocument; class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter { public: + using Definition = KSyntaxHighlighting::Definition; Highlighter(); - static KSyntaxHighlighting::Definition definitionForDocument(const TextDocument *document); - static KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType); - static KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName); + static Definition definitionForDocument(const TextDocument *document); + static Definition definitionForMimeType(const QString &mimeType); + static Definition definitionForFileName(const QString &fileName); static void addCustomHighlighterPath(const Utils::FileName &path); static void updateDefinitions(std::function callback = nullptr); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 8e5aaacbad3..32b5267b12d 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -8499,8 +8499,7 @@ void TextEditorWidget::configureGenericHighlighter() setCodeFoldingSupported(false); - const KSyntaxHighlighting::Definition definition = - Highlighter::definitionForDocument(textDocument()); + const Highlighter::Definition definition = Highlighter::definitionForDocument(textDocument()); if (definition.isValid()) { highlighter->setDefinition(definition); From e720a1f3717ce3200ade789eaec4b5d4750c730e Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 5 Feb 2019 10:08:58 +0100 Subject: [PATCH 16/44] Doc: adjust highlighting documentation Update text and screenshots to reflect the UI changes in the settings made with the kSyntaxHighlighting backend change. Change-Id: I9ba1ecfee13aedbfe15e3226e71378b5d349fbb8 Reviewed-by: David Schulz Reviewed-by: Leena Miettinen --- doc/images/qtcreator-generic-highlighter.png | Bin 12342 -> 0 bytes doc/images/qtcreator-manage-definitions.png | Bin 10729 -> 0 bytes doc/images/qtcreator-syntax-highlighter.png | Bin 0 -> 29169 bytes .../creator-semantic-highlighting.qdoc | 61 +++++++----------- 4 files changed, 22 insertions(+), 39 deletions(-) delete mode 100644 doc/images/qtcreator-generic-highlighter.png delete mode 100644 doc/images/qtcreator-manage-definitions.png create mode 100644 doc/images/qtcreator-syntax-highlighter.png diff --git a/doc/images/qtcreator-generic-highlighter.png b/doc/images/qtcreator-generic-highlighter.png deleted file mode 100644 index 19ccebed2bfa75d6af2af9ddfa485ba185da5acf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12342 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 Q#JVeuLw=p=dJyF zRq{)p*8GHP?;bLGNDI8Lof)#F4b7Z?rUb7@oR=++{DuIvM_d^ z&Ryo}=MEoMo)M&FBQiy0+0jRFQTFvtYa?x}tzVxvi(fR2o4>q!=N=CG`%4b3n$&i2 z@$1PO_sn=6c8yQs*D20dx#f1k=W|3B@wm1J8+or<9Tk4Q^s`RBdv^9}^}LOLejReS z9^likb?MgX(~pwEWXxB$#NXUjws3B0h1G&Qo5u~a8LkWT?EhMouTw&FuStnn8y43gLK!VZSc^YQn4va!8 z`nJStGT&do=ZRZxc?AX0??_#@< z_v_Z5zWO3XdnLz_j7smKCF0*%sx~f5J+7{$*zssuKw(|#tY^WxZz7GYi)G(VE?WC9 zLNh8d?%re>Ngj2rrBQphg-V<&m)QPY%+e_JK`f);;tuO6$?2kT*X~@2h`(>XRda^k zx5|?LAD7Rs*sv-sJ-c?^?VY=$Y=5jTU#T0d-8*Ie|GWEZ9(25nyB;&cNBozqoxY)+ zrtw}4&GmI9`SDdnS(oJ38syBq)ZY3`Z;`f%Ie+@@yZgUCne6|!!u0Up))_Nioqg%l ze>;BC>$GFqcjnuae?Ahny;Qx$I`Zain{C}Qt!)@{Tg)#tNKf9<(^-0aN!d2h)<=s! zsh3|{Wn2?ubLWkXv2?Zf&cJK_I&XC6@5z69dsE@2TW3nYekj^h@TAOt`-YQKo;>@k zU8`%}DCODhx$b^MR?mjYFCPxtO8Z=U6P7-sckSNZ?6ljbUbcFEcausm=v?mo*NJON z+Uwi%jw(Eo=vi{;-88kX``oXmhs{%b@}uI>X?L+}V&Cm6J2kU4xYeiSLQoUTiQu&*8#sNG1Nyp|}IPgr`_v_a^)`u~hZY7>5;eVZe=UDF49n!+{LZVNq zKFnMk&9u-Z(dFxtEEDC!d%wSU zSS|MD*};FWSYG$f-?O3OJg@xo?;rT{-gNC+9U8u?u2{)^dsKX7*1=QqyoL5ZfbXU1J#zthcc`)gaB#m7a} z)jn)1O+WEf?)qi3Z52OXrKsJwIa}m-SK`tD=GYlaSBKA9sgQ18z}{+s@2+WXH6c&oLl~TZ~b}3=8whSmz#eLt^WVK{oBGD1?QK)-}m0P ztKjQmlbBf9W$tZm)6UJ+I`;Tui^FaH|A*IS+!s-_WO8r#?PdQiEvde|PhkP$q?tkT|G&IV{%e{Pm8rQrs`~d4)n&(9_x#>G zJ#;nusi)UwFz^Q*V`-8}t=zSz6CkyJmWq)LdtpKFguv$AM-q#)4O`xDA)A=?z|Rjk~brhf39r zX7_o|yzl(_#l)joEnV_ldRfxO61Nzg%@uD=^Lgj8a-M1Wc{^^tPgIRlkXMb#S$^-8 zw;7Zbj#u*NwI5d5WOXq0X^t;X=g}^IFE7u;$;q{bSB~X=_?#%#d-|zS=Nr8OC29SG zLAQH%3CgUy)8Qes=WTq&V+WfRQ}(RtN@3dk+W$2-Q?1r7=fY$wLk*21-6t|-UUzKU z-m_X*LH+W=eGey=RF#<6o;hp3+P!JcS^@b;>#AMWzn`xVOxZXi?f0S6pMQ2Q=liF! z=JNi(XVztAE^Ik|Dl78ltEB(`-p`wQ*1PQaa+c$>E}Q4FOKiKGoT-_r`*GU-Kh4e& zo{@!ta6GsF&y9J3Gu%J%OW$DMo6**|=E3uIoLWz+R`oo2G_NFK*NU{Z zUxAOE@BP1`yDPCey*M}fvB&y)WnP0BJkhb4=ln8%Ul*?uP(J+h=f{i}!MiVIu1(x~ z>7?BZAwe0L;Qcpde>yO2=f;Z($k`nX6-=PtAx({LN$I)6pM- zO&*cg=Gomiu_8iEZ_b(dR~T*|-16xQ=kZqK=q)FHZY;{)vD?yA>B`}Gb_=b3KAy>b ze-R^FAmi+bH<@-Vnb4>rcI@*1*1h3Dp1#4wzrSSEYt5b)v5)0UU?x-dQ9qTREQX(F z{a88UcwfxNl}jcZd+@1@S-59%tTn zgU{maskDg(hBG|!PQSR~QSMw*z@eugBz{`&t=r{QrdB789@AB@((dp4%>8uhw&@jn z3cTNo%ITOMPt1v3!`W-h6i{`)#^!U---Cm%Y

uFLS1i2rJJDnQ6PdH}(>wBZA3JPX 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 E02w7l@&Et; literal 0 HcmV?d00001 diff --git a/doc/src/editors/creator-semantic-highlighting.qdoc b/doc/src/editors/creator-semantic-highlighting.qdoc index 86e3dc0a588..28dc1a17633 100644 --- a/doc/src/editors/creator-semantic-highlighting.qdoc +++ b/doc/src/editors/creator-semantic-highlighting.qdoc @@ -51,49 +51,32 @@ \section1 Generic Highlighting - Generic highlighting is based on highlight definition files that are - provided by the - \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} - {Kate Editor}. You can download highlight definition files for use with \QC. - For more information about the definition files, see - \l{http://kde-files.org/index.php?xcontentmode=680}{KDE-Files.org}. + Generic highlighting is provided by + \l{https://api.kde.org/frameworks/syntax-highlighting/html/index.html} + {KSyntaxHighlighting}, which is the syntax highlighting engine for Kate + syntax definitions. \QC comes with most of the commonly used syntax files, + and you can download additional files. For more information about the + definition files, see + \l{https://docs.kde.org/stable5/en/applications/katepart/highlight.html} + {Working with Syntax Highlighting}. - If you have a Unix installation that comes with the Kate Editor, you might - already have the definition files installed. Typically, the files are - located in a read-only directory, and therefore, you cannot manage them. \QC - can try to locate them and use them as fallback files, when the primary - location does not contain the definition for the current file type. You can - also specify the directory that contains preinstalled highlight - definition files as the primary location. + If the editor cannot find the highlight definition for a file that you open + for editing, it prompts you to update the highlight definition files. Select + \uicontrol {Update Definitions} to update the files. - When you open a file for editing and the editor cannot find the highlight - definition for it, an alert appears. To suppress the alerts, you can specify - patterns for ignoring files. + To suppress the message for a particular file pattern, select + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} + > \uicontrol {Generic Highlighter} and add the pattern to the + \uicontrol {Ignored file patterns} field. - To download highlight definition files: + \image qtcreator-syntax-highlighter.png "Generic Highlighter options" - \list 1 - \li Select \uicontrol Tools > \uicontrol Options > - \uicontrol {Text Editor} > \uicontrol {Generic Highlighter}. - \image qtcreator-generic-highlighter.png "Generic Highlighter options" - \li In the \uicontrol Location field, specify the path to the primary - location for highlight definition files. - \li Click \uicontrol {Download Definitions} to open a list of highlight - definition files available for download. - \image qtcreator-manage-definitions.png "Download Definitions dialog" - \li Select highlight definition files in the list and click - \uicontrol {Download Selected Definitions}. - \li Select the \uicontrol {Use fallback location} check box to specify - the secondary location where the editor will look for highlight - definition files. - \li Click \uicontrol Autodetect to allow \QC to look for highlight - definition files on your system, or click \uicontrol Browse to - locate them in the file system yourself. - \li In the \uicontrol {Ignored file patterns} field, specify file - patterns to suppress alerts if the highlight definitions for the - specified files are not found. - \li Click \uicontrol OK to save your changes. - \endlist + If you have written your own syntax definition files, you + can provide an additional definition search path in the + \uicontrol {User Highlight Definition Files} field. + + To manually update the highlight definition files, select + \uicontrol {Update Definitions}. \section1 Highlighting and Folding Blocks From d122049aeea62794ba97dd60516cf97c2cdaaffa Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 09:29:15 +0100 Subject: [PATCH 17/44] ClangTools: Fix order of ExplainingStepItems We sorted by line/column/text, but we should not change the order for these items as the original order is crucial to understand the diagnostics. For example, the clang static analyzer diagnostics provide step by step notes to explain the main diagnostics and these does not match the line/column order. Change-Id: I1e7235b37eb5713b0b7135aab46124f590a1443a Reviewed-by: Ivan Donchevskii --- .../clangtools/clangtoolsdiagnosticmodel.cpp | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index 7a2d78ed3a3..6e16cc6eec5 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -70,12 +70,14 @@ QVariant FilePathItem::data(int column, int role) const class ExplainingStepItem : public Utils::TreeItem { public: - ExplainingStepItem(const ExplainingStep &step); + ExplainingStepItem(const ExplainingStep &step, int index); + int index() const { return m_index; } private: QVariant data(int column, int role) const override; const ExplainingStep m_step; + const int m_index = 0; }; ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *parent) @@ -350,8 +352,8 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag, if (!diag.explainingSteps.isEmpty()) m_parentModel->stepsToItemsCache[diag.explainingSteps].push_back(this); - foreach (const ExplainingStep &s, diag.explainingSteps) - appendChild(new ExplainingStepItem(s)); + for (int i = 0; i < diag.explainingSteps.size(); ++i ) + appendChild(new ExplainingStepItem(diag.explainingSteps[i], i)); } DiagnosticItem::~DiagnosticItem() @@ -487,9 +489,10 @@ bool DiagnosticItem::hasNewFixIts() const return m_parentModel->stepsToItemsCache[m_diagnostic.explainingSteps].front() == this; } -ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step) -{ -} +ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step, int index) + : m_step(step) + , m_index(index) +{} // We expect something like "note: ..." static QVariant iconForExplainingStepMessage(const QString &message) @@ -561,7 +564,6 @@ QVariant ExplainingStepItem::data(int column, int role) const return QVariant(); } - DiagnosticFilterModel::DiagnosticFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { @@ -655,22 +657,34 @@ bool DiagnosticFilterModel::lessThan(const QModelIndex &l, const QModelIndex &r) const bool isComparingDiagnostics = !dynamic_cast(itemLeft); if (sortColumn() == Debugger::DetailedErrorView::DiagnosticColumn && isComparingDiagnostics) { - using Debugger::DiagnosticLocation; - const int role = Debugger::DetailedErrorView::LocationRole; + bool result = false; + if (dynamic_cast(itemLeft)) { + using Debugger::DiagnosticLocation; + const int role = Debugger::DetailedErrorView::LocationRole; - const auto leftLoc = sourceModel()->data(l, role).value(); - const auto leftText = sourceModel()->data(l, ClangToolsDiagnosticModel::TextRole).toString(); + const auto leftLoc = sourceModel()->data(l, role).value(); + const auto leftText + = sourceModel()->data(l, ClangToolsDiagnosticModel::TextRole).toString(); - const auto rightLoc = sourceModel()->data(r, role).value(); - const auto rightText = sourceModel()->data(r, ClangToolsDiagnosticModel::TextRole).toString(); + const auto rightLoc = sourceModel()->data(r, role).value(); + const auto rightText + = sourceModel()->data(r, ClangToolsDiagnosticModel::TextRole).toString(); + + result = std::tie(leftLoc.line, leftLoc.column, leftText) + < std::tie(rightLoc.line, rightLoc.column, rightText); + } else if (auto left = dynamic_cast(itemLeft)) { + const auto right = dynamic_cast(model->itemForIndex(r)); + result = left->index() < right->index(); + } else { + QTC_CHECK(false && "Unexpected item"); + } - const int result = std::tie(leftLoc.line, leftLoc.column, leftText) - < std::tie(rightLoc.line, rightLoc.column, rightText); if (sortOrder() == Qt::DescendingOrder) - return !result; // Ensure that we always sort location from top to bottom. + return !result; // Do not change the order of these item as this might be confusing. return result; } + // FilePathItem return QSortFilterProxyModel::lessThan(l, r); } From 72cb9e26a1c1ba5596cb5cee94adc266ad03df91 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 14:11:31 +0100 Subject: [PATCH 18/44] PathChooser: Move setTextKeepingActiveCursor() to FancyLineEdit We want to re-use it elsewhere. Change-Id: Iadb03e2e85bc25f9111a8817170b9ec1f2f0a7b1 Reviewed-by: Eike Ziller --- src/libs/utils/fancylineedit.cpp | 9 +++++++++ src/libs/utils/fancylineedit.h | 2 ++ src/libs/utils/pathchooser.cpp | 13 ++----------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp index 2cebbce64ca..6b5b11995ce 100644 --- a/src/libs/utils/fancylineedit.cpp +++ b/src/libs/utils/fancylineedit.cpp @@ -27,6 +27,7 @@ #include "fancylineedit.h" #include "historycompleter.h" #include "hostosinfo.h" +#include "optional.h" #include "qtcassert.h" #include "stylehelper.h" #include "utilsicons.h" @@ -175,6 +176,14 @@ FancyLineEdit::~FancyLineEdit() } } +void FancyLineEdit::setTextKeepingActiveCursor(const QString &text) +{ + optional cursor = hasFocus() ? make_optional(cursorPosition()) : nullopt; + setText(text); + if (cursor) + setCursorPosition(*cursor); +} + void FancyLineEdit::setButtonVisible(Side side, bool visible) { d->m_iconbutton[side]->setVisible(visible); diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h index 3f40d93df26..fd0b121d88d 100644 --- a/src/libs/utils/fancylineedit.h +++ b/src/libs/utils/fancylineedit.h @@ -82,6 +82,8 @@ public: explicit FancyLineEdit(QWidget *parent = nullptr); ~FancyLineEdit() override; + void setTextKeepingActiveCursor(const QString &text); + QIcon buttonIcon(Side side) const; void setButtonIcon(Side side, const QIcon &icon); diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index 45600b7aa1d..e29b0c76632 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -26,7 +26,6 @@ #include "pathchooser.h" #include "environment.h" -#include "optional.h" #include "qtcassert.h" #include "macroexpander.h" @@ -348,22 +347,14 @@ QString PathChooser::expandedDirectory(const QString &input, const Environment & return path; } -void setTextKeepingActiveCursor(QLineEdit *edit, const QString &text) -{ - optional cursor = edit->hasFocus() ? make_optional(edit->cursorPosition()) : nullopt; - edit->setText(text); - if (cursor) - edit->setCursorPosition(*cursor); -} - void PathChooser::setPath(const QString &path) { - setTextKeepingActiveCursor(d->m_lineEdit, QDir::toNativeSeparators(path)); + d->m_lineEdit->setTextKeepingActiveCursor(QDir::toNativeSeparators(path)); } void PathChooser::setFileName(const FileName &fn) { - setTextKeepingActiveCursor(d->m_lineEdit, fn.toUserOutput()); + d->m_lineEdit->setTextKeepingActiveCursor(fn.toUserOutput()); } void PathChooser::setErrorColor(const QColor &errorColor) From 8e888df8529767bf80a598a1457d57460e6603db Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 6 Feb 2019 14:33:11 +0100 Subject: [PATCH 19/44] Squish: Update FancyToolButton Change-Id: Ia8c8b270ee2147a63eb1b90d14ff0792bfa95cd2 Reviewed-by: Robert Loehning Reviewed-by: Christian Stenger --- tests/system/objects.map | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/system/objects.map b/tests/system/objects.map index b3852a89eab..27cb7429d0c 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -1,16 +1,16 @@ -:*Qt Creator.Build Project_Core::Internal::FancyToolButton {text?='Build Project*' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator.Build Project_Core::Internal::FancyToolButton {name='Build.Button' text?='Build Project*' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Cancel Build_QToolButton {text='Cancel Build' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Clear_QToolButton {text='Clear' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:*Qt Creator.Continue_Core::Internal::FancyToolButton {toolTip?='Continue *' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator.Continue_Core::Internal::FancyToolButton {name='Debug.Button' toolTip?='Continue *' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Find_Find::Internal::FindToolBar {name='Core__Internal__FindWidget' type='Core::Internal::FindToolBar' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Find'} :*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack {name='FormEditorStack' type='Designer::Internal::FormEditorStack' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:*Qt Creator.Interrupt_Core::Internal::FancyToolButton {toolTip='Interrupt' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator.Interrupt_Core::Internal::FancyToolButton {name='Debug.Button' toolTip='Interrupt' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.ProjectSelectorDockWidget_QDockWidget {name='ProjectSelectorDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:*Qt Creator.Run_Core::Internal::FancyToolButton {text='Run' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:*Qt Creator.Start Debugging_Core::Internal::FancyToolButton {toolTip?='Start debugging*' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator.Run_Core::Internal::FancyToolButton {name='Run.Button' text='Run' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator.Start Debugging_Core::Internal::FancyToolButton {name='Debug.Button' toolTip?='Start debugging*' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Widget Box_QDockWidget {name='WidgetBoxDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Widget Box'} :*Qt Creator.findEdit_Utils::FilterLineEdit {name='findEdit' type='Utils::FancyLineEdit' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:*Qt Creator_Core::Internal::FancyToolButton {occurrence='3' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:*Qt Creator_Core::Internal::FancyToolButton {name='KitSelector.Button' type='Core::Internal::FancyToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator_Utils::FilterLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator_Utils::IconButton {occurrence='4' type='Utils::IconButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :About Qt Creator_Core::Internal::VersionDialog {type='Core::Internal::VersionDialog' unnamed='1' visible='1' windowTitle='About Qt Creator'} From 499ccca115b9ad1a03fcb4f4a8b8e1052915a995 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 14:12:49 +0100 Subject: [PATCH 20/44] RemoteLinux: Fix jumpy cursor when editing custom remote exeutables Amends 93a6dd0c67. Change-Id: I88e4537112c4c4dc5a471b4baffe6a93ed3b76ba Fixes: QTCREATORBUG-21030 Reviewed-by: Eike Ziller --- src/plugins/projectexplorer/projectconfigurationaspects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectconfigurationaspects.cpp b/src/plugins/projectexplorer/projectconfigurationaspects.cpp index 49a854d0e6a..c6f9ad95522 100644 --- a/src/plugins/projectexplorer/projectconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/projectconfigurationaspects.cpp @@ -282,7 +282,7 @@ void BaseStringAspect::update() } if (d->m_lineEditDisplay) { - d->m_lineEditDisplay->setText(displayedString); + d->m_lineEditDisplay->setTextKeepingActiveCursor(displayedString); d->m_lineEditDisplay->setEnabled(enabled); } From c02ceb180eb99afd47db8c45a525f40d95d2a627 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 09:40:40 +0100 Subject: [PATCH 21/44] Syntax Highlighter: return all definitions for a file name/mimetype Can be used to create user controls to switch between multiple definitions for a file or mime type. Change-Id: I5fd3744db1e819d0d6f8448a53adaf9d2c7c168d Reviewed-by: Christian Stenger --- .../syntax-highlighting/src/lib/repository.cpp | 17 +++++++++++++---- .../syntax-highlighting/src/lib/repository.h | 12 ++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp index 6b2fabd07ad..922225a7e1b 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp @@ -78,7 +78,7 @@ Definition Repository::definitionForName(const QString& defName) const return d->m_defs.value(defName); } -static Definition bestCandidate(QVector& candidates) +static Definition bestCandidate(QVector &&candidates) { if (candidates.isEmpty()) return Definition(); @@ -91,6 +91,11 @@ static Definition bestCandidate(QVector& candidates) } Definition Repository::definitionForFileName(const QString& fileName) const +{ + return bestCandidate(definitionsForFileName(fileName)); +} + +QVector Repository::definitionsForFileName(const QString &fileName) const { QFileInfo fi(fileName); const auto name = fi.fileName(); @@ -106,10 +111,15 @@ Definition Repository::definitionForFileName(const QString& fileName) const } } - return bestCandidate(candidates); + return candidates; } Definition Repository::definitionForMimeType(const QString& mimeType) const +{ + return bestCandidate(definitionsForMimeType(mimeType)); +} + +QVector Repository::definitionsForMimeType(const QString &mimeType) const { QVector candidates; for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) { @@ -121,8 +131,7 @@ Definition Repository::definitionForMimeType(const QString& mimeType) const } } } - - return bestCandidate(candidates); + return candidates; } QVector Repository::definitions() const diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h index c35da5ec376..e4e9bed69f7 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h @@ -166,6 +166,13 @@ public: */ Definition definitionForFileName(const QString &fileName) const; + /** + * Returns all Definition%s for the file named @p fileName. + * The match is performed based on the \e extensions and @e mimetype of + * the definition files. + */ + QVector definitionsForFileName(const QString &fileName) const; + /** * Returns the best matching Definition to the type named @p mimeType * @@ -176,6 +183,11 @@ public: */ Definition definitionForMimeType(const QString &mimeType) const; + /** + * Returns all Definition%s to the type named @p mimeType + */ + QVector definitionsForMimeType(const QString &mimeType) const; + /** * Returns all available Definition%s. * Definition%ss are ordered by translated section and translated names, From 67b0d9be2e9d00a83fdf3e607986e7ad13d60cb9 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 6 Feb 2019 10:52:32 +0100 Subject: [PATCH 22/44] TextEditor: return all definitions for a file name/mimetype/document Change-Id: Ifd4ee9ab71b95a66cf11e30e2de688d421094a4a Reviewed-by: Christian Stenger --- src/plugins/texteditor/highlighter.cpp | 21 +++++++++++++++++++++ src/plugins/texteditor/highlighter.h | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index 5c88110b8a6..c88a5aacb59 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -121,6 +121,27 @@ Highlighter::Definition Highlighter::definitionForFileName(const QString &fileNa return highlightRepository()->definitionForFileName(fileName); } +Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document) +{ + const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType()); + Definitions definitions; + if (mimeType.isValid()) + definitions = Highlighter::definitionsForMimeType(mimeType.name()); + if (definitions.isEmpty()) + definitions = Highlighter::definitionsForFileName(document->filePath().fileName()); + return definitions; +} + +Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType) +{ + return highlightRepository()->definitionsForMimeType(mimeType).toList(); +} + +Highlighter::Definitions Highlighter::definitionsForFileName(const QString &fileName) +{ + return highlightRepository()->definitionsForFileName(fileName).toList(); +} + void Highlighter::addCustomHighlighterPath(const Utils::FileName &path) { highlightRepository()->addCustomSearchPath(path.toString()); diff --git a/src/plugins/texteditor/highlighter.h b/src/plugins/texteditor/highlighter.h index 22fd23b26fe..cec2b0fb698 100644 --- a/src/plugins/texteditor/highlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -40,12 +40,17 @@ class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::Abstra { public: using Definition = KSyntaxHighlighting::Definition; + using Definitions = QList; Highlighter(); static Definition definitionForDocument(const TextDocument *document); static Definition definitionForMimeType(const QString &mimeType); static Definition definitionForFileName(const QString &fileName); + static Definitions definitionsForDocument(const TextDocument *document); + static Definitions definitionsForMimeType(const QString &mimeType); + static Definitions definitionsForFileName(const QString &fileName); + static void addCustomHighlighterPath(const Utils::FileName &path); static void updateDefinitions(std::function callback = nullptr); From 874dde6863129ce5b236a8c7b08e75aec2d5f5dc Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 7 Feb 2019 08:36:57 +0100 Subject: [PATCH 23/44] TextEditor: extract initilizing the generic highlighter Change-Id: Ibdd37aeb761087118dd4974a06d82c0dbe1f1731 Reviewed-by: Christian Stenger --- src/plugins/texteditor/texteditor.cpp | 38 +++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 32b5267b12d..247fd12352e 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -612,6 +612,7 @@ public: void reconfigure(); void updateSyntaxInfoBar(bool showInfo); + void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition); public: TextEditorWidget *q; @@ -3297,6 +3298,25 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(bool showInfo) } } +void TextEditorWidgetPrivate::configureGenericHighlighter( + const KSyntaxHighlighting::Definition &definition) +{ + auto highlighter = new Highlighter(); + m_document->setSyntaxHighlighter(highlighter); + + if (definition.isValid()) { + highlighter->setDefinition(definition); + m_commentDefinition.singleLine = definition.singleLineCommentMarker(); + m_commentDefinition.multiLineStart = definition.multiLineCommentMarker().first; + m_commentDefinition.multiLineEnd = definition.multiLineCommentMarker().second; + q->setCodeFoldingSupported(true); + } else { + q->setCodeFoldingSupported(false); + } + + m_document->setFontSettings(TextEditorSettings::fontSettings()); +} + bool TextEditorWidget::codeFoldingVisible() const { return d->m_codeFoldingVisible; @@ -8494,27 +8514,11 @@ QString TextEditorWidget::textAt(int from, int to) const void TextEditorWidget::configureGenericHighlighter() { - auto highlighter = new Highlighter(); - textDocument()->setSyntaxHighlighter(highlighter); - - setCodeFoldingSupported(false); - const Highlighter::Definition definition = Highlighter::definitionForDocument(textDocument()); - - if (definition.isValid()) { - highlighter->setDefinition(definition); - d->m_commentDefinition.singleLine = definition.singleLineCommentMarker(); - d->m_commentDefinition.multiLineStart = definition.multiLineCommentMarker().first; - d->m_commentDefinition.multiLineEnd = definition.multiLineCommentMarker().second; - - setCodeFoldingSupported(true); - } - + d->configureGenericHighlighter(definition); d->updateSyntaxInfoBar(!definition.isValid() && !TextEditorSettings::highlighterSettings().isIgnoredFilePattern( textDocument()->filePath().fileName())); - - textDocument()->setFontSettings(TextEditorSettings::fontSettings()); } int TextEditorWidget::blockNumberForVisibleRow(int row) const From 5481a35b989ae51cfba58ff8ee3fde2c6c2e9c9a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 7 Feb 2019 14:33:13 +0100 Subject: [PATCH 24/44] Bump copyright year Change-Id: I532c92311fda448fc272ab31e26ad562d9fb3ce5 Reviewed-by: Christian Kandeler --- qbs/modules/qtc/qtc.qbs | 2 +- qtcreator.pri | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 3d43178bbd8..0a5f04b6fc5 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -17,7 +17,7 @@ Module { property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release - property string qtcreator_copyright_year: '2018' + property string qtcreator_copyright_year: '2019' property string qtcreator_copyright_string: "(C) " + qtcreator_copyright_year + " The Qt Company Ltd" property string ide_display_name: 'Qt Creator' diff --git a/qtcreator.pri b/qtcreator.pri index 63c2030c14e..254a52a5c99 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -5,7 +5,7 @@ QTCREATOR_VERSION = 4.8.2 QTCREATOR_COMPAT_VERSION = 4.8.0 VERSION = $$QTCREATOR_VERSION QTCREATOR_DISPLAY_VERSION = 4.8.2 -QTCREATOR_COPYRIGHT_YEAR = 2018 +QTCREATOR_COPYRIGHT_YEAR = 2019 BINARY_ARTIFACTS_BRANCH = 4.8 isEmpty(IDE_DISPLAY_NAME): IDE_DISPLAY_NAME = Qt Creator From dd778bcb2388bdc643e1d5eb5ce60c03cee2719b Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Thu, 31 Jan 2019 10:30:58 +0100 Subject: [PATCH 25/44] Clang: Use full paths in compilation database for symbol collector We we FilePath and NativeFilePath so that compiler warns us if we mix them up. Change-Id: I33d7abc7e4e724dff2a9b2b9b23deea8b358ccfd Reviewed-by: Marco Bubke --- src/libs/clangsupport/commandlinebuilder.h | 17 ++-- src/libs/clangsupport/filepath.h | 4 +- src/libs/clangsupport/nativefilepath.h | 13 ++- src/libs/utils/smallstringview.h | 3 +- .../source/pchcreator.cpp | 17 ++-- .../source/pchcreator.h | 2 +- .../source/clangquerygatherer.cpp | 7 +- .../source/clangtool.cpp | 69 +++++--------- .../source/clangtool.h | 48 +++------- .../source/refactoringcompilationdatabase.cpp | 26 +++-- .../source/refactoringcompilationdatabase.h | 6 +- .../source/refactoringserver.cpp | 14 ++- tests/unit/unittest/clangquery-test.cpp | 31 ++++-- .../unit/unittest/clangquerygatherer-test.cpp | 15 ++- .../unit/unittest/commandlinebuilder-test.cpp | 38 ++++---- tests/unit/unittest/filesystem-utilities.h | 35 +++---- .../unit/unittest/gtest-creator-printing.cpp | 14 +++ tests/unit/unittest/gtest-creator-printing.h | 8 ++ tests/unit/unittest/nativefilepath-test.cpp | 1 + tests/unit/unittest/pchcreator-test.cpp | 13 +-- .../refactoringcompilationdatabase-test.cpp | 56 ++++++----- .../unit/unittest/refactoringserver-test.cpp | 23 +++-- .../unittest/sourcerangeextractor-test.cpp | 4 +- tests/unit/unittest/symbolfinder-test.cpp | 94 +++++++++++++------ tests/unit/unittest/symbolindexer-test.cpp | 85 ++++++++--------- tests/unit/unittest/testclangtool.cpp | 9 +- tests/unit/unittest/testclangtool.h | 7 +- 27 files changed, 355 insertions(+), 304 deletions(-) diff --git a/src/libs/clangsupport/commandlinebuilder.h b/src/libs/clangsupport/commandlinebuilder.h index 9b5bced9328..03d042322d9 100644 --- a/src/libs/clangsupport/commandlinebuilder.h +++ b/src/libs/clangsupport/commandlinebuilder.h @@ -25,7 +25,7 @@ #pragma once -#include "filepathview.h" +#include "filepath.h" #include #include @@ -35,7 +35,7 @@ namespace ClangBackEnd { -template> +template class CommandLineBuilder { public: @@ -213,7 +213,7 @@ public: { for (const IncludeSearchPath &path : projectIncludeSearchPaths) { commandLine.emplace_back("-I"); - commandLine.emplace_back(path.path); + commandLine.emplace_back(NativeFilePath(FilePathView(path.path))); } } @@ -228,7 +228,7 @@ public: for (const IncludeSearchPath &path : systemIncludeSearchPaths) { if (path.type != IncludeSearchPathType::BuiltIn) { commandLine.emplace_back(includeOption(path.type)); - commandLine.emplace_back(path.path); + commandLine.emplace_back(NativeFilePath(FilePathView(path.path))); } } } @@ -238,7 +238,7 @@ public: for (const IncludeSearchPath &path : systemIncludeSearchPaths) { if (path.type == IncludeSearchPathType::BuiltIn) { commandLine.emplace_back(includeOption(path.type)); - commandLine.emplace_back(path.path); + commandLine.emplace_back(NativeFilePath(FilePathView(path.path))); } } } @@ -247,23 +247,24 @@ public: { if (!outputPath.isEmpty()) { commandLine.emplace_back("-o"); - commandLine.emplace_back(outputPath); + commandLine.emplace_back(NativeFilePath(outputPath)); } } void addSourcePath(FilePathView sourcePath) { if (!sourcePath.isEmpty()) - commandLine.emplace_back(sourcePath); + commandLine.emplace_back(NativeFilePath(sourcePath)); } void addIncludePchPath(FilePathView includePchPath) { + if (!includePchPath.isEmpty()) { commandLine.emplace_back("-Xclang"); commandLine.emplace_back("-include-pch"); commandLine.emplace_back("-Xclang"); - commandLine.emplace_back(includePchPath); + commandLine.emplace_back(NativeFilePath(includePchPath)); } } diff --git a/src/libs/clangsupport/filepath.h b/src/libs/clangsupport/filepath.h index e08f3f4996b..72076841945 100644 --- a/src/libs/clangsupport/filepath.h +++ b/src/libs/clangsupport/filepath.h @@ -28,7 +28,7 @@ #include "clangsupport_global.h" #include "filepathview.h" -#include "filepathview.h" +#include "nativefilepath.h" #include #include @@ -37,6 +37,8 @@ namespace ClangBackEnd { +class NativeFilePath; + class FilePath : public Utils::PathString { using size_type = Utils::PathString::size_type; diff --git a/src/libs/clangsupport/nativefilepath.h b/src/libs/clangsupport/nativefilepath.h index 31b6778ed04..fefaa9c2057 100644 --- a/src/libs/clangsupport/nativefilepath.h +++ b/src/libs/clangsupport/nativefilepath.h @@ -26,13 +26,15 @@ #pragma once #include "filepathview.h" -#include "filepathview.h" +#include "filepath.h" #include #include namespace ClangBackEnd { +class FilePath; + class NativeFilePath { using size_type = Utils::PathString::size_type; @@ -50,8 +52,13 @@ public: NativeFilePath(NativeFilePathView filePathView) : m_path(filePathView.toStringView()), m_slashIndex(filePathView.slashIndex()) - { - } + {} + + explicit NativeFilePath(FilePathView filePathView) { *this = fromFilePath(filePathView); } + + explicit NativeFilePath(const FilePath &filePath) + : NativeFilePath{FilePathView{filePath}} + {} template NativeFilePath(const char(&string)[Size]) noexcept diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h index d821edbf9b8..6052ff8777f 100644 --- a/src/libs/utils/smallstringview.h +++ b/src/libs/utils/smallstringview.h @@ -90,8 +90,7 @@ public: SmallStringView(const String &string) noexcept : m_pointer(string.data()), m_size(string.size()) - { - } + {} static SmallStringView fromUtf8(const char *const characterPointer) diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 777252dece5..4333d5706ac 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -94,10 +94,9 @@ FilePath PchCreator::generatePchFilePath() const ".pch"}}; } -std::vector PchCreator::generateClangCompilerArguments( - const PchTask &pchTask, - FilePathView sourceFilePath, - FilePathView pchOutputPath) +Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTask &pchTask, + FilePathView sourceFilePath, + FilePathView pchOutputPath) { CommandLineBuilder builder{pchTask, pchTask.toolChainArguments, @@ -114,10 +113,12 @@ void PchCreator::generatePch(PchTask &&pchTask) auto content = generatePchIncludeFileContent(pchTask.includes); auto pchOutputPath = generatePchFilePath(); - m_clangTool.addFile(m_environment.pchBuildDirectory().toStdString(), - "dummy.h", - Utils::SmallStringView(content), - generateClangCompilerArguments(pchTask, "dummy.h", pchOutputPath)); + FilePath headerFilePath{m_environment.pchBuildDirectory().toStdString(), "dummy.h"}; + Utils::SmallStringVector commandLine = generateClangCompilerArguments(pchTask, + headerFilePath, + pchOutputPath); + + m_clangTool.addFile(std::move(headerFilePath), std::move(content), std::move(commandLine)); bool success = generatePch(); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 1e36e18b6e1..37d0c7c8a1e 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -84,7 +84,7 @@ public: bool generatePch(); FilePath generatePchFilePath() const; - static std::vector generateClangCompilerArguments(const PchTask &pchTask, + static Utils::SmallStringVector generateClangCompilerArguments(const PchTask &pchTask, FilePathView includePchHeaderPath, FilePathView pchPath); diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp index 21cd0d26e54..42fb7d88bc2 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp @@ -50,10 +50,9 @@ ClangQueryGatherer::createSourceRangesForSource( { ClangQuery clangQuery(*filePathCache, std::move(query)); - clangQuery.addFile(std::string(source.filePath.directory()), - std::string(source.filePath.name()), - std::string(source.unsavedFileContent), - std::vector(source.commandLineArguments)); + clangQuery.addFile(std::move(source.filePath), + std::move(source.unsavedFileContent), + std::move(source.commandLineArguments)); clangQuery.addUnsavedFiles(unsaved); diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp index 66f85c6d36d..5ae87793dbd 100644 --- a/src/tools/clangrefactoringbackend/source/clangtool.cpp +++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp @@ -27,6 +27,8 @@ #include +#include + namespace ClangBackEnd { namespace { @@ -44,67 +46,37 @@ String toNativePath(String &&path) } } -void ClangTool::addFile(std::string &&directory, - std::string &&fileName, - std::string &&content, - std::vector &&commandLine) +void ClangTool::addFile(FilePath &&filePath, + Utils::SmallString &&content, + Utils::SmallStringVector &&commandLine) { - m_fileContents.emplace_back(toNativePath(std::move(directory)), - std::move(fileName), - std::move(content), - std::move(commandLine)); + NativeFilePath nativeFilePath{filePath}; - const auto &fileContent = m_fileContents.back(); + m_compilationDatabase.addFile(nativeFilePath, std::move(commandLine)); + m_sourceFilePaths.push_back(Utils::SmallStringView{nativeFilePath}); - m_compilationDatabase.addFile(fileContent.directory, fileContent.fileName, fileContent.commandLine); - m_sourceFilePaths.push_back(fileContent.filePath); + m_fileContents.emplace_back(std::move(nativeFilePath), std::move(content)); } void ClangTool::addFiles(const FilePaths &filePaths, const Utils::SmallStringVector &arguments) { for (const FilePath &filePath : filePaths) { - std::vector commandLine(arguments.begin(), arguments.end()); - commandLine.push_back(std::string(filePath.name())); + std::string filePathStr(filePath.path()); + auto commandLine = arguments; + NativeFilePath nativeFilePath{filePath}; - addFile(filePath.directory(), - filePath.name(), - {}, - std::move(commandLine)); + commandLine.push_back(nativeFilePath.path()); + + addFile(filePath.clone(), {}, std::move(commandLine)); } } -template -void ClangTool::addFiles(const Container &filePaths, - const Utils::SmallStringVector &arguments) -{ - for (const typename Container::value_type &filePath : filePaths) { - auto found = std::find(filePath.rbegin(), filePath.rend(), '/'); - - auto fileNameBegin = found.base(); - - std::vector commandLine(arguments.begin(), arguments.end()); - commandLine.push_back(std::string(filePath)); - - addFile({filePath.begin(), std::prev(fileNameBegin)}, - {fileNameBegin, filePath.end()}, - {}, - std::move(commandLine)); - } -} - -template -void ClangTool::addFiles(const Utils::SmallStringVector &filePaths, - const Utils::SmallStringVector &arguments); -template -void ClangTool::addFiles(const Utils::PathStringVector &filePaths, - const Utils::SmallStringVector &arguments); - void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles) { m_unsavedFileContents.reserve(m_unsavedFileContents.size() + unsavedFiles.size()); - auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) { - return UnsavedFileContent{toNativePath(unsavedFile.filePath.path().clone()), + auto convertToUnsavedFileContent = [](const V2::FileContainer &unsavedFile) { + return UnsavedFileContent{NativeFilePath{unsavedFile.filePath}, unsavedFile.unsavedFileContent.clone()}; }; @@ -120,7 +92,12 @@ llvm::StringRef toStringRef(const String &string) { return llvm::StringRef(string.data(), string.size()); } + +llvm::StringRef toStringRef(const NativeFilePath &path) +{ + return llvm::StringRef(path.path().data(), path.path().size()); } +} // namespace clang::tooling::ClangTool ClangTool::createTool() const { @@ -128,7 +105,7 @@ clang::tooling::ClangTool ClangTool::createTool() const for (const auto &fileContent : m_fileContents) { if (!fileContent.content.empty()) - tool.mapVirtualFile(fileContent.filePath, fileContent.content); + tool.mapVirtualFile(toStringRef(fileContent.filePath), fileContent.content); } for (const auto &unsavedFileContent : m_unsavedFileContents) diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h index 8b4e47df682..e3ff8357998 100644 --- a/src/tools/clangrefactoringbackend/source/clangtool.h +++ b/src/tools/clangrefactoringbackend/source/clangtool.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -43,50 +44,34 @@ namespace ClangBackEnd { struct FileContent { - FileContent(const std::string &directory, - const std::string &fileName, - const std::string &content, - const std::vector &commandLine) - : directory(directory), - fileName(fileName), - filePath(directory + nativeSeparator + fileName), - content(content), - commandLine(commandLine) + FileContent(NativeFilePath &&filePath, const Utils::SmallString &content) + : filePath(std::move(filePath)) + , content(std::move(content)) {} - std::string directory; - std::string fileName; - std::string filePath; + NativeFilePath filePath; std::string content; - std::vector commandLine; }; struct UnsavedFileContent { - UnsavedFileContent(Utils::PathString &&filePath, - Utils::SmallString &&content) - : filePath(std::move(filePath)), - content(std::move(content)) + UnsavedFileContent(NativeFilePath &&filePath, Utils::SmallString &&content) + : filePath(std::move(filePath)) + , content(std::move(content)) {} - Utils::PathString filePath; + NativeFilePath filePath; Utils::SmallString content; }; class ClangTool { public: - void addFile(std::string &&directory, - std::string &&fileName, - std::string &&content, - std::vector &&commandLine); - - template - void addFiles(const Container &filePaths, - const Utils::SmallStringVector &arguments); - void addFiles(const FilePaths &filePaths, - const Utils::SmallStringVector &arguments); + void addFile(FilePath &&filePath, + Utils::SmallString &&content, + Utils::SmallStringVector &&commandLine); + void addFiles(const FilePaths &filePaths, const Utils::SmallStringVector &arguments); void addUnsavedFiles(const V2::FileContainers &unsavedFiles); @@ -102,11 +87,4 @@ private: std::vector m_unsavedFileContents; }; -extern template -void ClangTool::addFiles(const Utils::SmallStringVector &filePaths, - const Utils::SmallStringVector &arguments); -extern template -void ClangTool::addFiles(const Utils::PathStringVector &filePaths, - const Utils::SmallStringVector &arguments); - } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp index c5906aaae47..1e1609d1a4f 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp @@ -27,20 +27,15 @@ #include "clangrefactoringbackend_global.h" +#include +#include + namespace ClangBackEnd { RefactoringCompilationDatabase::RefactoringCompilationDatabase() { } -namespace { - -std::string concatFilePath(const clang::tooling::CompileCommand &compileCommand) -{ - return compileCommand.Directory + nativeSeparator + compileCommand.Filename; -} -} - std::vector RefactoringCompilationDatabase::getCompileCommands(llvm::StringRef filePath) const { @@ -50,7 +45,7 @@ RefactoringCompilationDatabase::getCompileCommands(llvm::StringRef filePath) con m_compileCommands.end(), std::back_inserter(foundCommands), [&] (const clang::tooling::CompileCommand &compileCommand) { - return filePath == concatFilePath(compileCommand); + return filePath == compileCommand.Filename; }); return foundCommands; @@ -66,7 +61,7 @@ RefactoringCompilationDatabase::getAllFiles() const m_compileCommands.end(), std::back_inserter(filePaths), [&] (const clang::tooling::CompileCommand &compileCommand) { - return concatFilePath(compileCommand); + return compileCommand.Filename; }); return filePaths; @@ -78,12 +73,13 @@ RefactoringCompilationDatabase::getAllCompileCommands() const return m_compileCommands; } -void RefactoringCompilationDatabase::addFile(const std::string &directory, - const std::string &fileName, - const std::vector &commandLine) +void RefactoringCompilationDatabase::addFile(NativeFilePathView filePath, + Utils::SmallStringVector &&commandLine) { - - m_compileCommands.emplace_back(directory, fileName, commandLine, llvm::StringRef()); + m_compileCommands.emplace_back(std::string(filePath.directory()), + std::string(filePath), + std::vector(commandLine), + llvm::StringRef()); } } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h index ca2d1338191..b25e43e4834 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h +++ b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h @@ -27,6 +27,8 @@ #include "clang/Tooling/CompilationDatabase.h" +#include + namespace ClangBackEnd { @@ -39,9 +41,7 @@ public: std::vector getAllFiles() const override; std::vector getAllCompileCommands() const override; - void addFile(const std::string &directory, - const std::string &fileName, - const std::vector &commandLine); + void addFile(NativeFilePathView filePath, Utils::SmallStringVector &&commandLine); private: std::vector m_compileCommands; diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp index 4b51ee0d69d..83aa5a31fd8 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp @@ -62,10 +62,9 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo { SymbolFinder symbolFinder(message.line, message.column, m_filePathCache); - symbolFinder.addFile(std::string(message.filePath.directory()), - std::string(message.filePath.name()), - std::string(message.unsavedContent), - std::vector(message.commandLine)); + symbolFinder.addFile(std::move(message.filePath), + std::move(message.unsavedContent), + std::move(message.commandLine)); symbolFinder.findSymbol(); @@ -79,10 +78,9 @@ void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage( { ClangQuery clangQuery(m_filePathCache, message.takeQuery()); - clangQuery.addFile(std::string(message.source.filePath.directory()), - std::string(message.source.filePath.name()), - std::string(message.source.unsavedFileContent), - std::vector(message.source.commandLineArguments)); + clangQuery.addFile(std::move(message.source.filePath), + std::move(message.source.unsavedFileContent), + std::move(message.source.commandLineArguments)); clangQuery.findLocations(); diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp index 8c486a47d78..35842e01439 100644 --- a/tests/unit/unittest/clangquery-test.cpp +++ b/tests/unit/unittest/clangquery-test.cpp @@ -94,7 +94,9 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange) TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange) { ::ClangQuery query(filePathCache); - query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); + query.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, + "#include \"unsaved.h\"", + {"cc", toNativePath(TESTDATA_DIR "/query_simplefunction.cpp").path(), "-std=c++14"}); query.setQuery("functionDecl()"); ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}}; query.addUnsavedFiles({unsavedFile}); @@ -108,7 +110,9 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange) TEST_F(ClangQuerySlowTest, FileIsNotExistingButTheUnsavedDataIsParsed) { ::ClangQuery query(filePathCache); - query.addFile(TESTDATA_DIR, "foo.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/foo.cpp"), "-std=c++14"}); + query.addFile({TESTDATA_DIR "/foo.cpp"}, + "void f() {}", + {"cc", toNativePath(TESTDATA_DIR "/foo.cpp").path(), "-std=c++14"}); query.setQuery("functionDecl()"); query.findLocations(); @@ -120,9 +124,13 @@ TEST_F(ClangQuerySlowTest, FileIsNotExistingButTheUnsavedDataIsParsed) TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang { ::ClangQuery query(filePathCache); - query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); + query.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, + "void f() {}", + {"cc", toNativePath(TESTDATA_DIR "/query_simplefunction.cpp").path(), "-std=c++14"}); query.setQuery("functionDecl()"); - ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}}; + ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR "/query_simplefunction.cpp"}, + "void unsaved();", + {}}; query.addUnsavedFiles({unsavedFile}); query.findLocations(); @@ -215,8 +223,15 @@ TEST_F(ClangQuerySlowTest, DiagnosticForWrongArgumenType) void ClangQuery::SetUp() { - simpleFunctionQuery.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); - simpleClassQuery.addFile(TESTDATA_DIR, "query_simpleclass.cpp", "", {"cc", "query_simpleclass.cpp", "-std=c++14"}); - -} + simpleFunctionQuery.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, + "", + {"cc", + toNativePath(TESTDATA_DIR "/query_simplefunction.cpp").path(), + "-std=c++14"}); + simpleClassQuery.addFile({TESTDATA_DIR "/query_simpleclass.cpp"}, + "", + {"cc", + toNativePath(TESTDATA_DIR "/query_simpleclass.cpp").path(), + "-std=c++14"}); } +} // namespace diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp index 9c575f6a0f5..b0ea9cb3e0e 100644 --- a/tests/unit/unittest/clangquerygatherer-test.cpp +++ b/tests/unit/unittest/clangquerygatherer-test.cpp @@ -87,13 +87,22 @@ protected: Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"}; FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), - {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-I", TESTDATA_DIR}}; + {"cc", + toNativePath(TESTDATA_DIR "/query_simplefunction.cpp").path(), + "-I", + TESTDATA_DIR}}; FileContainer source2{{TESTDATA_DIR, "query_simplefunction2.cpp"}, {}, - {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction2.cpp"), "-I", TESTDATA_DIR}}; + {"cc", + toNativePath(TESTDATA_DIR "/query_simplefunction2.cpp").path(), + "-I", + TESTDATA_DIR}}; FileContainer source3{{TESTDATA_DIR, "query_simplefunction3.cpp"}, {}, - {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction3.cpp"), "-I", TESTDATA_DIR}}; + {"cc", + toNativePath(TESTDATA_DIR "/query_simplefunction3.cpp").path(), + "-I", + TESTDATA_DIR}}; Utils::SmallString unsavedContent{"void f();"}; FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"}, unsavedContent.clone(), diff --git a/tests/unit/unittest/commandlinebuilder-test.cpp b/tests/unit/unittest/commandlinebuilder-test.cpp index c3dad70de3c..9de48fe0d55 100644 --- a/tests/unit/unittest/commandlinebuilder-test.cpp +++ b/tests/unit/unittest/commandlinebuilder-test.cpp @@ -25,6 +25,8 @@ #include "googletest.h" +#include "filesystem-utilities.h" + #include #include #include @@ -136,7 +138,7 @@ TYPED_TEST(CommandLineBuilder, CTask) ASSERT_THAT( builder.commandLine, - ElementsAre("clang", "-x", "c-header", "-std=c11", "-nostdinc", "-nostdinc++", "/source/file.c")); + ElementsAre("clang", "-x", "c-header", "-std=c11", "-nostdinc", "-nostdinc++", toNativePath("/source/file.c").path())); } TYPED_TEST(CommandLineBuilder, ObjectiveCTask) @@ -154,7 +156,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCTask) "-std=c11", "-nostdinc", "-nostdinc++", - "/source/file.c")); + toNativePath("/source/file.c").path())); } TYPED_TEST(CommandLineBuilder, CppTask) @@ -171,7 +173,7 @@ TYPED_TEST(CommandLineBuilder, CppTask) "-std=c++98", "-nostdinc", "-nostdinc++", - "/source/file.cpp")); + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, ObjectiveCppTask) @@ -189,7 +191,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCppTask) "-std=c++98", "-nostdinc", "-nostdinc++", - "/source/file.cpp")); + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, Cpp98) @@ -422,18 +424,18 @@ TYPED_TEST(CommandLineBuilder, IncludesOrder) "-nostdinc", "-nostdinc++", "-I", - "/include/foo", + toNativePath("/include/foo").path(), "-I", - "/include/bar", + toNativePath("/include/bar").path(), "-F", - "/system/foo", + toNativePath("/system/foo").path(), "-isystem", - "/system/bar", + toNativePath("/system/bar").path(), "-isystem", - "/builtin/foo", + toNativePath("/builtin/foo").path(), "-isystem", - "/builtin/bar", - "/source/file.cpp")); + toNativePath("/builtin/bar").path(), + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, EmptySourceFile) @@ -455,7 +457,7 @@ TYPED_TEST(CommandLineBuilder, SourceFile) "-std=c++98", "-nostdinc", "-nostdinc++", - "/source/file.cpp")); + toNativePath("/source/file.cpp").path())); } @@ -470,7 +472,7 @@ TYPED_TEST(CommandLineBuilder, EmptyOutputFile) "-std=c++98", "-nostdinc", "-nostdinc++", - "/source/file.cpp")); + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, OutputFile) @@ -485,8 +487,8 @@ TYPED_TEST(CommandLineBuilder, OutputFile) "-nostdinc", "-nostdinc++", "-o", - "/output/file.o", - "/source/file.cpp")); + toNativePath("/output/file.o").path(), + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, IncludePchPath) @@ -503,10 +505,10 @@ TYPED_TEST(CommandLineBuilder, IncludePchPath) "-Xclang", "-include-pch", "-Xclang", - "/pch/file.pch", + toNativePath("/pch/file.pch").path(), "-o", - "/output/file.o", - "/source/file.cpp")); + toNativePath("/output/file.o").path(), + toNativePath("/source/file.cpp").path())); } TYPED_TEST(CommandLineBuilder, CompilerMacros) diff --git a/tests/unit/unittest/filesystem-utilities.h b/tests/unit/unittest/filesystem-utilities.h index 3bbafdf3686..9a4fd8e2db7 100644 --- a/tests/unit/unittest/filesystem-utilities.h +++ b/tests/unit/unittest/filesystem-utilities.h @@ -26,32 +26,27 @@ #pragma once #include -#include -#include +#include -// use std::filesystem::path if it is supported by all compilers -static const char nativeSeparator = Utils::HostOsInfo::isWindowsHost() ? '\\' : '/'; - - -template -std::string toNativePath(const char (&text)[Size]) +template +ClangBackEnd::NativeFilePath toNativePath(const char (&text)[Size]) { - std::string path = text; + ClangBackEnd::FilePath path = text; - if (Utils::HostOsInfo::isWindowsHost()) - std::replace(path.begin(), path.end(), '/', '\\'); - - return path; + return ClangBackEnd::NativeFilePath{path}; } -inline -std::string toNativePath(const QString &qStringPath) +inline ClangBackEnd::NativeFilePath toNativePath(const QString &text) { - auto path = qStringPath.toStdString(); + ClangBackEnd::FilePath path{text}; - if (Utils::HostOsInfo::isWindowsHost()) - std::replace(path.begin(), path.end(), '/', '\\'); - - return path; + return ClangBackEnd::NativeFilePath{path}; +} + +inline ClangBackEnd::NativeFilePath toNativePath(Utils::SmallStringView text) +{ + ClangBackEnd::FilePath path{text}; + + return ClangBackEnd::NativeFilePath{path}; } diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 3901cb0d305..30660376e1f 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -69,10 +69,24 @@ #include #include +#include + namespace { ClangBackEnd::FilePathCaching *filePathCache = nullptr; } +namespace clang { +namespace tooling { +struct CompileCommand; + +std::ostream &operator<<(std::ostream &out, const CompileCommand &command) +{ + return out << "(" << command.Directory << ", " << command.Filename << ", " + << command.CommandLine << ", " << command.Output << ")"; +} +} // namespace tooling +} // namespace clang + void PrintTo(const Utf8String &text, ::std::ostream *os) { *os << text; diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index ec54af30850..d0f0013f609 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -40,6 +40,14 @@ class Utf8String; void PrintTo(const Utf8String &text, ::std::ostream *os); +namespace clang { +namespace tooling { +struct CompileCommand; + +std::ostream &operator<<(std::ostream &out, const CompileCommand &command); +} // namespace tooling +} // namespace clang + namespace Core { class LocatorFilterEntry; diff --git a/tests/unit/unittest/nativefilepath-test.cpp b/tests/unit/unittest/nativefilepath-test.cpp index 864c91dc608..327cff42dc6 100644 --- a/tests/unit/unittest/nativefilepath-test.cpp +++ b/tests/unit/unittest/nativefilepath-test.cpp @@ -25,6 +25,7 @@ #include "googletest.h" +#include #include namespace { diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index a75ff4267ab..8a1e1ffa8ef 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -26,6 +26,7 @@ #include "googletest.h" #include "fakeprocess.h" +#include "filesystem-utilities.h" #include "mockclangpathwatcher.h" #include "mockpchmanagerclient.h" @@ -144,11 +145,11 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArguments) "-nostdinc", "-nostdinc++", "-I", - TESTDATA_DIR "/builddependencycollector/project", + toNativePath(TESTDATA_DIR "/builddependencycollector/project").path(), "-isystem", - TESTDATA_DIR "/builddependencycollector/external", + toNativePath(TESTDATA_DIR "/builddependencycollector/external").path(), "-isystem", - TESTDATA_DIR "/builddependencycollector/system", + toNativePath(TESTDATA_DIR "/builddependencycollector/system").path(), "-o", "project.pch", "project.h")); @@ -170,11 +171,11 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch) "-nostdinc", "-nostdinc++", "-I", - TESTDATA_DIR "/builddependencycollector/project", + toNativePath(TESTDATA_DIR "/builddependencycollector/project").path(), "-isystem", - TESTDATA_DIR "/builddependencycollector/external", + toNativePath(TESTDATA_DIR "/builddependencycollector/external").path(), "-isystem", - TESTDATA_DIR "/builddependencycollector/system", + toNativePath(TESTDATA_DIR "/builddependencycollector/system").path(), "-Xclang", "-include-pch", "-Xclang", diff --git a/tests/unit/unittest/refactoringcompilationdatabase-test.cpp b/tests/unit/unittest/refactoringcompilationdatabase-test.cpp index b635d174a98..59f88f8b53d 100644 --- a/tests/unit/unittest/refactoringcompilationdatabase-test.cpp +++ b/tests/unit/unittest/refactoringcompilationdatabase-test.cpp @@ -24,8 +24,10 @@ ****************************************************************************/ #include "googletest.h" +#include "filesystem-utilities.h" #include +#include #include @@ -38,16 +40,16 @@ using testing::PrintToString; namespace { -MATCHER_P3(IsCompileCommand, directory, fileName, commandLine, - std::string(negation ? "isn't" : "is") - + " compile command with directory "+ PrintToString(directory) - + ", file name " + PrintToString(fileName) - + " and command line " + PrintToString(commandLine) - ) +MATCHER_P3(IsCompileCommand, + directory, + filePath, + commandLine, + std::string(negation ? "isn't" : "is") + " compile command with directory " + + PrintToString(directory) + ", file name " + PrintToString(filePath) + + " and command line " + PrintToString(commandLine)) { - if (arg.Directory != directory - || arg.Filename != fileName - || arg.CommandLine != commandLine) + if (arg.Directory != std::string(directory) || arg.Filename != std::string(filePath) + || arg.CommandLine != commandLine) return false; return true; @@ -56,7 +58,11 @@ MATCHER_P3(IsCompileCommand, directory, fileName, commandLine, class RefactoringCompilationDatabase : public ::testing::Test { protected: - void SetUp(); + RefactoringCompilationDatabase() + { + database.addFile(ClangBackEnd::NativeFilePathView{temporarySourceFilePath}, + {"cc", toNativePath(temporaryDirectoryPath + "/data.cpp").path(), "-DNO_DEBUG"}); + } protected: ClangBackEnd::RefactoringCompilationDatabase database; @@ -76,18 +82,28 @@ TEST_F(RefactoringCompilationDatabase, CompileCommandForFilePath) { auto compileCommands = database.getAllCompileCommands(); - ASSERT_THAT(compileCommands, Contains(IsCompileCommand(temporaryDirectoryPath, - "data.cpp", - std::vector{"cc", "data.cpp", "-DNO_DEBUG"}))); + ASSERT_THAT(compileCommands, + Contains(IsCompileCommand( + temporaryDirectoryPath, + toNativePath(temporaryDirectoryPath + "/data.cpp").path(), + std::vector{ + "cc", + std::string(toNativePath(temporaryDirectoryPath + "/data.cpp").path()), + "-DNO_DEBUG"}))); } TEST_F(RefactoringCompilationDatabase, NoCompileCommandForFilePath) { auto compileCommands = database.getAllCompileCommands(); - ASSERT_THAT(compileCommands, Not(Contains(IsCompileCommand(temporaryDirectoryPath, - "data.cpp2", - std::vector{"cc", "data.cpp", "-DNO_DEBUG"})))); + ASSERT_THAT(compileCommands, + Not(Contains(IsCompileCommand( + temporaryDirectoryPath, + toNativePath(temporaryDirectoryPath + "/data.cpp2").path(), + std::vector{ + "cc", + std::string(toNativePath(temporaryDirectoryPath + "/data.cpp").path()), + "-DNO_DEBUG"})))); } TEST_F(RefactoringCompilationDatabase, FilePaths) @@ -96,10 +112,4 @@ TEST_F(RefactoringCompilationDatabase, FilePaths) ASSERT_THAT(filePaths, Contains(std::string(temporarySourceFilePath))); } - -void RefactoringCompilationDatabase::SetUp() -{ - database.addFile(std::string(temporaryDirectoryPath), "data.cpp", {"cc", "data.cpp", "-DNO_DEBUG"}); -} - -} +} // namespace diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp index b8b97437e4a..56f5e6950dd 100644 --- a/tests/unit/unittest/refactoringserver-test.cpp +++ b/tests/unit/unittest/refactoringserver-test.cpp @@ -102,8 +102,9 @@ protected: Utils::SmallString sourceContent{"void f()\n {}"}; FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), - {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}}; - QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath() + "/clangQuery-XXXXXX.cpp"}; + {"cc", toNativePath(TESTDATA_DIR "/query_simplefunction.cpp").path()}}; + QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath() + + "/clangQuery-XXXXXX.cpp"}; int processingSlotCount = 2; }; @@ -266,10 +267,11 @@ TEST_F(RefactoringServer, PollTimerNotIsActiveAfterCanceling) TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSourceRange) { - RequestSourceRangesAndDiagnosticsForQueryMessage message("functionDecl()", - {FilePath(temporaryFile.fileName()), - "void f() {}", - {"cc", toNativePath(temporaryFile.fileName())}}); + RequestSourceRangesAndDiagnosticsForQueryMessage message( + "functionDecl()", + {FilePath(temporaryFile.fileName()), + "void f() {}", + {"cc", toNativePath(temporaryFile.fileName()).path()}}); EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage( @@ -285,10 +287,11 @@ TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSo TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGetDiagnostics) { - RequestSourceRangesAndDiagnosticsForQueryMessage message("func()", - {FilePath(temporaryFile.fileName()), - "void f() {}", - {"cc", toNativePath(temporaryFile.fileName())}}); + RequestSourceRangesAndDiagnosticsForQueryMessage message( + "func()", + {FilePath(temporaryFile.fileName()), + "void f() {}", + {"cc", toNativePath(temporaryFile.fileName()).path()}}); EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage( diff --git a/tests/unit/unittest/sourcerangeextractor-test.cpp b/tests/unit/unittest/sourcerangeextractor-test.cpp index ae9d670bf4b..171db9b956d 100644 --- a/tests/unit/unittest/sourcerangeextractor-test.cpp +++ b/tests/unit/unittest/sourcerangeextractor-test.cpp @@ -57,7 +57,9 @@ protected: void TearDown() override; protected: - TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}}; + TestClangTool clangTool{{TESTDATA_DIR "/sourcerangeextractor_location.cpp"}, + "", + {"cc", "sourcerangeextractor_location.cpp"}}; ClangBackEnd::SourceRangesContainer sourceRangesContainer; const clang::SourceManager &sourceManager{clangTool.sourceManager()}; Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; diff --git a/tests/unit/unittest/symbolfinder-test.cpp b/tests/unit/unittest/symbolfinder-test.cpp index 6ab0bd06cd9..1dad3184d68 100644 --- a/tests/unit/unittest/symbolfinder-test.cpp +++ b/tests/unit/unittest/symbolfinder-test.cpp @@ -31,28 +31,30 @@ #include "filesystem-utilities.h" -using ClangBackEnd::SymbolFinder; using ClangBackEnd::FileContent; - +using ClangBackEnd::FilePathView; +using ClangBackEnd::NativeFilePath; +using ClangBackEnd::NativeFilePathView; +using ClangBackEnd::SymbolFinder; namespace { -MATCHER_P2(IsSourceLocation, line, column, - std::string(negation ? "isn't" : "is") - + "line " + PrintToString(line) - + ", column " + PrintToString(column) - ) +inline bool operator==(const ClangBackEnd::NativeFilePath &first, const std::string &second) +{ + return first.path() == second; +} +MATCHER_P2(IsSourceLocation, + line, + column, + std::string(negation ? "isn't" : "is") + "line " + PrintToString(line) + ", column " + + PrintToString(column)) { return arg.line == uint(line) && arg.column == uint(column); } -MATCHER_P(StrEq, text, - std::string(negation ? "isn't" : "is") - + " text " + PrintToString(text) - ) +MATCHER_P(StrEq, text, std::string(negation ? "isn't" : "is") + " text " + PrintToString(text)) { return std::string(arg.data(), arg.size()) == std::string(text); } - using Finder = SymbolFinder; class SymbolFinder : public testing::Test @@ -65,7 +67,7 @@ using SymbolFinderSlowTest = SymbolFinder; TEST_F(SymbolFinder, FileContentFilePath) { - FileContent fileContent(toNativePath("/tmp"), "data.cpp", "int variable;", {"cc", "data.cpp"}); + FileContent fileContent(NativeFilePath{FilePathView{"/tmp/data.cpp"}}, "int variable;"); ASSERT_THAT(fileContent.filePath, toNativePath("/tmp/data.cpp")); } @@ -73,7 +75,9 @@ TEST_F(SymbolFinder, FileContentFilePath) TEST_F(SymbolFinderSlowTest, FindName) { Finder finder(1, 5, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "int variable;", {"cc", "renamevariable.cpp"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "int variable;", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path()}); finder.findSymbol(); @@ -83,7 +87,9 @@ TEST_F(SymbolFinderSlowTest, FindName) TEST_F(SymbolFinderSlowTest, FindNameInUnsavedFile) { Finder finder(1, 5, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "int newVariable;", {"cc", "renamevariable.cpp"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "int newVariable;", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path()}); finder.findSymbol(); @@ -93,7 +99,9 @@ TEST_F(SymbolFinderSlowTest, FindNameInUnsavedFile) TEST_F(SymbolFinderSlowTest, FindUsrs) { Finder finder(1, 5, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "int variable;", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "int variable;", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -103,7 +111,9 @@ TEST_F(SymbolFinderSlowTest, FindUsrs) TEST_F(SymbolFinderSlowTest, VariableDeclarationSourceLocations) { Finder finder(1, 5, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -115,7 +125,9 @@ TEST_F(SymbolFinderSlowTest, VariableDeclarationSourceLocations) TEST_F(SymbolFinderSlowTest, VariableUsageSourceLocations) { Finder finder(3, 9, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -127,7 +139,9 @@ TEST_F(SymbolFinderSlowTest, VariableUsageSourceLocations) TEST_F(SymbolFinderSlowTest, TemplateMemberVariableDeclarationSourceLocations) { Finder finder(8, 18, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -140,7 +154,9 @@ TEST_F(SymbolFinderSlowTest, TemplateMemberVariableDeclarationSourceLocations) TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageSourceLocations) { Finder finder(15, 14, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -153,7 +169,9 @@ TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageSourceLocations) TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageInLambdaSourceLocations) { Finder finder(18, 19, filePathCaching); - finder.addFile(TESTDATA_DIR, "renamevariable.cpp", "", {"cc", "renamevariable.cpp", "-std=c++14"}); + finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/renamevariable.cpp").path(), "-std=c++14"}); finder.findSymbol(); @@ -166,7 +184,9 @@ TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageInLambdaSourceLocations) TEST_F(SymbolFinderSlowTest, CursorOverMacroDefintionSymbolName) { Finder finder(1, 9, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -176,7 +196,9 @@ TEST_F(SymbolFinderSlowTest, CursorOverMacroDefintionSymbolName) TEST_F(SymbolFinderSlowTest, CursorOverMacroExpansionSymbolName) { Finder finder(10, 10, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -186,7 +208,9 @@ TEST_F(SymbolFinderSlowTest, CursorOverMacroExpansionSymbolName) TEST_F(SymbolFinderSlowTest, FindMacroDefinition) { Finder finder(1, 9, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -197,7 +221,9 @@ TEST_F(SymbolFinderSlowTest, FindMacroDefinition) TEST_F(SymbolFinderSlowTest, FindMacroExpansion) { Finder finder(1, 9, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -208,7 +234,9 @@ TEST_F(SymbolFinderSlowTest, FindMacroExpansion) TEST_F(SymbolFinderSlowTest, DoNotFindUndedefinedMacroExpansion) { Finder finder(1, 9, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -219,7 +247,9 @@ TEST_F(SymbolFinderSlowTest, DoNotFindUndedefinedMacroExpansion) TEST_F(SymbolFinderSlowTest, FindMacroDefinitionFromMacroExpansion) { Finder finder(10, 10, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -231,7 +261,9 @@ TEST_F(SymbolFinderSlowTest, FindMacroDefinitionFromMacroExpansion) TEST_F(SymbolFinderSlowTest, FindMacroExpansionBeforeMacroExpansionWithCursor) { Finder finder(12, 10, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -242,7 +274,9 @@ TEST_F(SymbolFinderSlowTest, FindMacroExpansionBeforeMacroExpansionWithCursor) TEST_F(SymbolFinderSlowTest, FindMacroExpansionAfterMacroExpansionWithCursor) { Finder finder(10, 10, filePathCaching); - finder.addFile(TESTDATA_DIR, "symbolfinder_macro.cpp", "", {"cc", "symbolfinder_macro.cpp"}); + finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, + "", + {"cc", toNativePath(TESTDATA_DIR "/symbolfinder_macro.cpp").path()}); finder.findSymbol(); @@ -250,4 +284,4 @@ TEST_F(SymbolFinderSlowTest, FindMacroExpansionAfterMacroExpansionWithCursor) Contains(IsSourceLocation(12, 10))); } -} +} // namespace diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 104c17b11b3..ce0fadfdf8c 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "googletest.h" +#include "filesystem-utilities.h" #include "mockclangpathwatcher.h" #include "mocksymbolscollector.h" #include "mocksymbolstorage.h" @@ -273,15 +274,15 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); indexer.updateProjectParts({projectPart1}); } @@ -303,19 +304,19 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInColl "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes", + toNativePath("/includes").path(), "-Xclang", "-include-pch", "-Xclang", - "/path/to/pch"))); + toNativePath("/path/to/pch").path()))); indexer.updateProjectParts({projectPart1}); } @@ -336,15 +337,15 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithoutPrecompiledHeaderInC "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); indexer.updateProjectParts({projectPart1}); } @@ -516,15 +517,15 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); EXPECT_CALL(mockCollector, collectSymbols()); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); @@ -568,15 +569,15 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); EXPECT_CALL(mockCollector, collectSymbols()); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); @@ -624,15 +625,15 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); EXPECT_CALL(mockCollector, collectSymbols()); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); @@ -686,19 +687,19 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes", + toNativePath("/includes").path(), "-Xclang", "-include-pch", "-Xclang", - "/path/to/pch"))); + toNativePath("/path/to/pch").path()))); indexer.pathsChanged({sourceFileIds[0]}); } @@ -721,15 +722,15 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists) "-DBAR=1", "-DFOO=1", "-I", - "/project/includes", + toNativePath("/project/includes").path(), "-I", - "/other/project/includes", + toNativePath("/other/project/includes").path(), "-isystem", - TESTDATA_DIR, + toNativePath(TESTDATA_DIR).path(), "-isystem", - "/other/includes", + toNativePath("/other/includes").path(), "-isystem", - "/includes"))); + toNativePath("/includes").path()))); indexer.pathsChanged({sourceFileIds[0]}); } diff --git a/tests/unit/unittest/testclangtool.cpp b/tests/unit/unittest/testclangtool.cpp index de41e42a814..bea5afeb4c8 100644 --- a/tests/unit/unittest/testclangtool.cpp +++ b/tests/unit/unittest/testclangtool.cpp @@ -25,12 +25,11 @@ #include "testclangtool.h" -TestClangTool::TestClangTool(std::string &&directory, - std::string &&fileName, - std::string &&content, - std::vector &&commandLine) +TestClangTool::TestClangTool(ClangBackEnd::FilePath &&filePath, + Utils::SmallString &&content, + Utils::SmallStringVector &&commandLine) { - addFile(std::move(directory), std::move(fileName), std::move(content), std::move(commandLine)); + addFile(std::move(filePath), std::move(content), std::move(commandLine)); auto clangTool = createTool(); diff --git a/tests/unit/unittest/testclangtool.h b/tests/unit/unittest/testclangtool.h index f8ae0caf165..448c4e51ae8 100644 --- a/tests/unit/unittest/testclangtool.h +++ b/tests/unit/unittest/testclangtool.h @@ -30,10 +30,9 @@ class TestClangTool : public ClangBackEnd::ClangTool { public: - TestClangTool(std::string &&directory, - std::string &&fileName, - std::string &&content, - std::vector &&commandLine); + TestClangTool(ClangBackEnd::FilePath &&filePath, + Utils::SmallString &&content, + Utils::SmallStringVector &&commandLine); const clang::ASTUnit *ast() const; const clang::SourceManager &sourceManager() const; From c6d3e106fe5fd49c484554b6d18984825cb3fdba Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 7 Feb 2019 14:17:48 +0100 Subject: [PATCH 26/44] Add changes file for 4.8.2 Change-Id: I988aaa653b9829899317237343d0906807408c94 Reviewed-by: Leena Miettinen --- dist/changes-4.8.2.md | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 dist/changes-4.8.2.md diff --git a/dist/changes-4.8.2.md b/dist/changes-4.8.2.md new file mode 100644 index 00000000000..22a930d9a40 --- /dev/null +++ b/dist/changes-4.8.2.md @@ -0,0 +1,72 @@ +Qt Creator version 4.8.2 contains bug fixes. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/v4.8.1..v4.8.2 + +Editing + +* Fixed highlighting of search results of regular expression search + (QTCREATORBUG-21887) + +Autotools Projects + +* Fixed that includes, defines and flags of `SUBDIRS` were ignored + (QTCREATORBUG-21618) + +C++ Support + +* Fixed crash when expanding macros (QTCREATORBUG-21642) + +QML Support + +* Fixed auto-insertion of single quotes + +Debugging + +* GDB + * Fixed detaching from process (QTCREATORBUG-21908) +* LLDB + * Fixed stopping at some breakpoints with newer LLDB (QTCREATORBUG-21615) + * Fixed `Attach to Process` and `Run in Terminal` with newer LLDB +* CDB + * Fixed display of `QDateTime` (QTCREATORBUG-21864) + +Qt Quick Designer + +* Added support for more JavaScript functions in `.ui.qml` files + +Test Integration + +* Fixed handling of empty tests + +Platform Specific + +macOS + +* Fixed crash when file change dialog is triggered while another modal dialog + is open +* Fixed running of user applications that need access to camera, microphone or + other restricted services on macOS 10.14 (QTCREATORBUG-21887) + +Android + +* Fixed upload of GDB server on some devices (QTCREATORBUG-21317) + +Credits for these changes go to: +André Pönitz +Christian Kandeler +Christian Stenger +David Schulz +Eike Ziller +Ivan Donchevskii +Leena Miettinen +Liang Qi +Oliver Wolff +Raoul Hecky +Robert Löhning +Thomas Hartmann +Vikas Pachdha From d45d5b79f0d17c396183ae72e9c89011ffec8b93 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 10:22:23 +0100 Subject: [PATCH 27/44] QmlDesigner: Fix warnings about unused variables and functions Change-Id: I97a969f10bf9679c36bee8571309d415a733e4b0 Reviewed-by: Thomas Hartmann --- .../qmldesignerextension/timelineeditor/timelineitem.cpp | 6 ------ .../timelineeditor/timelinemovetool.cpp | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineitem.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineitem.cpp index 1bb9fff0fd8..ebe3644e4e8 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineitem.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineitem.cpp @@ -152,12 +152,6 @@ static int devicePixelHeight(const QPixmap &pixmap) return pixmap.height() / pixmap.devicePixelRatioF(); } -static QString iconPath() -{ - return Core::ICore::resourcePath() - + QLatin1String("/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images/"); -} - void TimelineFrameHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp index ab92bb2dc62..49d35b781b9 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp @@ -120,7 +120,7 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, Q_UNUSED(event); if (auto *current = currentItem()) { - if (auto *playhead = current->asTimelineFrameHandle()) { + if (current->asTimelineFrameHandle()) { double mousePos = event->pos().x(); double start = current->mapFromFrameToScene(scene()->startFrame()); double end = current->mapFromFrameToScene(scene()->endFrame()); @@ -142,7 +142,7 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, current->commitPosition(mapToItem(current, current->rect().center())); - if (TimelineKeyframeItem *currentKeyframe = current->asTimelineKeyframeItem()) { + if (current->asTimelineKeyframeItem()) { double frame = std::round( current->mapFromSceneToFrame(current->rect().center().x())); From 666a9704588ad2d12486eac81f967c79e72ded23 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 15:15:57 +0100 Subject: [PATCH 28/44] QbsProjectManager: Remove unused function Output parsers are created elswehere these days. Change-Id: I196d158747883df091f7b55354c3580515d9759e Reviewed-by: Christian Stenger --- src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp | 6 ------ src/plugins/qbsprojectmanager/qbsbuildconfiguration.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp index 1d464039f54..21e24cffa80 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp @@ -179,12 +179,6 @@ Internal::QbsProject *QbsBuildConfiguration::project() const return qobject_cast(BuildConfiguration::project()); } -IOutputParser *QbsBuildConfiguration::createOutputParser() const -{ - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); - return tc ? tc->outputParser() : nullptr; -} - bool QbsBuildConfiguration::isEnabled() const { return !project()->isParsing() && project()->hasParseResult(); diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h index 19c29ac33fc..1db60592522 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h @@ -57,8 +57,6 @@ public: Internal::QbsProject *project() const override; - ProjectExplorer::IOutputParser *createOutputParser() const; - bool isEnabled() const override; QString disabledReason() const override; From 791d791f2ca80dc623e6dac78c9f469e442516c3 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 5 Feb 2019 12:49:35 +0100 Subject: [PATCH 29/44] Make deployqt target recursive So perfparser's deploy target is triggered too Change-Id: I131a23b46127130967767fd7fee629ac5a97b17a Reviewed-by: Ulf Hermann --- qtcreator.pro | 3 +++ src/app/app.pro | 2 ++ src/libs/libs.pro | 2 ++ src/plugins/plugins.pro | 2 ++ src/shared/shared.pro | 28 ++++++++++++++++++++++++++++ src/src.pro | 32 ++++++-------------------------- src/tools/perfparser | 2 +- src/tools/tools.pro | 5 +++++ 8 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 src/shared/shared.pro diff --git a/qtcreator.pro b/qtcreator.pro index 214740353a3..98a897aa2b0 100644 --- a/qtcreator.pro +++ b/qtcreator.pro @@ -150,4 +150,7 @@ win32 { bindist_installer.commands ~= s,/,\\\\,g } +deployqt.CONFIG += recursive +deployqt.recurse = src + QMAKE_EXTRA_TARGETS += deployqt bindist bindist_installer bindist_debug diff --git a/src/app/app.pro b/src/app/app.pro index 08af263b476..89b9554a9ff 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -52,3 +52,5 @@ DISTFILES += qtcreator.rc \ QMAKE_SUBSTITUTES += $$PWD/app_version.h.in CONFIG += no_batch + +QMAKE_EXTRA_TARGETS += deployqt # dummy diff --git a/src/libs/libs.pro b/src/libs/libs.pro index 1ffb3bc9a49..8bc99461a71 100644 --- a/src/libs/libs.pro +++ b/src/libs/libs.pro @@ -48,3 +48,5 @@ win32: isEmpty(QTC_SKIP_CDBEXT) { message("environment variable pointing to your CDB installation.") } } + +QMAKE_EXTRA_TARGETS += deployqt # dummy diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index e935e7b5e8b..9efcf77bf11 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -133,3 +133,5 @@ for(p, SUBDIRS) { linux-* { SUBDIRS += debugger/ptracepreload.pro } + +QMAKE_EXTRA_TARGETS += deployqt # dummy diff --git a/src/shared/shared.pro b/src/shared/shared.pro new file mode 100644 index 00000000000..e75970c0fb3 --- /dev/null +++ b/src/shared/shared.pro @@ -0,0 +1,28 @@ +TEMPLATE = subdirs + +QBS_DIRS = \ + qbscorelib \ + qbsqtprofilesetup \ + qbsapps \ + qbslibexec \ + qbsplugins \ + qbsstatic + +qbscorelib.subdir = qbs/src/lib/corelib +qbsqtprofilesetup.subdir = qbs/src/lib/qtprofilesetup +qbsqtprofilesetup.depends = qbscorelib +qbsapps.subdir = qbs/src/app +qbsapps.depends = qbsqtprofilesetup +qbslibexec.subdir = qbs/src/libexec +qbslibexec.depends = qbscorelib +qbsplugins.subdir = qbs/src/plugins +qbsplugins.depends = qbscorelib +qbsstatic.file = qbs/static.pro + +exists(qbs/qbs.pro) { + isEmpty(QBS_INSTALL_DIR):QBS_INSTALL_DIR = $$(QBS_INSTALL_DIR) + isEmpty(QBS_INSTALL_DIR):SUBDIRS += $$QBS_DIRS +} +TR_EXCLUDE = qbs + +QMAKE_EXTRA_TARGETS += deployqt # dummy diff --git a/src/src.pro b/src/src.pro index 496c500dbdd..4380ec271d4 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,36 +1,16 @@ -include(../qtcreator.pri) - TEMPLATE = subdirs CONFIG += ordered -QBS_DIRS = \ - qbscorelib \ - qbsqtprofilesetup \ - qbsapps \ - qbslibexec \ - qbsplugins \ - qbsstatic - -qbscorelib.subdir = shared/qbs/src/lib/corelib -qbsqtprofilesetup.subdir = shared/qbs/src/lib/qtprofilesetup -qbsqtprofilesetup.depends = qbscorelib -qbsapps.subdir = shared/qbs/src/app -qbsapps.depends = qbsqtprofilesetup -qbslibexec.subdir = shared/qbs/src/libexec -qbslibexec.depends = qbscorelib -qbsplugins.subdir = shared/qbs/src/plugins -qbsstatic.file = shared/qbs/static.pro - -exists(shared/qbs/qbs.pro) { - isEmpty(QBS_INSTALL_DIR):QBS_INSTALL_DIR = $$(QBS_INSTALL_DIR) - isEmpty(QBS_INSTALL_DIR):SUBDIRS += $$QBS_DIRS -} -TR_EXCLUDE = shared/qbs - SUBDIRS += \ + shared \ libs \ app \ plugins \ tools \ share/qtcreator/data.pro \ share/3rdparty/data.pro + +# delegate deployqt target +deployqt.CONFIG += recursive +deployqt.recurse = shared libs app plugins tools +QMAKE_EXTRA_TARGETS += deployqt diff --git a/src/tools/perfparser b/src/tools/perfparser index 15a4e2d8dcd..5222205d9ac 160000 --- a/src/tools/perfparser +++ b/src/tools/perfparser @@ -1 +1 @@ -Subproject commit 15a4e2d8dcde52994a85361154c44e7810779d7a +Subproject commit 5222205d9acca1107507bfdeebaab194157012e0 diff --git a/src/tools/tools.pro b/src/tools/tools.pro index 07cc2c2114a..61a8d07cc59 100644 --- a/src/tools/tools.pro +++ b/src/tools/tools.pro @@ -81,3 +81,8 @@ exists(perfparser/perfparser.pro) { } OTHER_FILES += tools.qbs + +# delegate deployqt target +deployqt.CONFIG += recursive +deployqt.recurse = perfparser +QMAKE_EXTRA_TARGETS += deployqt From 7ba74c2ba409180567d01d2f4f34c62cdbd852d4 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 6 Feb 2019 08:57:33 +0100 Subject: [PATCH 30/44] AutoTest: Use TypedTreeItem for TestResultItem Simplifies code and reduces (visible) static_casts on the auto test plugin's side. Change-Id: I31ae3e4f1a32d3e74527ccb36080944848f3b1fa Reviewed-by: David Schulz --- src/libs/utils/treemodel.h | 5 +++ src/plugins/autotest/testresultmodel.cpp | 48 ++++++++++-------------- src/plugins/autotest/testresultmodel.h | 4 +- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 92f501ff4a6..7ab043032a6 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -148,6 +148,11 @@ public: }; TreeItem::insertOrderedChild(item, cmp0); } + + ChildType *reverseFindAnyChild(const std::function &pred) const + { + return static_cast(TreeItem::reverseFindAnyChild(pred)); + } }; class QTCREATOR_UTILS_EXPORT StaticTreeItem : public TreeItem diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 0a1ee0c6169..99e1ee15ac2 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -163,7 +163,7 @@ TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) cons QTC_ASSERT(item, return nullptr); const TestResult *otherResult = item->testResult(); for (int row = childCount() - 1; row >= 0; --row) { - TestResultItem *child = static_cast(childAt(row)); + TestResultItem *child = childAt(row); const TestResult *testResult = child->testResult(); if (testResult->result() != Result::MessageIntermediate) continue; @@ -186,7 +186,7 @@ TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem /********************************* TestResultModel *****************************************/ TestResultModel::TestResultModel(QObject *parent) - : Utils::TreeModel<>(parent) + : Utils::TreeModel(new TestResultItem(TestResultPtr()), parent) { } @@ -194,16 +194,15 @@ void TestResultModel::updateParent(const TestResultItem *item) { QTC_ASSERT(item, return); QTC_ASSERT(item->testResult(), return); - Utils::TreeItem *parentItem = item->parent(); + TestResultItem *parentItem = item->parent(); if (parentItem == rootItem()) // do not update invisible root item return; bool changed = false; - TestResultItem *parentResultItem = static_cast(parentItem); - parentResultItem->updateResult(changed, item->testResult()->result()); + parentItem->updateResult(changed, item->testResult()->result()); if (!changed) return; emit dataChanged(parentItem->index(), parentItem->index()); - updateParent(parentResultItem); + updateParent(parentItem); } void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand) @@ -212,7 +211,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx if (testResult->result() == Result::MessageCurrentTest) { // MessageCurrentTest should always be the last top level item if (lastRow >= 0) { - TestResultItem *current = static_cast(rootItem()->childAt(lastRow)); + TestResultItem *current = rootItem()->childAt(lastRow); const TestResult *result = current->testResult(); if (result && result->result() == Result::MessageCurrentTest) { current->updateDescription(testResult->description()); @@ -235,14 +234,11 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx if (AutotestPlugin::settings()->displayApplication) { const QString application = testResult->id(); if (!application.isEmpty()) { - for (int row = rootItem()->childCount() - 1; row >= 0; --row) { - TestResultItem *tmp = static_cast(rootItem()->childAt(row)); - auto tmpTestResult = tmp->testResult(); - if (tmpTestResult->id() == application) { - root = tmp; - break; - } - } + root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) { + QTC_ASSERT(child, return false); + return child->testResult()->id() == application; + }); + if (!root) { TestResult *tmpAppResult = new TestResult(application, application); tmpAppResult->setResult(Result::Application); @@ -264,7 +260,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx updateParent(newItem); } else { if (lastRow >= 0) { - TestResultItem *current = static_cast(rootItem()->childAt(lastRow)); + TestResultItem *current = rootItem()->childAt(lastRow); const TestResult *result = current->testResult(); if (result && result->result() == Result::MessageCurrentTest) { rootItem()->insertChild(current->index().row(), newItem); @@ -278,15 +274,11 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx void TestResultModel::removeCurrentTestMessage() { - std::vector topLevelItems(rootItem()->begin(), rootItem()->end()); - auto end = topLevelItems.rend(); - for (auto it = topLevelItems.rbegin(); it != end; ++it) { - TestResultItem *current = static_cast(*it); - if (current->testResult()->result() == Result::MessageCurrentTest) { - destroyItem(current); - break; - } - } + TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) { + return (it->testResult()->result() == Result::MessageCurrentTest); + }); + if (currentMessageItem) + destroyItem(currentMessageItem); } void TestResultModel::clearTestResults() @@ -302,7 +294,7 @@ void TestResultModel::clearTestResults() const TestResult *TestResultModel::testResult(const QModelIndex &idx) { if (idx.isValid()) - return static_cast(itemForIndex(idx))->testResult(); + return itemForIndex(idx)->testResult(); return nullptr; } @@ -353,7 +345,7 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item, if (root == nullptr && !name.isEmpty()) { for (int row = rootItem()->childCount() - 1; row >= 0; --row) { - TestResultItem *tmp = static_cast(rootItem()->childAt(row)); + TestResultItem *tmp = rootItem()->childAt(row); auto tmpTestResult = tmp->testResult(); if (tmpTestResult->id() == id && tmpTestResult->name() == name) { root = tmp; @@ -369,7 +361,7 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item, TestResultItem *currentItem = static_cast(it); return currentItem->testResult()->isDirectParentOf(result, &needsIntermediate); }; - TestResultItem *parent = static_cast(root->reverseFindAnyChild(predicate)); + TestResultItem *parent = root->reverseFindAnyChild(predicate); if (parent) { if (needsIntermediate) { // check if the intermediate is present already diff --git a/src/plugins/autotest/testresultmodel.h b/src/plugins/autotest/testresultmodel.h index de48db5a0df..0366e8e0895 100644 --- a/src/plugins/autotest/testresultmodel.h +++ b/src/plugins/autotest/testresultmodel.h @@ -37,7 +37,7 @@ namespace Autotest { namespace Internal { -class TestResultItem : public Utils::TreeItem +class TestResultItem : public Utils::TypedTreeItem { public: explicit TestResultItem(const TestResultPtr &testResult); @@ -53,7 +53,7 @@ private: TestResultPtr m_testResult; }; -class TestResultModel : public Utils::TreeModel<> +class TestResultModel : public Utils::TreeModel { public: explicit TestResultModel(QObject *parent = nullptr); From ae388a85b98f9004e8e19e72cccac6cf6e8bc282 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 13:09:29 +0100 Subject: [PATCH 31/44] CppTools: Fix failing tests Amends 4dd4d088c5514030bc1e6b088f582f9fc03c98b5. Change-Id: I9099dd6fa74b0ad8369234cc7dad4cbe1f8624c8 Reviewed-by: Ivan Donchevskii Reviewed-by: Orgad Shaneh --- .../cpptools/cpppointerdeclarationformatter_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp b/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp index f412c9ab690..7b9fff7f0ee 100644 --- a/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp +++ b/src/plugins/cpptools/cpppointerdeclarationformatter_test.cpp @@ -490,7 +490,7 @@ void CppToolsPlugin::test_format_pointerdeclaration_multiple_declarators_data() QTest::newRow("function-pointer_in-start") << "char *s, @*(*foo)(char *s) = 0;" - << "char *s, *(*foo)(char * s) = 0;"; + << "char *s, * (*foo)(char * s) = 0;"; } void CppToolsPlugin::test_format_pointerdeclaration_multiple_matches() @@ -534,8 +534,8 @@ void CppToolsPlugin::test_format_pointerdeclaration_multiple_matches_data() << "int g() { for (char * s; char * t = 0; s++) { char * u = 0; } }"; QTest::newRow("multiple-declarators") - << "const char c, *s, *(*foo)(char *s) = 0;" - << "const char c, * s, *(*foo)(char * s) = 0;"; + << "const char c, *s, * (*foo)(char *s) = 0;" + << "const char c, * s, * (*foo)(char * s) = 0;"; QTest::newRow("complex") << @@ -568,7 +568,7 @@ void CppToolsPlugin::test_format_pointerdeclaration_multiple_matches_data() " int (*bar)[] = 0;\n" "\n" " char * s = 0, * f(int i) = 0;\n" - " const char c, * s, *(*foo)(char * s) = 0;" + " const char c, * s, * (*foo)(char * s) = 0;" "\n" " for (char * s; char * t = 0; s++) { char * u = 0; }" "\n" From 4b26a8c66e6303e090e9e070c7f3a425e26d90bf Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 12:41:04 +0100 Subject: [PATCH 32/44] ClangCodeModel: Fix some clazy level0 warnings Use QString instead of an empty QStringLiteral [-Wclazy-empty-qstringliteral] Use the static QFileInfo::exists() instead. It's documented to be faster. [-Wclazy-qfileinfo-exists] Unused CppTools::ClangDiagnosticConfigs [-Wclazy-unused-non-trivial-variable] Change-Id: Ia4098d1191d6fcfc6e0774f71c39acdea3f0f36c Reviewed-by: Orgad Shaneh Reviewed-by: Ivan Donchevskii --- src/plugins/clangcodemodel/clangbackendcommunicator.cpp | 6 ++---- src/plugins/clangcodemodel/clangtextmark.cpp | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index 31e8a852661..28a31f05538 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -63,9 +63,7 @@ enum { backEndStartTimeOutInMs = 10000 }; static QString backendProcessPath() { - return Core::ICore::libexecPath() - + QStringLiteral("/clangbackend") - + QStringLiteral(QTC_HOST_EXE_SUFFIX); + return Core::ICore::libexecPath() + "/clangbackend" + QTC_HOST_EXE_SUFFIX; } namespace ClangCodeModel { @@ -121,7 +119,7 @@ BackendCommunicator::~BackendCommunicator() void BackendCommunicator::initializeBackend() { const QString clangBackEndProcessPath = backendProcessPath(); - if (!QFileInfo(clangBackEndProcessPath).exists()) { + if (!QFileInfo::exists(clangBackEndProcessPath)) { logExecutableDoesNotExist(); return; } diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index 41ee4c1533e..61a4c7716c6 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -133,7 +133,6 @@ void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticConta currentConfigId = globalSettings->clangDiagnosticConfigId(); // Get config - const ClangDiagnosticConfigs originalConfigs = globalSettings->clangCustomDiagnosticConfigs(); ClangDiagnosticConfigsModel configsModel(globalSettings->clangCustomDiagnosticConfigs()); QTC_ASSERT(configsModel.hasConfigWithId(currentConfigId), return ); ClangDiagnosticConfig config = configsModel.configWithId(currentConfigId); From 612393889a2819f8e4268cc8bfbab517b6c013cb Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 12:29:36 +0100 Subject: [PATCH 33/44] CppEditor: Fix some clazy level0 warnings Use leftRef() instead [-Wclazy-qstring-ref] Use multi-arg instead [-Wclazy-qstring-arg] Change-Id: I4aa67e0d518060cdec4f96cb7a03a9a499f28f27 Reviewed-by: Ivan Donchevskii Reviewed-by: Orgad Shaneh --- .../cppdocumentationcommenthelper.cpp | 2 +- src/plugins/cppeditor/cppquickfixes.cpp | 44 +++++++++---------- .../cppeditor/resourcepreviewhoverhandler.cpp | 3 +- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp b/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp index 0fb67c9b220..65c3dc9769b 100644 --- a/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp +++ b/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp @@ -173,7 +173,7 @@ bool handleDoxygenCppStyleContinuation(QTextCursor &cursor) return false; QString newLine(QLatin1Char('\n')); - newLine.append(text.left(offset)); // indent correctly + newLine.append(text.leftRef(offset)); // indent correctly newLine.append(commentMarker); newLine.append(QLatin1Char(' ')); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index eeba204dbaf..840274792f6 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3101,13 +3101,13 @@ public: const QString declarationGetterTypeAndNameString = oo.prettyType(getterType, m_getterName); const QString declarationGetter = QString::fromLatin1("%1%2()%3;\n") - .arg(isStatic ? QLatin1String("static ") : QString()) - .arg(declarationGetterTypeAndNameString) - .arg(isStatic ? QString() : QLatin1String(" const")); + .arg(isStatic ? QLatin1String("static ") : QString(), + declarationGetterTypeAndNameString, + isStatic ? QString() : QLatin1String(" const")); const QString declarationSetter = QString::fromLatin1("%1void %2(%3);\n") - .arg(isStatic ? QLatin1String("static ") : QString()) - .arg(m_setterName) - .arg(paramString); + .arg(isStatic ? QLatin1String("static ") : QString(), + m_setterName, + paramString); if (generateGetter()) declaration += declarationGetter; @@ -3118,22 +3118,22 @@ public: // Construct implementation strings const QString implementationGetterTypeAndNameString = oo.prettyType( getterType, QString::fromLatin1("%1::%2").arg(classString, m_getterName)); - const QString implementationGetter = QString::fromLatin1( - "%1()%2\n" - "{\n" - "return %3;\n" - "}") - .arg(implementationGetterTypeAndNameString) - .arg(isStatic ? QString() : QLatin1String(" const")) - .arg(m_variableString); - const QString implementationSetter = QString::fromLatin1( - "void %1::%2(%3)\n" - "{\n" - "%4 = %5;\n" - "}") - .arg(classString).arg(m_setterName) - .arg(paramString).arg(m_variableString) - .arg(paramName); + const QString implementationGetter = QString::fromLatin1("%1()%2\n" + "{\n" + "return %3;\n" + "}") + .arg(implementationGetterTypeAndNameString, + isStatic ? QString() : QLatin1String(" const"), + m_variableString); + const QString implementationSetter = QString::fromLatin1("void %1::%2(%3)\n" + "{\n" + "%4 = %5;\n" + "}") + .arg(classString, + m_setterName, + paramString, + m_variableString, + paramName); QString implementation; if (generateGetter()) diff --git a/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp b/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp index a454361d302..72fb74f0876 100644 --- a/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp +++ b/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp @@ -204,8 +204,7 @@ QString ResourcePreviewHoverHandler::makeTooltip() const ret += QString("
").arg(m_resPath); ret += QString("
%2") - .arg(m_resPath) - .arg(QDir::toNativeSeparators(m_resPath)); + .arg(m_resPath, QDir::toNativeSeparators(m_resPath)); return ret; } From 55f4c288893754b8640b058d479aa582201cfc6a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 11:56:47 +0100 Subject: [PATCH 34/44] CppEditor: modernize-loop-convert Change-Id: I80382880a3c35ef0b59729bd222a626bc5c4a32b Reviewed-by: Orgad Shaneh Reviewed-by: Ivan Donchevskii --- src/plugins/cppeditor/cppeditorwidget.cpp | 3 +-- src/plugins/cppeditor/cppquickfixes.cpp | 20 ++++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 286ef4cdf91..1aa2aba8acd 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -674,8 +674,7 @@ void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit) ASTPath astPathFinder(d->m_lastSemanticInfo.doc); const QList astPath = astPathFinder(textCursor()); - for (int i = 0, size = astPath.size(); i < size; ++i) { - AST *ast = astPath.at(i); + for (AST *ast : astPath) { if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) { if ((functionDefinitionSymbol = functionDefinitionAST->symbol)) break; // Function definition found! diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 840274792f6..e09358d25da 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3920,8 +3920,7 @@ public: ASTPath astPath(result.file->cppDocument()); const QList path = astPath(s->line(), s->column()); SimpleDeclarationAST *simpleDecl = nullptr; - for (int idx = 0; idx < path.size(); ++idx) { - AST *node = path.at(idx); + for (AST *node : path) { simpleDecl = node->asSimpleDeclaration(); if (simpleDecl) { if (simpleDecl->symbols && !simpleDecl->symbols->next) { @@ -3945,13 +3944,12 @@ public: return FoundDeclaration(); const LookupContext lc(result.file->cppDocument(), snapshot()); const QList candidates = lc.lookup(func->name(), matchingNamespace); - for (int i = 0; i < candidates.size(); ++i) { - if (Symbol *s = candidates.at(i).declaration()) { + for (const LookupItem &candidate : candidates) { + if (Symbol *s = candidate.declaration()) { if (s->asDeclaration()) { ASTPath astPath(result.file->cppDocument()); const QList path = astPath(s->line(), s->column()); - for (int idx = 0; idx < path.size(); ++idx) { - AST *node = path.at(idx); + for (AST *node : path) { SimpleDeclarationAST *simpleDecl = node->asSimpleDeclaration(); if (simpleDecl) { result.ast = functionDeclarator(simpleDecl); @@ -5154,13 +5152,12 @@ void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOpe const CppRefactoringFilePtr declFile = refactoring.file(declFileName); const LookupContext lc(declFile->cppDocument(), interface.snapshot()); const QList candidates = lc.lookup(func->name(), matchingNamespace); - for (int i = 0; i < candidates.size(); ++i) { - if (Symbol *s = candidates.at(i).declaration()) { + for (const LookupItem &candidate : candidates) { + if (Symbol *s = candidate.declaration()) { if (s->asDeclaration()) { ASTPath astPath(declFile->cppDocument()); const QList path = astPath(s->line(), s->column()); - for (int idx = 0; idx < path.size(); ++idx) { - AST *node = path.at(idx); + for (AST *node : path) { if (SimpleDeclarationAST *simpleDecl = node->asSimpleDeclaration()) { declRange = declFile->range(simpleDecl); declText = declFile->textOf(simpleDecl); @@ -5604,8 +5601,7 @@ private: static QByteArray escapeString(const QByteArray &contents) { QByteArray newContents; - for (int i = 0; i < contents.length(); ++i) { - quint8 c = contents.at(i); + for (const quint8 c : contents) { if (isascii(c) && isprint(c)) { newContents += c; } else { From 05bb8e9e30169f160bc9159ed9d0945f78298e4d Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sat, 2 Feb 2019 21:14:07 +0100 Subject: [PATCH 35/44] DocumentContentCompletion: Don't propose word under cursor ... unless it is already contained in the text. For the following text: Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Typing "con|" now should only provide "consetetur" as proposal, as "con" is just currently typed and therefore no valid completion. This avoids pressing line down before the first valid proposal is available. The exception is, if "con" would already be used elsewhere in the text. Change-Id: I7034f4b2b2ebe70e98acc616fb7590118faac0af Reviewed-by: David Schulz --- .../codeassist/documentcontentcompletion.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp index 437afcbdb6c..ee0deab71c7 100644 --- a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp +++ b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp @@ -80,17 +80,26 @@ DocumentContentCompletionProcessor::~DocumentContentCompletionProcessor() m_watcher.cancel(); } -static void createProposal(QFutureInterface &future, const QString text) +static void createProposal(QFutureInterface &future, const QString &text, + const QString &wordUnderCursor) { const QRegularExpression wordRE("([a-zA-Z_][a-zA-Z0-9_]{2,})"); QSet words; QRegularExpressionMatchIterator it = wordRE.globalMatch(text); + int wordUnderCursorFound = 0; while (it.hasNext()) { if (future.isCanceled()) return; QRegularExpressionMatch match = it.next(); const QString &word = match.captured(); + if (word == wordUnderCursor) { + // Only add the word under cursor if it + // already appears elsewhere in the text + if (++wordUnderCursorFound < 2) + continue; + } + if (!words.contains(word)) words.insert(word); } @@ -113,16 +122,18 @@ IAssistProposal *DocumentContentCompletionProcessor::perform(const AssistInterfa } while (chr.isLetterOrNumber() || chr == '_'); ++pos; + int length = interface->position() - pos; if (interface->reason() == IdleEditor) { QChar characterUnderCursor = interface->characterAt(interface->position()); - if (characterUnderCursor.isLetterOrNumber() || interface->position() - pos < 3) + if (characterUnderCursor.isLetterOrNumber() || length < 3) return nullptr; } + const QString wordUnderCursor = interface->textAt(pos, length); const QString text = interface->textDocument()->toPlainText(); - m_watcher.setFuture(Utils::runAsync(&createProposal, text)); + m_watcher.setFuture(Utils::runAsync(&createProposal, text, wordUnderCursor)); QObject::connect(&m_watcher, &QFutureWatcher::resultReadyAt, &m_watcher, [this, pos](int index){ const TextEditor::SnippetAssistCollector snippetCollector( From 49afb01e0a657a42221723ac29a69c1cfa9edc54 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sun, 3 Feb 2019 21:00:11 +0100 Subject: [PATCH 36/44] QtOutputFormatter: Allow standalone file:// links Either alone on a line, or with text before, or with text afterwards, separated by colon, space, tab, or brace as before. Especially thought to capture cases like file:///home/user/main.cpp:157 on a single line, but accept that also as long as the file link is separated by a word separator from the sourrounding text. Fixes: QTCREATORBUG-20406 Change-Id: I25bceb186818c9ea680741573a806f66395c3e16 Reviewed-by: Samuel Gaist Reviewed-by: Orgad Shaneh --- src/plugins/qtsupport/qtoutputformatter.cpp | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index 8fba2797767..c5a4d7a427b 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -53,7 +53,7 @@ public: : qmlError("(" QT_QML_URL_REGEXP // url ":\\d+" // colon, line "(?::\\d+)?)" // colon, column (optional) - "[: \t)]") // colon, space, tab or brace + "\\b") // word boundary , qtError("Object::.*in (.*:\\d+)") , qtAssert(QT_ASSERT_REGEXP) , qtAssertX(QT_ASSERT_X_REGEXP) @@ -364,6 +364,26 @@ void QtSupportPlugin::testQtOutputFormatter_data() << 0 << 19 << "file:///main.qml:20" << "/main.qml" << 20 << -1; + QTest::newRow("File link without further text") + << "file:///home/user/main.cpp:157" + << 0 << 30 << "file:///home/user/main.cpp:157" + << "/home/user/main.cpp" << 157 << -1; + + QTest::newRow("File link with text before") + << "Text before: file:///home/user/main.cpp:157" + << 13 << 43 << "file:///home/user/main.cpp:157" + << "/home/user/main.cpp" << 157 << -1; + + QTest::newRow("File link with text afterwards") + << "file:///home/user/main.cpp:157: Text afterwards" + << 0 << 30 << "file:///home/user/main.cpp:157" + << "/home/user/main.cpp" << 157 << -1; + + QTest::newRow("File link with text before and afterwards") + << "Text before file:///home/user/main.cpp:157 and text afterwards" + << 12 << 42 << "file:///home/user/main.cpp:157" + << "/home/user/main.cpp" << 157 << -1; + QTest::newRow("Unix file link with timestamp") << "file:///home/user/main.cpp:157 2018-03-21 10:54:45.706" << 0 << 30 << "file:///home/user/main.cpp:157" From e0c7722441a465a854f972f04146f1e2eda8db8f Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 11:04:13 +0100 Subject: [PATCH 37/44] CppEditor: Modernize modernize-orgad modernize-return-braced-init-list modernize-use-auto modernize-use-default-member-init modernize-use-equals-default modernize-use-nullptr modernize-use-override modernize-use-using Change-Id: Ifa862782fb7b56ed3f93d9f98685c3af616797c2 Reviewed-by: Orgad Shaneh --- src/plugins/cppeditor/cppautocompleter.h | 2 - .../cppeditor/cppcodemodelinspectordialog.cpp | 143 ++++---- .../cppeditor/cppcodemodelinspectordialog.h | 6 +- src/plugins/cppeditor/cppeditordocument.cpp | 14 +- src/plugins/cppeditor/cppeditordocument.h | 10 +- src/plugins/cppeditor/cppeditorplugin.cpp | 2 +- src/plugins/cppeditor/cppeditorplugin.h | 2 +- src/plugins/cppeditor/cppeditorwidget.cpp | 19 +- .../cppeditor/cppfunctiondecldeflink.cpp | 40 ++- .../cppeditor/cppfunctiondecldeflink.h | 2 +- src/plugins/cppeditor/cpphighlighter.h | 2 +- src/plugins/cppeditor/cppincludehierarchy.cpp | 6 +- src/plugins/cppeditor/cppincludehierarchy.h | 2 +- .../cppeditor/cppinsertvirtualmethods.cpp | 137 ++++---- .../cppeditor/cppinsertvirtualmethods.h | 6 +- .../cppeditor/cppminimizableinfobars.h | 2 +- src/plugins/cppeditor/cpppreprocessordialog.h | 4 +- src/plugins/cppeditor/cppquickfix.cpp | 3 +- src/plugins/cppeditor/cppquickfix.h | 4 +- src/plugins/cppeditor/cppquickfixassistant.h | 2 +- src/plugins/cppeditor/cppquickfixes.cpp | 307 ++++++++---------- src/plugins/cppeditor/cppquickfixes.h | 4 +- src/plugins/cppeditor/cpptypehierarchy.cpp | 14 +- src/plugins/cppeditor/cpptypehierarchy.h | 8 +- .../cppeditor/cppuseselectionsupdater.h | 2 +- 25 files changed, 341 insertions(+), 402 deletions(-) diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h index 5c90d73dca3..eb90c15b48d 100644 --- a/src/plugins/cppeditor/cppautocompleter.h +++ b/src/plugins/cppeditor/cppautocompleter.h @@ -33,8 +33,6 @@ namespace Internal { class CppAutoCompleter : public TextEditor::AutoCompleter { public: - CppAutoCompleter() {} - bool contextAllowsAutoBrackets(const QTextCursor &cursor, const QString &textToInsert = QString()) const override; bool contextAllowsAutoQuotes(const QTextCursor &cursor, diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp index 30e0b0e1695..1cedfbfd9d0 100644 --- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp +++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp @@ -85,8 +85,6 @@ QSizePolicy sizePolicyWithStretchFactor(int stretchFactor) class DepthFinder : public SymbolVisitor { public: - DepthFinder() : m_symbol(0), m_depth(-1), m_foundDepth(-1), m_stop(false) {} - int operator()(const Document::Ptr &document, Symbol *symbol) { m_symbol = symbol; @@ -94,7 +92,7 @@ public: return m_foundDepth; } - bool preVisit(Symbol *symbol) + bool preVisit(Symbol *symbol) override { if (m_stop) return false; @@ -111,17 +109,17 @@ public: return false; } - void postVisit(Symbol *symbol) + void postVisit(Symbol *symbol) override { if (symbol->asScope()) --m_depth; } private: - Symbol *m_symbol; - int m_depth; - int m_foundDepth; - bool m_stop; + Symbol *m_symbol = nullptr; + int m_depth = -1; + int m_foundDepth = -1; + bool m_stop = false; }; } // anonymous namespace @@ -169,12 +167,12 @@ FilterableView::FilterableView(QWidget *parent) QPushButton *clearButton = new QPushButton(QLatin1String("&Clear"), this); QObject::connect(clearButton, &QAbstractButton::clicked, this, &FilterableView::clearFilter); - QHBoxLayout *filterBarLayout = new QHBoxLayout(); + auto filterBarLayout = new QHBoxLayout(); filterBarLayout->addWidget(label); filterBarLayout->addWidget(lineEdit); filterBarLayout->addWidget(clearButton); - QVBoxLayout *mainLayout = new QVBoxLayout(); + auto mainLayout = new QVBoxLayout(); mainLayout->addWidget(view); mainLayout->addLayout(filterBarLayout); @@ -222,10 +220,10 @@ public: enum Columns { FileKindColumn, FilePathColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: ProjectFiles m_files; @@ -305,10 +303,10 @@ public: enum Columns { TypeColumn, PathColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: ProjectExplorer::HeaderPaths m_paths; @@ -377,7 +375,7 @@ class KeyValueModel : public QAbstractListModel { Q_OBJECT public: - typedef QList > Table; + using Table = QList>; KeyValueModel(QObject *parent); void configure(const Table &table); @@ -385,10 +383,10 @@ public: enum Columns { KeyColumn, ValueColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: Table m_table; @@ -465,10 +463,10 @@ public: enum Columns { SymbolCountColumn, SharedColumn, FilePathColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QList m_documents; @@ -498,7 +496,7 @@ QModelIndex SnapshotModel::indexForDocument(const QString &filePath) if (document->fileName() == filePath) return index(i, FilePathColumn); } - return QModelIndex(); + return {}; } int SnapshotModel::rowCount(const QModelIndex &/*parent*/) const @@ -565,10 +563,10 @@ public: enum Columns { ResolvedOrNotColumn, LineNumberColumn, FilePathsColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QList m_includes; @@ -667,10 +665,10 @@ public: enum Columns { LevelColumn, LineColumnNumberColumn, MessageColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QList m_messages; @@ -716,8 +714,7 @@ QVariant DiagnosticMessagesModel::data(const QModelIndex &index, int role) const static const QBrush darkRedBrushQColor(QColor(139, 0, 0)); const Document::DiagnosticMessage message = m_messages.at(index.row()); - const Document::DiagnosticMessage::Level level - = static_cast(message.level()); + const auto level = static_cast(message.level()); if (role == Qt::DisplayRole) { const int column = index.column(); @@ -775,10 +772,10 @@ public: enum Columns { LineNumberColumn, MacroColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QList m_macros; @@ -854,12 +851,12 @@ public: enum Columns { SymbolColumn, LineNumberColumn, ColumnCount }; - QModelIndex index(int row, int column, const QModelIndex &parent) const; - QModelIndex parent(const QModelIndex &child) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &child) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: Document::Ptr m_document; @@ -886,21 +883,19 @@ void SymbolsModel::clear() static Symbol *indexToSymbol(const QModelIndex &index) { - if (Symbol *symbol = static_cast(index.internalPointer())) - return symbol; - return 0; + return static_cast(index.internalPointer()); } static Scope *indexToScope(const QModelIndex &index) { if (Symbol *symbol = indexToSymbol(index)) return symbol->asScope(); - return 0; + return nullptr; } QModelIndex SymbolsModel::index(int row, int column, const QModelIndex &parent) const { - Scope *scope = 0; + Scope *scope = nullptr; if (parent.isValid()) scope = indexToScope(parent); else if (m_document) @@ -911,13 +906,13 @@ QModelIndex SymbolsModel::index(int row, int column, const QModelIndex &parent) return createIndex(row, column, scope->memberAt(row)); } - return QModelIndex(); + return {}; } QModelIndex SymbolsModel::parent(const QModelIndex &child) const { if (!child.isValid()) - return QModelIndex(); + return {}; if (Symbol *symbol = indexToSymbol(child)) { if (Scope *scope = symbol->enclosingScope()) { @@ -926,7 +921,7 @@ QModelIndex SymbolsModel::parent(const QModelIndex &child) const } } - return QModelIndex(); + return {}; } int SymbolsModel::rowCount(const QModelIndex &parent) const @@ -994,10 +989,10 @@ public: BytesAndCodePointsColumn, GeneratedColumn, ExpandedColumn, WhiteSpaceColumn, NewlineColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: struct TokenInfo { @@ -1126,10 +1121,10 @@ public: enum Columns { PartNameColumn, PartFilePathColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QList m_projectPartsList; @@ -1161,7 +1156,7 @@ void ProjectPartsModel::configure(const QList &projectInfos, QModelIndex ProjectPartsModel::indexForCurrentEditorsProjectPart() const { if (m_currentEditorsProjectPartIndex == -1) - return QModelIndex(); + return {}; return createIndex(m_currentEditorsProjectPartIndex, PartFilePathColumn); } @@ -1232,10 +1227,10 @@ public: enum Columns { RevisionColumn, FilePathColumn, ColumnCount }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: struct WorkingCopyEntry { @@ -1275,7 +1270,7 @@ QModelIndex WorkingCopyModel::indexForFile(const QString &filePath) if (entry.filePath == filePath) return index(i, FilePathColumn); } - return QModelIndex(); + return {}; } int WorkingCopyModel::rowCount(const QModelIndex &/*parent*/) const @@ -1542,11 +1537,11 @@ void CppCodeModelInspectorDialog::refresh() dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true); TextEditor::BaseTextEditor *editor = currentEditor(); - CppTools::CppEditorDocumentHandle *cppEditorDocument = 0; + CppTools::CppEditorDocumentHandle *cppEditorDocument = nullptr; if (editor) { const QString editorFilePath = editor->document()->filePath().toString(); cppEditorDocument = cmmi->cppEditorDocument(editorFilePath); - if (auto *documentProcessor = CppToolsBridge::baseEditorDocumentProcessor(editorFilePath)) { + if (auto documentProcessor = CppToolsBridge::baseEditorDocumentProcessor(editorFilePath)) { const Snapshot editorSnapshot = documentProcessor->snapshot(); m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot)); const QString editorSnapshotTitle @@ -1555,7 +1550,7 @@ void CppCodeModelInspectorDialog::refresh() dumper.dumpSnapshot(editorSnapshot, editorSnapshotTitle); m_ui->snapshotSelector->addItem(editorSnapshotTitle); } - CppEditorWidget *cppEditorWidget = qobject_cast(editor->editorWidget()); + auto cppEditorWidget = qobject_cast(editor->editorWidget()); if (cppEditorWidget) { SemanticInfo semanticInfo = cppEditorWidget->semanticInfo(); Snapshot snapshot; @@ -1855,7 +1850,7 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr & bool CppCodeModelInspectorDialog::event(QEvent *e) { if (e->type() == QEvent::ShortcutOverride) { - QKeyEvent *ke = static_cast(e); + auto ke = static_cast(e); if (ke->key() == Qt::Key_Escape && !ke->modifiers()) { ke->accept(); close(); diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.h b/src/plugins/cppeditor/cppcodemodelinspectordialog.h index 01d24ea0b88..7faf93da847 100644 --- a/src/plugins/cppeditor/cppcodemodelinspectordialog.h +++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.h @@ -65,8 +65,8 @@ class CppCodeModelInspectorDialog : public QDialog Q_OBJECT public: - explicit CppCodeModelInspectorDialog(QWidget *parent = 0); - ~CppCodeModelInspectorDialog(); + explicit CppCodeModelInspectorDialog(QWidget *parent = nullptr); + ~CppCodeModelInspectorDialog() override; private: void onRefreshRequested(); @@ -90,7 +90,7 @@ private: void clearProjectPartData(); void updateProjectPartData(const CppTools::ProjectPart::Ptr &part); - bool event(QEvent *e); + bool event(QEvent *e) override; private: Ui::CppCodeModelInspectorDialog *m_ui; diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index d18735c7501..c1577424570 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -80,7 +80,10 @@ public: mm()->registerCppEditorDocument(this); } - ~CppEditorDocumentHandleImpl() { mm()->unregisterCppEditorDocument(m_registrationFilePath); } + ~CppEditorDocumentHandleImpl() override + { + mm()->unregisterCppEditorDocument(m_registrationFilePath); + } QString filePath() const override { return m_cppEditorDocument->filePath().toString(); } QByteArray contents() const override { return m_cppEditorDocument->contentsText(); } @@ -100,12 +103,7 @@ private: }; CppEditorDocument::CppEditorDocument() - : m_fileIsBeingReloaded(false) - , m_isObjCEnabled(false) - , m_cachedContentsRevision(-1) - , m_processorRevision(0) - , m_completionAssistProvider(0) - , m_minimizableInfoBars(*infoBar()) + : m_minimizableInfoBars(*infoBar()) { setId(CppEditor::Constants::CPPEDITOR_ID); setSyntaxHighlighter(new CppHighlighter); @@ -352,7 +350,7 @@ unsigned CppEditorDocument::contentsRevision() const void CppEditorDocument::releaseResources() { if (m_processor) - disconnect(m_processor.data(), 0, this, 0); + disconnect(m_processor.data(), nullptr, this, nullptr); m_processor.reset(); } diff --git a/src/plugins/cppeditor/cppeditordocument.h b/src/plugins/cppeditor/cppeditordocument.h index 26cff2043aa..5055b2654a2 100644 --- a/src/plugins/cppeditor/cppeditordocument.h +++ b/src/plugins/cppeditor/cppeditordocument.h @@ -115,19 +115,19 @@ private: void initializeTimer(); private: - bool m_fileIsBeingReloaded; - bool m_isObjCEnabled; + bool m_fileIsBeingReloaded = false; + bool m_isObjCEnabled = false; // Caching contents mutable QMutex m_cachedContentsLock; mutable QByteArray m_cachedContents; - mutable int m_cachedContentsRevision; + mutable int m_cachedContentsRevision = -1; - unsigned m_processorRevision; + unsigned m_processorRevision = 0; QTimer m_processorTimer; QScopedPointer m_processor; - CppTools::CppCompletionAssistProvider *m_completionAssistProvider; + CppTools::CppCompletionAssistProvider *m_completionAssistProvider = nullptr; // (Un)Registration in CppModelManager QScopedPointer m_editorDocumentHandle; diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index bf533f038f7..f46c3db17d4 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -310,7 +310,7 @@ static CppEditorWidget *currentCppEditorWidget() { if (IEditor *currentEditor = EditorManager::currentEditor()) return qobject_cast(currentEditor->widget()); - return 0; + return nullptr; } void CppEditorPlugin::switchDeclarationDefinition() diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index 263af42a123..f4d024f33f9 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -40,7 +40,7 @@ class CppEditorPlugin : public ExtensionSystem::IPlugin public: CppEditorPlugin(); - ~CppEditorPlugin(); + ~CppEditorPlugin() override; static CppEditorPlugin *instance(); diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 1aa2aba8acd..df37a22d29c 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -261,7 +261,7 @@ void CppEditorWidget::finalizeInitialization() void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *other) { QTC_ASSERT(other, return); - CppEditorWidget *cppEditorWidget = qobject_cast(other); + auto cppEditorWidget = qobject_cast(other); QTC_ASSERT(cppEditorWidget, return); if (cppEditorWidget->isSemanticInfoValidExceptLocalUses()) @@ -278,10 +278,7 @@ void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *o d->m_cppEditorDocument->parseContextModel().areMultipleAvailable()); } -CppEditorWidget::~CppEditorWidget() -{ - // non-inline destructor, see section "Forward Declared Pointers" of QScopedPointer. -} +CppEditorWidget::~CppEditorWidget() = default; CppEditorDocument *CppEditorWidget::cppEditorDocument() const { @@ -357,7 +354,7 @@ static QString getDocumentLine(const QTextDocument &document, int line) static QString getFileLine(const QString &path, int line) { const IDocument *document = DocumentModel::documentForFilePath(path); - const TextDocument *textDocument = qobject_cast(document); + const auto textDocument = qobject_cast(document); if (textDocument) return getDocumentLine(*textDocument->document(), line); @@ -543,7 +540,7 @@ ProjectPart *findProjectPartForCurrentProject(const QList &pro if (found != projectParts.cend()) return (*found).data(); - return 0; + return nullptr; } } // namespace @@ -551,7 +548,7 @@ ProjectPart *findProjectPartForCurrentProject(const QList &pro ProjectPart *CppEditorWidget::projectPart() const { if (!d->m_modelManager) - return 0; + return nullptr; auto projectParts = fetchProjectParts(d->m_modelManager, textDocument()->filePath()); @@ -668,8 +665,8 @@ void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit) return; // Find function declaration or definition under cursor - Function *functionDefinitionSymbol = 0; - Symbol *functionDeclarationSymbol = 0; + Function *functionDefinitionSymbol = nullptr; + Symbol *functionDeclarationSymbol = nullptr; ASTPath astPathFinder(d->m_lastSemanticInfo.doc); const QList astPath = astPathFinder(textCursor()); @@ -998,7 +995,7 @@ AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistR } else { return TextEditorWidget::createAssistInterface(kind, reason); } - return 0; + return nullptr; } QSharedPointer CppEditorWidget::declDefLink() const diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index a1af83596f8..2a53648b312 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -96,19 +96,17 @@ static bool findDeclOrDef(const Document::Ptr &doc, int line, int column, // by CompoundStatement/CtorInitializer // for function declarations, look for SimpleDeclarations with a single Declarator // with a FunctionDeclarator postfix - FunctionDefinitionAST *funcDef = 0; - SimpleDeclarationAST *simpleDecl = 0; - *decl = 0; + *decl = nullptr; for (int i = path.size() - 1; i > 0; --i) { AST *ast = path.at(i); if (ast->asCompoundStatement() || ast->asCtorInitializer()) break; - if ((funcDef = ast->asFunctionDefinition()) != 0) { + if (FunctionDefinitionAST *funcDef = ast->asFunctionDefinition()) { *parent = funcDef; *decl = funcDef->declarator; break; } - if ((simpleDecl = ast->asSimpleDeclaration()) != 0) { + if (SimpleDeclarationAST *simpleDecl = ast->asSimpleDeclaration()) { *parent = simpleDecl; if (!simpleDecl->declarator_list || !simpleDecl->declarator_list->value) break; @@ -142,12 +140,12 @@ static void declDefLinkStartEnd(const CppRefactoringFileConstPtr &file, static DeclaratorIdAST *getDeclaratorId(DeclaratorAST *declarator) { if (!declarator || !declarator->core_declarator) - return 0; + return nullptr; if (DeclaratorIdAST *id = declarator->core_declarator->asDeclaratorId()) return id; if (NestedDeclaratorAST *nested = declarator->core_declarator->asNestedDeclarator()) return getDeclaratorId(nested->declarator); - return 0; + return nullptr; } static QSharedPointer findLinkHelper(QSharedPointer link, CppRefactoringChanges changes) @@ -156,7 +154,7 @@ static QSharedPointer findLinkHelper(QSharedPointersourceDeclaration->asFunctionDefinition()) { QList nameMatch, argumentCountMatch, typeMatch; @@ -178,9 +176,9 @@ static QSharedPointer findLinkHelper(QSharedPointerisValid()) return noResult; - DeclarationAST *targetParent = 0; - FunctionDeclaratorAST *targetFuncDecl = 0; - DeclaratorAST *targetDeclarator = 0; + DeclarationAST *targetParent = nullptr; + FunctionDeclaratorAST *targetFuncDecl = nullptr; + DeclaratorAST *targetDeclarator = nullptr; if (!findDeclOrDef(targetFile->cppDocument(), target->line(), target->column(), &targetParent, &targetDeclarator, &targetFuncDecl)) return noResult; @@ -213,9 +211,9 @@ void FunctionDeclDefLinkFinder::startFindLinkAt( QTextCursor cursor, const Document::Ptr &doc, const Snapshot &snapshot) { // check if cursor is on function decl/def - DeclarationAST *parent = 0; - FunctionDeclaratorAST *funcDecl = 0; - DeclaratorAST *declarator = 0; + DeclarationAST *parent = nullptr; + FunctionDeclaratorAST *funcDecl = nullptr; + DeclaratorAST *declarator = nullptr; if (!findDeclOrDef(doc, cursor.blockNumber() + 1, cursor.columnNumber() + 1, &parent, &declarator, &funcDecl)) return; @@ -455,10 +453,10 @@ static SpecifierAST *findFirstReplaceableSpecifier(TranslationUnit *translationU if (canReplaceSpecifier(translationUnit, it->value)) return it->value; } - return 0; + return nullptr; } -typedef QVarLengthArray IndicesList; +using IndicesList = QVarLengthArray; template static int findUniqueTypeMatch(int sourceParamIndex, Function *sourceFunction, Function *newFunction, @@ -597,8 +595,8 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse Control *control = sourceContext.bindings()->control().data(); // get return type start position and declarator info from declaration - DeclaratorAST *declarator = 0; - SpecifierAST *firstReplaceableSpecifier = 0; + DeclaratorAST *declarator = nullptr; + SpecifierAST *firstReplaceableSpecifier = nullptr; TranslationUnit *targetTranslationUnit = targetFile->cppDocument()->translationUnit(); if (SimpleDeclarationAST *simple = targetDeclaration->asSimpleDeclaration()) { declarator = simple->declarator_list->value; @@ -790,7 +788,7 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse if (hasCommentedName(targetFile->cppDocument()->translationUnit(), QString::fromUtf8(targetFile->cppDocument()->utf8Source()), targetFunctionDeclarator, existingParamIndex)) - replacementName = 0; + replacementName = nullptr; // track renames if (replacementName != targetParam->name() && replacementName) @@ -914,8 +912,8 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse changes.insert(targetFile->endOf(targetFunctionDeclarator->rparen_token), cvString); // modify/remove existing specifiers } else { - SimpleSpecifierAST *constSpecifier = 0; - SimpleSpecifierAST *volatileSpecifier = 0; + SimpleSpecifierAST *constSpecifier = nullptr; + SimpleSpecifierAST *volatileSpecifier = nullptr; for (SpecifierListAST *it = targetFunctionDeclarator->cv_qualifier_list; it; it = it->next) { if (SimpleSpecifierAST *simple = it->value->asSimpleSpecifier()) { unsigned kind = targetFile->tokenAt(simple->specifier_token).kind(); diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.h b/src/plugins/cppeditor/cppfunctiondecldeflink.h index 4d6437965db..136e0694492 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.h +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.h @@ -45,7 +45,7 @@ class FunctionDeclDefLinkFinder : public QObject { Q_OBJECT public: - FunctionDeclDefLinkFinder(QObject *parent = 0); + FunctionDeclDefLinkFinder(QObject *parent = nullptr); void startFindLinkAt(QTextCursor cursor, const CPlusPlus::Document::Ptr &doc, diff --git a/src/plugins/cppeditor/cpphighlighter.h b/src/plugins/cppeditor/cpphighlighter.h index 2e4b870b048..e43ce63172b 100644 --- a/src/plugins/cppeditor/cpphighlighter.h +++ b/src/plugins/cppeditor/cpphighlighter.h @@ -41,7 +41,7 @@ class CppHighlighter : public TextEditor::SyntaxHighlighter Q_OBJECT public: - CppHighlighter(QTextDocument *document = 0); + CppHighlighter(QTextDocument *document = nullptr); void setLanguageFeatures(const CPlusPlus::LanguageFeatures &languageFeatures); void highlightBlock(const QString &text) override; diff --git a/src/plugins/cppeditor/cppincludehierarchy.cpp b/src/plugins/cppeditor/cppincludehierarchy.cpp index 5f8084ad622..6bd90f5471b 100644 --- a/src/plugins/cppeditor/cppincludehierarchy.cpp +++ b/src/plugins/cppeditor/cppincludehierarchy.cpp @@ -80,7 +80,7 @@ static Snapshot globalSnapshot() struct FileAndLine { - FileAndLine() {} + FileAndLine() = default; FileAndLine(const QString &f, int l) : file(f), line(l) {} QString file; @@ -122,7 +122,7 @@ class CppIncludeHierarchyItem { public: enum SubTree { RootItem, InIncludes, InIncludedBy }; - CppIncludeHierarchyItem() {} + CppIncludeHierarchyItem() = default; void createChild(const QString &filePath, SubTree subTree, int line = 0, bool definitelyNoChildren = false) @@ -348,7 +348,7 @@ class CppIncludeHierarchyWidget : public QWidget public: CppIncludeHierarchyWidget(); - ~CppIncludeHierarchyWidget() { delete m_treeView; } + ~CppIncludeHierarchyWidget() override { delete m_treeView; } void perform(); diff --git a/src/plugins/cppeditor/cppincludehierarchy.h b/src/plugins/cppeditor/cppincludehierarchy.h index 4b9a867215c..99310a8904c 100644 --- a/src/plugins/cppeditor/cppincludehierarchy.h +++ b/src/plugins/cppeditor/cppincludehierarchy.h @@ -38,7 +38,7 @@ class CppIncludeHierarchyItem; class CppIncludeHierarchyModel : public Utils::TreeModel { Q_OBJECT - typedef Utils::TreeModel base_type; + using base_type = Utils::TreeModel; public: CppIncludeHierarchyModel(); diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 260fa5235ba..748c48cf0bc 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -92,8 +92,8 @@ public: ModeImplementationFile = 0x00000008 }; - InsertVirtualMethodsDialog(QWidget *parent = 0); - ~InsertVirtualMethodsDialog(); + InsertVirtualMethodsDialog(QWidget *parent = nullptr); + ~InsertVirtualMethodsDialog() override; void initGui(); void initData(); virtual void saveSettings(); @@ -113,20 +113,20 @@ private: void updateOverrideReplacementsComboBox(); private: - QTreeView *m_view; - QLineEdit *m_filter; - QCheckBox *m_hideReimplementedFunctions; - QComboBox *m_insertMode; - QCheckBox *m_virtualKeyword; - QCheckBox *m_overrideReplacementCheckBox; - QComboBox *m_overrideReplacementComboBox; - QToolButton *m_clearUserAddedReplacementsButton; - QDialogButtonBox *m_buttons; + QTreeView *m_view = nullptr; + QLineEdit *m_filter = nullptr; + QCheckBox *m_hideReimplementedFunctions = nullptr; + QComboBox *m_insertMode = nullptr; + QCheckBox *m_virtualKeyword = nullptr; + QCheckBox *m_overrideReplacementCheckBox = nullptr; + QComboBox *m_overrideReplacementComboBox = nullptr; + QToolButton *m_clearUserAddedReplacementsButton = nullptr; + QDialogButtonBox *m_buttons = nullptr; QList m_expansionStateNormal; QList m_expansionStateReimp; QStringList m_availableOverrideReplacements; - bool m_hasImplementationFile; - bool m_hasReimplementedFunctions; + bool m_hasImplementationFile = false; + bool m_hasReimplementedFunctions = false; protected: VirtualMethodsSettings *m_settings; @@ -149,15 +149,11 @@ namespace { class InsertVirtualMethodsItem { public: - InsertVirtualMethodsItem(InsertVirtualMethodsItem *parent) : - row(-1), - m_parent(parent) - { - } + InsertVirtualMethodsItem(InsertVirtualMethodsItem *parent) + : m_parent(parent) + {} - virtual ~InsertVirtualMethodsItem() - { - } + virtual ~InsertVirtualMethodsItem() = default; virtual QString description() const = 0; virtual Qt::ItemFlags flags() const = 0; @@ -165,10 +161,10 @@ public: InsertVirtualMethodsItem *parent() { return m_parent; } - int row; + int row = -1; private: - InsertVirtualMethodsItem *m_parent; + InsertVirtualMethodsItem *m_parent = nullptr; }; class FunctionItem; @@ -177,11 +173,11 @@ class ClassItem : public InsertVirtualMethodsItem { public: ClassItem(const QString &className, const Class *clazz); - ~ClassItem(); + ~ClassItem() override; - QString description() const { return name; } - Qt::ItemFlags flags() const; - Qt::CheckState checkState() const; + QString description() const override { return name; } + Qt::ItemFlags flags() const override; + Qt::CheckState checkState() const override; void removeFunction(int row); const Class *klass; @@ -193,9 +189,9 @@ class FunctionItem : public InsertVirtualMethodsItem { public: FunctionItem(const Function *func, const QString &functionName, ClassItem *parent); - QString description() const; - Qt::ItemFlags flags() const; - Qt::CheckState checkState() const { return checked ? Qt::Checked : Qt::Unchecked; } + QString description() const override; + Qt::ItemFlags flags() const override; + Qt::CheckState checkState() const override { return checked ? Qt::Checked : Qt::Unchecked; } const Function *function = nullptr; InsertionPointLocator::AccessSpec accessSpec = InsertionPointLocator::Invalid; @@ -209,7 +205,7 @@ private: }; ClassItem::ClassItem(const QString &className, const Class *clazz) : - InsertVirtualMethodsItem(0), + InsertVirtualMethodsItem(nullptr), klass(clazz), name(className) { @@ -339,7 +335,7 @@ public: bool insertOverrideReplacement = false; private: - typedef QLatin1String _; + using _ = QLatin1String; static QString group() { return _("QuickFix/InsertVirtualMethods"); } static QString insertVirtualKeywordKey() { return _("insertKeywordVirtual"); } static QString insertOverrideReplacementKey() { return _("insertOverrideReplacement"); } @@ -352,13 +348,13 @@ private: class InsertVirtualMethodsModel : public QAbstractItemModel { public: - InsertVirtualMethodsModel(QObject *parent = 0) : QAbstractItemModel(parent) + InsertVirtualMethodsModel(QObject *parent = nullptr) : QAbstractItemModel(parent) { const FontSettings &fs = TextEditorSettings::fontSettings(); formatReimpFunc = fs.formatFor(C_DISABLED_CODE); } - ~InsertVirtualMethodsModel() + ~InsertVirtualMethodsModel() override { clear(); } @@ -371,26 +367,26 @@ public: endResetModel(); } - QModelIndex index(int row, int column, const QModelIndex &parent) const + QModelIndex index(int row, int column, const QModelIndex &parent) const override { if (column != 0) - return QModelIndex(); + return {}; if (parent.isValid()) { - ClassItem *classItem = static_cast(parent.internalPointer()); + auto classItem = static_cast(parent.internalPointer()); return createIndex(row, column, classItem->functions.at(row)); } return createIndex(row, column, classes.at(row)); } - QModelIndex parent(const QModelIndex &child) const + QModelIndex parent(const QModelIndex &child) const override { if (!child.isValid()) - return QModelIndex(); + return {}; InsertVirtualMethodsItem *parent = itemForIndex(child)->parent(); return parent ? createIndex(parent->row, 0, parent) : QModelIndex(); } - int rowCount(const QModelIndex &parent) const + int rowCount(const QModelIndex &parent) const override { if (!parent.isValid()) return classes.count(); @@ -400,7 +396,7 @@ public: return static_cast(item)->functions.count(); } - int columnCount(const QModelIndex &) const + int columnCount(const QModelIndex &) const override { return 1; } @@ -416,13 +412,13 @@ public: void removeFunction(FunctionItem *funcItem) { - ClassItem *classItem = static_cast(funcItem->parent()); + auto classItem = static_cast(funcItem->parent()); beginRemoveRows(createIndex(classItem->row, 0, classItem), funcItem->row, funcItem->row); classItem->removeFunction(funcItem->row); endRemoveRows(); } - QVariant data(const QModelIndex &index, int role) const + QVariant data(const QModelIndex &index, int role) const override { if (!index.isValid()) return QVariant(); @@ -446,7 +442,7 @@ public: break; case InsertVirtualMethodsDialog::Reimplemented: if (item->parent()) { - FunctionItem *function = static_cast(item); + auto function = static_cast(item); return QVariant(function->alreadyFound); } @@ -454,7 +450,7 @@ public: return QVariant(); } - bool setData(const QModelIndex &index, const QVariant &value, int role) + bool setData(const QModelIndex &index, const QVariant &value, int role) override { if (!index.isValid()) return false; @@ -464,7 +460,7 @@ public: case Qt::CheckStateRole: { bool checked = value.toInt() == Qt::Checked; if (item->parent()) { - FunctionItem *funcItem = static_cast(item); + auto funcItem = static_cast(item); while (funcItem->checked != checked) { funcItem->checked = checked; const QModelIndex funcIndex = createIndex(funcItem->row, 0, funcItem); @@ -475,7 +471,7 @@ public: funcItem = funcItem->nextOverride; } } else { - ClassItem *classItem = static_cast(item); + auto classItem = static_cast(item); foreach (FunctionItem *funcItem, classItem->functions) { if (funcItem->alreadyFound || funcItem->checked == checked) continue; @@ -489,7 +485,7 @@ public: return QAbstractItemModel::setData(index, value, role); } - Qt::ItemFlags flags(const QModelIndex &index) const + Qt::ItemFlags flags(const QModelIndex &index) const override { if (!index.isValid()) return Qt::NoItemFlags; @@ -586,7 +582,7 @@ public: if (!name || name->asDestructorNameId()) continue; - const Function *firstVirtual = 0; + const Function *firstVirtual = nullptr; const bool isVirtual = FunctionUtils::isVirtualFunction( func, interface.context(), &firstVirtual); if (!isVirtual) @@ -594,7 +590,7 @@ public: if (func->isFinal()) { if (FunctionItem *first = virtualFunctions[firstVirtual]) { - FunctionItem *next = 0; + FunctionItem *next = nullptr; for (FunctionItem *removed = first; next != first; removed = next) { next = removed->nextOverride; m_factory->classFunctionModel->removeFunction(removed); @@ -643,7 +639,7 @@ public: itemName += QLatin1String(" : ") + itemReturnTypeString; if (isReimplemented) itemName += QLatin1String(" (redeclared)"); - FunctionItem *funcItem = new FunctionItem(func, itemName, itemBase); + auto funcItem = new FunctionItem(func, itemName, itemBase); if (isReimplemented) { factory->setHasReimplementedFunctions(true); funcItem->reimplemented = true; @@ -734,7 +730,7 @@ public: return spec; } - void perform() + void perform() override { if (!m_factory->gather()) return; @@ -897,12 +893,11 @@ class InsertVirtualMethodsFilterModel : public QSortFilterProxyModel { Q_OBJECT public: - InsertVirtualMethodsFilterModel(QObject *parent = 0) + InsertVirtualMethodsFilterModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent) - , m_hideReimplemented(false) {} - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); @@ -941,22 +936,11 @@ public: } private: - bool m_hideReimplemented; + bool m_hideReimplemented = false; }; InsertVirtualMethodsDialog::InsertVirtualMethodsDialog(QWidget *parent) : QDialog(parent) - , m_view(0) - , m_filter(0) - , m_hideReimplementedFunctions(0) - , m_insertMode(0) - , m_virtualKeyword(0) - , m_overrideReplacementCheckBox(0) - , m_overrideReplacementComboBox(0) - , m_clearUserAddedReplacementsButton(0) - , m_buttons(0) - , m_hasImplementationFile(false) - , m_hasReimplementedFunctions(false) , m_settings(new VirtualMethodsSettings) , classFunctionModel(new InsertVirtualMethodsModel(this)) , classFunctionFilterModel(new InsertVirtualMethodsFilterModel(this)) @@ -976,11 +960,11 @@ void InsertVirtualMethodsDialog::initGui() return; setWindowTitle(tr("Insert Virtual Functions")); - QVBoxLayout *globalVerticalLayout = new QVBoxLayout; + auto globalVerticalLayout = new QVBoxLayout; // View QGroupBox *groupBoxView = new QGroupBox(tr("&Functions to insert:"), this); - QVBoxLayout *groupBoxViewLayout = new QVBoxLayout(groupBoxView); + auto groupBoxViewLayout = new QVBoxLayout(groupBoxView); m_filter = new QLineEdit(this); m_filter->setClearButtonEnabled(true); m_filter->setPlaceholderText(tr("Filter")); @@ -995,7 +979,7 @@ void InsertVirtualMethodsDialog::initGui() // Insertion options QGroupBox *groupBoxImplementation = new QGroupBox(tr("&Insertion options:"), this); - QVBoxLayout *groupBoxImplementationLayout = new QVBoxLayout(groupBoxImplementation); + auto groupBoxImplementationLayout = new QVBoxLayout(groupBoxImplementation); m_insertMode = new QComboBox(this); m_insertMode->addItem(tr("Insert only declarations"), ModeOnlyDeclarations); m_insertMode->addItem(tr("Insert definitions inside class"), ModeInsideClass); @@ -1012,7 +996,7 @@ void InsertVirtualMethodsDialog::initGui() connect(m_overrideReplacementCheckBox, &QCheckBox::clicked, m_overrideReplacementComboBox, &QComboBox::setEnabled); - QAction *clearUserAddedReplacements = new QAction(this); + auto clearUserAddedReplacements = new QAction(this); clearUserAddedReplacements->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon()); clearUserAddedReplacements->setText(tr("Clear Added \"override\" Equivalents")); connect(clearUserAddedReplacements, &QAction::triggered, [this]() { @@ -1023,7 +1007,7 @@ void InsertVirtualMethodsDialog::initGui() m_clearUserAddedReplacementsButton = new QToolButton(this); m_clearUserAddedReplacementsButton->setDefaultAction(clearUserAddedReplacements); - QHBoxLayout *overrideWidgetsLayout = new QHBoxLayout(this); + auto overrideWidgetsLayout = new QHBoxLayout(this); overrideWidgetsLayout->setSpacing(0); overrideWidgetsLayout->setMargin(0); overrideWidgetsLayout->addWidget(m_overrideReplacementCheckBox); @@ -1145,8 +1129,7 @@ void InsertVirtualMethodsDialog::setHasReimplementedFunctions(bool functions) void InsertVirtualMethodsDialog::setHideReimplementedFunctions(bool hide) { - InsertVirtualMethodsFilterModel *model = - qobject_cast(classFunctionFilterModel); + auto model = qobject_cast(classFunctionFilterModel); if (m_expansionStateNormal.isEmpty() && m_expansionStateReimp.isEmpty()) { model->setHideReimplementedFunctions(hide); @@ -1172,8 +1155,7 @@ void InsertVirtualMethodsDialog::updateOverrideReplacementsComboBox() void InsertVirtualMethodsDialog::saveExpansionState() { - InsertVirtualMethodsFilterModel *model = - qobject_cast(classFunctionFilterModel); + auto model = qobject_cast(classFunctionFilterModel); QList &state = model->hideReimplemented() ? m_expansionStateReimp : m_expansionStateNormal; @@ -1184,8 +1166,7 @@ void InsertVirtualMethodsDialog::saveExpansionState() void InsertVirtualMethodsDialog::restoreExpansionState() { - InsertVirtualMethodsFilterModel *model = - qobject_cast(classFunctionFilterModel); + auto model = qobject_cast(classFunctionFilterModel); const QList &state = model->hideReimplemented() ? m_expansionStateReimp : m_expansionStateNormal; diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.h b/src/plugins/cppeditor/cppinsertvirtualmethods.h index cc48fede938..c185ec90dd6 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.h +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.h @@ -36,9 +36,9 @@ class InsertVirtualMethods : public CppQuickFixFactory { Q_OBJECT public: - InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = 0); - ~InsertVirtualMethods(); - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result); + InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = nullptr); + ~InsertVirtualMethods() override; + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; #ifdef WITH_TESTS static InsertVirtualMethods *createTestFactory(); #endif diff --git a/src/plugins/cppeditor/cppminimizableinfobars.h b/src/plugins/cppeditor/cppminimizableinfobars.h index 624433d86f8..f53c43c084e 100644 --- a/src/plugins/cppeditor/cppminimizableinfobars.h +++ b/src/plugins/cppeditor/cppminimizableinfobars.h @@ -51,7 +51,7 @@ public: static Actions createShowInfoBarActions(const ActionCreator &actionCreator); public: - explicit MinimizableInfoBars(Core::InfoBar &infoBar, QObject *parent = 0); + explicit MinimizableInfoBars(Core::InfoBar &infoBar, QObject *parent = nullptr); // Expected call order: processHasProjectPart(), processHeaderDiagnostics() void processHasProjectPart(bool hasProjectPart); diff --git a/src/plugins/cppeditor/cpppreprocessordialog.h b/src/plugins/cppeditor/cpppreprocessordialog.h index 2bca50f4011..81943069332 100644 --- a/src/plugins/cppeditor/cpppreprocessordialog.h +++ b/src/plugins/cppeditor/cpppreprocessordialog.h @@ -38,9 +38,9 @@ class CppPreProcessorDialog : public QDialog public: explicit CppPreProcessorDialog(const QString &filePath, QWidget *parent); - ~CppPreProcessorDialog(); + ~CppPreProcessorDialog() override; - int exec(); + int exec() override; QString extraPreprocessorDirectives() const; diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index c91c4dccb81..a22b85f5e40 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -39,5 +39,4 @@ CppQuickFixOperation::CppQuickFixOperation(const CppQuickFixInterface &interface : QuickFixOperation(priority), CppQuickFixInterface(interface) {} -CppQuickFixOperation::~CppQuickFixOperation() -{} +CppQuickFixOperation::~CppQuickFixOperation() = default; diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h index 48ba6ece666..3fe054f8a04 100644 --- a/src/plugins/cppeditor/cppquickfix.h +++ b/src/plugins/cppeditor/cppquickfix.h @@ -39,7 +39,7 @@ class CPPEDITOR_EXPORT CppQuickFixOperation { public: explicit CppQuickFixOperation(const CppQuickFixInterface &interface, int priority = -1); - ~CppQuickFixOperation(); + ~CppQuickFixOperation() override; }; /*! @@ -60,7 +60,7 @@ class CPPEDITOR_EXPORT CppQuickFixFactory : public QObject public: CppQuickFixFactory(); - ~CppQuickFixFactory(); + ~CppQuickFixFactory() override; using QuickFixOperations = TextEditor::QuickFixOperations; diff --git a/src/plugins/cppeditor/cppquickfixassistant.h b/src/plugins/cppeditor/cppquickfixassistant.h index 89aa798aa42..bc9fc415420 100644 --- a/src/plugins/cppeditor/cppquickfixassistant.h +++ b/src/plugins/cppeditor/cppquickfixassistant.h @@ -35,7 +35,7 @@ namespace CppTools { class CppRefactoringFile; -typedef QSharedPointer CppRefactoringFilePtr; +using CppRefactoringFilePtr = QSharedPointer; } namespace CppEditor { diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index e09358d25da..c17850662fc 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -173,23 +173,23 @@ inline bool isQtFuzzyComparable(const QString &typeName) Class *isMemberFunction(const LookupContext &context, Function *function) { - QTC_ASSERT(function, return 0); + QTC_ASSERT(function, return nullptr); Scope *enclosingScope = function->enclosingScope(); while (!(enclosingScope->isNamespace() || enclosingScope->isClass())) enclosingScope = enclosingScope->enclosingScope(); - QTC_ASSERT(enclosingScope != 0, return 0); + QTC_ASSERT(enclosingScope != nullptr, return nullptr); const Name *functionName = function->name(); if (!functionName) - return 0; + return nullptr; if (!functionName->isQualifiedNameId()) - return 0; // trying to add a declaration for a global function + return nullptr; // trying to add a declaration for a global function const QualifiedNameId *q = functionName->asQualifiedNameId(); if (!q->base()) - return 0; + return nullptr; if (ClassOrNamespace *binding = context.lookupType(q->base(), enclosingScope)) { foreach (Symbol *s, binding->symbols()) { @@ -198,23 +198,23 @@ Class *isMemberFunction(const LookupContext &context, Function *function) } } - return 0; + return nullptr; } Namespace *isNamespaceFunction(const LookupContext &context, Function *function) { - QTC_ASSERT(function, return 0); + QTC_ASSERT(function, return nullptr); if (isMemberFunction(context, function)) - return 0; + return nullptr; Scope *enclosingScope = function->enclosingScope(); while (!(enclosingScope->isNamespace() || enclosingScope->isClass())) enclosingScope = enclosingScope->enclosingScope(); - QTC_ASSERT(enclosingScope != 0, return 0); + QTC_ASSERT(enclosingScope != nullptr, return nullptr); const Name *functionName = function->name(); if (!functionName) - return 0; + return nullptr; // global namespace if (!functionName->isQualifiedNameId()) { @@ -222,12 +222,12 @@ Namespace *isNamespaceFunction(const LookupContext &context, Function *function) if (Namespace *matchingNamespace = s->asNamespace()) return matchingNamespace; } - return 0; + return nullptr; } const QualifiedNameId *q = functionName->asQualifiedNameId(); if (!q->base()) - return 0; + return nullptr; if (ClassOrNamespace *binding = context.lookupType(q->base(), enclosingScope)) { foreach (Symbol *s, binding->symbols()) { @@ -236,7 +236,7 @@ Namespace *isNamespaceFunction(const LookupContext &context, Function *function) } } - return 0; + return nullptr; } // Given include is e.g. "afile.h" or (quotes/angle brackets included!). @@ -308,10 +308,12 @@ namespace { class InverseLogicalComparisonOp: public CppQuickFixOperation { public: - InverseLogicalComparisonOp(const CppQuickFixInterface &interface, int priority, - BinaryExpressionAST *binary, Kind invertToken) + InverseLogicalComparisonOp(const CppQuickFixInterface &interface, + int priority, + BinaryExpressionAST *binary, + Kind invertToken) : CppQuickFixOperation(interface, priority) - , binary(binary), nested(0), negation(0) + , binary(binary) { Token tok; tok.f.kind = invertToken; @@ -324,19 +326,17 @@ public: // check for ! before parentheses if (nested && priority - 2 >= 0) { negation = interface.path()[priority - 2]->asUnaryExpression(); - if (negation - && !interface.currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM)) { - negation = 0; - } + if (negation && !interface.currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM)) + negation = nullptr; } } - QString description() const + QString description() const override { return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -357,9 +357,9 @@ public: } private: - BinaryExpressionAST *binary; - NestedExpressionAST *nested; - UnaryExpressionAST *negation; + BinaryExpressionAST *binary = nullptr; + NestedExpressionAST *nested = nullptr; + UnaryExpressionAST *negation = nullptr; QString replacement; }; @@ -420,7 +420,7 @@ public: setPriority(priority); } - QString description() const + QString description() const override { if (replacement.isEmpty()) return QApplication::translate("CppTools::QuickFix", "Swap Operands"); @@ -428,7 +428,7 @@ public: return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -515,7 +515,7 @@ public: pattern = mk->BinaryExpression(left, right); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -539,7 +539,7 @@ public: void RewriteLogicalAnd::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - BinaryExpressionAST *expression = 0; + BinaryExpressionAST *expression = nullptr; const QList &path = interface.path(); CppRefactoringFilePtr file = interface.currentFile(); @@ -582,10 +582,10 @@ static bool checkDeclarationForSplit(SimpleDeclarationAST *declaration) for (SpecifierListAST *it = declaration->decl_specifier_list; it; it = it->next) { SpecifierAST *specifier = it->value; - if (specifier->asEnumSpecifier() != 0) + if (specifier->asEnumSpecifier() != nullptr) return false; - else if (specifier->asClassSpecifier() != 0) + else if (specifier->asClassSpecifier() != nullptr) return false; } @@ -612,7 +612,7 @@ public: "Split Declaration")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -655,7 +655,7 @@ private: void SplitSimpleDeclaration::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - CoreDeclaratorAST *core_declarator = 0; + CoreDeclaratorAST *core_declarator = nullptr; const QList &path = interface.path(); CppRefactoringFilePtr file = interface.currentFile(); const int cursorPosition = file->cursor().selectionStart(); @@ -702,7 +702,7 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Add Curly Braces")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -775,7 +775,7 @@ public: pattern = mk.IfStatement(condition); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -806,7 +806,7 @@ void MoveDeclarationOutOfIf::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); - typedef QSharedPointer Ptr; + using Ptr = QSharedPointer; Ptr op(new MoveDeclarationOutOfIfOp(interface)); int index = path.size() - 1; @@ -849,7 +849,7 @@ public: pattern = mk.WhileStatement(condition); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -928,7 +928,7 @@ public: "Split if Statement")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -997,7 +997,7 @@ private: void SplitIfStatement::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - IfStatementAST *pattern = 0; + IfStatementAST *pattern = nullptr; const QList &path = interface.path(); int index = path.size() - 1; @@ -1118,10 +1118,10 @@ static ExpressionAST *analyzeStringLiteral(const QList &path, if (enclosingFunction) enclosingFunction->clear(); if (enclosingFunctionCall) - *enclosingFunctionCall = 0; + *enclosingFunctionCall = nullptr; if (path.isEmpty()) - return 0; + return nullptr; ExpressionAST *literal = path.last()->asExpression(); if (literal) { @@ -1167,7 +1167,7 @@ public: setDescription(description); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -1371,7 +1371,7 @@ public: "Convert to Objective-C String Literal")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -1414,7 +1414,7 @@ void ConvertCStringToNSString::match(const CppQuickFixInterface &interface, if (!literal || type != TypeString) return; if (!isQtStringLiteral(enclosingFunction)) - qlatin1Call = 0; + qlatin1Call = nullptr; result << new ConvertCStringToNSStringOp(interface, path.size() - 1, literal->asStringLiteral(), qlatin1Call); @@ -1433,7 +1433,7 @@ public: , replacement(replacement) {} - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -1595,7 +1595,7 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -1652,10 +1652,10 @@ void AddLocalDeclaration::match(const CppQuickFixInterface &interface, QuickFixO && file->tokenAt(binary->binary_op_token).is(T_EQUAL)) { IdExpressionAST *idExpr = binary->left_expression->asIdExpression(); if (interface.isCursorOn(binary->left_expression) && idExpr - && idExpr->name->asSimpleName() != 0) { + && idExpr->name->asSimpleName() != nullptr) { SimpleNameAST *nameAST = idExpr->name->asSimpleName(); const QList results = interface.context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken())); - Declaration *decl = 0; + Declaration *decl = nullptr; foreach (const LookupItem &r, results) { if (!r.declaration()) continue; @@ -1689,7 +1689,7 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Camel Case")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -1727,7 +1727,7 @@ void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOp return; AST * const ast = path.last(); - const Name *name = 0; + const Name *name = nullptr; if (const NameAST * const nameAst = ast->asName()) { if (nameAst->name && nameAst->name->asNameId()) name = nameAst->name; @@ -1832,9 +1832,9 @@ ProjectExplorer::HeaderPaths relevantHeaderPaths(const QString &filePath) NameAST *nameUnderCursor(const QList &path) { if (path.isEmpty()) - return 0; + return nullptr; - NameAST *nameAst = 0; + NameAST *nameAst = nullptr; for (int i = path.size() - 1; i >= 0; --i) { AST * const ast = path.at(i); if (SimpleNameAST *simpleName = ast->asSimpleName()) { @@ -2037,7 +2037,7 @@ public: setDescription(targetString); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -2063,7 +2063,7 @@ void RearrangeParamDeclarationList::match(const CppQuickFixInterface &interface, { const QList path = interface.path(); - ParameterDeclarationAST *paramDecl = 0; + ParameterDeclarationAST *paramDecl = nullptr; int index = path.size() - 1; for (; index != -1; --index) { paramDecl = path.at(index)->asParameterDeclaration(); @@ -2078,7 +2078,7 @@ void RearrangeParamDeclarationList::match(const CppQuickFixInterface &interface, QTC_ASSERT(paramDeclClause && paramDeclClause->parameter_declaration_list, return); ParameterDeclarationListAST *paramListNode = paramDeclClause->parameter_declaration_list; - ParameterDeclarationListAST *prevParamListNode = 0; + ParameterDeclarationListAST *prevParamListNode = nullptr; while (paramListNode) { if (paramDecl == paramListNode->value) break; @@ -2117,7 +2117,7 @@ public: setDescription(description); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -2135,15 +2135,6 @@ private: class ReformatPointerDeclarationASTPathResultsFilter { public: - ReformatPointerDeclarationASTPathResultsFilter() - : m_hasSimpleDeclaration(false) - , m_hasFunctionDefinition(false) - , m_hasParameterDeclaration(false) - , m_hasIfStatement(false) - , m_hasWhileStatement(false) - , m_hasForStatement(false) - , m_hasForeachStatement(false) {} - QList filter(const QList &astPathList) { QList filtered; @@ -2179,13 +2170,13 @@ public: } private: - bool m_hasSimpleDeclaration; - bool m_hasFunctionDefinition; - bool m_hasParameterDeclaration; - bool m_hasIfStatement; - bool m_hasWhileStatement; - bool m_hasForStatement; - bool m_hasForeachStatement; + bool m_hasSimpleDeclaration = false; + bool m_hasFunctionDefinition = false; + bool m_hasParameterDeclaration = false; + bool m_hasIfStatement = false; + bool m_hasWhileStatement = false; + bool m_hasForStatement = false; + bool m_hasForeachStatement = false; }; } // anonymous namespace @@ -2248,7 +2239,7 @@ public: return values; } - bool preVisit(AST *ast) { + bool preVisit(AST *ast) override { if (CaseStatementAST *cs = ast->asCaseStatement()) { foundCaseStatementLevel = true; if (ExpressionAST *csExpression = cs->expression) { @@ -2288,7 +2279,7 @@ public: "Complete Switch Statement")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -2335,7 +2326,7 @@ static Enum *findEnum(const QList &results, const LookupContext &ctx } } - return 0; + return nullptr; } Enum *conditionEnum(const CppQuickFixInterface &interface, SwitchStatementAST *statement) @@ -2418,7 +2409,7 @@ public: .arg(InsertionPointLocator::accessSpecToString(xsSpec))); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); @@ -2478,7 +2469,7 @@ void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOpe const QList &path = interface.path(); CppRefactoringFilePtr file = interface.currentFile(); - FunctionDefinitionAST *funDef = 0; + FunctionDefinitionAST *funDef = nullptr; int idx = 0; for (; idx < path.size(); ++idx) { AST *node = path.at(idx); @@ -2593,7 +2584,7 @@ public: } } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); if (!m_loc.isValid()) @@ -2714,7 +2705,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe // Insert Position: Implementation File DeclaratorAST *declAST = simpleDecl->declarator_list->value; - InsertDefOperation *op = 0; + InsertDefOperation *op = nullptr; ProjectFile::Kind kind = ProjectFile::classify(interface.fileName()); const bool isHeaderFile = ProjectFile::isHeader(kind); if (isHeaderFile) { @@ -2752,7 +2743,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe } // Determine if we are dealing with a free function - const bool isFreeFunction = func->enclosingClass() == 0; + const bool isFreeFunction = func->enclosingClass() == nullptr; // Insert Position: Outside Class if (!isFreeFunction) { @@ -2817,15 +2808,6 @@ public: GenerateGetterSetterOperation(const CppQuickFixInterface &interface) : CppQuickFixOperation(interface) - , m_type(InvalidType) - , m_variableName(0) - , m_declaratorId(0) - , m_declarator(0) - , m_variableDecl(0) - , m_classSpecifier(0) - , m_classDecl(0) - , m_symbol(0) - , m_offerQuickFix(true) { const QList &path = interface.path(); // We expect something like @@ -3037,7 +3019,7 @@ public: && m_offerQuickFix; } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -3175,20 +3157,20 @@ public: currentFile->apply(); } - OperationType m_type; - SimpleNameAST *m_variableName; - DeclaratorIdAST *m_declaratorId; - DeclaratorAST *m_declarator; - SimpleDeclarationAST *m_variableDecl; - ClassSpecifierAST *m_classSpecifier; - SimpleDeclarationAST *m_classDecl; - Symbol *m_symbol; + OperationType m_type = InvalidType; + SimpleNameAST *m_variableName = nullptr; + DeclaratorIdAST *m_declaratorId = nullptr; + DeclaratorAST *m_declarator = nullptr; + SimpleDeclarationAST *m_variableDecl = nullptr; + ClassSpecifierAST *m_classSpecifier = nullptr; + SimpleDeclarationAST *m_classDecl = nullptr; + Symbol *m_symbol = nullptr; QString m_baseName; QString m_getterName; QString m_setterName; QString m_variableString; - bool m_offerQuickFix; + bool m_offerQuickFix = true; }; } // anonymous namespace @@ -3196,7 +3178,7 @@ public: void GenerateGetterSetter::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - GenerateGetterSetterOperation *op = new GenerateGetterSetterOperation(interface); + auto op = new GenerateGetterSetterOperation(interface); if (op->m_type != GenerateGetterSetterOperation::InvalidType) { result << op; if (op->m_type == GenerateGetterSetterOperation::GetterSetterType) { @@ -3215,9 +3197,6 @@ namespace { class ExtractFunctionOptions { public: - ExtractFunctionOptions() : access(InsertionPointLocator::Public) - {} - static bool isValidFunctionName(const QString &name) { return !name.isEmpty() && isValidIdentifier(name); @@ -3229,7 +3208,7 @@ public: } QString funcName; - InsertionPointLocator::AccessSpec access; + InsertionPointLocator::AccessSpec access = InsertionPointLocator::Public; }; class ExtractFunctionOperation : public CppQuickFixOperation @@ -3254,7 +3233,7 @@ public: setDescription(QCoreApplication::translate("QuickFix::ExtractFunction", "Extract Function")); } - void perform() + void perform() override { QTC_ASSERT(!m_funcReturn || !m_relevantDecls.isEmpty(), return); CppRefactoringChanges refactoring(snapshot()); @@ -3524,7 +3503,7 @@ public: return !m_failed; } - bool preVisit(AST *) + bool preVisit(AST *) override { if (m_done) return false; @@ -3553,13 +3532,13 @@ public: accept(stmt); } - bool visit(CaseStatementAST *stmt) + bool visit(CaseStatementAST *stmt) override { statement(stmt->statement); return false; } - bool visit(CompoundStatementAST *stmt) + bool visit(CompoundStatementAST *stmt) override { for (StatementListAST *it = stmt->statement_list; it; it = it->next) { statement(it->value); @@ -3569,25 +3548,25 @@ public: return false; } - bool visit(DoStatementAST *stmt) + bool visit(DoStatementAST *stmt) override { statement(stmt->statement); return false; } - bool visit(ForeachStatementAST *stmt) + bool visit(ForeachStatementAST *stmt) override { statement(stmt->statement); return false; } - bool visit(RangeBasedForStatementAST *stmt) + bool visit(RangeBasedForStatementAST *stmt) override { statement(stmt->statement); return false; } - bool visit(ForStatementAST *stmt) + bool visit(ForStatementAST *stmt) override { statement(stmt->initializer); if (!m_done) @@ -3595,7 +3574,7 @@ public: return false; } - bool visit(IfStatementAST *stmt) + bool visit(IfStatementAST *stmt) override { statement(stmt->statement); if (!m_done) @@ -3603,7 +3582,7 @@ public: return false; } - bool visit(TryBlockStatementAST *stmt) + bool visit(TryBlockStatementAST *stmt) override { statement(stmt->statement); for (CatchClauseListAST *it = stmt->catch_clause_list; it; it = it->next) { @@ -3614,13 +3593,13 @@ public: return false; } - bool visit(WhileStatementAST *stmt) + bool visit(WhileStatementAST *stmt) override { statement(stmt->statement); return false; } - bool visit(DeclarationStatementAST *declStmt) + bool visit(DeclarationStatementAST *declStmt) override { // We need to collect the declarations we see before the extraction or even inside it. // They might need to be used as either a parameter or return value. Actually, we could @@ -3649,7 +3628,7 @@ public: return false; } - bool visit(ReturnStatementAST *) + bool visit(ReturnStatementAST *) override { if (m_extractionStart) { m_done = true; @@ -3686,7 +3665,7 @@ void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOpera return; const QList &path = interface.path(); - FunctionDefinitionAST *refFuncDef = 0; // The "reference" function, which we will extract from. + FunctionDefinitionAST *refFuncDef = nullptr; // The "reference" function, which we will extract from. for (int i = path.size() - 1; i >= 0; --i) { refFuncDef = path.at(i)->asFunctionDefinition(); if (refFuncDef) @@ -3751,7 +3730,7 @@ void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOpera } // Identify what would be parameters for the new function and its return value, if any. - Symbol *funcReturn = 0; + Symbol *funcReturn = nullptr; QList > relevantDecls; SemanticInfo::LocalUseIterator it(interface.semanticInfo().localUses); while (it.hasNext()) { @@ -3853,7 +3832,7 @@ public: } private: - bool visit(T *ast) + bool visit(T *ast) override { if (ast != m_literal && strcmp(m_file->tokenAt(ast->firstToken()).spell(), m_literalTokenText) != 0) { @@ -3887,11 +3866,7 @@ public: struct FoundDeclaration { - FoundDeclaration() - : ast(0) - {} - - FunctionDeclaratorAST *ast; + FunctionDeclaratorAST *ast = nullptr; CppRefactoringFilePtr file; }; @@ -3963,7 +3938,7 @@ public: return result; } - void perform() + void perform() override { FunctionDeclaratorAST *functionDeclaratorOfDefinition = functionDeclarator(m_functionDefinition); @@ -4043,7 +4018,7 @@ private: if (functionDeclaratorAST) return functionDeclaratorAST; } - return 0; + return nullptr; } FunctionDeclaratorAST *functionDeclarator(DeclaratorAST *ast) const @@ -4053,7 +4028,7 @@ private: if (funcdecl) return funcdecl; } - return 0; + return nullptr; } FunctionDeclaratorAST *functionDeclarator(FunctionDefinitionAST *ast) const @@ -4197,7 +4172,7 @@ private: { ExpressionListParenAST *exprlist = newExprAST->new_initializer ? newExprAST->new_initializer->asExpressionListParen() - : 0; + : nullptr; if (exprlist && exprlist->expression_list) { // remove 'new' keyword and type before initializer @@ -4403,8 +4378,8 @@ void ConvertFromAndToPointer::match(const CppQuickFixInterface &interface, SimpleNameAST *identifier = path.last()->asSimpleName(); if (!identifier) return; - SimpleDeclarationAST *simpleDeclaration = 0; - DeclaratorAST *declarator = 0; + SimpleDeclarationAST *simpleDeclaration = nullptr; + DeclaratorAST *declarator = nullptr; bool isFunctionLocal = false; bool isClassLocal = false; ConvertFromAndToPointerOp::Mode mode = ConvertFromAndToPointerOp::FromVariable; @@ -4426,7 +4401,7 @@ void ConvertFromAndToPointer::match(const CppQuickFixInterface &interface, if (!isFunctionLocal || !simpleDeclaration || !declarator) return; - Symbol *symbol = 0; + Symbol *symbol = nullptr; for (List *lst = simpleDeclaration->symbols; lst; lst = lst->next) { if (lst->value->name() == identifier->name) { symbol = lst->value; @@ -4499,7 +4474,7 @@ public: setDescription(CppQuickFixFactory::tr("Generate Missing Q_PROPERTY Members")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr file = refactoring.file(fileName()); @@ -4601,7 +4576,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, if (!qtPropertyDeclaration || !qtPropertyDeclaration->type_id) return; - ClassSpecifierAST *klass = 0; + ClassSpecifierAST *klass = nullptr; for (int i = path.size() - 2; i >= 0; --i) { klass = path.at(i)->asClassSpecifier(); if (klass) @@ -4673,7 +4648,7 @@ public: , m_link(link) {} - void perform() + void perform() override { if (editor()->declDefLink() == m_link) editor()->applyDeclDefLinkChanges(/*don't jump*/false); @@ -4840,7 +4815,7 @@ public: } } - void perform() + void perform() override { MoveFuncDefRefactoringHelper helper(this, m_type, m_headerFileName, m_cppFileName); helper.performMove(m_funcDef); @@ -4859,8 +4834,8 @@ private: void MoveFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); - SimpleDeclarationAST *classAST = 0; - FunctionDefinitionAST *funcAST = 0; + SimpleDeclarationAST *classAST = nullptr; + FunctionDefinitionAST *funcAST = nullptr; bool moveOutsideMemberDefinition = false; const int pathSize = path.size(); @@ -4883,7 +4858,7 @@ void MoveFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFixOp break; } } - funcAST = 0; + funcAST = nullptr; } } @@ -4933,7 +4908,7 @@ public: } } - void perform() + void perform() override { MoveFuncDefRefactoringHelper helper(this, m_type, m_headerFileName, m_cppFileName); for (DeclarationListAST *it = m_classDef->member_specifier_list; it; it = it->next) { @@ -5024,7 +4999,7 @@ public: } } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr fromFile = refactoring.file(m_fromFileName); @@ -5065,8 +5040,8 @@ private: void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); - AST *completeDefAST = 0; - FunctionDefinitionAST *funcAST = 0; + AST *completeDefAST = nullptr; + FunctionDefinitionAST *funcAST = nullptr; const int pathSize = path.size(); for (int idx = 1; idx < pathSize; ++idx) { @@ -5082,7 +5057,7 @@ void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOpe completeDefAST = enclosingAST->asTemplateDeclaration() ? enclosingAST : funcAST; break; } - funcAST = 0; + funcAST = nullptr; } } @@ -5196,7 +5171,7 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Assign to Local Variable")); } - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr file = refactoring.file(fileName()); @@ -5271,8 +5246,8 @@ private: void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); - AST *outerAST = 0; - SimpleNameAST *nameAST = 0; + AST *outerAST = nullptr; + SimpleNameAST *nameAST = nullptr; for (int i = path.size() - 3; i >= 0; --i) { if (CallAST *callAST = path.at(i)->asCall()) { @@ -5404,7 +5379,7 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Optimize for-Loop")); } - void perform() + void perform() override { QTC_ASSERT(m_forAst, return); @@ -5491,7 +5466,7 @@ private: void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList path = interface.path(); - ForStatementAST *forAst = 0; + ForStatementAST *forAst = nullptr; if (!path.isEmpty()) forAst = path.last()->asForStatement(); if (!forAst || !interface.isCursorOn(forAst)) @@ -5511,7 +5486,7 @@ void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOpera // Check for optimizing condition bool optimizeCondition = false; FullySpecifiedType conditionType; - ExpressionAST *conditionExpression = 0; + ExpressionAST *conditionExpression = nullptr; if (forAst->initializer && forAst->condition) { if (BinaryExpressionAST *binary = forAst->condition->asBinaryExpression()) { // Get the expression against which we should evaluate @@ -5563,7 +5538,7 @@ void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOpera if (optimizePostcrement || optimizeCondition) { result << new OptimizeForLoopOperation(interface, forAst, optimizePostcrement, - (optimizeCondition) ? conditionExpression : 0, + optimizeCondition ? conditionExpression : nullptr, conditionType); } } @@ -5661,7 +5636,7 @@ private: // QuickFixOperation interface public: - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -5748,7 +5723,7 @@ public: } private: - void perform() + void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.file(fileName()); @@ -5766,7 +5741,7 @@ Symbol *skipForwardDeclarations(const QList &symbols) return symbol; } - return 0; + return nullptr; } bool findRawAccessFunction(Class *klass, PointerType *pointerType, QString *objAccessFunction) @@ -5784,7 +5759,7 @@ bool findRawAccessFunction(Class *klass, PointerType *pointerType, QString *objA } } } - const Name *funcName = 0; + const Name *funcName = nullptr; switch (candidates.size()) { case 0: return false; @@ -5811,7 +5786,7 @@ PointerType *determineConvertedType(NamedType *namedType, const LookupContext &c Scope *scope, QString *objAccessFunction) { if (!namedType) - return 0; + return nullptr; if (ClassOrNamespace *binding = context.lookupType(namedType->name(), scope)) { if (Symbol *objectClassSymbol = skipForwardDeclarations(binding->symbols())) { if (Class *klass = objectClassSymbol->asClass()) { @@ -5830,7 +5805,7 @@ PointerType *determineConvertedType(NamedType *namedType, const LookupContext &c } } - return 0; + return nullptr; } Class *senderOrReceiverClass(const CppQuickFixInterface &interface, @@ -5852,33 +5827,33 @@ Class *senderOrReceiverClass(const CppQuickFixInterface &interface, toe.init(interface.semanticInfo().doc, interface.snapshot(), context.bindings()); const QList objectPointerExpressions = toe(objectPointerExpression, objectPointerScope, TypeOfExpression::Preprocess); - QTC_ASSERT(objectPointerExpressions.size() == 1, return 0); + QTC_ASSERT(objectPointerExpressions.size() == 1, return nullptr); Type *objectPointerTypeBase = objectPointerExpressions.first().type().type(); - QTC_ASSERT(objectPointerTypeBase, return 0); + QTC_ASSERT(objectPointerTypeBase, return nullptr); PointerType *objectPointerType = objectPointerTypeBase->asPointerType(); if (!objectPointerType) { objectPointerType = determineConvertedType(objectPointerTypeBase->asNamedType(), context, objectPointerScope, objAccessFunction); } - QTC_ASSERT(objectPointerType, return 0); + QTC_ASSERT(objectPointerType, return nullptr); Type *objectTypeBase = objectPointerType->elementType().type(); // Dereference - QTC_ASSERT(objectTypeBase, return 0); + QTC_ASSERT(objectTypeBase, return nullptr); NamedType *objectType = objectTypeBase->asNamedType(); - QTC_ASSERT(objectType, return 0); + QTC_ASSERT(objectType, return nullptr); ClassOrNamespace *objectClassCON = context.lookupType(objectType->name(), objectPointerScope); if (!objectClassCON) { objectClassCON = objectPointerExpressions.first().binding(); - QTC_ASSERT(objectClassCON, return 0); + QTC_ASSERT(objectClassCON, return nullptr); } - QTC_ASSERT(!objectClassCON->symbols().isEmpty(), return 0); + QTC_ASSERT(!objectClassCON->symbols().isEmpty(), return nullptr); Symbol *objectClassSymbol = skipForwardDeclarations(objectClassCON->symbols()); - QTC_ASSERT(objectClassSymbol, return 0); + QTC_ASSERT(objectClassSymbol, return nullptr); return objectClassSymbol->asClass(); } @@ -5992,7 +5967,7 @@ bool collectConnectArguments(const ExpressionListAST *arguments, // Take care of three-arg version, with 'this' receiver. if (QtMethodAST *receiverMethod = arguments->value->asQtMethod()) { - *arg3 = 0; // Means 'this' + *arg3 = nullptr; // Means 'this' *arg4 = receiverMethod; return true; } diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h index 21dadf0d0f4..20e3c87563e 100644 --- a/src/plugins/cppeditor/cppquickfixes.h +++ b/src/plugins/cppeditor/cppquickfixes.h @@ -65,7 +65,7 @@ class AddIncludeForUndefinedIdentifierOp: public CppQuickFixOperation public: AddIncludeForUndefinedIdentifierOp(const CppQuickFixInterface &interface, int priority, const QString &include); - void perform(); + void perform() override; private: QString m_include; @@ -383,7 +383,7 @@ public: class ExtractFunction : public CppQuickFixFactory { public: - typedef std::function FunctionNameGetter; + using FunctionNameGetter = std::function; ExtractFunction(FunctionNameGetter functionNameGetter = FunctionNameGetter()); void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp index 1b9d51851a4..822ec44ff99 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.cpp +++ b/src/plugins/cppeditor/cpptypehierarchy.cpp @@ -59,7 +59,7 @@ enum ItemRole { QStandardItem *itemForClass(const CppClass &cppClass) { - QStandardItem *item = new QStandardItem; + auto item = new QStandardItem; item->setFlags(item->flags() | Qt::ItemIsDragEnabled); item->setData(cppClass.name, Qt::DisplayRole); if (cppClass.name != cppClass.qualifiedName) @@ -88,8 +88,7 @@ namespace CppEditor { namespace Internal { // CppTypeHierarchyWidget -CppTypeHierarchyWidget::CppTypeHierarchyWidget() : - QWidget(0) +CppTypeHierarchyWidget::CppTypeHierarchyWidget() { m_inspectedClass = new TextEditor::TextEditorLinkLabel(this); m_inspectedClass->setMargin(5); @@ -114,7 +113,7 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget() : m_noTypeHierarchyAvailableLabel->setBackgroundRole(QPalette::Base); m_hierarchyWidget = new QWidget(this); - QVBoxLayout *layout = new QVBoxLayout; + auto layout = new QVBoxLayout; layout->setMargin(0); layout->setSpacing(0); layout->addWidget(m_inspectedClass); @@ -130,18 +129,17 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget() : connect(CppEditorPlugin::instance(), &CppEditorPlugin::typeHierarchyRequested, this, &CppTypeHierarchyWidget::perform); } -CppTypeHierarchyWidget::~CppTypeHierarchyWidget() -{} +CppTypeHierarchyWidget::~CppTypeHierarchyWidget() = default; void CppTypeHierarchyWidget::perform() { showNoTypeHierarchyLabel(); - CppEditor *editor = qobject_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (!editor) return; - CppEditorWidget *widget = qobject_cast(editor->widget()); + auto widget = qobject_cast(editor->widget()); if (!widget) return; diff --git a/src/plugins/cppeditor/cpptypehierarchy.h b/src/plugins/cppeditor/cpptypehierarchy.h index e99d8a180e8..24e7bb95ae1 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.h +++ b/src/plugins/cppeditor/cpptypehierarchy.h @@ -61,9 +61,9 @@ class CppTypeHierarchyModel : public QStandardItemModel public: CppTypeHierarchyModel(QObject *parent); - Qt::DropActions supportedDragActions() const; - QStringList mimeTypes() const; - QMimeData *mimeData(const QModelIndexList &indexes) const; + Qt::DropActions supportedDragActions() const override; + QStringList mimeTypes() const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; }; class CppTypeHierarchyWidget : public QWidget @@ -71,7 +71,7 @@ class CppTypeHierarchyWidget : public QWidget Q_OBJECT public: CppTypeHierarchyWidget(); - virtual ~CppTypeHierarchyWidget(); + ~CppTypeHierarchyWidget() override; void perform(); diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.h b/src/plugins/cppeditor/cppuseselectionsupdater.h index ec18b222f45..b031420e93c 100644 --- a/src/plugins/cppeditor/cppuseselectionsupdater.h +++ b/src/plugins/cppeditor/cppuseselectionsupdater.h @@ -44,7 +44,7 @@ class CppUseSelectionsUpdater : public QObject public: explicit CppUseSelectionsUpdater(TextEditor::TextEditorWidget *editorWidget); - ~CppUseSelectionsUpdater(); + ~CppUseSelectionsUpdater() override; void scheduleUpdate(); void abortSchedule(); From 69281bcdcf20d98ffada890573c5e2df5d832fa1 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 12:24:22 +0100 Subject: [PATCH 38/44] CppEditor: Avoid connecting multiple times to lambda MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppincludehierarchy.cpp:516:8: warning: UniqueConnection is not supported with non-member functions Change-Id: I9d4e743aa2fb4c05df85f566ccea7da98587d31b Reviewed-by: André Hartmann Reviewed-by: Orgad Shaneh --- src/plugins/cppeditor/cppincludehierarchy.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/cppeditor/cppincludehierarchy.cpp b/src/plugins/cppeditor/cppincludehierarchy.cpp index 6bd90f5471b..eaa1b064c82 100644 --- a/src/plugins/cppeditor/cppincludehierarchy.cpp +++ b/src/plugins/cppeditor/cppincludehierarchy.cpp @@ -509,9 +509,9 @@ void CppIncludeHierarchyWidget::syncFromEditorManager() // Use cppDocumentUpdated to catch parsing finished and later file updates. // The timer limits the amount of hierarchy updates. - connect(document, &CppEditorDocument::cppDocumentUpdated, this, [this]() { - m_timer->start(); - }, Qt::UniqueConnection); + connect(document, &CppEditorDocument::cppDocumentUpdated, + m_timer, QOverload<>::of(&QTimer::start), + Qt::UniqueConnection); } // CppIncludeHierarchyFactory From 12f4b1ee865a7c616dfe4f2049e731d2bd4d4dcb Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 10:09:21 +0100 Subject: [PATCH 39/44] CppTools: Modernize Change-Id: I78af9cd4ccddfa4ed744dce96b772ae5644c89d2 Reviewed-by: Orgad Shaneh --- src/plugins/cpptools/builtincursorinfo.cpp | 20 ++++----- .../cpptools/clangdiagnosticconfigswidget.cpp | 12 +++--- src/plugins/cpptools/cppcodeformatter.cpp | 2 +- src/plugins/cpptools/cppcodemodelsettings.cpp | 2 +- .../cpptools/cppcodestylepreferences.cpp | 2 +- src/plugins/cpptools/cppcodestylesettings.cpp | 34 +++------------ src/plugins/cpptools/cppcodestylesettings.h | 42 +++++++++---------- src/plugins/cpptools/cppcompletionassist.cpp | 5 +-- src/plugins/cpptools/cppqtstyleindenter.cpp | 2 +- .../cpptools/cpprefactoringchanges.cpp | 4 +- src/plugins/cpptools/doxygengenerator.cpp | 7 +--- src/plugins/cpptools/doxygengenerator.h | 8 ++-- .../cpptools/insertionpointlocator.cpp | 11 ++--- src/plugins/cpptools/insertionpointlocator.h | 4 +- src/plugins/cpptools/searchsymbols.h | 2 +- 15 files changed, 61 insertions(+), 96 deletions(-) diff --git a/src/plugins/cpptools/builtincursorinfo.cpp b/src/plugins/cpptools/builtincursorinfo.cpp index ffbe196760e..486db2c5033 100644 --- a/src/plugins/cpptools/builtincursorinfo.cpp +++ b/src/plugins/cpptools/builtincursorinfo.cpp @@ -50,7 +50,7 @@ namespace { CursorInfo::Range toRange(const SemanticInfo::Use &use) { - return CursorInfo::Range(use.line, use.column, use.length); + return {use.line, use.column, use.length}; } CursorInfo::Range toRange(int tokenIndex, TranslationUnit *translationUnit) @@ -60,10 +60,9 @@ CursorInfo::Range toRange(int tokenIndex, TranslationUnit *translationUnit) if (column) --column; // adjust the column position. - return CursorInfo::Range( - line, - column +1, - translationUnit->tokenAt(static_cast(tokenIndex)).utf16chars()); + return {line, + column + 1, + translationUnit->tokenAt(static_cast(tokenIndex)).utf16chars()}; } CursorInfo::Range toRange(const QTextCursor &textCursor, @@ -74,10 +73,9 @@ CursorInfo::Range toRange(const QTextCursor &textCursor, cursor.setPosition(static_cast(utf16offset)); const QTextBlock textBlock = cursor.block(); - return CursorInfo::Range( - static_cast(textBlock.blockNumber() + 1), - static_cast(cursor.position() - textBlock.position() + 1), - length); + return {static_cast(textBlock.blockNumber() + 1), + static_cast(cursor.position() - textBlock.position() + 1), + length}; } CursorInfo::Ranges toRanges(const SemanticUses &uses) @@ -216,8 +214,8 @@ private: bool good = false; foreach (const CppTools::SemanticInfo::Use &use, uses) { - unsigned l = static_cast(m_line); - unsigned c = static_cast(m_column); + const auto l = static_cast(m_line); + const auto c = static_cast(m_column); if (l == use.line && c >= use.column && c <= (use.column + use.length)) { good = true; break; diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp index 6d45b428be5..e5ff4cd9f54 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp @@ -51,6 +51,8 @@ #include #include +#include + namespace CppTools { using namespace Constants; @@ -383,7 +385,7 @@ private: } } - QVariant data(const QModelIndex &fullIndex, int role = Qt::DisplayRole) const override final + QVariant data(const QModelIndex &fullIndex, int role = Qt::DisplayRole) const final { if (!fullIndex.isValid() || role == Qt::DecorationRole) return QVariant(); @@ -447,7 +449,7 @@ private: QModelIndex indexForTree(const ClazyChecksTree *tree) const { if (!tree) - return QModelIndex(); + return {}; QModelIndex result; traverse(index(0, 0, QModelIndex()), [&](const QModelIndex &index){ @@ -989,11 +991,11 @@ static void setupTreeView(QTreeView *view, QAbstractItemModel *model, int expand void ClangDiagnosticConfigsWidget::setupTabs() { - m_clangBaseChecks.reset(new CppTools::Ui::ClangBaseChecks); + m_clangBaseChecks = std::make_unique(); m_clangBaseChecksWidget = new QWidget(); m_clangBaseChecks->setupUi(m_clangBaseChecksWidget); - m_clazyChecks.reset(new CppTools::Ui::ClazyChecks); + m_clazyChecks = std::make_unique(); m_clazyChecksWidget = new QWidget(); m_clazyChecks->setupUi(m_clazyChecksWidget); m_clazySortFilterProxyModel = new ClazyChecksSortFilterModel(this); @@ -1030,7 +1032,7 @@ void ClangDiagnosticConfigsWidget::setupTabs() = codeModelSettings()->enableLowerClazyLevels() ? Qt::Checked : Qt::Unchecked; m_clazyChecks->enableLowerLevelsCheckBox->setCheckState(checkEnableLowerClazyLevels); - m_tidyChecks.reset(new CppTools::Ui::TidyChecks); + m_tidyChecks = std::make_unique(); m_tidyChecksWidget = new QWidget(); m_tidyChecks->setupUi(m_tidyChecksWidget); setupTreeView(m_tidyChecks->checksPrefixesTree, m_tidyTreeModel.get()); diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp index 03a7da91806..069359d8691 100644 --- a/src/plugins/cpptools/cppcodeformatter.cpp +++ b/src/plugins/cpptools/cppcodeformatter.cpp @@ -666,7 +666,7 @@ CodeFormatter::State CodeFormatter::state(int belowTop) const if (belowTop < m_currentState.size()) return m_currentState.at(m_currentState.size() - 1 - belowTop); else - return State(); + return {}; } int CodeFormatter::tokenIndex() const diff --git a/src/plugins/cpptools/cppcodemodelsettings.cpp b/src/plugins/cpptools/cppcodemodelsettings.cpp index 35b81a9b7a5..78690cc3b91 100644 --- a/src/plugins/cpptools/cppcodemodelsettings.cpp +++ b/src/plugins/cpptools/cppcodemodelsettings.cpp @@ -36,7 +36,7 @@ using namespace CppTools; static Core::Id initialClangDiagnosticConfigId() -{ return Core::Id(Constants::CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS); } +{ return {Constants::CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS}; } static CppCodeModelSettings::PCHUsage initialPchUsage() { return CppCodeModelSettings::PchUse_BuildSystem; } diff --git a/src/plugins/cpptools/cppcodestylepreferences.cpp b/src/plugins/cpptools/cppcodestylepreferences.cpp index 6a49086d6b1..ea7f100a59e 100644 --- a/src/plugins/cpptools/cppcodestylepreferences.cpp +++ b/src/plugins/cpptools/cppcodestylepreferences.cpp @@ -76,7 +76,7 @@ CppCodeStyleSettings CppCodeStylePreferences::currentCodeStyleSettings() const QVariant v = currentValue(); if (!v.canConvert()) { // warning - return CppCodeStyleSettings(); + return {}; } return v.value(); } diff --git a/src/plugins/cpptools/cppcodestylesettings.cpp b/src/plugins/cpptools/cppcodestylesettings.cpp index 745ea3ab62a..5b07d843345 100644 --- a/src/plugins/cpptools/cppcodestylesettings.cpp +++ b/src/plugins/cpptools/cppcodestylesettings.cpp @@ -67,30 +67,7 @@ using namespace CppTools; // ------------------ CppCodeStyleSettingsWidget -CppCodeStyleSettings::CppCodeStyleSettings() : - indentBlockBraces(false) - , indentBlockBody(true) - , indentClassBraces(false) - , indentEnumBraces(false) - , indentNamespaceBraces(false) - , indentNamespaceBody(false) - , indentAccessSpecifiers(false) - , indentDeclarationsRelativeToAccessSpecifiers(true) - , indentFunctionBody(true) - , indentFunctionBraces(false) - , indentSwitchLabels(false) - , indentStatementsRelativeToSwitchLabels(true) - , indentBlocksRelativeToSwitchLabels(false) - , indentControlFlowRelativeToSwitchLabels(true) - , bindStarToIdentifier(true) - , bindStarToTypeName(false) - , bindStarToLeftSpecifier(false) - , bindStarToRightSpecifier(false) - , extraPaddingForConditionsIfConfusingAlign(true) - , alignAssignments(false) - , preferGetterNameWithoutGetPrefix(true) -{ -} +CppCodeStyleSettings::CppCodeStyleSettings() = default; void CppCodeStyleSettings::toSettings(const QString &category, QSettings *s) const { @@ -203,21 +180,20 @@ bool CppCodeStyleSettings::equals(const CppCodeStyleSettings &rhs) const Utils::optional CppCodeStyleSettings::currentProjectCodeStyle() { ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject(); - using OptSettings = Utils::optional; if (!project) - return OptSettings(); + return {}; ProjectExplorer::EditorConfiguration *editorConfiguration = project->editorConfiguration(); - QTC_ASSERT(editorConfiguration, return OptSettings()); + QTC_ASSERT(editorConfiguration, return {}); TextEditor::ICodeStylePreferences *codeStylePreferences = editorConfiguration->codeStyle(Constants::CPP_SETTINGS_ID); - QTC_ASSERT(codeStylePreferences, return OptSettings()); + QTC_ASSERT(codeStylePreferences, return {}); auto cppCodeStylePreferences = dynamic_cast(codeStylePreferences); if (!cppCodeStylePreferences) - return OptSettings(); + return {}; return cppCodeStylePreferences->currentCodeStyleSettings(); } diff --git a/src/plugins/cpptools/cppcodestylesettings.h b/src/plugins/cpptools/cppcodestylesettings.h index 4e39e05afc9..8b477be354b 100644 --- a/src/plugins/cpptools/cppcodestylesettings.h +++ b/src/plugins/cpptools/cppcodestylesettings.h @@ -45,26 +45,26 @@ class CPPTOOLS_EXPORT CppCodeStyleSettings public: CppCodeStyleSettings(); - bool indentBlockBraces; - bool indentBlockBody; - bool indentClassBraces; - bool indentEnumBraces; - bool indentNamespaceBraces; - bool indentNamespaceBody; - bool indentAccessSpecifiers; - bool indentDeclarationsRelativeToAccessSpecifiers; - bool indentFunctionBody; - bool indentFunctionBraces; - bool indentSwitchLabels; - bool indentStatementsRelativeToSwitchLabels; - bool indentBlocksRelativeToSwitchLabels; - bool indentControlFlowRelativeToSwitchLabels; + bool indentBlockBraces = false; + bool indentBlockBody = true; + bool indentClassBraces = false; + bool indentEnumBraces = false; + bool indentNamespaceBraces = false; + bool indentNamespaceBody = false; + bool indentAccessSpecifiers = false; + bool indentDeclarationsRelativeToAccessSpecifiers = true; + bool indentFunctionBody = true; + bool indentFunctionBraces = false; + bool indentSwitchLabels = false; + bool indentStatementsRelativeToSwitchLabels = true; + bool indentBlocksRelativeToSwitchLabels = false; + bool indentControlFlowRelativeToSwitchLabels = true; // Formatting of pointer and reference declarations, see Overview::StarBindFlag. - bool bindStarToIdentifier; - bool bindStarToTypeName; - bool bindStarToLeftSpecifier; - bool bindStarToRightSpecifier; + bool bindStarToIdentifier = true; + bool bindStarToTypeName = false; + bool bindStarToLeftSpecifier = false; + bool bindStarToRightSpecifier = false; // false: if (a && // b) @@ -75,15 +75,15 @@ public: // but always: while (a && // b) // foo; - bool extraPaddingForConditionsIfConfusingAlign; + bool extraPaddingForConditionsIfConfusingAlign = true; // false: a = a + // b; // true: a = a + // b - bool alignAssignments; + bool alignAssignments = false; - bool preferGetterNameWithoutGetPrefix; + bool preferGetterNameWithoutGetPrefix = true; void toSettings(const QString &category, QSettings *s) const; void fromSettings(const QString &category, const QSettings *s); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index ab125a86c7f..12b226f7562 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1737,9 +1737,8 @@ void InternalCppCompletionAssistProcessor::addClassMembersToCompletion(Scope *sc else addCompletionItem(member); } - std::set::const_iterator citEnd = nestedAnonymouses.end(); - for (std::set::const_iterator cit = nestedAnonymouses.begin(); cit != citEnd; ++cit) - addClassMembersToCompletion(*cit, staticLookup); + for (Class *klass : nestedAnonymouses) + addClassMembersToCompletion(klass, staticLookup); } bool InternalCppCompletionAssistProcessor::completeQtMethod(const QList &results, diff --git a/src/plugins/cpptools/cppqtstyleindenter.cpp b/src/plugins/cpptools/cppqtstyleindenter.cpp index fe9b17828e8..8979ad62e8c 100644 --- a/src/plugins/cpptools/cppqtstyleindenter.cpp +++ b/src/plugins/cpptools/cppqtstyleindenter.cpp @@ -179,7 +179,7 @@ CppCodeStyleSettings CppQtStyleIndenter::codeStyleSettings() const { if (m_cppCodeStylePreferences) return m_cppCodeStylePreferences->currentCodeStyleSettings(); - return CppCodeStyleSettings(); + return {}; } TextEditor::IndentationForBlock CppQtStyleIndenter::indentationForBlocks( diff --git a/src/plugins/cpptools/cpprefactoringchanges.cpp b/src/plugins/cpptools/cpprefactoringchanges.cpp index 138a5a3693b..f3c27073a9e 100644 --- a/src/plugins/cpptools/cpprefactoringchanges.cpp +++ b/src/plugins/cpptools/cpprefactoringchanges.cpp @@ -198,12 +198,12 @@ Utils::ChangeSet::Range CppRefactoringFile::range(unsigned tokenIndex) const unsigned line, column; cppDocument()->translationUnit()->getPosition(token.utf16charsBegin(), &line, &column); const int start = document()->findBlockByNumber(line - 1).position() + column - 1; - return Utils::ChangeSet::Range(start, start + token.utf16chars()); + return {start, static_cast(start + token.utf16chars())}; } Utils::ChangeSet::Range CppRefactoringFile::range(AST *ast) const { - return Utils::ChangeSet::Range(startOf(ast), endOf(ast)); + return {startOf(ast), endOf(ast)}; } int CppRefactoringFile::startOf(unsigned index) const diff --git a/src/plugins/cpptools/doxygengenerator.cpp b/src/plugins/cpptools/doxygengenerator.cpp index 4ae67721cfb..764930cbc91 100644 --- a/src/plugins/cpptools/doxygengenerator.cpp +++ b/src/plugins/cpptools/doxygengenerator.cpp @@ -42,12 +42,7 @@ using namespace CppTools; using namespace CPlusPlus; -DoxygenGenerator::DoxygenGenerator() - : m_addLeadingAsterisks(true) - , m_generateBrief(true) - , m_startComment(true) - , m_style(QtStyle) -{} +DoxygenGenerator::DoxygenGenerator() = default; void DoxygenGenerator::setStyle(DocumentationStyle style) { diff --git a/src/plugins/cpptools/doxygengenerator.h b/src/plugins/cpptools/doxygengenerator.h index 051ecfbd3e2..780525b65e5 100644 --- a/src/plugins/cpptools/doxygengenerator.h +++ b/src/plugins/cpptools/doxygengenerator.h @@ -85,10 +85,10 @@ private: void assignCommentOffset(QTextCursor cursor); QString offsetString() const; - bool m_addLeadingAsterisks; - bool m_generateBrief; - bool m_startComment; - DocumentationStyle m_style; + bool m_addLeadingAsterisks = true; + bool m_generateBrief = true; + bool m_startComment = true; + DocumentationStyle m_style = QtStyle; CPlusPlus::Overview m_printer; QString m_commentOffset; }; diff --git a/src/plugins/cpptools/insertionpointlocator.cpp b/src/plugins/cpptools/insertionpointlocator.cpp index b73d6723064..e6db241d794 100644 --- a/src/plugins/cpptools/insertionpointlocator.cpp +++ b/src/plugins/cpptools/insertionpointlocator.cpp @@ -248,10 +248,7 @@ private: } // end of anonymous namespace -InsertionLocation::InsertionLocation() - : m_line(0) - , m_column(0) -{} +InsertionLocation::InsertionLocation() = default; InsertionLocation::InsertionLocation(const QString &fileName, const QString &prefix, @@ -316,11 +313,9 @@ class HighestValue { Key _key; Value _value; - bool _set; + bool _set = false; public: - HighestValue() - : _key(), _set(false) - {} + HighestValue() = default; HighestValue(const Key &initialKey, const Value &initialValue) : _key(initialKey) diff --git a/src/plugins/cpptools/insertionpointlocator.h b/src/plugins/cpptools/insertionpointlocator.h index 480d1b592b8..c05bc0f6ffa 100644 --- a/src/plugins/cpptools/insertionpointlocator.h +++ b/src/plugins/cpptools/insertionpointlocator.h @@ -63,8 +63,8 @@ private: QString m_fileName; QString m_prefix; QString m_suffix; - unsigned m_line; - unsigned m_column; + unsigned m_line = 0; + unsigned m_column = 0; }; class CPPTOOLS_EXPORT InsertionPointLocator diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index fdda209244a..37e5de08ebf 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -41,7 +41,7 @@ namespace CppTools { class SearchSymbols: protected CPlusPlus::SymbolVisitor { public: - typedef SymbolSearcher::SymbolTypes SymbolTypes; + using SymbolTypes = SymbolSearcher::SymbolTypes; static SymbolTypes AllTypes; From c62f811c4bf706cb5df5c17ddac7484a0c4d7904 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 12:36:07 +0100 Subject: [PATCH 40/44] CppTools: Fix some clazy level0 warnings Use midRef() instead [-Wclazy-qstring-ref] Use multi-arg instead [-Wclazy-qstring-arg] Change-Id: I74d79c4d9595aabd6b2b621743055b807652383c Reviewed-by: Orgad Shaneh --- src/plugins/cpptools/cppcodemodelsettings.cpp | 2 +- src/plugins/cpptools/cppprojectfilecategorizer.cpp | 2 +- src/plugins/cpptools/symbolsfindfilter.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/cpptools/cppcodemodelsettings.cpp b/src/plugins/cpptools/cppcodemodelsettings.cpp index 78690cc3b91..2f8d0b3d42c 100644 --- a/src/plugins/cpptools/cppcodemodelsettings.cpp +++ b/src/plugins/cpptools/cppcodemodelsettings.cpp @@ -90,7 +90,7 @@ static QString convertToNewClazyChecksFormat(const QString &checks) if (checks.size() == 6 && checks.startsWith("level")) { bool ok = false; - const int level = checks.mid(5).toInt(&ok); + const int level = checks.midRef(5).toInt(&ok); QTC_ASSERT(ok, return QString()); return clazyChecksForLevel(level); } diff --git a/src/plugins/cpptools/cppprojectfilecategorizer.cpp b/src/plugins/cpptools/cppprojectfilecategorizer.cpp index ddb841f9de6..35ec2d9263e 100644 --- a/src/plugins/cpptools/cppprojectfilecategorizer.cpp +++ b/src/plugins/cpptools/cppprojectfilecategorizer.cpp @@ -47,7 +47,7 @@ ProjectFileCategorizer::ProjectFileCategorizer(const QString &projectPartName, QString ProjectFileCategorizer::partName(const QString &languageName) const { if (hasMultipleParts()) - return QString::fromLatin1("%1 (%2)").arg(m_partName).arg(languageName); + return QString::fromLatin1("%1 (%2)").arg(m_partName, languageName); return m_partName; } diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp index 1fd758a3fa4..f6bc1f52ba4 100644 --- a/src/plugins/cpptools/symbolsfindfilter.cpp +++ b/src/plugins/cpptools/symbolsfindfilter.cpp @@ -248,9 +248,9 @@ QString SymbolsFindFilter::toolTip(FindFlags findFlags) const if (m_symbolsToSearch & SymbolSearcher::Declarations) types.append(tr("Declarations")); return tr("Scope: %1\nTypes: %2\nFlags: %3") - .arg(searchScope() == SymbolSearcher::SearchGlobal ? tr("All") : tr("Projects")) - .arg(types.join(tr(", "))) - .arg(IFindFilter::descriptionForFindFlags(findFlags)); + .arg(searchScope() == SymbolSearcher::SearchGlobal ? tr("All") : tr("Projects"), + types.join(", "), + IFindFilter::descriptionForFindFlags(findFlags)); } // #pragma mark -- SymbolsFindFilterConfigWidget From 9d25cb872022e08161672cb070735fb52440b625 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 7 Feb 2019 12:53:52 +0100 Subject: [PATCH 41/44] CppTools: Avoid unused values Value stored to 'newPosStart' during its initialization is never read [clang-analyzer-deadcode.DeadStores] Change-Id: Ib8e16cd1bfc3930588e4c10639f463d4f742da0e Reviewed-by: Orgad Shaneh --- src/plugins/cpptools/cppselectionchanger.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/plugins/cpptools/cppselectionchanger.cpp b/src/plugins/cpptools/cppselectionchanger.cpp index e19c1711a61..98437c1cedc 100644 --- a/src/plugins/cpptools/cppselectionchanger.cpp +++ b/src/plugins/cpptools/cppselectionchanger.cpp @@ -560,7 +560,6 @@ void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions) qDebug() << "Is raw literal."; // Start from positions that include quotes. - int newPosStart = positions.astPosStart; int newPosEnd = positions.astPosEnd; // Decrement last position to skip last quote. @@ -572,7 +571,7 @@ void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions) // Start position will be the end position minus the size of the actual contents of the // literal. - newPosStart = newPosEnd - static_cast(firstToken.string->size()); + int newPosStart = newPosEnd - static_cast(firstToken.string->size()); // Skip raw literal parentheses. if (isRawLiteral) @@ -591,13 +590,8 @@ void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions) if (debug) qDebug() << "Selecting inner contents of char literal."; - int newPosStart = positions.astPosStart; - int newPosEnd = positions.astPosEnd; - newPosEnd = newPosEnd - 1; - newPosStart = newPosEnd - static_cast(firstToken.literal->size()); - - positions.astPosStart = newPosStart; - positions.astPosEnd = newPosEnd; + positions.astPosEnd = positions.astPosEnd - 1; + positions.astPosStart = positions.astPosEnd - int(firstToken.literal->size()); } } } else if (ForStatementAST *forStatementAST = ast->asForStatement()) { From 583e6ff5eb445e22b141c97f30b9a0a2a8db6933 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 7 Feb 2019 15:20:58 +0100 Subject: [PATCH 42/44] Toolchains: Fall back to C compiler for output parser creation Otherwise, there will be no output parser for toolchains that register only a C compiler. Change-Id: I3f3448ee85a0dc03701a6c9b21ec23b1d8ca2f22 Reviewed-by: Nikolai Kosjar --- src/plugins/projectexplorer/kitinformation.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index c093678645b..f4da43f0959 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -390,8 +390,11 @@ void ToolChainKitInformation::addToMacroExpander(Kit *kit, Utils::MacroExpander IOutputParser *ToolChainKitInformation::createOutputParser(const Kit *k) const { - ToolChain *tc = toolChain(k, Constants::CXX_LANGUAGE_ID); - return tc ? tc->outputParser() : nullptr; + for (const Core::Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) { + if (const ToolChain * const tc = toolChain(k, langId)) + return tc->outputParser(); + } + return nullptr; } QSet ToolChainKitInformation::availableFeatures(const Kit *k) const From dbf7c9f658ce9a0984bd4704b73f02803b062eb2 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 8 Feb 2019 10:54:32 +0100 Subject: [PATCH 43/44] LSP: Fix build Change-Id: Ic43ce5e2f55dc450fb0a4628dc5de22a4a6f3dbd Reviewed-by: Christian Stenger --- src/libs/languageserverprotocol/languagefeatures.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index 29d60dc7f73..6672bbc2b87 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -25,6 +25,8 @@ #include "languagefeatures.h" +#include + namespace LanguageServerProtocol { constexpr const char HoverRequest::methodName[]; @@ -406,7 +408,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) emplace(result); return; } - emplace(nullptr); + emplace(nullptr); } bool CodeAction::isValid(QStringList *error) const From e27744e966d7c689b69f515b60972b0a17acc4ed Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 8 Feb 2019 11:24:47 +0100 Subject: [PATCH 44/44] macOS: Fix broken Info.plist Fixup of dd0156d1facc5422464dc1b430696a0b63db605f For some reason Xcode removed the closing tags when editing the Info.plist file in its editor... Change-Id: Ib9e53dce0be13ad0bb03ae46386c632b448b6a9a Reviewed-by: Vikas Pachdha --- src/app/app-Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/app-Info.plist b/src/app/app-Info.plist index d87130d5e49..c2f2ce95f5c 100644 --- a/src/app/app-Info.plist +++ b/src/app/app-Info.plist @@ -274,3 +274,5 @@ A user application wants to access the photo library. NSRemindersUsageDescription A user application wants to access the reminders. + +