diff --git a/README.md b/README.md index 87bc9e34fbe..dbaa481626e 100644 --- a/README.md +++ b/README.md @@ -242,14 +242,14 @@ http://llvm.org/docs/GettingStarted.html#git-mirror: 1. Clone LLVM and switch to a suitable branch - git clone http://llvm.org/git/llvm.git + git clone https://git.llvm.org/git/llvm.git/ cd llvm git checkout release_39 2. Clone Clang into llvm/tools/clang and switch to a suitable branch cd tools - git clone http://llvm.org/git/clang.git + git clone https://git.llvm.org/git/clang.git/ cd clang git checkout release_39 diff --git a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp index 53e7c7533ad..9cd0e2a9531 100644 --- a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp @@ -388,7 +388,8 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size) } struct stat statBuffer; - fstat(m_fileHandle, &statBuffer); + if (fstat(m_fileHandle, &statBuffer) == -1) + return false; int fileSize = statBuffer.st_size; if (fileSize < size) { @@ -457,7 +458,8 @@ bool SharedMemory::attachInternal(QSharedMemory::AccessMode mode) } struct stat statBuffer; - fstat(m_fileHandle, &statBuffer); + if (fstat(m_fileHandle, &statBuffer) == -1) + return false; int size = statBuffer.st_size; int protection = mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_WRITE; diff --git a/src/libs/clangsupport/clangsupport_global.h b/src/libs/clangsupport/clangsupport_global.h index b2fc639291a..f69b11b7d2e 100644 --- a/src/libs/clangsupport/clangsupport_global.h +++ b/src/libs/clangsupport/clangsupport_global.h @@ -154,7 +154,7 @@ struct MessageTrait \ using MixinHighlightingTypes = Utils::SizedArray; struct HighlightingTypes { - HighlightingType mainHighlightingType; + HighlightingType mainHighlightingType = HighlightingType::Invalid; MixinHighlightingTypes mixinHighlightingTypes; }; diff --git a/src/libs/timeline/timelineabstractrenderer.h b/src/libs/timeline/timelineabstractrenderer.h index 0412371efa3..444e143171c 100644 --- a/src/libs/timeline/timelineabstractrenderer.h +++ b/src/libs/timeline/timelineabstractrenderer.h @@ -35,8 +35,6 @@ namespace Timeline { -class TimelineRenderPass; -class TimelineRenderState; class TIMELINE_EXPORT TimelineAbstractRenderer : public QQuickItem { diff --git a/src/libs/timeline/timelinerenderer.h b/src/libs/timeline/timelinerenderer.h index 9965458d0b9..09814d07f7a 100644 --- a/src/libs/timeline/timelinerenderer.h +++ b/src/libs/timeline/timelinerenderer.h @@ -35,8 +35,6 @@ namespace Timeline { -class TimelineRenderPass; -class TimelineRenderState; class TIMELINE_EXPORT TimelineRenderer : public TimelineAbstractRenderer { diff --git a/src/libs/utils/camelhumpmatcher.cpp b/src/libs/utils/camelhumpmatcher.cpp index 0661499c7a3..cb99cff1372 100644 --- a/src/libs/utils/camelhumpmatcher.cpp +++ b/src/libs/utils/camelhumpmatcher.cpp @@ -73,6 +73,7 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp( const QLatin1String uppercaseWordContinuation("[a-z0-9_]*"); const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?"); const QLatin1String upperSnakeWordContinuation("[A-Z0-9]*_"); + keyRegExp += "(?:"; for (const QChar &c : pattern) { if (!c.isLetter()) { if (c == question) @@ -108,6 +109,8 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp( first = false; } + keyRegExp += ")|(" + QRegularExpression::escape(pattern) + ')'; + return QRegularExpression(keyRegExp); } diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 764cf543a1b..912a563fa83 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -74,13 +74,13 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) m_description = line; if (m_iteration > 1) m_description.append(' ' + tr("(iteration %1)").arg(m_iteration)); - TestResultPtr testResult = TestResultPtr(new GTestResult); + TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); testResult->setResult(Result::MessageInternal); testResult->setDescription(m_description); m_futureInterface.reportResult(testResult); m_description.clear(); } else if (disabledTests.exactMatch(line)) { - TestResultPtr testResult = TestResultPtr(new GTestResult); + TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); testResult->setResult(Result::MessageDisabledTests); int disabled = disabledTests.cap(1).toInt(); testResult->setDescription(tr("You have %n disabled test(s).", 0, disabled)); @@ -98,7 +98,6 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) m_futureInterface.reportResult(TestResultPtr(testResult)); m_currentTestName.clear(); m_currentTestSet.clear(); - m_normalizedCurrentTestSet.clear(); } else if (newTestStarts.exactMatch(line)) { setCurrentTestName(newTestStarts.cap(1)); TestResultPtr testResult = TestResultPtr(createDefaultResult()); @@ -112,7 +111,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) m_futureInterface.reportResult(testResult); } else if (newTestSetStarts.exactMatch(line)) { setCurrentTestSet(newTestSetStarts.cap(1)); - TestResultPtr testResult = TestResultPtr(new GTestResult); + TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); testResult->setResult(Result::MessageCurrentTest); testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet)); m_futureInterface.reportResult(testResult); @@ -163,39 +162,21 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) void GTestOutputReader::setCurrentTestSet(const QString &testSet) { m_currentTestSet = testSet; - m_normalizedCurrentTestSet = normalizeName(testSet); } void GTestOutputReader::setCurrentTestName(const QString &testName) { m_currentTestName = testName; - m_normalizedTestName = normalizeTestName(testName); -} - -QString GTestOutputReader::normalizeName(const QString &name) const -{ - static QRegExp parameterIndex("/\\d+"); - - QString nameWithoutParameterIndices = name; - nameWithoutParameterIndices.remove(parameterIndex); - - return nameWithoutParameterIndices.split('/').last(); -} - -QString GTestOutputReader::normalizeTestName(const QString &testname) const -{ - QString nameWithoutTypeParam = testname.split(',').first(); - - return normalizeName(nameWithoutTypeParam); } GTestResult *GTestOutputReader::createDefaultResult() const { - GTestResult *result = new GTestResult(m_executable, m_currentTestName); + GTestResult *result = new GTestResult(m_executable, m_projectFile, m_currentTestName); result->setTestSetName(m_currentTestSet); result->setIteration(m_iteration); - const TestTreeItem *testItem = findTestTreeItemForCurrentLine(); + const TestTreeItem *testItem = result->findTestTreeItem(); + if (testItem && testItem->line()) { result->setFileName(testItem->filePath()); result->setLine(static_cast(testItem->line())); @@ -204,43 +185,5 @@ GTestResult *GTestOutputReader::createDefaultResult() const return result; } -const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const -{ - const auto item = TestTreeModel::instance()->findNonRootItem([&](const Utils::TreeItem *item) { - const TestTreeItem &treeItem = static_cast(*item); - return matches(treeItem); - }); - - return static_cast(item); -} - -bool GTestOutputReader::matches(const TestTreeItem &treeItem) const -{ - if (treeItem.proFile() != m_projectFile) - return false; - - if (m_currentTestSet.isEmpty()) - return matchesTestCase(treeItem); - - return matchesTestFunctionOrSet(treeItem); -} - -bool GTestOutputReader::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const -{ - if (treeItem.type() != TestTreeItem::TestFunctionOrSet) - return false; - - const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name(); - return testItemTestSet == m_normalizedCurrentTestSet; -} - -bool GTestOutputReader::matchesTestCase(const TestTreeItem &treeItem) const -{ - if (treeItem.type() != TestTreeItem::TestCase) - return false; - - return treeItem.name() == m_normalizedTestName; -} - } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtestoutputreader.h b/src/plugins/autotest/gtest/gtestoutputreader.h index e46e29fcd3f..ebe59cd64d4 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.h +++ b/src/plugins/autotest/gtest/gtestoutputreader.h @@ -50,20 +50,12 @@ protected: private: void setCurrentTestSet(const QString &testSet); void setCurrentTestName(const QString &testName); - QString normalizeName(const QString &name) const; - QString normalizeTestName(const QString &testname) const; GTestResult *createDefaultResult() const; - const TestTreeItem *findTestTreeItemForCurrentLine() const; - bool matches(const TestTreeItem &treeItem) const; - bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const; - bool matchesTestCase(const TestTreeItem &treeItem) const; QString m_executable; QString m_projectFile; QString m_currentTestName; - QString m_normalizedTestName; QString m_currentTestSet; - QString m_normalizedCurrentTestSet; QString m_description; int m_iteration = 1; }; diff --git a/src/plugins/autotest/gtest/gtestresult.cpp b/src/plugins/autotest/gtest/gtestresult.cpp index cbccaea837e..5945ebf5aa9 100644 --- a/src/plugins/autotest/gtest/gtestresult.cpp +++ b/src/plugins/autotest/gtest/gtestresult.cpp @@ -24,17 +24,20 @@ ****************************************************************************/ #include "gtestresult.h" +#include "../testtreemodel.h" +#include "../testtreeitem.h" namespace Autotest { namespace Internal { -GTestResult::GTestResult(const QString &name) - : TestResult(name) +GTestResult::GTestResult(const QString &projectFile, const QString &name) + : TestResult(name), m_projectFile(projectFile) { } -GTestResult::GTestResult(const QString &executable, const QString &name) - : TestResult(executable, name) +GTestResult::GTestResult(const QString &executable, const QString &projectFile, + const QString &name) + : TestResult(executable, name), m_projectFile(projectFile) { } @@ -68,5 +71,60 @@ bool GTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermedi return isTest() && gtOther->isTestSet(); } +static QString normalizeName(const QString &name) +{ + static QRegExp parameterIndex("/\\d+"); + + QString nameWithoutParameterIndices = name; + nameWithoutParameterIndices.remove(parameterIndex); + + return nameWithoutParameterIndices.split('/').last(); +} + +static QString normalizeTestName(const QString &testname) +{ + QString nameWithoutTypeParam = testname.split(',').first(); + + return normalizeName(nameWithoutTypeParam); +} + +const TestTreeItem *GTestResult::findTestTreeItem() const +{ + const auto item = TestTreeModel::instance()->findNonRootItem([this](const Utils::TreeItem *item) { + const TestTreeItem &treeItem = static_cast(*item); + return matches(treeItem); + }); + + return static_cast(item); +} + +bool GTestResult::matches(const TestTreeItem &treeItem) const +{ + if (treeItem.proFile() != m_projectFile) + return false; + + if (isTest()) + return matchesTestCase(treeItem); + + return matchesTestFunctionOrSet(treeItem); +} + +bool GTestResult::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestFunctionOrSet) + return false; + + const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name(); + return testItemTestSet == normalizeName(m_testSetName); +} + +bool GTestResult::matchesTestCase(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestCase) + return false; + + return treeItem.name() == normalizeTestName(name()); +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtestresult.h b/src/plugins/autotest/gtest/gtestresult.h index 491fe41662f..88e5476085c 100644 --- a/src/plugins/autotest/gtest/gtestresult.h +++ b/src/plugins/autotest/gtest/gtestresult.h @@ -33,17 +33,25 @@ namespace Internal { class GTestResult : public TestResult { public: - explicit GTestResult(const QString &name = QString()); - GTestResult(const QString &executable, const QString &name); + GTestResult(const QString &projectFile, const QString &name = QString()); + GTestResult(const QString &executable, const QString &projectFile, const QString &name); const QString outputString(bool selected) const override; void setTestSetName(const QString &testSetName) { m_testSetName = testSetName; } void setIteration(int iteration) { m_iteration = iteration; } bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override; + virtual const TestTreeItem *findTestTreeItem() const override; + private: bool isTest() const { return m_testSetName.isEmpty(); } bool isTestSet() const { return !m_testSetName.isEmpty(); } + + bool matches(const TestTreeItem &item) const; + bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const; + bool matchesTestCase(const TestTreeItem &treeItem) const; + QString m_testSetName; + QString m_projectFile; int m_iteration = 1; }; diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp index ddc010ef0d2..aaeef64a1a6 100644 --- a/src/plugins/autotest/testnavigationwidget.cpp +++ b/src/plugins/autotest/testnavigationwidget.cpp @@ -301,25 +301,7 @@ void TestNavigationWidget::onRunThisTestTriggered(TestRunMode runMode) return; TestTreeItem *item = static_cast(sourceIndex.internalPointer()); - TestConfiguration *configuration; - switch (runMode) { - case TestRunMode::Run: - case TestRunMode::RunWithoutDeploy: - configuration = item->testConfiguration(); - break; - case TestRunMode::Debug: - case TestRunMode::DebugWithoutDeploy: - configuration = item->debugConfiguration(); - break; - default: - configuration = nullptr; - } - - if (configuration) { - TestRunner *runner = TestRunner::instance(); - runner->setSelectedTests({configuration}); - runner->prepareToRunTests(runMode); - } + TestRunner::instance()->runTest(runMode, item); } TestNavigationWidgetFactory::TestNavigationWidgetFactory() diff --git a/src/plugins/autotest/testresult.cpp b/src/plugins/autotest/testresult.cpp index 2dcd9dda70a..96db2b10c63 100644 --- a/src/plugins/autotest/testresult.cpp +++ b/src/plugins/autotest/testresult.cpp @@ -58,6 +58,11 @@ const QString TestResult::outputString(bool selected) const return selected ? m_description : m_description.split('\n').first(); } +const TestTreeItem *TestResult::findTestTreeItem() const +{ + return nullptr; +} + Result::Type TestResult::resultFromString(const QString &resultString) { if (resultString == "pass") diff --git a/src/plugins/autotest/testresult.h b/src/plugins/autotest/testresult.h index a7414f85d36..d094c345ed3 100644 --- a/src/plugins/autotest/testresult.h +++ b/src/plugins/autotest/testresult.h @@ -35,6 +35,8 @@ namespace Autotest { namespace Internal { +class TestTreeItem; + namespace Result{ enum Type { Pass, FIRST_TYPE = Pass, @@ -76,6 +78,7 @@ public: virtual ~TestResult() {} virtual const QString outputString(bool selected) const; + virtual const TestTreeItem *findTestTreeItem() const; QString executable() const { return m_executable; } QString name() const { return m_name; } diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index 332a518d94f..c3317fdfe96 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -144,7 +144,7 @@ TestResultsPane::TestResultsPane(QObject *parent) : connect(m_treeView, &Utils::TreeView::customContextMenuRequested, this, &TestResultsPane::onCustomContextMenuRequested); connect(m_treeView, &ResultsTreeView::copyShortcutTriggered, [this] () { - onCopyItemTriggered(m_treeView->currentIndex()); + onCopyItemTriggered(getTestResult(m_treeView->currentIndex())); }); connect(m_model, &TestResultModel::requestExpansion, [this] (QModelIndex idx) { m_treeView->expand(m_filterModel->mapFromSource(idx)); @@ -562,11 +562,12 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos) { const bool resultsAvailable = m_filterModel->hasResults(); const bool enabled = !m_testRunning && resultsAvailable; - const QModelIndex clicked = m_treeView->indexAt(pos); + const TestResult *clicked = getTestResult(m_treeView->indexAt(pos)); QMenu menu; + QAction *action = new QAction(tr("Copy"), &menu); action->setShortcut(QKeySequence(QKeySequence::Copy)); - action->setEnabled(resultsAvailable); + action->setEnabled(resultsAvailable && clicked); connect(action, &QAction::triggered, [this, clicked] () { onCopyItemTriggered(clicked); }); @@ -582,14 +583,36 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos) connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered); menu.addAction(action); + action = new QAction(tr("Run This Test"), &menu); + action->setEnabled(clicked && clicked->findTestTreeItem()); + connect(action, &QAction::triggered, this, [this, clicked] { + onRunThisTestTriggered(TestRunMode::Run, clicked); + }); + menu.addAction(action); + + action = new QAction(tr("Debug This Test"), &menu); + action->setEnabled(clicked && clicked->findTestTreeItem()); + connect(action, &QAction::triggered, this, [this, clicked] { + onRunThisTestTriggered(TestRunMode::Debug, clicked); + }); + menu.addAction(action); + menu.exec(m_treeView->mapToGlobal(pos)); } -void TestResultsPane::onCopyItemTriggered(const QModelIndex &idx) +const TestResult *TestResultsPane::getTestResult(const QModelIndex &idx) { if (!idx.isValid()) - return; + return nullptr; + const TestResult *result = m_filterModel->testResult(idx); + QTC_CHECK(result); + + return result; +} + +void TestResultsPane::onCopyItemTriggered(const TestResult *result) +{ QTC_ASSERT(result, return); QApplication::clipboard()->setText(result->outputString(true)); } @@ -614,6 +637,16 @@ void TestResultsPane::onSaveWholeTriggered() } } +void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResult *result) +{ + QTC_ASSERT(result, return); + + const TestTreeItem *item = result->findTestTreeItem(); + + if (item) + TestRunner::instance()->runTest(runMode, item); +} + void TestResultsPane::toggleOutputStyle() { const bool displayText = m_outputWidget->currentIndex() == 0; diff --git a/src/plugins/autotest/testresultspane.h b/src/plugins/autotest/testresultspane.h index 6b837055672..911396b1939 100644 --- a/src/plugins/autotest/testresultspane.h +++ b/src/plugins/autotest/testresultspane.h @@ -52,6 +52,7 @@ namespace Internal { class TestResultModel; class TestResultFilterModel; +class TestResult; class ResultsTreeView : public Utils::TreeView { @@ -109,9 +110,11 @@ private: void onScrollBarRangeChanged(int, int max); void updateRunActions(); void onCustomContextMenuRequested(const QPoint &pos); - void onCopyItemTriggered(const QModelIndex &idx); + const TestResult *getTestResult(const QModelIndex &idx); + void onCopyItemTriggered(const TestResult *result); void onCopyWholeTriggered(); void onSaveWholeTriggered(); + void onRunThisTestTriggered(TestRunMode runMode, const TestResult *result); void toggleOutputStyle(); QString getWholeOutput(const QModelIndex &parent = QModelIndex()); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index b263f44e557..81bc2c7451d 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -31,6 +31,7 @@ #include "testrunconfiguration.h" #include "testsettings.h" #include "testoutputreader.h" +#include "testtreeitem.h" #include #include @@ -106,6 +107,28 @@ void TestRunner::setSelectedTests(const QList &selected) m_selectedTests = selected; } +void TestRunner::runTest(TestRunMode mode, const TestTreeItem *item) +{ + TestConfiguration *configuration; + switch (mode) { + case TestRunMode::Run: + case TestRunMode::RunWithoutDeploy: + configuration = item->testConfiguration(); + break; + case TestRunMode::Debug: + case TestRunMode::DebugWithoutDeploy: + configuration = item->debugConfiguration(); + break; + default: + configuration = nullptr; + } + + if (configuration) { + setSelectedTests({configuration}); + prepareToRunTests(mode); + } +} + static QString processInformation(const QProcess &proc) { QString information("\nCommand line: " + proc.program() + ' ' + proc.arguments().join(' ')); diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index 004c4f48313..0638401ca08 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -55,6 +55,7 @@ public: ~TestRunner(); void setSelectedTests(const QList &selected); + void runTest(TestRunMode mode, const TestTreeItem *item); bool isTestRunning() const { return m_executingTests; } void prepareToRunTests(TestRunMode mode); diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.h b/src/plugins/autotoolsprojectmanager/autotoolsproject.h index 2183ee92b73..b9016bdcc04 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.h @@ -39,7 +39,6 @@ namespace AutotoolsProjectManager { namespace Internal { class MakefileParserThread; -class AutotoolsTarget; /** * @brief Implementation of the ProjectExplorer::Project interface. diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index ff1cf8f0750..8a953af9c32 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -313,125 +313,111 @@ void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) futureInterface.reportFinished(); } -class IpcSender : public IpcSenderInterface -{ -public: - IpcSender(ClangBackEnd::ClangCodeModelConnectionClient &connectionClient) - : m_connection(connectionClient) - {} - - void end() override; - void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; - void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; - void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; - void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; - void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; - void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; - void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; - void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; - void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; - void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; - void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; - void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; - -private: - ClangBackEnd::ClangCodeModelConnectionClient &m_connection; -}; +IpcSender::IpcSender(ClangCodeModelConnectionClient *connectionClient) + : m_connection(connectionClient) +{} void IpcSender::end() { - QTC_CHECK(m_connection.isConnected()); - qCDebug(log) << ">>>" << ClangBackEnd::EndMessage(); - m_connection.sendEndMessage(); + QTC_CHECK(m_connection->isConnected()); + qCDebug(log) << ">>>" << ClangBackEnd::EndMessage(); + m_connection->sendEndMessage(); } void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().registerTranslationUnitsForEditor(message); + m_connection->serverProxy().registerTranslationUnitsForEditor(message); } void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().updateTranslationUnitsForEditor(message); + m_connection->serverProxy().updateTranslationUnitsForEditor(message); } void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().unregisterTranslationUnitsForEditor(message); + m_connection->serverProxy().unregisterTranslationUnitsForEditor(message); } void IpcSender::registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().registerProjectPartsForEditor(message); + m_connection->serverProxy().registerProjectPartsForEditor(message); } void IpcSender::unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().unregisterProjectPartsForEditor(message); + m_connection->serverProxy().unregisterProjectPartsForEditor(message); } void IpcSender::registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().registerUnsavedFilesForEditor(message); + m_connection->serverProxy().registerUnsavedFilesForEditor(message); } void IpcSender::unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().unregisterUnsavedFilesForEditor(message); + m_connection->serverProxy().unregisterUnsavedFilesForEditor(message); } void IpcSender::completeCode(const CompleteCodeMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().completeCode(message); + m_connection->serverProxy().completeCode(message); } void IpcSender::requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().requestDocumentAnnotations(message); + m_connection->serverProxy().requestDocumentAnnotations(message); } void IpcSender::requestReferences(const RequestReferencesMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().requestReferences(message); + m_connection->serverProxy().requestReferences(message); } void IpcSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().requestFollowSymbol(message); + m_connection->serverProxy().requestFollowSymbol(message); } void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) { - QTC_CHECK(m_connection.isConnected()); + QTC_CHECK(m_connection->isConnected()); qCDebug(log) << ">>>" << message; - m_connection.serverProxy().updateVisibleTranslationUnits(message); + m_connection->serverProxy().updateVisibleTranslationUnits(message); } -class DummyIpcSender : public IpcSenderInterface +bool IpcSender::isConnected() const +{ + return m_connection && m_connection->isConnected(); +} + +class DummyIpcSender : public IpcSender { public: + DummyIpcSender() : IpcSender(nullptr) {} + void end() override {} void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &) override {} void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &) override {} @@ -451,7 +437,7 @@ enum { backEndStartTimeOutInMs = 10000 }; IpcCommunicator::IpcCommunicator() : m_connection(&m_ipcReceiver) - , m_ipcSender(new DummyIpcSender) + , m_ipcSender(new DummyIpcSender()) { m_backendStartTimeOut.setSingleShot(true); connect(&m_backendStartTimeOut, &QTimer::timeout, @@ -804,7 +790,7 @@ void IpcCommunicator::onConnectedToBackend() logRestartedDueToUnexpectedFinish(); m_ipcReceiver.reset(); - m_ipcSender.reset(new IpcSender(m_connection)); + m_ipcSender.reset(new IpcSender(&m_connection)); initializeBackendWithCurrentData(); } @@ -869,9 +855,9 @@ void IpcCommunicator::initializeBackendWithCurrentData() emit backendReinitialized(); } -IpcSenderInterface *IpcCommunicator::setIpcSender(IpcSenderInterface *ipcSender) +IpcSender *IpcCommunicator::setIpcSender(IpcSender *ipcSender) { - IpcSenderInterface *previousMessageSender = m_ipcSender.take(); + IpcSender *previousMessageSender = m_ipcSender.take(); m_ipcSender.reset(ipcSender); return previousMessageSender; } diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index 589c0357818..5c7eb6f9225 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -115,24 +115,30 @@ private: QHash> m_followTable; }; -class IpcSenderInterface +class IpcSender : public ClangBackEnd::ClangCodeModelServerInterface { public: - virtual ~IpcSenderInterface() {} + IpcSender(ClangBackEnd::ClangCodeModelConnectionClient *connectionClient); - virtual void end() = 0; - virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0; - virtual void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) = 0; - virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0; - virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0; - virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0; - virtual void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) = 0; - virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0; - virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0; - virtual void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) = 0; - virtual void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) = 0; - virtual void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) = 0; - virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0; + void end() override; + void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; + void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; + void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; + void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; + void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; + void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; + void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; + void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; + void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; + void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; + void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; + void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; + +private: + bool isConnected() const; + +private: + ClangBackEnd::ClangCodeModelConnectionClient *m_connection = nullptr; }; class IpcCommunicator : public QObject @@ -193,7 +199,7 @@ public: bool isNotWaitingForCompletion() const; public: // for tests - IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender); + IpcSender *setIpcSender(IpcSender *ipcSender); void killBackendProcess(); signals: // for tests @@ -226,7 +232,7 @@ private: IpcReceiver m_ipcReceiver; ClangBackEnd::ClangCodeModelConnectionClient m_connection; QTimer m_backendStartTimeOut; - QScopedPointer m_ipcSender; + QScopedPointer m_ipcSender; int m_connectedCount = 0; }; diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 7a5e0446d8e..9165ccca29c 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -26,7 +26,6 @@ #include "clangcodecompletion_test.h" #include "clangautomationutils.h" -#include "../clangbackendipcintegration.h" #include "../clangcompletionassistinterface.h" #include "../clangmodelmanagersupport.h" @@ -61,9 +60,6 @@ namespace { QString qrcPath(const QByteArray relativeFilePath) { return QLatin1String(":/unittests/ClangCodeModel/") + QString::fromUtf8(relativeFilePath); } -QString fileName(const QString &filePath) -{ return QFileInfo(filePath).fileName(); } - CppTools::Tests::TemporaryDir *globalTemporaryDir() { static CppTools::Tests::TemporaryDir dir; @@ -71,77 +67,6 @@ CppTools::Tests::TemporaryDir *globalTemporaryDir() return &dir; } -struct LogOutput -{ - LogOutput(const QString &text) : text(text.toUtf8()) {} - LogOutput(const char text[]) : text(text) {} - QByteArray text; -}; - -void printRawLines(QTextStream &out, const QList &lines) -{ - foreach (const QByteArray &line, lines) { - QByteArray rawLine = line; - rawLine.prepend("\""); - rawLine.append("\\n\"\n"); - out << rawLine; - } -} - -void printDifference(const LogOutput &actual, const LogOutput &expected) -{ - QTextStream out(stderr); - - const QList actualLines = actual.text.split('\n'); - const QList expectedLines = expected.text.split('\n'); - - out << "-- ACTUAL:\n"; - printRawLines(out, actualLines); - out << "-- EXPECTED:\n"; - printRawLines(out, expectedLines); - - if (actualLines.size() != expectedLines.size()) { - out << "-- DIFFERENCE IN LINE COUNT:\n" - << " actual lines:" << actualLines.size() << '\n' - << " expected lines:" << expectedLines.size() << '\n'; - } - - out << "-- FIRST LINE THAT DIFFERS:\n"; - auto actualLineIt = actualLines.cbegin(); - auto expectedLineIt = expectedLines.cbegin(); - int line = 1; - forever { - if (actualLineIt == actualLines.cend() && expectedLineIt != expectedLines.cend()) { - out << " line: " << line << '\n'; - out << " actual: \n"; - out << " expected: \"" << *expectedLineIt << "\"\n"; - } else if (actualLineIt != actualLines.cend() && expectedLineIt == expectedLines.cend()) { - out << " line: " << line << '\n'; - out << " actual: \"" << *actualLineIt << "\"\n"; - out << " expected: \n"; - } else { - if (*actualLineIt != *expectedLineIt) { - out << " line: " << line << '\n'; - out << " actual: \"" << *actualLineIt << "\"\n"; - out << " expected: \"" << *expectedLineIt << "\"\n"; - return; - } - } - - ++line; - ++actualLineIt; - ++expectedLineIt; - } -} - -bool compare(const LogOutput &actual, const LogOutput &expected) -{ - const bool isEqual = actual.text == expected.text; - if (!isEqual) - printDifference(actual, expected); - return isEqual; -} - QByteArray readFile(const QString &filePath) { QFile file(filePath); @@ -186,197 +111,6 @@ private: Core::IDocument::ReloadSetting m_previousValue; }; -class ChangeIpcSender -{ -public: - ChangeIpcSender(IpcSenderInterface *ipcSender) - { - auto &ipc = ModelManagerSupportClang::instance()->ipcCommunicator(); - m_previousSender = ipc.setIpcSender(ipcSender); - } - - ~ChangeIpcSender() - { - auto &ipc = ModelManagerSupportClang::instance()->ipcCommunicator(); - ipc.setIpcSender(m_previousSender); - } - -private: - IpcSenderInterface *m_previousSender; -}; - -QString toString(const FileContainer &fileContainer) -{ - QString out; - QTextStream ts(&out); - ts << " Path: " << fileName(fileContainer.filePath().toString()) - << " ProjectPart: " << fileName(fileContainer.projectPartId().toString()) << "\n"; - return out; -} - -QString toString(const QVector &fileContainers) -{ - QString out; - QTextStream ts(&out); - foreach (const FileContainer &fileContainer, fileContainers) - ts << toString(fileContainer); - return out; -} - -QString toString(const ProjectPartContainer &projectPartContainer) -{ - QString out; - QTextStream ts(&out); - ts << " ProjectPartContainer" - << " id: " << fileName(projectPartContainer.projectPartId().toString()); - return out; -} - -QString toString(const QVector &projectPartContainers) -{ - QString out; - QTextStream ts(&out); - foreach (const ProjectPartContainer &projectPartContainer, projectPartContainers) - ts << toString(projectPartContainer); - return out; -} - -QString toString(const EndMessage &) -{ - return QLatin1String("EndMessage\n"); -} - -QString toString(const RegisterTranslationUnitForEditorMessage &message) -{ - QString out; - QTextStream ts(&out); - - ts << "RegisterTranslationUnitForEditorMessage\n" - << toString(message.fileContainers()); - return out; -} - -QString toString(const UpdateTranslationUnitsForEditorMessage &message) -{ - QString out; - QTextStream ts(&out); - - ts << "UpdateTranslationUnitForEditorMessage\n" - << toString(message.fileContainers()); - return out; -} - -QString toString(const UnregisterTranslationUnitsForEditorMessage &) -{ - return QLatin1String("UnregisterTranslationUnitsForEditorMessage\n"); -} - -QString toString(const RegisterProjectPartsForEditorMessage &message) -{ - QString out; - QTextStream ts(&out); - - ts << "RegisterProjectPartsForEditorMessage\n" - << toString(message.projectContainers()) << "\n"; - return out; -} - -QString toString(const UnregisterProjectPartsForEditorMessage &message) -{ - QString out; - QTextStream ts(&out); - - ts << "UnregisterProjectPartsForEditorMessage\n" - << message.projectPartIds().join(Utf8String::fromUtf8(",")).toByteArray() << "\n"; - return out; -} - -QString toString(const RegisterUnsavedFilesForEditorMessage &message) -{ - QString out; - QTextStream ts(&out); - - ts << "RegisterUnsavedFilesForEditorMessage\n" - << toString(message.fileContainers()); - return out; -} - -QString toString(const UnregisterUnsavedFilesForEditorMessage &) -{ - return QLatin1String("UnregisterUnsavedFilesForEditorMessage\n"); -} - -QString toString(const CompleteCodeMessage &) -{ - return QLatin1String("CompleteCodeMessage\n"); -} - -QString toString(const RequestDocumentAnnotationsMessage &) -{ - return QStringLiteral("RequestDocumentAnnotationsMessage\n"); -} - -QString toString(const RequestReferencesMessage &) -{ - return QStringLiteral("RequestReferencesMessage\n"); -} - -QString toString(const RequestFollowSymbolMessage &) -{ - return QStringLiteral("RequestFollowSymbolMessage\n"); -} - -QString toString(const UpdateVisibleTranslationUnitsMessage &) -{ - return QStringLiteral("UpdateVisibleTranslationUnitsMessage\n"); -} - -class IpcSenderSpy : public IpcSenderInterface -{ -public: - void end() override - { senderLog.append(toString(EndMessage())); } - - void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override - { senderLog.append(toString(message)); } - - void completeCode(const CompleteCodeMessage &message) override - { senderLog.append(toString(message)); } - - void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) override - { senderLog.append(toString(message)); } - - void requestReferences(const RequestReferencesMessage &message) override - { senderLog.append(toString(message)); } - - void requestFollowSymbol(const RequestFollowSymbolMessage &message) override - { senderLog.append(toString(message)); } - - void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override - { senderLog.append(toString(message)); } - -public: - QString senderLog; -}; - class TestDocument { public: @@ -1060,85 +794,6 @@ void ClangCodeCompletionTest::testCompleteAfterChangingIncludedAndNotOpenHeaderE QVERIFY(hasItem(proposal, "globalFromHeaderReloaded")); } -void ClangCodeCompletionTest::testUpdateBackendAfterRestart() -{ - QSKIP("Must be rewritten with a more robust approach instead of sender log!"); - IpcSenderSpy spy; - ChangeIpcSender changeIpcSender(&spy); - - CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app")); - QVERIFY(testDir.isValid()); - - // Open file not part of any project... - const TestDocument headerDocument("myheader.h", &testDir); - QVERIFY(headerDocument.isCreated()); - OpenEditorAtCursorPosition openHeader(headerDocument); - QVERIFY(openHeader.succeeded()); - // ... and modify it, so we have an unsaved file. - insertTextAtTopOfEditor(openHeader.editor(), "int someGlobal;\n"); - // Open project ... - MonitorGeneratedUiFile monitorGeneratedUiFile; - const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro"); - CppTools::Tests::ProjectOpenerAndCloser projectManager; - const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true); - QVERIFY(projectInfo.isValid()); - QVERIFY(monitorGeneratedUiFile.waitUntilGenerated()); - // ...and a file of the project - const QString completionFile = testDir.absolutePath("mainwindow.cpp"); - const TestDocument testDocument = TestDocument::fromExistingFile(completionFile); - QVERIFY(testDocument.isCreatedAndHasValidCursorPosition()); - OpenEditorAtCursorPosition openSource(testDocument); - QVERIFY(openSource.succeeded()); - - // Check messages that would have been sent - QVERIFY(compare(LogOutput(spy.senderLog), - LogOutput( - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RequestDiagnosticsMessage\n" - " ProjectPartContainer id: qt-widgets-app.pro qt-widgets-app\n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RequestDiagnosticsMessage\n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RequestDiagnosticsMessage\n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: ui_mainwindow.h ProjectPart: \n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: mainwindow.cpp ProjectPart: qt-widgets-app.pro qt-widgets-app\n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: mainwindow.cpp ProjectPart: qt-widgets-app.pro qt-widgets-app\n" - "RequestDiagnosticsMessage\n" - - ))); - spy.senderLog.clear(); - - // Kill backend process... - auto &ipcCommunicator = ModelManagerSupportClang::instance()->ipcCommunicator(); - ipcCommunicator.killBackendProcess(); - QSignalSpy waitForReinitializedBackend(&ipcCommunicator, - SIGNAL(backendReinitialized())); - QVERIFY(waitForReinitializedBackend.wait()); - - // ...and check if code model backend would have been provided with current data - QVERIFY(compare(LogOutput(spy.senderLog), - LogOutput( - "RegisterProjectPartsForEditorMessage\n" - " ProjectPartContainer id: \n" - "RegisterProjectPartsForEditorMessage\n" - " ProjectPartContainer id: qt-widgets-app.pro qt-widgets-app\n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: myheader.h ProjectPart: \n" - "RegisterTranslationUnitForEditorMessage\n" - " Path: ui_mainwindow.h ProjectPart: \n" - ))); -} - } // namespace Tests } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h index 24b36da4f0d..b2659d064d5 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h @@ -58,8 +58,6 @@ private slots: void testCompleteAfterModifyingIncludedHeaderByRefactoringActions(); void testCompleteAfterChangingIncludedAndOpenHeaderExternally(); void testCompleteAfterChangingIncludedAndNotOpenHeaderExternally(); - - void testUpdateBackendAfterRestart(); }; } // namespace Tests diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp index e18b9747b81..c67b811f52d 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp @@ -130,21 +130,6 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString addAutoReleasedObject(new ClangStaticAnalyzerTool); addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage); - auto constraint = [](RunConfiguration *runConfiguration) { - Target *target = runConfiguration->target(); - QTC_ASSERT(target, return false); - - Project *project = target->project(); - QTC_ASSERT(project, return false); - - const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID; - return project->projectLanguages().contains(cxx) - && ToolChainKitInformation::toolChain(target->kit(), cxx); - }; - - RunControl::registerWorker - (Constants::CLANGSTATICANALYZER_RUN_MODE, constraint, /*priority*/ -1); - return true; } diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 94468e913e4..ef1c79b7bb1 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -35,6 +35,7 @@ #include +#include #include #include @@ -46,8 +47,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -55,6 +58,7 @@ #include #include +#include #include #include @@ -63,71 +67,74 @@ using namespace CppTools; using namespace ProjectExplorer; +using namespace Utils; static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol") namespace ClangStaticAnalyzer { namespace Internal { -ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl) - : RunWorker(runControl) +class ProjectBuilder : public RunWorker { - setDisplayName("ClangStaticAnalyzerRunner"); - runControl->setDisplayName(tr("Clang Static Analyzer")); - runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); - setSupportsReRunning(false); - - RunConfiguration *runConfiguration = runControl->runConfiguration(); - auto tool = ClangStaticAnalyzerTool::instance(); - tool->stopAction()->disconnect(); - connect(tool->stopAction(), &QAction::triggered, runControl, [&] { - initiateStop(); - appendMessage(tr("Clang Static Analyzer stopped by user."), - Utils::NormalMessageFormat); - }); - tool->handleWorkerStart(this); - - ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild(); - QTC_ASSERT(projectInfoBeforeBuild.isValid(), return); - - QTC_ASSERT(runConfiguration, return); - Target * const target = runConfiguration->target(); - QTC_ASSERT(target, return); - Project * const project = target->project(); - QTC_ASSERT(project, return); - - // so pass on the updated Project Info unless no configuration change - // (defines/includes/files) happened. - const CppTools::ProjectInfo projectInfoAfterBuild - = CppTools::CppModelManager::instance()->projectInfo(project); - - if (projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild)) { - // If it's more than a release/debug build configuration change, e.g. - // a version control checkout, files might be not valid C++ anymore - // or even gone, so better stop here. - - tool->resetCursorAndProjectInfoBeforeBuild(); - reportFailure(tr( - "The project configuration changed since the start of the Clang Static Analyzer. " - "Please re-run with current configuration.")); - return; +public: + ProjectBuilder(RunControl *runControl, Project *project) + : RunWorker(runControl), m_project(project) + { + setDisplayName("ProjectBuilder"); } - // Some projects provides CompilerCallData once a build is finished, - QTC_ASSERT(!projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild), - return); + bool success() const { return m_success; } - m_projectInfo = projectInfoAfterBuild; +private: + void start() final + { + Target *target = m_project->activeTarget(); + QTC_ASSERT(target, reportFailure(); return); - BuildConfiguration *buildConfiguration = target->activeBuildConfiguration(); - QTC_ASSERT(buildConfiguration, return); - m_environment = buildConfiguration->environment(); + BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown; + if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) + buildType = buildConfig->buildType(); - ToolChain *toolChain = ToolChainKitInformation::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); - QTC_ASSERT(toolChain, return); - m_targetTriple = toolChain->originalTargetTriple(); - m_toolChainType = toolChain->typeId(); -} + if (buildType == BuildConfiguration::Release) { + const QString wrongMode = ClangStaticAnalyzerTool::tr("Release"); + const QString toolName = ClangStaticAnalyzerTool::tr("Clang Static Analyzer"); + const QString title = ClangStaticAnalyzerTool::tr("Run %1 in %2 Mode?").arg(toolName) + .arg(wrongMode); + const QString message = ClangStaticAnalyzerTool::tr( + "" + "

You are trying to run the tool \"%1\" on an application in %2 mode. The tool is " + "designed to be used in Debug mode since enabled assertions can reduce the number of " + "false positives.

" + "

Do you want to continue and run the tool in %2 mode?

" + "") + .arg(toolName).arg(wrongMode); + if (CheckableMessageBox::doNotAskAgainQuestion(Core::ICore::mainWindow(), + title, message, Core::ICore::settings(), + "ClangStaticAnalyzerCorrectModeWarning") != QDialogButtonBox::Yes) + { + reportFailure(); + return; + } + } + + connect(BuildManager::instance(), &BuildManager::buildQueueFinished, + this, &ProjectBuilder::onBuildFinished, Qt::QueuedConnection); + + ProjectExplorerPlugin::buildProject(m_project); + } + + void onBuildFinished(bool success) + { + disconnect(BuildManager::instance(), &BuildManager::buildQueueFinished, + this, &ProjectBuilder::onBuildFinished); + m_success = success; + reportDone(); + } + +private: + QPointer m_project; + bool m_success = false; +}; static void prependWordWidthArgumentIfNotIncluded(QStringList *arguments, ProjectPart::ToolChainWordWidth wordWidth) @@ -390,16 +397,47 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits) return debug; } +ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl, Target *target) + : RunWorker(runControl), m_target(target) +{ + setDisplayName("ClangStaticAnalyzerRunner"); + setSupportsReRunning(false); + + m_projectBuilder = new ProjectBuilder(runControl, target->project()); + addStartDependency(m_projectBuilder); + + m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(target->project()); + + BuildConfiguration *buildConfiguration = target->activeBuildConfiguration(); + QTC_ASSERT(buildConfiguration, return); + m_environment = buildConfiguration->environment(); + + ToolChain *toolChain = ToolChainKitInformation::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + QTC_ASSERT(toolChain, return); + m_targetTriple = toolChain->originalTargetTriple(); + m_toolChainType = toolChain->typeId(); +} + void ClangStaticAnalyzerToolRunner::start() { - m_success = false; - ClangStaticAnalyzerTool::instance()->onEngineIsStarting(); + m_success = m_projectBuilder->success(); + if (!m_success) { + reportFailure(); + return; + } - connect(runControl(), &RunControl::stopped, this, [this] { - ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success); - }); + m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project()); + + // Some projects provides CompilerCallData once a build is finished, + if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) { + // If it's more than a release/debug build configuration change, e.g. + // a version control checkout, files might be not valid C++ anymore + // or even gone, so better stop here. + reportFailure(tr("The project configuration changed since the start of " + "the Clang Static Analyzer. Please re-run with current configuration.")); + return; + } - QTC_ASSERT(m_projectInfo.isValid(), reportFailure(); return); const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath(); appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()), Utils::NormalMessageFormat); @@ -502,7 +540,7 @@ void ClangStaticAnalyzerToolRunner::stop() m_runners.clear(); m_unitsToProcess.clear(); m_progress.reportFinished(); - ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success); + //ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success); reportStopped(); } diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index e75660287ff..16d50f085cd 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -36,6 +36,7 @@ namespace ClangStaticAnalyzer { namespace Internal { class ClangStaticAnalyzerRunner; +class ProjectBuilder; class Diagnostic; struct AnalyzeUnit { @@ -52,14 +53,15 @@ class ClangStaticAnalyzerToolRunner : public ProjectExplorer::RunWorker Q_OBJECT public: - explicit ClangStaticAnalyzerToolRunner(ProjectExplorer::RunControl *runControl); - - void start() override; - void stop() override; + ClangStaticAnalyzerToolRunner(ProjectExplorer::RunControl *runControl, + ProjectExplorer::Target *target); bool success() const { return m_success; } // For testing. private: + void start() final; + void stop() final; + AnalyzeUnits sortedUnitsToAnalyze(); void analyzeNextFile(); ClangStaticAnalyzerRunner *createRunner(); @@ -74,6 +76,10 @@ private: void finalize(); private: + QPointer m_target; + ProjectBuilder *m_projectBuilder; + + CppTools::ProjectInfo m_projectInfoBeforeBuild; CppTools::ProjectInfo m_projectInfo; QString m_targetTriple; Core::Id m_toolChainType; diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index 9e90a024676..25bdff2760d 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -36,24 +36,19 @@ #include #include -#include - #include -#include +#include #include -#include +#include #include +#include -#include #include #include #include -#include -#include #include -#include #include #include @@ -65,23 +60,6 @@ using namespace Utils; namespace ClangStaticAnalyzer { namespace Internal { -class DummyRunConfiguration : public RunConfiguration -{ - Q_OBJECT - -public: - DummyRunConfiguration(Target *parent) - : RunConfiguration(parent) - { - initialize("ClangStaticAnalyzer.DummyRunConfig"); - setDefaultDisplayName(tr("Clang Static Analyzer")); - setEnabled(true); - } - -private: - QWidget *createConfigurationWidget() override { return 0; } -}; - static ClangStaticAnalyzerTool *s_instance; ClangStaticAnalyzerTool::ClangStaticAnalyzerTool() @@ -180,90 +158,43 @@ ClangStaticAnalyzerTool *ClangStaticAnalyzerTool::instance() return s_instance; } -static bool dontStartAfterHintForDebugMode(Project *project) -{ - BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown; - if (project) { - if (const Target *target = project->activeTarget()) { - if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) - buildType = buildConfig->buildType(); - } - } - - if (buildType == BuildConfiguration::Release) { - const QString wrongMode = ClangStaticAnalyzerTool::tr("Release"); - const QString toolName = ClangStaticAnalyzerTool::tr("Clang Static Analyzer"); - const QString title = ClangStaticAnalyzerTool::tr("Run %1 in %2 Mode?").arg(toolName) - .arg(wrongMode); - const QString message = ClangStaticAnalyzerTool::tr( - "" - "

You are trying to run the tool \"%1\" on an application in %2 mode. The tool is " - "designed to be used in Debug mode since enabled assertions can reduce the number of " - "false positives.

" - "

Do you want to continue and run the tool in %2 mode?

" - "") - .arg(toolName).arg(wrongMode); - if (Utils::CheckableMessageBox::doNotAskAgainQuestion(Core::ICore::mainWindow(), - title, message, Core::ICore::settings(), - QLatin1String("ClangStaticAnalyzerCorrectModeWarning")) != QDialogButtonBox::Yes) - return true; - } - - return false; -} - -void ClangStaticAnalyzerTool::handleWorkerStart(RunWorker *runWorker) -{ - RunControl *runControl = runWorker->runControl(); - Project *project = runControl->project(); - QTC_ASSERT(project, emit finished(false); return); - - Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId); - m_diagnosticModel->clear(); - setBusyCursor(true); - m_diagnosticFilterModel->setProject(project); - m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(project); - QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), emit finished(false); return); - m_running = true; - handleStateUpdate(); - - m_toolBusy = true; - updateRunActions(); -} - void ClangStaticAnalyzerTool::startTool() { + auto runControl = new RunControl(nullptr, Constants::CLANGSTATICANALYZER_RUN_MODE); + runControl->setDisplayName(tr("Clang Static Analyzer")); + runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); + Project *project = SessionManager::startupProject(); QTC_ASSERT(project, return); - Target *target = project->activeTarget(); - QTC_ASSERT(target, return); - DummyRunConfiguration *& rc = m_runConfigs[target]; - if (!rc) { - rc = new DummyRunConfiguration(target); - connect(project, &Project::aboutToRemoveTarget, this, - [this](Target *t) { m_runConfigs.remove(t); }); - const auto onProjectRemoved = [this](Project *p) { - foreach (Target * const t, p->targets()) - m_runConfigs.remove(t); - }; - connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject, this, - onProjectRemoved, Qt::UniqueConnection); - } - if (dontStartAfterHintForDebugMode(project)) - return; - ProjectExplorerPlugin::runRunConfiguration(rc, Constants::CLANGSTATICANALYZER_RUN_MODE); -} + auto clangTool = new ClangStaticAnalyzerToolRunner(runControl, project->activeTarget()); -CppTools::ProjectInfo ClangStaticAnalyzerTool::projectInfoBeforeBuild() const -{ - return m_projectInfoBeforeBuild; -} + m_stopAction->disconnect(); + connect(m_stopAction, &QAction::triggered, runControl, [this, runControl] { + runControl->appendMessage(tr("Clang Static Analyzer stopped by user."), + NormalMessageFormat); + runControl->initiateStop(); + }); -void ClangStaticAnalyzerTool::resetCursorAndProjectInfoBeforeBuild() -{ - setBusyCursor(false); - m_projectInfoBeforeBuild = CppTools::ProjectInfo(); + connect(runControl, &RunControl::stopped, this, [this, clangTool] { + bool success = clangTool->success(); + setToolBusy(false); + m_running = false; + handleStateUpdate(); + updateRunActions(); + emit finished(success); + }); + + Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId); + + m_diagnosticModel->clear(); + setToolBusy(true); + m_diagnosticFilterModel->setProject(project); + m_running = true; + handleStateUpdate(); + updateRunActions(); + + ProjectExplorerPlugin::startRunControl(runControl); } QList ClangStaticAnalyzerTool::diagnostics() const @@ -271,27 +202,12 @@ QList ClangStaticAnalyzerTool::diagnostics() const return m_diagnosticModel->diagnostics(); } -void ClangStaticAnalyzerTool::onEngineIsStarting() -{ - QTC_ASSERT(m_diagnosticModel, return); -} - void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList &diagnostics) { QTC_ASSERT(m_diagnosticModel, return); m_diagnosticModel->addDiagnostics(diagnostics); } -void ClangStaticAnalyzerTool::onEngineFinished(bool success) -{ - resetCursorAndProjectInfoBeforeBuild(); - m_running = false; - handleStateUpdate(); - emit finished(success); - m_toolBusy = false; - updateRunActions(); -} - void ClangStaticAnalyzerTool::updateRunActions() { if (m_toolBusy) { @@ -299,19 +215,27 @@ void ClangStaticAnalyzerTool::updateRunActions() m_startAction->setToolTip(tr("Clang Static Analyzer is still running.")); m_stopAction->setEnabled(true); } else { - QString whyNot = tr("Start Clang Static Analyzer."); - bool canRun = ProjectExplorerPlugin::canRunStartupProject( - Constants::CLANGSTATICANALYZER_RUN_MODE, &whyNot); - m_startAction->setToolTip(whyNot); + QString toolTip = tr("Start Clang Static Analyzer."); + Project *project = SessionManager::startupProject(); + Target *target = project ? project->activeTarget() : nullptr; + const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID; + bool canRun = target && project->projectLanguages().contains(cxx) + && ToolChainKitInformation::toolChain(target->kit(), cxx); + if (!canRun) + toolTip = tr("This is not C++ project"); + + m_startAction->setToolTip(toolTip); m_startAction->setEnabled(canRun); m_stopAction->setEnabled(false); } } -void ClangStaticAnalyzerTool::setBusyCursor(bool busy) + +void ClangStaticAnalyzerTool::setToolBusy(bool busy) { QTC_ASSERT(m_diagnosticView, return); QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor); m_diagnosticView->setCursor(cursor); + m_toolBusy = busy; } void ClangStaticAnalyzerTool::handleStateUpdate() @@ -326,8 +250,12 @@ void ClangStaticAnalyzerTool::handleStateUpdate() m_goBack->setEnabled(issuesVisible > 1); m_goNext->setEnabled(issuesVisible > 1); - QString message = m_running ? tr("Clang Static Analyzer is running.") - : tr("Clang Static Analyzer finished."); + QString message; + if (m_running) + message = tr("Clang Static Analyzer is running."); + else + message = tr("Clang Static Analyzer finished."); + message += QLatin1Char(' '); if (issuesFound == 0) { message += tr("No issues found."); @@ -340,5 +268,3 @@ void ClangStaticAnalyzerTool::handleStateUpdate() } // namespace Internal } // namespace ClangStaticAnalyzer - -#include "clangstaticanalyzertool.moc" diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h index 06550bce315..334ec07b93c 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h @@ -28,8 +28,6 @@ #include #include -#include - namespace ClangStaticAnalyzer { namespace Internal { @@ -37,7 +35,6 @@ class ClangStaticAnalyzerDiagnosticFilterModel; class ClangStaticAnalyzerDiagnosticModel; class ClangStaticAnalyzerDiagnosticView; class Diagnostic; -class DummyRunConfiguration; const char ClangStaticAnalyzerPerspectiveId[] = "ClangStaticAnalyzer.Perspective"; const char ClangStaticAnalyzerDockId[] = "ClangStaticAnalyzer.Dock"; @@ -51,32 +48,21 @@ public: ~ClangStaticAnalyzerTool(); static ClangStaticAnalyzerTool *instance(); - QAction *stopAction() { return m_stopAction; } - - CppTools::ProjectInfo projectInfoBeforeBuild() const; - void resetCursorAndProjectInfoBeforeBuild(); // For testing. QList diagnostics() const; void startTool(); - void handleWorkerStart(ProjectExplorer::RunWorker *runWorker); - - void onEngineIsStarting(); void onNewDiagnosticsAvailable(const QList &diagnostics); - void onEngineFinished(bool success); signals: void finished(bool success); // For testing. private: - void setBusyCursor(bool busy); + void setToolBusy(bool busy); void handleStateUpdate(); void updateRunActions(); -private: - CppTools::ProjectInfo m_projectInfoBeforeBuild; - ClangStaticAnalyzerDiagnosticModel *m_diagnosticModel = nullptr; ClangStaticAnalyzerDiagnosticFilterModel *m_diagnosticFilterModel = nullptr; ClangStaticAnalyzerDiagnosticView *m_diagnosticView = nullptr; @@ -85,7 +71,6 @@ private: QAction *m_stopAction = nullptr; QAction *m_goBack = nullptr; QAction *m_goNext = nullptr; - QHash m_runConfigs; bool m_running = false; bool m_toolBusy = false; }; diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 67ae9387af0..b64898d2b4f 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -62,10 +62,6 @@ BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : m_buildConfiguration(bc) { QTC_ASSERT(bc, return); - - m_reparseTimer.setSingleShot(true); - - connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse); } BuildDirManager::~BuildDirManager() = default; @@ -209,7 +205,7 @@ void BuildDirManager::maybeForceReparseOnceReaderReady() // The critical keys *must* be set in cmake configuration, so those were already // handled above. if (mustReparse || kcit != targetConfig.constEnd()) - parseOnceReaderReady(true); + emit requestReparse(true); } bool BuildDirManager::isParsing() const @@ -232,7 +228,7 @@ void BuildDirManager::becameDirty() if (!tool->isAutoRun()) return; - m_reparseTimer.start(1000); + emit requestReparse(false); } void BuildDirManager::forceReparse() @@ -272,11 +268,6 @@ void BuildDirManager::resetData() m_buildTargets.clear(); } -bool BuildDirManager::updateCMakeStateBeforeBuild() -{ - return m_reparseTimer.isActive(); -} - bool BuildDirManager::persistCMakeState() { if (!m_tempDir) @@ -455,7 +446,7 @@ void BuildDirManager::maybeForceReparse() return; if (!m_reader || !m_reader->hasData()) { - forceReparse(); + emit requestReparse(true); return; } diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 489ca67ff7f..4db167d0428 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -67,7 +67,6 @@ public: void forceReparseWithoutCheckingForChanges(); void maybeForceReparse(); // Only reparse if the configuration has changed... void resetData(); - bool updateCMakeStateBeforeBuild(); bool persistCMakeState(); void generateProjectTree(CMakeProjectNode *root, @@ -83,6 +82,7 @@ public: CMakeBuildConfiguration *buildConfiguration() const { return m_buildConfiguration; } signals: + void requestReparse(bool urgent) const; void configurationStarted() const; void dataAvailable() const; void errorOccured(const QString &err) const; @@ -109,8 +109,6 @@ private: mutable std::unique_ptr m_tempDir = nullptr; mutable CMakeConfig m_cmakeCache; - QTimer m_reparseTimer; - std::unique_ptr m_reader; mutable QList m_buildTargets; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 59bdaf1168b..a62fa7f4af4 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -142,10 +142,12 @@ void CMakeBuildConfiguration::ctor() target()->kit(), displayName(), BuildConfiguration::Unknown)); + connect(m_buildDirManager.get(), &BuildDirManager::requestReparse, + this, [this](bool urgent) { emit requestReparse(this, urgent); }); connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable, this, [this, project]() { clearError(); - project->updateProjectData(this); + project->handleParsingSuccess(this); }); connect(m_buildDirManager.get(), &BuildDirManager::errorOccured, this, [this, project](const QString &msg) { @@ -153,9 +155,9 @@ void CMakeBuildConfiguration::ctor() project->handleParsingError(this); }); connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted, - this, [this, project]() { - project->handleParsingStarted(this); + this, [this]() { clearError(ForceEnabledChanged::True); + emit parsingStarted(this); }); connect(this, &CMakeBuildConfiguration::environmentChanged, @@ -188,7 +190,7 @@ bool CMakeBuildConfiguration::persistCMakeState() bool CMakeBuildConfiguration::updateCMakeStateBeforeBuild() { - return m_buildDirManager->updateCMakeStateBeforeBuild(); + return static_cast(project())->mustUpdateCMakeStateBeforeBuild(); } void CMakeBuildConfiguration::runCMake() diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 5cc58bbdcb4..45a45ede73d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -97,6 +97,9 @@ public: void buildTarget(const QString &buildTarget); signals: + void requestReparse(CMakeBuildConfiguration *, bool isUrgent); + void parsingStarted(CMakeBuildConfiguration *); + void errorOccured(const QString &message); void warningOccured(const QString &message); diff --git a/src/plugins/cmakeprojectmanager/cmakecbpparser.h b/src/plugins/cmakeprojectmanager/cmakecbpparser.h index 6069b7d1ad6..d1f5cf9569f 100644 --- a/src/plugins/cmakeprojectmanager/cmakecbpparser.h +++ b/src/plugins/cmakeprojectmanager/cmakecbpparser.h @@ -38,7 +38,6 @@ namespace ProjectExplorer { class FileNode; -class Kit; } // namespace ProjectExplorer namespace CMakeProjectManager { diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.h b/src/plugins/cmakeprojectmanager/cmakeeditor.h index 7d5bda378cf..93151db5471 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.h +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.h @@ -32,7 +32,6 @@ namespace CMakeProjectManager { namespace Internal { class CMakeEditorWidget; -class CMakeSettingsPage; class CMakeEditor : public TextEditor::BaseTextEditor { diff --git a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h index 934d7b64e88..387addeac1d 100644 --- a/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h +++ b/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.h @@ -31,7 +31,6 @@ namespace CMakeProjectManager { namespace Internal { -class CMakeSettingsPage; class CMakeFileCompletionAssist : public TextEditor::KeywordsCompletionAssistProcessor { diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 57de95ad1fa..2ab0037bd0e 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -76,12 +77,27 @@ using namespace Internal; CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEMIMETYPE, fileName), m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { + m_delayedParsingTimer.setSingleShot(true); + + connect(&m_delayedParsingTimer, &QTimer::timeout, + this, [this]() { startParsingProject(PARSE); }); + setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setDisplayName(projectDirectory().fileName()); - connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged); + connect(this, &Project::activeProjectConfigurationChanged, + this, &CMakeProject::handleActiveProjectConfigurationChanged); + + subscribeSignal(&CMakeBuildConfiguration::requestReparse, + this, [this](CMakeBuildConfiguration *bc, bool isUrgent) { + if (bc->isActive()) { + m_delayedParsingTimer.setInterval(isUrgent ? 0 : 1000); + m_delayedParsingTimer.start(); + } + }); + connect(&m_treeScanner, &TreeScanner::finished, this, &CMakeProject::handleTreeScanningFinished); m_treeScanner.setFilter([this](const Utils::MimeType &mimeType, const Utils::FileName &fn) { @@ -116,8 +132,6 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM } return type; }); - - scanProjectTree(); } CMakeProject::~CMakeProject() @@ -134,14 +148,11 @@ CMakeProject::~CMakeProject() void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) { + Target *const t = activeTarget(); + QTC_ASSERT(bc, return); - - Target *t = activeTarget(); - if (!t || t->activeBuildConfiguration() != bc) - return; - - if (!m_treeScanner.isFinished() || bc->isParsing()) - return; + QTC_ASSERT(bc == (t ? t->activeBuildConfiguration() : nullptr), return); + QTC_ASSERT(m_treeScanner.isFinished() && !bc->isParsing(), return); Kit *k = t->kit(); @@ -189,19 +200,6 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) emit fileListChanged(); emit bc->emitBuildTypeChanged(); - - emitParsingFinished(true); -} - -void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc) -{ - QTC_ASSERT(bc, return); - - Target *t = activeTarget(); - if (!t || t->activeBuildConfiguration() != bc) - return; - - emitParsingFinished(false); } void CMakeProject::updateQmlJSCodeModel() @@ -263,12 +261,49 @@ bool CMakeProject::supportsKit(Kit *k, QString *errorMessage) const void CMakeProject::runCMake() { - CMakeBuildConfiguration *bc = nullptr; - if (activeTarget()) - bc = qobject_cast(activeTarget()->activeBuildConfiguration()); + if (isParsing()) + return; - if (bc) + startParsingProject(PARSE); +} + +void CMakeProject::runCMakeAndScanProjectTree() +{ + if (isParsing()) + return; + + startParsingProject(static_cast(PARSE | SCAN)); +} + +void CMakeProject::startParsingProject(const CMakeProject::DataCollectionAction action) +{ + const bool runParse = action & PARSE; + const bool runScan = action & SCAN; + + CMakeBuildConfiguration *bc = activeTarget() + ? qobject_cast(activeTarget()->activeBuildConfiguration()) + : nullptr; + if (!bc) + return; + + if (!m_treeScanner.isFinished() || m_waitingForScan) + return; + + emitParsingStarted(); + + m_waitingForParse = runParse; + m_waitingForScan = runScan; + m_combinedScanAndParseResult = true; + + if (runParse) bc->runCMake(); + + if (runScan) { + m_treeScanner.asyncScanForFiles(projectDirectory()); + Core::ProgressManager::addTask(m_treeScanner.future(), + tr("Scan \"%1\" project tree").arg(displayName()), + "CMake.Scan.Tree"); + } } void CMakeProject::buildCMakeTarget(const QString &buildTarget) @@ -330,75 +365,84 @@ bool CMakeProject::setupTarget(Target *t) return true; } -void CMakeProject::scanProjectTree() +void CMakeProject::handleActiveProjectConfigurationChanged(ProjectConfiguration *pc) { - if (!m_treeScanner.isFinished()) + if (auto bc = qobject_cast(pc)) { + if (!bc->isActive()) + return; + } else if (!qobject_cast(pc)) { return; - m_treeScanner.asyncScanForFiles(projectDirectory()); - Core::ProgressManager::addTask(m_treeScanner.future(), - tr("Scan \"%1\" project tree").arg(displayName()), - "CMake.Scan.Tree"); -} - -void CMakeProject::handleActiveTargetChanged() -{ - if (m_connectedTarget) { - disconnect(m_connectedTarget, &Target::activeBuildConfigurationChanged, - this, &CMakeProject::handleActiveBuildConfigurationChanged); - disconnect(m_connectedTarget, &Target::kitChanged, - this, &CMakeProject::handleActiveBuildConfigurationChanged); } - m_connectedTarget = activeTarget(); - - if (m_connectedTarget) { - connect(m_connectedTarget, &Target::activeBuildConfigurationChanged, - this, &CMakeProject::handleActiveBuildConfigurationChanged); - connect(m_connectedTarget, &Target::kitChanged, - this, &CMakeProject::handleActiveBuildConfigurationChanged); - } - - handleActiveBuildConfigurationChanged(); -} - -void CMakeProject::handleActiveBuildConfigurationChanged() -{ - if (!activeTarget() || !activeTarget()->activeBuildConfiguration()) - return; - auto activeBc = qobject_cast(activeTarget()->activeBuildConfiguration()); - - foreach (Target *t, targets()) { - foreach (BuildConfiguration *bc, t->buildConfigurations()) { + for (Target *t : targets()) { + for (BuildConfiguration *bc : t->buildConfigurations()) { auto i = qobject_cast(bc); QTC_ASSERT(i, continue); - if (i == activeBc) + if (i->isActive()) { + m_waitingForParse = true; i->maybeForceReparse(); - else + } else { i->resetData(); + } } } } -void CMakeProject::handleParsingStarted(const CMakeBuildConfiguration *bc) -{ - if (activeTarget() && activeTarget()->activeBuildConfiguration() == bc) - emitParsingStarted(); -} - void CMakeProject::handleTreeScanningFinished() { + QTC_CHECK(m_waitingForScan); + qDeleteAll(m_allFiles); m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; }); auto t = activeTarget(); - if (!t) + auto bc = qobject_cast(t ? t->activeBuildConfiguration() : nullptr); + QTC_ASSERT(bc, return); + + m_combinedScanAndParseResult = m_combinedScanAndParseResult && true; + m_waitingForScan = false; + + combineScanAndParse(bc); +} + +void CMakeProject::handleParsingSuccess(CMakeBuildConfiguration *bc) +{ + QTC_CHECK(m_waitingForParse); + + if (!bc || !bc->isActive()) return; - auto bc = qobject_cast(t->activeBuildConfiguration()); - if (!bc) + m_waitingForParse = false; + m_combinedScanAndParseResult = m_combinedScanAndParseResult && true; + + combineScanAndParse(bc); +} + +void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc) +{ + QTC_CHECK(m_waitingForParse); + + if (!bc || !bc->isActive()) return; - updateProjectData(bc); + m_waitingForParse = false; + m_combinedScanAndParseResult = false; + + combineScanAndParse(bc); +} + + +void CMakeProject::combineScanAndParse(CMakeBuildConfiguration *bc) +{ + QTC_ASSERT(bc && bc->isActive(), return); + + if (m_waitingForParse || m_waitingForScan) + return; + + if (m_combinedScanAndParseResult) + updateProjectData(bc); + + emitParsingFinished(m_combinedScanAndParseResult); } CMakeBuildTarget CMakeProject::buildTargetForTitle(const QString &title) @@ -539,6 +583,11 @@ void CMakeProject::updateApplicationAndDeploymentTargets() t->setDeploymentData(deploymentData); } +bool CMakeProject::mustUpdateCMakeStateBeforeBuild() +{ + return m_delayedParsingTimer.isActive(); +} + void CMakeProject::createGeneratedCodeModelSupport() { qDeleteAll(m_extraCompilers); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 1d3e047683f..40d3382a64b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -37,13 +37,10 @@ #include #include +#include #include -QT_BEGIN_NAMESPACE -class QFileSystemWatcher; -QT_END_NAMESPACE - namespace CppTools { class CppProjectUpdater; } namespace CMakeProjectManager { @@ -99,7 +96,7 @@ public: bool supportsKit(ProjectExplorer::Kit *k, QString *errorMessage = 0) const final; void runCMake(); - void scanProjectTree(); + void runCMakeAndScanProjectTree(); // Context menu actions: void buildCMakeTarget(const QString &buildTarget); @@ -113,12 +110,15 @@ protected: private: QList buildTargets() const; - void handleActiveTargetChanged(); - void handleActiveBuildConfigurationChanged(); - void handleParsingStarted(const Internal::CMakeBuildConfiguration *bc); + enum DataCollectionAction { PARSE = 1, SCAN = 2 }; + void startParsingProject(const DataCollectionAction a); + + void handleActiveProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc); void handleTreeScanningFinished(); - void updateProjectData(Internal::CMakeBuildConfiguration *bc); + void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc); void handleParsingError(Internal::CMakeBuildConfiguration *bc); + void combineScanAndParse(Internal::CMakeBuildConfiguration *bc); + void updateProjectData(Internal::CMakeBuildConfiguration *bc); void updateQmlJSCodeModel(); void createGeneratedCodeModelSupport(); @@ -126,7 +126,7 @@ private: void updateTargetRunConfigurations(ProjectExplorer::Target *t); void updateApplicationAndDeploymentTargets(); - ProjectExplorer::Target *m_connectedTarget = nullptr; + bool mustUpdateCMakeStateBeforeBuild(); // TODO probably need a CMake specific node structure QList m_buildTargets; @@ -134,10 +134,17 @@ private: QList m_extraCompilers; Internal::TreeScanner m_treeScanner; + + bool m_waitingForScan = false; + bool m_waitingForParse = false; + bool m_combinedScanAndParseResult = false; + QHash m_mimeBinaryCache; QList m_allFiles; mutable std::unique_ptr m_projectImporter; + QTimer m_delayedParsingTimer; + friend class Internal::CMakeBuildConfiguration; friend class Internal::CMakeBuildSettingsWidget; }; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 7464261e8c3..420e0d0bd2d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -152,6 +152,5 @@ void CMakeManager::rescanProject(Project *project) if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration()) return; - cmakeProject->scanProjectTree(); - cmakeProject->runCMake(); // by my experience: every rescan run requires cmake run too + cmakeProject->runCMakeAndScanProjectTree();// by my experience: every rescan run requires cmake run too } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index c1d19514ea5..0a045c19c04 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -34,7 +34,6 @@ QT_END_NAMESPACE namespace CMakeProjectManager { namespace Internal { -class CMakeSettingsPage; class CMakeManager : public QObject { diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h index de3112184a0..7f8524ff745 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h @@ -34,7 +34,6 @@ namespace Utils { class ParameterAction; } namespace CMakeProjectManager { class CMakeProject; -class CMakeToolManager; namespace Internal { diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index f861483227a..bf5fe7337e7 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -36,7 +36,6 @@ namespace CMakeProjectManager { namespace Internal { -class CMakeListsNode; class ServerModeReader : public BuildDirReader { diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 2f29eac491a..e8c661b9899 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -35,7 +35,6 @@ QT_BEGIN_NAMESPACE class QAction; -class QSettings; class QString; QT_END_NAMESPACE diff --git a/src/plugins/coreplugin/actionmanager/actionmanager_p.h b/src/plugins/coreplugin/actionmanager/actionmanager_p.h index 0269fc4992e..5ac100ba784 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager_p.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager_p.h @@ -34,18 +34,12 @@ #include #include -QT_BEGIN_NAMESPACE -class QLabel; -class QSettings; -QT_END_NAMESPACE - namespace Core { namespace Internal { class Action; class ActionContainerPrivate; -class MainWindow; class ActionManagerPrivate : public QObject { diff --git a/src/plugins/coreplugin/actionmanager/commandmappings.h b/src/plugins/coreplugin/actionmanager/commandmappings.h index 89abe7efb08..ddfd7ff2809 100644 --- a/src/plugins/coreplugin/actionmanager/commandmappings.h +++ b/src/plugins/coreplugin/actionmanager/commandmappings.h @@ -30,7 +30,6 @@ #include QT_BEGIN_NAMESPACE -class QLineEdit; class QTreeWidget; class QTreeWidgetItem; QT_END_NAMESPACE diff --git a/src/plugins/coreplugin/basefilewizardfactory.h b/src/plugins/coreplugin/basefilewizardfactory.h index 61972f17e16..8e68fb07221 100644 --- a/src/plugins/coreplugin/basefilewizardfactory.h +++ b/src/plugins/coreplugin/basefilewizardfactory.h @@ -34,10 +34,8 @@ #include QT_BEGIN_NAMESPACE -class QIcon; class QWizard; class QWizardPage; -class QDebug; QT_END_NAMESPACE namespace Utils { class Wizard; } diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index 7a69887c36a..2f86226a711 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -35,7 +35,6 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; -class Theme; } namespace Core { diff --git a/src/plugins/coreplugin/dialogs/newdialog.h b/src/plugins/coreplugin/dialogs/newdialog.h index 5d73546aa96..9461efae261 100644 --- a/src/plugins/coreplugin/dialogs/newdialog.h +++ b/src/plugins/coreplugin/dialogs/newdialog.h @@ -39,7 +39,6 @@ class QSortFilterProxyModel; class QPushButton; class QStandardItem; class QStandardItemModel; -class QStringList; QT_END_NAMESPACE namespace Core { diff --git a/src/plugins/coreplugin/dialogs/openwithdialog.h b/src/plugins/coreplugin/dialogs/openwithdialog.h index d93ea71d6d2..a3f0db0366f 100644 --- a/src/plugins/coreplugin/dialogs/openwithdialog.h +++ b/src/plugins/coreplugin/dialogs/openwithdialog.h @@ -30,7 +30,6 @@ namespace Core { -class ICore; namespace Internal { diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.h b/src/plugins/coreplugin/dialogs/saveitemsdialog.h index 1048ca03481..37d321fade8 100644 --- a/src/plugins/coreplugin/dialogs/saveitemsdialog.h +++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.h @@ -30,18 +30,12 @@ #include "ui_saveitemsdialog.h" -QT_BEGIN_NAMESPACE -class QCheckBox; -QT_END_NAMESPACE - namespace Core { class IDocument; -class EditorManager; namespace Internal { -class MainWindow; class SaveItemsDialog : public QDialog { diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.h b/src/plugins/coreplugin/dialogs/shortcutsettings.h index 4607d68419f..c3359f00648 100644 --- a/src/plugins/coreplugin/dialogs/shortcutsettings.h +++ b/src/plugins/coreplugin/dialogs/shortcutsettings.h @@ -36,7 +36,6 @@ QT_BEGIN_NAMESPACE class QGroupBox; -class QKeyEvent; class QLabel; QT_END_NAMESPACE @@ -47,7 +46,6 @@ class Command; namespace Internal { class ActionManagerPrivate; -class MainWindow; struct ShortcutItem { diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 052a7ee7bd4..3cf9b47bfe7 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -32,16 +32,12 @@ QT_BEGIN_NAMESPACE class QStringList; -class QAction; -class QMainWindow; -class QMenu; QT_END_NAMESPACE namespace Utils { class FileName; } namespace Core { -class IContext; class IDocument; namespace Internal { diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 7c28c27eb70..7b467ac1ac0 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -41,15 +41,10 @@ namespace Utils { class MimeType; } namespace Core { -class IContext; class IEditor; class IEditorFactory; class IExternalEditor; class IDocument; -class IMode; -class IVersionControl; - -class EditorToolBar; class SearchResultItem; enum MakeWritableResult { @@ -60,13 +55,8 @@ enum MakeWritableResult { }; namespace Internal { -class EditorClosingCoreListener; class EditorManagerPrivate; -class EditorView; class MainWindow; -class OpenEditorsViewFactory; -class OpenEditorsWindow; -class SplitterOrView; } // namespace Internal class CORE_EXPORT EditorManagerPlaceHolder : public QWidget diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index abeb0f125e6..6653616efd8 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -41,8 +41,6 @@ #include QT_BEGIN_NAMESPACE -class QAction; -class QComboBox; class QFrame; class QLabel; class QMenu; @@ -53,11 +51,9 @@ class QToolButton; QT_END_NAMESPACE namespace Core { -class IContext; class IDocument; class IEditor; class InfoBarDisplay; -class DocumentModel; class EditorToolBar; namespace Internal { diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.h b/src/plugins/coreplugin/editormanager/openeditorswindow.h index e497411b771..9bd769bf8cc 100644 --- a/src/plugins/coreplugin/editormanager/openeditorswindow.h +++ b/src/plugins/coreplugin/editormanager/openeditorswindow.h @@ -39,7 +39,6 @@ QT_END_NAMESPACE namespace Core { -class IDocument; class IEditor; namespace Internal { @@ -51,7 +50,6 @@ public: QSize sizeHint() const; }; -class EditorHistoryItem; class OpenEditorsWindow : public QFrame { diff --git a/src/plugins/coreplugin/find/searchresultwindow.h b/src/plugins/coreplugin/find/searchresultwindow.h index f62c2163110..a22f6ad0a22 100644 --- a/src/plugins/coreplugin/find/searchresultwindow.h +++ b/src/plugins/coreplugin/find/searchresultwindow.h @@ -39,11 +39,9 @@ QT_END_NAMESPACE namespace Core { namespace Internal { - class SearchResultTreeView; class SearchResultWindowPrivate; class SearchResultWidget; } -class Find; class SearchResultWindow; class CORE_EXPORT SearchResult : public QObject diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index b2d789b6d8d..89c6ada1808 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -44,9 +44,7 @@ namespace Core { class IWizardFactory; class Context; class IContext; -class ProgressManager; class SettingsDatabase; -class VcsManager; namespace Internal { class MainWindow; } diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.h b/src/plugins/coreplugin/locator/locatorsettingspage.h index f9e4383d466..ed7143ae584 100644 --- a/src/plugins/coreplugin/locator/locatorsettingspage.h +++ b/src/plugins/coreplugin/locator/locatorsettingspage.h @@ -34,7 +34,6 @@ #include QT_BEGIN_NAMESPACE -class QListWidgetItem; class QSortFilterProxyModel; QT_END_NAMESPACE diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h index c4ce3c4a14d..6b645134cce 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.h +++ b/src/plugins/coreplugin/locator/locatorwidget.h @@ -34,10 +34,7 @@ QT_BEGIN_NAMESPACE class QAction; -class QLabel; -class QLineEdit; class QMenu; -class QTreeView; QT_END_NAMESPACE namespace Utils { class FancyLineEdit; } diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 7a7042fd36a..a50fa8b6a7c 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -37,7 +37,6 @@ #include QT_BEGIN_NAMESPACE -class QSettings; class QPrinter; class QToolButton; QT_END_NAMESPACE @@ -47,10 +46,8 @@ namespace Core { class StatusBarWidget; class EditorManager; class ExternalToolManager; -class DocumentManager; class HelpManager; class IDocument; -class IWizardFactory; class JsExpander; class MessageManager; class ModeManager; diff --git a/src/plugins/coreplugin/navigationwidget.h b/src/plugins/coreplugin/navigationwidget.h index e2b49ee95c0..0f43e4ce042 100644 --- a/src/plugins/coreplugin/navigationwidget.h +++ b/src/plugins/coreplugin/navigationwidget.h @@ -33,7 +33,6 @@ QT_BEGIN_NAMESPACE class QSettings; class QAbstractItemModel; -class QStandardItemModel; QT_END_NAMESPACE namespace Core { diff --git a/src/plugins/coreplugin/outputpanemanager.h b/src/plugins/coreplugin/outputpanemanager.h index b8885dd21d0..90dc7b04a0d 100644 --- a/src/plugins/coreplugin/outputpanemanager.h +++ b/src/plugins/coreplugin/outputpanemanager.h @@ -32,9 +32,7 @@ QT_BEGIN_NAMESPACE class QAction; -class QComboBox; class QLabel; -class QSplitter; class QStackedWidget; class QTimeLine; class QLabel; diff --git a/src/plugins/coreplugin/rightpane.h b/src/plugins/coreplugin/rightpane.h index 4fb410f5eb9..ab3aab18e7d 100644 --- a/src/plugins/coreplugin/rightpane.h +++ b/src/plugins/coreplugin/rightpane.h @@ -36,7 +36,6 @@ QT_END_NAMESPACE namespace Core { -class IMode; class RightPaneWidget; class CORE_EXPORT RightPanePlaceHolder : public QWidget diff --git a/src/plugins/coreplugin/sidebarwidget.h b/src/plugins/coreplugin/sidebarwidget.h index fbc6c09acca..e6db3c22006 100644 --- a/src/plugins/coreplugin/sidebarwidget.h +++ b/src/plugins/coreplugin/sidebarwidget.h @@ -28,10 +28,8 @@ #include QT_BEGIN_NAMESPACE -class QSettings; class QToolBar; class QAction; -class QToolButton; QT_END_NAMESPACE namespace Core { diff --git a/src/plugins/cpaster/cpasterplugin.h b/src/plugins/cpaster/cpasterplugin.h index e86b17983da..671fdbb71f6 100644 --- a/src/plugins/cpaster/cpasterplugin.h +++ b/src/plugins/cpaster/cpasterplugin.h @@ -37,8 +37,6 @@ class QAction; QT_END_NAMESPACE namespace CodePaster { -class CustomFetcher; -class CustomPoster; class Settings; class Protocol; diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index aa2f06fad76..c1d86a61591 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -37,9 +37,7 @@ namespace TextEditor { class BaseTextEditor; } namespace CppEditor { namespace Internal { -class CppEditorWidget; class CppCodeModelInspectorDialog; -class CppQuickFixCollector; class CppQuickFixAssistProvider; class CppEditorPlugin : public ExtensionSystem::IPlugin diff --git a/src/plugins/cppeditor/cppelementevaluator.h b/src/plugins/cppeditor/cppelementevaluator.h index ffc6bd760a1..5af04956aee 100644 --- a/src/plugins/cppeditor/cppelementevaluator.h +++ b/src/plugins/cppeditor/cppelementevaluator.h @@ -46,7 +46,6 @@ namespace CppTools { class CppModelManager; } namespace CppEditor { namespace Internal { -class CppEditorWidget; class CppElement; class CppElementEvaluator diff --git a/src/plugins/cppeditor/cpphighlighter.h b/src/plugins/cppeditor/cpphighlighter.h index 536ea30b6c9..2e4b870b048 100644 --- a/src/plugins/cppeditor/cpphighlighter.h +++ b/src/plugins/cppeditor/cpphighlighter.h @@ -35,7 +35,6 @@ namespace CppEditor { namespace Internal { -class CppEditorWidget; class CppHighlighter : public TextEditor::SyntaxHighlighter { diff --git a/src/plugins/cppeditor/cpptypehierarchy.h b/src/plugins/cppeditor/cpptypehierarchy.h index 125fb58338c..355f87065d9 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.h +++ b/src/plugins/cppeditor/cpptypehierarchy.h @@ -37,12 +37,9 @@ class QLabel; class QModelIndex; class QStackedLayout; class QStandardItem; -template class QVector; template class QList; QT_END_NAMESPACE -namespace Core { class IEditor; } - namespace TextEditor { class TextEditorLinkLabel; } namespace Utils { @@ -55,7 +52,6 @@ namespace Internal { class CppEditorWidget; class CppClass; -class CppClassLabel; class CppTypeHierarchyModel : public QStandardItemModel { diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 6d64a7e4409..a860e5defaf 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -180,7 +180,7 @@ namespace Internal { static inline bool isCreatorConsole(const DebuggerRunParameters &sp) { - return !boolSetting(UseCdbConsole) && sp.useTerminal + return !boolSetting(UseCdbConsole) && sp.inferior.runMode == ApplicationLauncher::Console && (sp.startMode == StartInternal || sp.startMode == StartExternal); } @@ -428,7 +428,7 @@ void CdbEngine::consoleStubProcessStarted() attachParameters.inferior.commandLineArguments.clear(); attachParameters.attachPID = ProcessHandle(m_consoleStub->applicationPID()); attachParameters.startMode = AttachExternal; - attachParameters.useTerminal = false; + attachParameters.inferior.runMode = ApplicationLauncher::Gui; // Force no terminal. showMessage(QString("Attaching to %1...").arg(attachParameters.attachPID.pid()), LogMisc); QString errorMessage; if (!launchCDB(attachParameters, &errorMessage)) { @@ -542,7 +542,7 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage // register idle (debuggee stop) notification << "-c" << ".idle_cmd " + m_extensionCommandPrefix + "idle"; - if (sp.useTerminal) // Separate console + if (sp.inferior.runMode == ApplicationLauncher::Console) // Separate console arguments << "-2"; if (boolSetting(IgnoreFirstChanceAccessViolation)) arguments << "-x"; @@ -610,7 +610,8 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage // Make sure that QTestLib uses OutputDebugString for logging. const QString qtLoggingToConsoleKey = QStringLiteral("QT_LOGGING_TO_CONSOLE"); - if (!sp.useTerminal && !inferiorEnvironment.hasKey(qtLoggingToConsoleKey)) + if (sp.inferior.runMode != ApplicationLauncher::Console + && !inferiorEnvironment.hasKey(qtLoggingToConsoleKey)) inferiorEnvironment.set(qtLoggingToConsoleKey, QString(QLatin1Char('0'))); m_process.setEnvironment(mergeEnvironment(inferiorEnvironment.toStringList(), diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 8668243ab46..64e1721f4de 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -406,8 +406,8 @@ void StartApplicationDialog::run(bool attachRemote) Kit *k = dialog.d->kitChooser->currentKit(); IDevice::ConstPtr dev = DeviceKitInformation::device(k); - DebuggerRunTool *debugger = DebuggerRunTool::createFromKit(k); - QTC_ASSERT(debugger, return); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, k); const StartApplicationParameters newParameters = dialog.parameters(); if (newParameters != history.back()) { @@ -425,7 +425,6 @@ void StartApplicationDialog::run(bool attachRemote) } StandardRunnable inferior = newParameters.runnable; - debugger->setUseTerminal(newParameters.runnable.runMode == ApplicationLauncher::Console); const QString inputAddress = dialog.d->channelOverrideEdit->text(); if (!inputAddress.isEmpty()) debugger->setRemoteChannel(inputAddress); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index ecf31ab8410..ad58dc42daa 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -106,7 +106,6 @@ QDebug operator<<(QDebug str, const DebuggerRunParameters &sp) << " debugger environment=<" << sp.debugger.environment.size() << " variables>" << " workingDir=" << sp.inferior.workingDirectory << " attachPID=" << sp.attachPID.pid() - << " useTerminal=" << sp.useTerminal << " remoteChannel=" << sp.remoteChannel << " abi=" << sp.toolChainAbi.toString() << '\n'; return str; @@ -329,7 +328,7 @@ public: // The state we had before something unexpected happend. DebuggerState m_lastGoodState = DebuggerNotReady; - Terminal m_terminal; +// Terminal m_terminal; ProcessHandle m_inferiorPid; ModulesHandler m_modulesHandler; @@ -545,18 +544,18 @@ void DebuggerEngine::start() d->m_lastGoodState = DebuggerNotReady; d->m_progress.setProgressValue(200); - d->m_terminal.setup(); - if (d->m_terminal.isUsable()) { - connect(&d->m_terminal, &Terminal::stdOutReady, [this](const QString &msg) { - d->m_runTool->appendMessage(msg, Utils::StdOutFormatSameLine); - }); - connect(&d->m_terminal, &Terminal::stdErrReady, [this](const QString &msg) { - d->m_runTool->appendMessage(msg, Utils::StdErrFormatSameLine); - }); - connect(&d->m_terminal, &Terminal::error, [this](const QString &msg) { - d->m_runTool->appendMessage(msg, Utils::ErrorMessageFormat); - }); - } +// d->m_terminal.setup(); +// if (d->m_terminal.isUsable()) { +// connect(&d->m_terminal, &Terminal::stdOutReady, [this](const QString &msg) { +// d->m_runTool->appendMessage(msg, Utils::StdOutFormatSameLine); +// }); +// connect(&d->m_terminal, &Terminal::stdErrReady, [this](const QString &msg) { +// d->m_runTool->appendMessage(msg, Utils::StdErrFormatSameLine); +// }); +// connect(&d->m_terminal, &Terminal::error, [this](const QString &msg) { +// d->m_runTool->appendMessage(msg, Utils::ErrorMessageFormat); +// }); +// } d->queueSetupEngine(); QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state()); @@ -1378,9 +1377,10 @@ DebuggerRunTool *DebuggerEngine::runTool() const return d->m_runTool.data(); } -Terminal *DebuggerEngine::terminal() const +TerminalRunner *DebuggerEngine::terminal() const { - return &d->m_terminal; + QTC_ASSERT(d->m_runTool, return nullptr); + return d->m_runTool->terminalRunner(); } void DebuggerEngine::selectWatchData(const QString &) diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 89723096d06..5178cb631c5 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -74,6 +74,7 @@ class QmlCppEngine; class DebuggerToolTipContext; class MemoryViewSetupData; class Terminal; +class TerminalRunner; class ThreadId; class DebuggerRunParameters @@ -87,7 +88,6 @@ public: Utils::Environment stubEnvironment; Utils::ProcessHandle attachPID; QStringList solibSearchPath; - bool useTerminal = false; // Used by Qml debugging. QUrl qmlServer; @@ -461,7 +461,7 @@ protected: void setMasterEngine(DebuggerEngine *masterEngine); ProjectExplorer::RunControl *runControl() const; - Terminal *terminal() const; + TerminalRunner *terminal() const; static QString msgStopped(const QString &reason = QString()); static QString msgStoppedBySignal(const QString &meaning, const QString &name); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index dcc07a6d87d..5e378ac20c0 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -637,6 +637,7 @@ public: bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); void aboutToShutdown(); + void doShutdown(); void connectEngine(DebuggerRunTool *runTool); void disconnectEngine() { connectEngine(0); } @@ -763,8 +764,6 @@ public: void aboutToUnloadSession(); void aboutToSaveSession(); - void coreShutdown(); - public: void updateDebugActions(); @@ -1050,6 +1049,7 @@ public: DebuggerPlugin *m_plugin = 0; SnapshotHandler *m_snapshotHandler = 0; + QTimer m_shutdownTimer; bool m_shuttingDown = false; QPointer m_previouslyActiveEngine; QPointer m_currentRunTool; @@ -1178,9 +1178,8 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, if (!kit) kit = guessKitFromAbis(Abi::abisOfBinary(FileName::fromString(executable))); - auto debugger = DebuggerRunTool::createFromKit(kit); - QTC_ASSERT(debugger, return false); - + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, kit); if (pid) { debugger->setStartMode(AttachExternal); debugger->setCloseMode(DetachAtClose); @@ -1221,8 +1220,8 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, return false; } qint64 pid = it->section(':', 1, 1).toULongLong(); - auto debugger = DebuggerRunTool::createFromKit(findUniversalCdbKit()); - QTC_ASSERT(debugger, return false); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, findUniversalCdbKit()); debugger->setStartMode(AttachCrashedExternal); debugger->setCrashParameter(it->section(':', 0, 0)); debugger->setAttachPid(pid); @@ -1319,8 +1318,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, m_debuggerSettings = new DebuggerSettings; m_debuggerSettings->readSettings(); - connect(ICore::instance(), &ICore::coreAboutToClose, this, &DebuggerPluginPrivate::coreShutdown); - const Context cppDebuggercontext(C_CPPDEBUGGER); const Context qmljsDebuggercontext(C_QMLDEBUGGER); @@ -1960,9 +1957,8 @@ void DebuggerPluginPrivate::attachCore() setConfigValue("LastExternalStartScript", dlg.overrideStartScript()); setConfigValue("LastForceLocalCoreFile", dlg.forcesLocalCoreFile()); - auto debugger = DebuggerRunTool::createFromKit(dlg.kit()); - QTC_ASSERT(debugger, return); - debugger->setMasterEngineType(DebuggerKitInformation::engineType(dlg.kit())); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, dlg.kit()); debugger->setInferiorExecutable(dlg.localExecutableFile()); debugger->setCoreFileName(dlg.localCoreFile()); debugger->setRunControlName(tr("Core file \"%1\"") @@ -1988,8 +1984,8 @@ void DebuggerPluginPrivate::startRemoteCdbSession() return; setConfigValue(connectionKey, dlg.connection()); - auto debugger = DebuggerRunTool::createFromKit(kit); - QTC_ASSERT(debugger, return); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, kit); debugger->setStartMode(AttachToRemoteServer); debugger->setCloseMode(KillAtClose); debugger->setRemoteChannel(dlg.connection()); @@ -2090,8 +2086,8 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit, return 0; } - auto debugger = DebuggerRunTool::createFromKit(kit); - QTC_ASSERT(debugger, return nullptr); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, kit); debugger->setAttachPid(ProcessHandle(process.pid)); debugger->setRunControlName(tr("Process %1").arg(process.pid)); debugger->setInferiorExecutable(process.exe); @@ -2106,20 +2102,14 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit, void DebuggerPlugin::attachExternalApplication(RunControl *rc) { - DebuggerRunTool *debugger; - if (RunConfiguration *runConfig = rc->runConfiguration()) { - debugger = DebuggerRunTool::createFromRunConfiguration(runConfig); - } else { - Kit *kit = guessKitFromAbis({rc->abi()}); - debugger = DebuggerRunTool::createFromKit(kit); - } - QTC_ASSERT(debugger, return); ProcessHandle pid = rc->applicationProcessHandle(); + RunConfiguration *runConfig = rc->runConfiguration(); + auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, guessKitFromAbis({rc->abi()})); debugger->setAttachPid(pid); debugger->setRunControlName(tr("Process %1").arg(pid.pid())); debugger->setStartMode(AttachExternal); debugger->setCloseMode(DetachAtClose); - debugger->setToolChainAbi(rc->abi()); debugger->startRunControl(); } @@ -2171,8 +2161,8 @@ void DebuggerPluginPrivate::attachToQmlPort() IDevice::ConstPtr device = DeviceKitInformation::device(kit); QTC_ASSERT(device, return); - auto debugger = DebuggerRunTool::createFromKit(kit); - QTC_ASSERT(debugger, return); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, kit); QUrl qmlServer = device->toolControlChannel(IDevice::QmlControlChannel); qmlServer.setPort(dlg.port()); @@ -2796,13 +2786,23 @@ void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout) m_mainWindow->showStatusMessage(msg, timeout); } -void DebuggerPluginPrivate::coreShutdown() +void DebuggerPluginPrivate::aboutToShutdown() { m_shuttingDown = true; - if (currentEngine()) { - if (currentEngine()->state() != Debugger::DebuggerNotReady) - currentEngine()->abortDebugger(); + + disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr); + + m_mainWindow->saveCurrentPerspective(); + m_shutdownTimer.setInterval(0); + m_shutdownTimer.setSingleShot(true); + connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown); + if (DebuggerEngine *engine = currentEngine()) { + if (engine->state() != Debugger::DebuggerNotReady) { + engine->abortDebugger(); + m_shutdownTimer.setInterval(3000); + } } + m_shutdownTimer.start(); } const CPlusPlus::Snapshot &cppCodeModelSnapshot() @@ -2878,8 +2878,9 @@ static void createNewDock(QWidget *widget) dockWidget->show(); } -static QString formatStartParameters(const DebuggerRunParameters &sp) +static QString formatStartParameters(const DebuggerRunTool *debugger) { + const DebuggerRunParameters &sp = debugger->runParameters(); QString rc; QTextStream str(&rc); str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode @@ -2893,7 +2894,7 @@ static QString formatStartParameters(const DebuggerRunParameters &sp) if (!sp.inferior.executable.isEmpty()) { str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable) << ' ' << sp.inferior.commandLineArguments; - if (sp.useTerminal) + if (debugger->terminalRunner()) str << " [terminal]"; str << '\n'; if (!sp.inferior.workingDirectory.isEmpty()) @@ -2928,7 +2929,7 @@ void DebuggerPluginPrivate::runControlStarted(DebuggerRunTool *runTool) .arg(runTool->engine()->objectName()) .arg(runTool->runParameters().toolChainAbi.toString()); showStatusMessage(message); - showMessage(formatStartParameters(runTool->runParameters()), LogDebug); + showMessage(formatStartParameters(runTool), LogDebug); showMessage(m_debuggerSettings->dump(), LogDebug); m_snapshotHandler->appendSnapshot(runTool); connectEngine(runTool); @@ -2938,11 +2939,13 @@ void DebuggerPluginPrivate::runControlFinished(DebuggerRunTool *runTool) { if (runTool && runTool->engine()) runTool->engine()->handleFinished(); - if (m_shuttingDown) - return; showStatusMessage(tr("Debugger finished.")); m_snapshotHandler->removeSnapshot(runTool); if (m_snapshotHandler->size() == 0) { + if (m_shuttingDown) { + doShutdown(); + return; + } // Last engine quits. disconnectEngine(); if (boolSetting(SwitchModeOnExit)) @@ -3120,11 +3123,9 @@ void showModuleSections(const QString &moduleName, const Sections §ions) createNewDock(w); } -void DebuggerPluginPrivate::aboutToShutdown() +void DebuggerPluginPrivate::doShutdown() { - disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr); - - m_mainWindow->saveCurrentPerspective(); + m_shutdownTimer.stop(); delete m_mainWindow; m_mainWindow = 0; @@ -3140,6 +3141,7 @@ void DebuggerPluginPrivate::aboutToShutdown() delete m_mode; m_mode = 0; + emit m_plugin->asynchronousShutdownFinished(); } void updateState(DebuggerRunTool *runTool) @@ -3302,7 +3304,7 @@ IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown() { removeObject(this); dd->aboutToShutdown(); - return SynchronousShutdown; + return AsynchronousShutdown; } QObject *DebuggerPlugin::remoteCommand(const QStringList &options, @@ -3648,7 +3650,9 @@ void DebuggerUnitTests::testStateMachine() RunConfiguration *rc = t->activeRunConfiguration(); QVERIFY(rc); - auto debugger = DebuggerRunTool::createFromRunConfiguration(rc); + auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl); + debugger->setInferior(rc->runnable().as()); debugger->setTestCase(TestNoBoundsOfCurrentFunction); diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index eeff836bc2f..5d9870d8679 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "debuggerruncontrol.h" +#include "terminal.h" #include "analyzer/analyzermanager.h" #include "console/console.h" @@ -76,7 +77,7 @@ namespace Debugger { namespace Internal { DebuggerEngine *createCdbEngine(QStringList *error, DebuggerStartMode sm); -DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode sm); +DebuggerEngine *createGdbEngine(); DebuggerEngine *createPdbEngine(); DebuggerEngine *createQmlEngine(bool useTerminal); DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal); @@ -173,8 +174,13 @@ public: Utils::QtcProcess m_proc; }; -} // namespace Internal +class DebuggerRunToolPrivate +{ +public: + QPointer terminalRunner; +}; +} // namespace Internal static bool breakOnMainNextTime = false; @@ -284,7 +290,13 @@ void DebuggerRunTool::setBreakOnMain(bool on) void DebuggerRunTool::setUseTerminal(bool on) { - m_runParameters.useTerminal = on; + if (on && !d->terminalRunner && m_runParameters.cppEngineType == GdbEngineType) { + d->terminalRunner = new TerminalRunner(this); + addStartDependency(d->terminalRunner); + } + if (!on && d->terminalRunner) { + QTC_CHECK(false); // User code can only switch from no terminal to one terminal. + } } void DebuggerRunTool::setCommandsAfterConnect(const QString &commands) @@ -339,15 +351,11 @@ void DebuggerRunTool::setOverrideStartScript(const QString &script) m_runParameters.overrideStartScript = script; } -void DebuggerRunTool::setToolChainAbi(const Abi &abi) -{ - m_runParameters.toolChainAbi = abi; -} - void DebuggerRunTool::setInferior(const Runnable &runnable) { QTC_ASSERT(runnable.is(), reportFailure(); return); m_runParameters.inferior = runnable.as(); + setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console); } void DebuggerRunTool::setInferiorExecutable(const QString &executable) @@ -397,11 +405,6 @@ void DebuggerRunTool::addQmlServerInferiorCommandLineArgumentIfNeeded() } } -void DebuggerRunTool::setMasterEngineType(DebuggerEngineType engineType) -{ - m_runParameters.masterEngineType = engineType; -} - void DebuggerRunTool::setCrashParameter(const QString &event) { m_runParameters.crashParameter = event; @@ -479,7 +482,7 @@ void DebuggerRunTool::start() switch (m_runParameters.cppEngineType) { case GdbEngineType: - cppEngine = createGdbEngine(m_runParameters.useTerminal, m_runParameters.startMode); + cppEngine = createGdbEngine(); break; case CdbEngineType: { QStringList errors; @@ -503,11 +506,11 @@ void DebuggerRunTool::start() switch (m_runParameters.masterEngineType) { case QmlEngineType: - m_engine = createQmlEngine(m_runParameters.useTerminal); + m_engine = createQmlEngine(terminalRunner() != nullptr); break; case QmlCppEngineType: if (cppEngine) - m_engine = createQmlCppEngine(cppEngine, m_runParameters.useTerminal); + m_engine = createQmlCppEngine(cppEngine, terminalRunner() != nullptr); break; default: m_engine = cppEngine; @@ -572,11 +575,6 @@ void DebuggerRunTool::debuggingFinished() reportStopped(); } -DebuggerRunParameters &DebuggerRunTool::runParameters() -{ - return m_runParameters; -} - const DebuggerRunParameters &DebuggerRunTool::runParameters() const { return m_runParameters; @@ -720,14 +718,6 @@ bool DebuggerRunTool::fixupParameters() } } - // FIXME: We can't handle terminals yet. - if (rp.useTerminal && rp.cppEngineType == LldbEngineType) { - qWarning("Run in Terminal is not supported yet with the LLDB backend"); - appendMessage(DebuggerPlugin::tr("Run in Terminal is not supported with the LLDB backend."), - ErrorMessageFormat); - rp.useTerminal = false; - } - if (rp.isNativeMixedDebugging()) rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1"); @@ -737,8 +727,13 @@ bool DebuggerRunTool::fixupParameters() return true; } -DebuggerRunTool::DebuggerRunTool(RunControl *runControl) - : RunWorker(runControl) +Internal::TerminalRunner *DebuggerRunTool::terminalRunner() const +{ + return d->terminalRunner; +} + +DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit) + : RunWorker(runControl), d(new DebuggerRunToolPrivate) { setDisplayName("DebuggerRunTool"); @@ -755,13 +750,25 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl) QString(), QString(), optionalPrompt); }); + if (runConfig) + m_runParameters.displayName = runConfig->displayName(); + + if (runConfig && !kit) + kit = runConfig->target()->kit(); + QTC_ASSERT(kit, return); + + m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit); + m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); + m_runParameters.macroExpander = kit->macroExpander(); + m_runParameters.debugger = DebuggerKitInformation::runnable(kit); + Runnable r = runnable(); if (r.is()) { m_runParameters.inferior = r.as(); - m_runParameters.useTerminal = m_runParameters.inferior.runMode == ApplicationLauncher::Console; // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) m_runParameters.inferior.workingDirectory = FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory); + setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console); } if (auto aspect = runConfig ? runConfig->extraAspect() : nullptr) { @@ -770,15 +777,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl) m_runParameters.multiProcess = aspect->useMultiProcess(); } - if (runConfig) - m_runParameters.displayName = runConfig->displayName(); - - const Kit *kit = runConfig->target()->kit(); - QTC_ASSERT(kit, return); - - m_runParameters.macroExpander = kit->macroExpander(); - - m_runParameters.debugger = DebuggerKitInformation::runnable(kit); const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); if (!envBinary.isEmpty()) m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary); @@ -796,9 +794,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl) if (ok) m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride); - m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit); - m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - // This will only be shown in some cases, but we don't want to access // the kit at that time anymore. const QList tasks = DebuggerKitInformation::validateDebugger(kit); @@ -807,7 +802,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl) m_runParameters.validationErrors.append(t.description); } - if (runConfig->property("supportsDebugger").toBool()) { + if (runConfig && runConfig->property("supportsDebugger").toBool()) { const QString mainScript = runConfig->property("mainScript").toString(); const QString interpreter = runConfig->property("interpreter").toString(); if (!interpreter.isEmpty() && mainScript.endsWith(".py")) { @@ -819,6 +814,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl) m_runParameters.inferior.commandLineArguments.append(' '); m_runParameters.inferior.commandLineArguments.append(args); } + m_runParameters.cppEngineType = PdbEngineType; m_runParameters.masterEngineType = PdbEngineType; } } @@ -829,45 +825,11 @@ DebuggerEngine *DebuggerRunTool::activeEngine() const return m_engine ? m_engine->activeEngine() : nullptr; } -class DummyProject : public Project -{ -public: - DummyProject() : Project(QString(""), FileName::fromString("")) {} -}; - -RunConfiguration *dummyRunConfigForKit(ProjectExplorer::Kit *kit) -{ - QTC_ASSERT(kit, return nullptr); // Caller needs to look for a suitable kit. - Project *project = SessionManager::startupProject(); - Target *target = project ? project->target(kit) : nullptr; - if (!target || !target->activeRunConfiguration()) { - project = new DummyProject; // FIXME: Leaks. - target = project->createTarget(kit); - } - QTC_ASSERT(target, return nullptr); - auto runConfig = target->activeRunConfiguration(); - return runConfig; -} - -DebuggerRunTool *DebuggerRunTool::createFromKit(Kit *kit) -{ - RunConfiguration *runConfig = dummyRunConfigForKit(kit); - return createFromRunConfiguration(runConfig); -} - void DebuggerRunTool::startRunControl() { ProjectExplorerPlugin::startRunControl(runControl()); } -DebuggerRunTool *DebuggerRunTool::createFromRunConfiguration(RunConfiguration *runConfig) -{ - QTC_ASSERT(runConfig, return nullptr); - auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE); - auto debugger = new DebuggerRunTool(runControl); - return debugger; -} - void DebuggerRunTool::addSolibSearchDir(const QString &str) { QString path = str; @@ -884,6 +846,7 @@ DebuggerRunTool::~DebuggerRunTool() engine->disconnect(); delete engine; } + delete d; } void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout) diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index ff46db5059f..794ee3ee6b6 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -37,19 +37,23 @@ namespace Debugger { +namespace Internal { +class TerminalRunner; +class DebuggerRunToolPrivate; +} // Internal + class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker { Q_OBJECT public: - explicit DebuggerRunTool(ProjectExplorer::RunControl *runControl); + explicit DebuggerRunTool(ProjectExplorer::RunControl *runControl, + ProjectExplorer::Kit *kit = nullptr); ~DebuggerRunTool(); Internal::DebuggerEngine *engine() const { return m_engine; } Internal::DebuggerEngine *activeEngine() const; - static DebuggerRunTool *createFromRunConfiguration(ProjectExplorer::RunConfiguration *runConfig); - static DebuggerRunTool *createFromKit(ProjectExplorer::Kit *kit); // Avoid, it's guessing. void startRunControl(); void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1); @@ -65,7 +69,6 @@ public: void abortDebugger(); void debuggingFinished(); - Internal::DebuggerRunParameters &runParameters(); const Internal::DebuggerRunParameters &runParameters() const; void startDying() { m_isDying = true; } @@ -87,7 +90,6 @@ public: void prependInferiorCommandLineArgument(const QString &arg); void addQmlServerInferiorCommandLineArgumentIfNeeded(); - void setMasterEngineType(DebuggerEngineType engineType); void setCrashParameter(const QString &event); void addExpectedSignal(const QString &signal); @@ -129,7 +131,8 @@ public: void setNeedFixup(bool) {} // FIXME: Remove after use in QtAppMan is gone. void setTestCase(int testCase); void setOverrideStartScript(const QString &script); - void setToolChainAbi(const ProjectExplorer::Abi &abi); + + Internal::TerminalRunner *terminalRunner() const; signals: void aboutToNotifyInferiorSetupOk(); @@ -137,6 +140,7 @@ signals: private: bool fixupParameters(); + Internal::DebuggerRunToolPrivate *d; QPointer m_engine; // Master engine Internal::DebuggerRunParameters m_runParameters; bool m_isDying = false; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index ece1d1c87c4..2370d6f22f9 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -137,11 +137,6 @@ static bool isMostlyHarmlessMessage(const QStringRef &msg) "Invalid argument\\n"; } -static QString mainFunction(const DebuggerRunParameters &rp) -{ - return QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS && !rp.useTerminal ? "qMain" : "main"); -} - /////////////////////////////////////////////////////////////////////// // // Debuginfo Taskhandler @@ -194,8 +189,7 @@ private: // /////////////////////////////////////////////////////////////////////// -GdbEngine::GdbEngine(bool useTerminal, DebuggerStartMode startMode) - : m_startMode(startMode), m_useTerminal(useTerminal), m_terminalTrap(useTerminal) +GdbEngine::GdbEngine() { setObjectName("GdbEngine"); @@ -221,26 +215,10 @@ GdbEngine::GdbEngine(bool useTerminal, DebuggerStartMode startMode) // Output connect(&m_outputCollector, &OutputCollector::byteDelivery, this, &GdbEngine::readDebuggeeOutput); - - if (isTermEngine()) { - if (HostOsInfo::isWindowsHost()) { - // Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win - if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) - m_stubProc.setMode(ConsoleProcess::Suspend); - else - m_stubProc.setMode(ConsoleProcess::Debug); - } else { - m_stubProc.setMode(ConsoleProcess::Debug); - m_stubProc.setSettings(ICore::settings()); - } - } } GdbEngine::~GdbEngine() { - if (isTermEngine()) - m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub - if (isCoreEngine()) { if (m_coreUnpackProcess) { m_coreUnpackProcess->blockSignals(true); @@ -781,9 +759,6 @@ void GdbEngine::interruptInferior() CHECK_STATE(InferiorStopRequested); - if (terminal()->sendInterrupt()) - return; - if (usesExecInterrupt()) { runCommand({"-exec-interrupt"}); } else { @@ -1079,7 +1054,7 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response) Abi abi = rp.toolChainAbi; if (abi.os() == Abi::WindowsOS && cmd.function.startsWith("attach") - && (rp.startMode == AttachExternal || rp.useTerminal)) + && (rp.startMode == AttachExternal || terminal())) { // Ignore spurious 'running' responses to 'attach'. } else { @@ -1240,11 +1215,13 @@ void GdbEngine::handleStopResponse(const GdbMi &data) { // Ignore trap on Windows terminals, which results in // spurious "* stopped" message. - if (m_terminalTrap && (!data.isValid() || !data["reason"].isValid()) - && Abi::hostAbi().os() == Abi::WindowsOS) { - m_terminalTrap = false; - showMessage("IGNORING TERMINAL SIGTRAP", LogMisc); - return; + if (m_expectTerminalTrap) { + m_expectTerminalTrap = false; + if ((!data.isValid() || !data["reason"].isValid()) + && Abi::hostAbi().os() == Abi::WindowsOS) { + showMessage("IGNORING TERMINAL SIGTRAP", LogMisc); + return; + } } if (isDying()) { @@ -1279,7 +1256,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) // Ignore signals from the process stub. const GdbMi frame = data["frame"]; const QString func = frame["from"].data(); - if (runParameters().useTerminal + if (terminal() && data["reason"].data() == "signal-received" && data["signal-name"].data() == "SIGSTOP" && (func.endsWith("/ld-linux.so.2") @@ -1371,8 +1348,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) // This is gdb 7+'s initial *stopped in response to attach that // appears before the ^done is seen. notifyEngineRunAndInferiorStopOk(); - const DebuggerRunParameters &rp = runParameters(); - if (rp.useTerminal) + if (terminal()) continueInferiorInternal(); return; } else { @@ -1497,7 +1473,7 @@ void GdbEngine::handleStop2(const GdbMi &data) bool isStopperThread = false; if (rp.toolChainAbi.os() == Abi::WindowsOS - && rp.useTerminal + && terminal() && reason == "signal-received" && data["signal-name"].data() == "SIGTRAP") { @@ -2345,7 +2321,7 @@ QString GdbEngine::breakpointLocation(const BreakpointParameters &data) if (data.type == BreakpointAtCatch) return QLatin1String("__cxa_begin_catch"); if (data.type == BreakpointAtMain) - return mainFunction(runParameters()); + return mainFunction(); if (data.type == BreakpointByFunction) return '"' + data.functionName + '"'; if (data.type == BreakpointByAddress) @@ -3293,8 +3269,9 @@ void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QStri const StackFrame &frame = frames.at(0); function = frame.function + ":" + QString::number(frame.line); } - auto debugger = DebuggerRunTool::createFromRunConfiguration(runControl()->runConfiguration()); - QTC_ASSERT(debugger, return); + QTC_ASSERT(runControl()->runConfiguration(), return); + auto rc = new RunControl(runControl()->runConfiguration(), ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(rc); debugger->setStartMode(AttachCore); debugger->setRunControlName(function + ": " + QDateTime::currentDateTime().toString()); debugger->setCoreFileName(coreFile, true); @@ -3799,6 +3776,7 @@ void GdbEngine::startGdb(const QStringList &args) showMessage("ENABLING TEST CASE: " + QString::number(test)); m_gdbProc.disconnect(); // From any previous runs + m_expectTerminalTrap = terminal(); const DebuggerRunParameters &rp = runParameters(); if (rp.debugger.executable.isEmpty()) { @@ -3950,8 +3928,8 @@ void GdbEngine::startGdb(const QStringList &args) // Don't use ConsoleCommand, otherwise Mac won't markup the output. const QString dumperSourcePath = ICore::resourcePath() + "/debugger/"; - if (terminal()->isUsable()) - runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())}); + //if (terminal()->isUsable()) + // runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())}); const QFileInfo gdbBinaryFile(rp.debugger.executable); const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python"; @@ -3976,9 +3954,7 @@ void GdbEngine::startGdb(const QStringList &args) void GdbEngine::handleGdbStartFailed() { - if (isTermEngine()) - m_stubProc.stop(); - else if (isPlainEngine()) + if (isPlainEngine()) m_outputCollector.shutdown(); } @@ -4119,7 +4095,7 @@ void GdbEngine::handleInferiorPrepared() //runCommand("set follow-exec-mode new"); if (rp.breakOnMain) - runCommand({"tbreak " + mainFunction(rp)}); + runCommand({"tbreak " + mainFunction()}); // Initial attempt to set breakpoints. if (rp.startMode != AttachCore) { @@ -4315,7 +4291,7 @@ void GdbEngine::debugLastCommand() bool GdbEngine::isPlainEngine() const { - return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && !m_terminalTrap; + return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && !terminal(); } bool GdbEngine::isCoreEngine() const @@ -4335,11 +4311,13 @@ bool GdbEngine::isAttachEngine() const bool GdbEngine::isTermEngine() const { - return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && m_terminalTrap; + return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && terminal(); } void GdbEngine::setupEngine() { + m_startMode = runParameters().startMode; + CHECK_STATE(EngineSetupRequested); showMessage("TRYING TO START ADAPTER"); @@ -4358,30 +4336,7 @@ void GdbEngine::setupEngine() showMessage("TRYING TO START ADAPTER"); - // Currently, GdbEngines are not re-used - // // We leave the console open, so recycle it now. - // m_stubProc.blockSignals(true); - // m_stubProc.stop(); - // m_stubProc.blockSignals(false); - - m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory); - // Set environment + dumper preload. - m_stubProc.setEnvironment(runParameters().stubEnvironment); - - connect(&m_stubProc, &ConsoleProcess::processError, - this, &GdbEngine::stubError); - connect(&m_stubProc, &ConsoleProcess::processStarted, - this, [this] { startGdb(); }); - connect(&m_stubProc, &ConsoleProcess::stubStopped, - this, &GdbEngine::stubExited); - // FIXME: Starting the stub implies starting the inferior. This is - // fairly unclean as far as the state machine and error reporting go. - - if (!m_stubProc.start(runParameters().inferior.executable, - runParameters().inferior.commandLineArguments)) { - // Error message for user is delivered via a signal. - handleAdapterStartFailed(QString()); - } + startGdb(); } else if (isCoreEngine()) { @@ -4491,8 +4446,8 @@ void GdbEngine::setupInferior() } else if (isTermEngine()) { - const qint64 attachedPID = m_stubProc.applicationPID(); - const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID(); + const qint64 attachedPID = terminal()->applicationPid(); + const qint64 attachedMainThreadID = terminal()->applicationMainThreadId(); notifyInferiorPid(ProcessHandle(attachedPID)); const QString msg = (attachedMainThreadID != -1) ? QString("Going to attach to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID) @@ -4550,9 +4505,12 @@ void GdbEngine::runEngine() } else if (isTermEngine()) { - const qint64 attachedPID = m_stubProc.applicationPID(); + const qint64 attachedPID = terminal()->applicationPid(); + const qint64 mainThreadId = terminal()->applicationMainThreadId(); runCommand({"attach " + QString::number(attachedPID), - [this](const DebuggerResponse &r) { handleStubAttached(r); }}); + [this, mainThreadId](const DebuggerResponse &r) { + handleStubAttached(r, mainThreadId); + }}); } else if (isPlainEngine()) { @@ -4910,7 +4868,7 @@ void GdbEngine::handleInterruptInferior(const DebuggerResponse &response) } } -void GdbEngine::handleStubAttached(const DebuggerResponse &response) +void GdbEngine::handleStubAttached(const DebuggerResponse &response, qint64 mainThreadId) { // InferiorStopOk can happen if the "*stopped" in response to the // 'attach' comes in before its '^done' @@ -4922,7 +4880,6 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response) if (runParameters().toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS) { QString errorMessage; // Resume thread that was suspended by console stub process (see stub code). - const qint64 mainThreadId = m_stubProc.applicationMainThreadID(); if (winResumeThread(mainThreadId, &errorMessage)) { showMessage(QString("Inferior attached, thread %1 resumed"). arg(mainThreadId), LogMisc); @@ -4955,22 +4912,6 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response) } } -void GdbEngine::stubError(const QString &msg) -{ - AsynchronousMessageBox::critical(tr("Debugger Error"), msg); - notifyEngineIll(); -} - -void GdbEngine::stubExited() -{ - if (state() == EngineShutdownRequested || state() == DebuggerFinished) { - showMessage("STUB EXITED EXPECTEDLY"); - } else { - showMessage("STUB EXITED"); - notifyEngineIll(); - } -} - static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile) { if (fileNameFromCore.isEmpty()) @@ -5211,13 +5152,19 @@ QString GdbEngine::msgPtraceError(DebuggerStartMode sm) "For more details, see /etc/sysctl.d/10-ptrace.conf\n"); } +QString GdbEngine::mainFunction() const +{ + const DebuggerRunParameters &rp = runParameters(); + return QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS && !terminal() ? "qMain" : "main"); +} + // // Factory // -DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode startMode) +DebuggerEngine *createGdbEngine() { - return new GdbEngine(useTerminal, startMode); + return new GdbEngine; } } // namespace Internal diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index a7537cfdebd..506f68c34c6 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -55,6 +55,7 @@ class DebuggerResponse; class DisassemblerAgentCookie; class GdbMi; class MemoryAgentCookie; +class TerminalRunner; struct CoreInfo { @@ -71,7 +72,7 @@ class GdbEngine : public DebuggerEngine Q_OBJECT public: - explicit GdbEngine(bool useTerminal, DebuggerStartMode startMode); + GdbEngine(); ~GdbEngine() final; private: ////////// General Interface ////////// @@ -91,7 +92,6 @@ private: ////////// General Interface ////////// ////////// General State ////////// - const DebuggerStartMode m_startMode; bool m_registerNamesListed = false; ////////// Gdb Process Management ////////// @@ -382,8 +382,7 @@ private: ////////// General Interface ////////// QString m_currentThread; QString m_lastWinException; QString m_lastMissingDebugInfo; - const bool m_useTerminal; - bool m_terminalTrap; + bool m_expectTerminalTrap = false; bool usesExecInterrupt() const; bool usesTargetAsync() const; @@ -441,10 +440,7 @@ private: ////////// General Interface ////////// void interruptLocalInferior(qint64 pid); // Terminal - void handleStubAttached(const DebuggerResponse &response); - void stubExited(); - void stubError(const QString &msg); - Utils::ConsoleProcess m_stubProc; + void handleStubAttached(const DebuggerResponse &response, qint64 mainThreadId); // Core void handleTargetCore(const DebuggerResponse &response); @@ -454,6 +450,7 @@ private: ////////// General Interface ////////// QString coreName() const; void continueSetupEngine(); + QString mainFunction() const; QString m_executable; QString m_coreName; @@ -464,6 +461,7 @@ private: ////////// General Interface ////////// Utils::QtcProcess m_gdbProc; OutputCollector m_outputCollector; QString m_errorString; + DebuggerStartMode m_startMode = NoStartMode; }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp index 7a0c8c65e3f..a9596269ca5 100644 --- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp +++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp @@ -209,9 +209,8 @@ void GdbServerStarter::attach(int port) QString remoteChannel = QString("%1:%2").arg(d->device->sshParameters().host).arg(port); - auto debugger = DebuggerRunTool::createFromKit(d->kit); - QTC_ASSERT(debugger, return); - debugger->setMasterEngineType(GdbEngineType); + auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE); + auto debugger = new DebuggerRunTool(runControl, d->kit); debugger->setRemoteChannel(remoteChannel); debugger->setRunControlName(tr("Remote: \"%1\"").arg(remoteChannel)); debugger->setInferiorExecutable(localExecutable); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index bf00138e9b4..e9f4e78bfb3 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,6 @@ LldbEngine::LldbEngine() LldbEngine::~LldbEngine() { - m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub m_lldbProc.disconnect(); } @@ -155,8 +155,6 @@ void LldbEngine::shutdownEngine() { QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); m_lldbProc.kill(); - if (runParameters().useTerminal) - m_stubProc.stop(); notifyEngineShutdownOk(); } @@ -167,48 +165,6 @@ void LldbEngine::abortDebuggerProcess() void LldbEngine::setupEngine() { - if (runParameters().useTerminal) { - QTC_CHECK(false); // See above. - if (HostOsInfo::isWindowsHost()) { - // Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win - if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) - m_stubProc.setMode(ConsoleProcess::Suspend); - else - m_stubProc.setMode(ConsoleProcess::Debug); - } else { - m_stubProc.setMode(ConsoleProcess::Debug); - m_stubProc.setSettings(ICore::settings()); - } - - QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); - showMessage("TRYING TO START ADAPTER"); - - // Currently, adapters are not re-used - // // We leave the console open, so recycle it now. - // m_stubProc.blockSignals(true); - // m_stubProc.stop(); - // m_stubProc.blockSignals(false); - - m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory); - // Set environment + dumper preload. - m_stubProc.setEnvironment(runParameters().stubEnvironment); - - connect(&m_stubProc, &ConsoleProcess::processError, this, &LldbEngine::stubError); - connect(&m_stubProc, &ConsoleProcess::processStarted, this, &LldbEngine::stubStarted); - connect(&m_stubProc, &ConsoleProcess::stubStopped, this, &LldbEngine::stubExited); - // FIXME: Starting the stub implies starting the inferior. This is - // fairly unclean as far as the state machine and error reporting go. - - if (!m_stubProc.start(runParameters().inferior.executable, - runParameters().inferior.commandLineArguments)) { - // Error message for user is delivered via a signal. - //handleAdapterStartFailed(QString()); - notifyEngineSetupFailed(); - return; - } - - } - QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); startLldb(); } @@ -299,17 +255,17 @@ void LldbEngine::setupInferior() DebuggerCommand cmd2("setupInferior"); cmd2.arg("executable", executable); cmd2.arg("breakonmain", rp.breakOnMain); - cmd2.arg("useterminal", rp.useTerminal); + cmd2.arg("useterminal", bool(terminal())); cmd2.arg("startmode", rp.startMode); cmd2.arg("nativemixed", isNativeMixedActive()); cmd2.arg("workingdirectory", rp.inferior.workingDirectory); cmd2.arg("environment", rp.inferior.environment.toStringList()); cmd2.arg("processargs", args.toUnixArgs()); - if (rp.useTerminal) { + if (terminal()) { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); - const qint64 attachedPID = m_stubProc.applicationPID(); - const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID(); + const qint64 attachedPID = terminal()->applicationPid(); + const qint64 attachedMainThreadID = terminal()->applicationMainThreadId(); const QString msg = (attachedMainThreadID != -1) ? QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID) : QString::fromLatin1("Attaching to %1").arg(attachedPID); @@ -1100,25 +1056,5 @@ DebuggerEngine *createLldbEngine() return new LldbEngine; } -void LldbEngine::stubStarted() -{ - startLldb(); -} - -void LldbEngine::stubError(const QString &msg) -{ - AsynchronousMessageBox::critical(tr("Debugger Error"), msg); -} - -void LldbEngine::stubExited() -{ - if (state() == EngineShutdownRequested || state() == DebuggerFinished) { - showMessage("STUB EXITED EXPECTEDLY"); - return; - } - showMessage("STUB EXITED"); - notifyEngineIll(); -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index dff437497b6..9bc4a0b7c93 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -154,12 +154,6 @@ private: QHash m_commandForToken; DebuggerCommandSequence m_onStop; - - // Console handling. - void stubError(const QString &msg); - void stubExited(); - void stubStarted(); - Utils::ConsoleProcess m_stubProc; }; } // namespace Internal diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index c4f4ba0ba9b..09dcdb156c2 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -25,11 +25,16 @@ #include "terminal.h" +#include "debuggerruncontrol.h" + #include #include #include +#include + #include +#include #ifdef Q_OS_UNIX # define DEBUGGER_USE_TERMINAL @@ -45,6 +50,10 @@ # include #endif +using namespace Core; +using namespace ProjectExplorer; +using namespace Utils; + namespace Debugger { namespace Internal { @@ -159,6 +168,67 @@ void Terminal::onSlaveReaderActivated(int fd) #endif } +TerminalRunner::TerminalRunner(DebuggerRunTool *debugger) + : RunWorker(debugger->runControl()) +{ + setDisplayName("TerminalRunner"); + + const DebuggerRunParameters &rp = debugger->runParameters(); + m_stubRunnable = rp.inferior; + m_stubRunnable.environment = rp.stubEnvironment; + m_stubRunnable.workingDirectory = rp.inferior.workingDirectory; + + connect(&m_stubProc, &ConsoleProcess::processError, + this, &TerminalRunner::stubError); + connect(&m_stubProc, &ConsoleProcess::processStarted, + this, &TerminalRunner::stubStarted); + connect(&m_stubProc, &ConsoleProcess::stubStopped, + this, &TerminalRunner::stubExited); +} + +void TerminalRunner::start() +{ + m_stubProc.setEnvironment(m_stubRunnable.environment); + m_stubProc.setWorkingDirectory(m_stubRunnable.workingDirectory); + + if (HostOsInfo::isWindowsHost()) { + // Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) + m_stubProc.setMode(ConsoleProcess::Suspend); + else + m_stubProc.setMode(ConsoleProcess::Debug); + } else { + m_stubProc.setMode(ConsoleProcess::Debug); + m_stubProc.setSettings(Core::ICore::settings()); + } + + // Error message for user is delivered via a signal. + m_stubProc.start(m_stubRunnable.executable, m_stubRunnable.commandLineArguments); +} + +void TerminalRunner::stop() +{ + m_stubProc.stop(); + reportStopped(); +} + +void TerminalRunner::stubStarted() +{ + m_applicationPid = m_stubProc.applicationPID(); + m_applicationMainThreadId = m_stubProc.applicationMainThreadID(); + reportStarted(); +} + +void TerminalRunner::stubError(const QString &msg) +{ + reportFailure(msg); +} + +void TerminalRunner::stubExited() +{ + reportStopped(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/terminal.h b/src/plugins/debugger/terminal.h index 67b3bf851a5..0745373e0ea 100644 --- a/src/plugins/debugger/terminal.h +++ b/src/plugins/debugger/terminal.h @@ -28,7 +28,15 @@ #include #include +#include +#include + +#include + namespace Debugger { + +class DebuggerRunTool; + namespace Internal { class Terminal : public QObject @@ -60,5 +68,28 @@ private: QByteArray m_slaveName; }; + +class TerminalRunner : public ProjectExplorer::RunWorker +{ +public: + explicit TerminalRunner(DebuggerRunTool *runControl); + + qint64 applicationPid() const { return m_applicationPid; } + qint64 applicationMainThreadId() const { return m_applicationMainThreadId; } + +private: + void start() final; + void stop() final; + + void stubStarted(); + void stubExited(); + void stubError(const QString &msg); + + Utils::ConsoleProcess m_stubProc; + ProjectExplorer::StandardRunnable m_stubRunnable; + qint64 m_applicationPid = 0; + qint64 m_applicationMainThreadId = 0; +}; + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/diffeditor/diffeditor.h b/src/plugins/diffeditor/diffeditor.h index 0777aed00e5..6da073439da 100644 --- a/src/plugins/diffeditor/diffeditor.h +++ b/src/plugins/diffeditor/diffeditor.h @@ -35,7 +35,6 @@ QT_BEGIN_NAMESPACE class QComboBox; class QSpinBox; class QToolBar; -class QToolButton; class QStackedWidget; QT_END_NAMESPACE diff --git a/src/plugins/diffeditor/diffview.h b/src/plugins/diffeditor/diffview.h index 34c473d00c4..cbdc2cbdfde 100644 --- a/src/plugins/diffeditor/diffview.h +++ b/src/plugins/diffeditor/diffview.h @@ -37,7 +37,6 @@ namespace TextEditor { class TextEditorWidget; } namespace DiffEditor { -class DiffEditorController; class FileData; namespace Internal { diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.h b/src/plugins/diffeditor/sidebysidediffeditorwidget.h index 2b03308c9eb..4f97494b804 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.h +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.h @@ -44,7 +44,6 @@ QT_END_NAMESPACE namespace DiffEditor { -class DiffEditorController; class FileData; namespace Internal { diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.h b/src/plugins/diffeditor/unifieddiffeditorwidget.h index c05d05e9af1..3e697f7b439 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.h +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.h @@ -35,11 +35,6 @@ class DisplaySettings; class FontSettings; } -QT_BEGIN_NAMESPACE -class QSplitter; -class QTextCharFormat; -QT_END_NAMESPACE - namespace DiffEditor { class ChunkData; diff --git a/src/plugins/git/branchdialog.h b/src/plugins/git/branchdialog.h index a967dc3bdf4..9d95dd59dac 100644 --- a/src/plugins/git/branchdialog.h +++ b/src/plugins/git/branchdialog.h @@ -36,7 +36,6 @@ namespace Internal { namespace Ui { class BranchDialog; } -class BranchAddDialog; class BranchModel; /** diff --git a/src/plugins/git/changeselectiondialog.h b/src/plugins/git/changeselectiondialog.h index 5fad19b836c..b87ce10eede 100644 --- a/src/plugins/git/changeselectiondialog.h +++ b/src/plugins/git/changeselectiondialog.h @@ -33,10 +33,6 @@ #include QT_BEGIN_NAMESPACE -class QPushButton; -class QLabel; -class QLineEdit; -class QPlainTextEdit; class QProcess; class QStringListModel; QT_END_NAMESPACE diff --git a/src/plugins/git/gerrit/gerritmodel.h b/src/plugins/git/gerrit/gerritmodel.h index d9efd0edd25..213de67db93 100644 --- a/src/plugins/git/gerrit/gerritmodel.h +++ b/src/plugins/git/gerrit/gerritmodel.h @@ -32,10 +32,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE - namespace Gerrit { namespace Internal { class QueryContext; diff --git a/src/plugins/git/gerrit/gerritplugin.h b/src/plugins/git/gerrit/gerritplugin.h index 2915f9b2b3c..404a2c9f255 100644 --- a/src/plugins/git/gerrit/gerritplugin.h +++ b/src/plugins/git/gerrit/gerritplugin.h @@ -32,10 +32,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - namespace Core { class ActionContainer; class Command; diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 7563f24531b..92988be65da 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -53,7 +53,6 @@ namespace VcsBase { } namespace DiffEditor { -class DiffEditorDocument; class DiffEditorController; } diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index d776d2ff5de..f074f8fedda 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -29,10 +29,6 @@ #include -QT_BEGIN_NAMESPACE -class QVariant; -QT_END_NAMESPACE - namespace Git { namespace Internal { diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 790f0959a8f..2772cddcb90 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -39,9 +39,7 @@ #include QT_BEGIN_NAMESPACE -class QFile; class QAction; -class QFileInfo; QT_END_NAMESPACE namespace Core { @@ -61,7 +59,6 @@ namespace Internal { class GitVersionControl; class GitClient; -class GitSubmitEditor; class CommitData; class StashDialog; class BranchDialog; diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h index 04f031901e5..40948f3b984 100644 --- a/src/plugins/git/gitsubmiteditor.h +++ b/src/plugins/git/gitsubmiteditor.h @@ -37,7 +37,6 @@ namespace VcsBase { class SubmitFileModel; } namespace Git { namespace Internal { -class GitClient; class GitSubmitEditorWidget; class GitSubmitEditorPanelData; diff --git a/src/plugins/git/mergetool.h b/src/plugins/git/mergetool.h index f905cf25a03..d5d3d45f645 100644 --- a/src/plugins/git/mergetool.h +++ b/src/plugins/git/mergetool.h @@ -36,8 +36,6 @@ QT_END_NAMESPACE namespace Git { namespace Internal { -class GitClient; - class MergeTool : public QObject { Q_OBJECT diff --git a/src/plugins/git/remotemodel.h b/src/plugins/git/remotemodel.h index 467d9de3b5a..6ac83e32faf 100644 --- a/src/plugins/git/remotemodel.h +++ b/src/plugins/git/remotemodel.h @@ -32,8 +32,6 @@ namespace Git { namespace Internal { -class GitClient; - class RemoteModel : public QAbstractTableModel { Q_OBJECT public: diff --git a/src/plugins/git/settingspage.h b/src/plugins/git/settingspage.h index 205bda707e6..3e2ca9087d6 100644 --- a/src/plugins/git/settingspage.h +++ b/src/plugins/git/settingspage.h @@ -32,10 +32,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QSettings; -QT_END_NAMESPACE - namespace VcsBase { class VcsBaseClientSettings; } // namespace VcsBase diff --git a/src/plugins/git/stashdialog.h b/src/plugins/git/stashdialog.h index a64857b3180..bf725090947 100644 --- a/src/plugins/git/stashdialog.h +++ b/src/plugins/git/stashdialog.h @@ -30,7 +30,6 @@ QT_BEGIN_NAMESPACE class QSortFilterProxyModel; class QPushButton; -class QModelIndex; QT_END_NAMESPACE namespace Git { diff --git a/src/plugins/help/centralwidget.h b/src/plugins/help/centralwidget.h index 088487e349f..1796088fa97 100644 --- a/src/plugins/help/centralwidget.h +++ b/src/plugins/help/centralwidget.h @@ -32,8 +32,6 @@ namespace Help { namespace Internal { -class HelpViewer; -class PrintHelper; class CentralWidget : public HelpWidget { diff --git a/src/plugins/help/generalsettingspage.h b/src/plugins/help/generalsettingspage.h index 0bfca8fdc64..7b5fe53146f 100644 --- a/src/plugins/help/generalsettingspage.h +++ b/src/plugins/help/generalsettingspage.h @@ -33,7 +33,6 @@ namespace Help { namespace Internal { -class CentralWidget; class GeneralSettingsPage : public Core::IOptionsPage { diff --git a/src/plugins/help/helpplugin.h b/src/plugins/help/helpplugin.h index d6985733efb..52eb5a73701 100644 --- a/src/plugins/help/helpplugin.h +++ b/src/plugins/help/helpplugin.h @@ -35,16 +35,11 @@ #include QT_BEGIN_NAMESPACE -class QAction; -class QMenu; -class QToolButton; class QUrl; QT_END_NAMESPACE namespace Core { -class MiniSplitter; class SideBar; -class SideBarItem; } // Core namespace Utils { class StyledBar; } @@ -54,12 +49,10 @@ namespace Internal { class CentralWidget; class DocSettingsPage; class FilterSettingsPage; -class GeneralSettingsPage; class HelpMode; class HelpViewer; class LocalHelpManager; class OpenPagesManager; -class SearchWidget; class SearchTaskHandler; class HelpPlugin : public ExtensionSystem::IPlugin diff --git a/src/plugins/help/helpwidget.h b/src/plugins/help/helpwidget.h index 3e27d28619c..cd1fffa4244 100644 --- a/src/plugins/help/helpwidget.h +++ b/src/plugins/help/helpwidget.h @@ -33,7 +33,6 @@ QT_BEGIN_NAMESPACE class QAction; class QComboBox; -class QFont; class QMenu; class QPrinter; class QStackedWidget; diff --git a/src/plugins/help/searchwidget.h b/src/plugins/help/searchwidget.h index d06a597b32a..e0ad8ebab56 100644 --- a/src/plugins/help/searchwidget.h +++ b/src/plugins/help/searchwidget.h @@ -34,7 +34,6 @@ QT_BEGIN_NAMESPACE class QHelpSearchEngine; class QHelpSearchResultWidget; -class QMouseEvent; class QUrl; QT_END_NAMESPACE diff --git a/src/plugins/macros/imacrohandler.cpp b/src/plugins/macros/imacrohandler.cpp index 15d36b63586..b9b3fbf2f46 100644 --- a/src/plugins/macros/imacrohandler.cpp +++ b/src/plugins/macros/imacrohandler.cpp @@ -67,55 +67,31 @@ using namespace Macros::Internal; the macro event. */ -class IMacroHandler::IMacroHandlerPrivate -{ -public: - IMacroHandlerPrivate(); - - Macro *currentMacro; -}; - -IMacroHandler::IMacroHandlerPrivate::IMacroHandlerPrivate() : - currentMacro(0) -{ -} - - // ---------- IMacroHandler ------------ -IMacroHandler::IMacroHandler(): - d(new IMacroHandlerPrivate) -{ -} - -IMacroHandler::~IMacroHandler() -{ - delete d; -} - void IMacroHandler::startRecording(Macro* macro) { - d->currentMacro = macro; + m_currentMacro = macro; } void IMacroHandler::endRecordingMacro(Macro* macro) { Q_UNUSED(macro) - d->currentMacro = 0; + m_currentMacro = nullptr; } void IMacroHandler::addMacroEvent(const MacroEvent& event) { - if (d->currentMacro) - d->currentMacro->append(event); + if (m_currentMacro) + m_currentMacro->append(event); } void IMacroHandler::setCurrentMacro(Macro *macro) { - d->currentMacro = macro; + m_currentMacro = macro; } bool IMacroHandler::isRecording() const { - return d->currentMacro != 0; + return m_currentMacro != nullptr; } diff --git a/src/plugins/macros/imacrohandler.h b/src/plugins/macros/imacrohandler.h index e05e4c063c7..b7c38a57ac9 100644 --- a/src/plugins/macros/imacrohandler.h +++ b/src/plugins/macros/imacrohandler.h @@ -39,9 +39,6 @@ class IMacroHandler: public QObject Q_OBJECT public: - IMacroHandler(); - ~IMacroHandler(); - virtual void startRecording(Macro* macro); virtual void endRecordingMacro(Macro* macro); @@ -58,8 +55,7 @@ protected: private: friend class MacroManager; - class IMacroHandlerPrivate; - IMacroHandlerPrivate *d; + Macro *m_currentMacro = nullptr; }; } // namespace Internal diff --git a/src/plugins/macros/macroevent.h b/src/plugins/macros/macroevent.h index 72ae9942d45..9cf82ac28f5 100644 --- a/src/plugins/macros/macroevent.h +++ b/src/plugins/macros/macroevent.h @@ -31,7 +31,6 @@ #include QT_BEGIN_NAMESPACE -class QByteArray; class QDataStream; QT_END_NAMESPACE diff --git a/src/plugins/macros/macrolocatorfilter.h b/src/plugins/macros/macrolocatorfilter.h index f8dc6577537..d16553db3a7 100644 --- a/src/plugins/macros/macrolocatorfilter.h +++ b/src/plugins/macros/macrolocatorfilter.h @@ -31,7 +31,6 @@ namespace Macros { -class MacroManager; namespace Internal { diff --git a/src/plugins/macros/macromanager.cpp b/src/plugins/macros/macromanager.cpp index 81fe1c4d412..8b6e5b0117d 100644 --- a/src/plugins/macros/macromanager.cpp +++ b/src/plugins/macros/macromanager.cpp @@ -96,8 +96,8 @@ public: MacroManager *q; QMap macros; QMap actions; - Macro *currentMacro; - bool isRecording; + Macro *currentMacro = nullptr; + bool isRecording = false; QList handlers; @@ -115,9 +115,7 @@ public: }; MacroManager::MacroManagerPrivate::MacroManagerPrivate(MacroManager *qq): - q(qq), - currentMacro(0), - isRecording(false) + q(qq) { // Load existing macros initialize(); @@ -179,7 +177,7 @@ void MacroManager::MacroManagerPrivate::removeMacro(const QString &name) // Remove macro from the map Macro *macro = macros.take(name); if (macro == currentMacro) - currentMacro = 0; + currentMacro = nullptr; delete macro; } @@ -243,7 +241,7 @@ void MacroManager::MacroManagerPrivate::showSaveDialog() // ---------- MacroManager ------------ -MacroManager *MacroManager::m_instance = 0; +MacroManager *MacroManager::m_instance = nullptr; MacroManager::MacroManager(QObject *parent) : QObject(parent), diff --git a/src/plugins/macros/macromanager.h b/src/plugins/macros/macromanager.h index 9fb6cb18adb..18779b7df30 100644 --- a/src/plugins/macros/macromanager.h +++ b/src/plugins/macros/macromanager.h @@ -28,10 +28,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - namespace Macros { namespace Internal { diff --git a/src/plugins/macros/macrooptionswidget.h b/src/plugins/macros/macrooptionswidget.h index 95a7e07fd0d..2e570c2a088 100644 --- a/src/plugins/macros/macrooptionswidget.h +++ b/src/plugins/macros/macrooptionswidget.h @@ -38,7 +38,6 @@ QT_END_NAMESPACE namespace Macros { namespace Internal { -class MacroSettings; namespace Ui { class MacroOptionsWidget; } diff --git a/src/plugins/macros/macrosplugin.cpp b/src/plugins/macros/macrosplugin.cpp index 7230bf29c96..38be1c5f8dc 100644 --- a/src/plugins/macros/macrosplugin.cpp +++ b/src/plugins/macros/macrosplugin.cpp @@ -48,10 +48,6 @@ using namespace Macros::Internal; -MacrosPlugin::MacrosPlugin() : m_macroManager(0) -{ -} - MacrosPlugin::~MacrosPlugin() { delete m_macroManager; diff --git a/src/plugins/macros/macrosplugin.h b/src/plugins/macros/macrosplugin.h index dcb14694b81..2b1263c824f 100644 --- a/src/plugins/macros/macrosplugin.h +++ b/src/plugins/macros/macrosplugin.h @@ -38,14 +38,13 @@ class MacrosPlugin : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Macros.json") public: - MacrosPlugin(); ~MacrosPlugin(); bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); private: - MacroManager *m_macroManager; + MacroManager *m_macroManager = nullptr; }; } // namespace Internal diff --git a/src/plugins/macros/texteditormacrohandler.cpp b/src/plugins/macros/texteditormacrohandler.cpp index 6626f103f4d..0dc766d9ed6 100644 --- a/src/plugins/macros/texteditormacrohandler.cpp +++ b/src/plugins/macros/texteditormacrohandler.cpp @@ -53,8 +53,7 @@ static quint8 AUTOREP = 4; static quint8 COUNT = 5; -TextEditorMacroHandler::TextEditorMacroHandler(): - IMacroHandler() +TextEditorMacroHandler::TextEditorMacroHandler() { Core::EditorManager *editorManager = Core::EditorManager::instance(); connect(editorManager, &Core::EditorManager::currentEditorChanged, @@ -140,5 +139,5 @@ void TextEditorMacroHandler::closeEditor(Core::IEditor *editor) Q_UNUSED(editor); if (isRecording() && m_currentEditor && m_currentEditor->widget()) m_currentEditor->widget()->removeEventFilter(this); - m_currentEditor = 0; + m_currentEditor = nullptr; } diff --git a/src/plugins/macros/texteditormacrohandler.h b/src/plugins/macros/texteditormacrohandler.h index 1c4cda35aca..251986a3e21 100644 --- a/src/plugins/macros/texteditormacrohandler.h +++ b/src/plugins/macros/texteditormacrohandler.h @@ -53,7 +53,7 @@ public: void closeEditor(Core::IEditor *editor); private: - TextEditor::BaseTextEditor *m_currentEditor; + TextEditor::BaseTextEditor *m_currentEditor = nullptr; }; } // namespace Internal diff --git a/src/plugins/mercurial/mercurialclient.h b/src/plugins/mercurial/mercurialclient.h index e3763439a35..8f23e0d76ef 100644 --- a/src/plugins/mercurial/mercurialclient.h +++ b/src/plugins/mercurial/mercurialclient.h @@ -30,7 +30,6 @@ namespace Mercurial { namespace Internal { -class MercurialDiffParameters; class MercurialClient : public VcsBase::VcsBaseClient { diff --git a/src/plugins/mercurial/mercurialplugin.h b/src/plugins/mercurial/mercurialplugin.h index 231f03effc4..890238b3752 100644 --- a/src/plugins/mercurial/mercurialplugin.h +++ b/src/plugins/mercurial/mercurialplugin.h @@ -37,11 +37,7 @@ QT_END_NAMESPACE namespace Core { class ActionContainer; -class ActionManager; class CommandLocator; -class ICore; -class Id; -class IEditor; } // namespace Core namespace Utils { class ParameterAction; } @@ -52,9 +48,6 @@ namespace Internal { class OptionsPage; class MercurialClient; -class MercurialControl; -class MercurialEditorWidget; -class MercurialSettings; class MercurialPlugin : public VcsBase::VcsBasePlugin { diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 10ed90d4e0a..9d29ead1a11 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -56,6 +56,7 @@ const int PATH_ROLE = Qt::UserRole; const int ID_ROLE = Qt::UserRole + 1; +const int SORT_ROLE = Qt::UserRole + 2; const char PROJECTSDIRECTORYROOT_ID[] = "A.Projects"; @@ -170,21 +171,38 @@ void FolderNavigationWidget::toggleAutoSynchronization() setAutoSynchronization(!m_autoSync); } +static bool itemLessThan(QComboBox *combo, + int index, + const FolderNavigationWidgetFactory::RootDirectory &directory) +{ + return combo->itemData(index, SORT_ROLE).toInt() < directory.sortValue + || (combo->itemData(index, SORT_ROLE).toInt() == directory.sortValue + && combo->itemData(index, Qt::DisplayRole).toString() < directory.displayName); +} + void FolderNavigationWidget::insertRootDirectory( const FolderNavigationWidgetFactory::RootDirectory &directory) { - // insert sorted + // Find existing. Do not remove yet, to not mess up the current selection. + int previousIndex = 0; + while (previousIndex < m_rootSelector->count() + && m_rootSelector->itemData(previousIndex, ID_ROLE).toString() != directory.id) + ++previousIndex; + // Insert sorted. int index = 0; - while (index < m_rootSelector->count() - && m_rootSelector->itemData(index, ID_ROLE).toString() < directory.id) + while (index < m_rootSelector->count() && itemLessThan(m_rootSelector, index, directory)) ++index; - if (m_rootSelector->itemData(index, ID_ROLE).toString() != directory.id) - m_rootSelector->insertItem(index, directory.displayName); + m_rootSelector->insertItem(index, directory.displayName); + if (index <= previousIndex) // item was inserted, update previousIndex + ++previousIndex; m_rootSelector->setItemData(index, qVariantFromValue(directory.path), PATH_ROLE); m_rootSelector->setItemData(index, directory.id, ID_ROLE); + m_rootSelector->setItemData(index, directory.sortValue, SORT_ROLE); m_rootSelector->setItemData(index, directory.path.toUserOutput(), Qt::ToolTipRole); - if (m_rootSelector->currentIndex() == index) - setRootDirectory(directory.path); + if (m_rootSelector->currentIndex() == previousIndex) + m_rootSelector->setCurrentIndex(index); + if (previousIndex < m_rootSelector->count()) + m_rootSelector->removeItem(previousIndex); if (m_autoSync) // we might find a better root for current selection now setCurrentEditor(Core::EditorManager::currentEditor()); } @@ -357,9 +375,12 @@ FolderNavigationWidgetFactory::FolderNavigationWidgetFactory() setPriority(400); setId("File System"); setActivationSequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Y") : tr("Alt+Y"))); - insertRootDirectory( - {QLatin1String("A.Computer"), FolderNavigationWidget::tr("Computer"), Utils::FileName()}); + insertRootDirectory({QLatin1String("A.Computer"), + 0 /*sortValue*/, + FolderNavigationWidget::tr("Computer"), + Utils::FileName()}); insertRootDirectory({QLatin1String("A.Home"), + 10 /*sortValue*/, FolderNavigationWidget::tr("Home"), Utils::FileName::fromString(QDir::homePath())}); updateProjectsDirectoryRoot(); @@ -440,6 +461,7 @@ int FolderNavigationWidgetFactory::rootIndex(const QString &id) void FolderNavigationWidgetFactory::updateProjectsDirectoryRoot() { insertRootDirectory({QLatin1String(PROJECTSDIRECTORYROOT_ID), + 20 /*sortValue*/, FolderNavigationWidget::tr("Projects"), Core::DocumentManager::projectsDirectory()}); } diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h index 06c91c17185..11e2bbc9ec8 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.h +++ b/src/plugins/projectexplorer/foldernavigationwidget.h @@ -53,6 +53,7 @@ class FolderNavigationWidgetFactory : public Core::INavigationWidgetFactory public: struct RootDirectory { QString id; + int sortValue; QString displayName; Utils::FileName path; }; diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index db50d1cafaf..1c38f856385 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -616,6 +616,8 @@ public: outputFormatter = runConfiguration->createOutputFormatter(); device = DeviceKitInformation::device(runConfiguration->target()->kit()); project = runConfiguration->target()->project(); + } else { + outputFormatter = new OutputFormatter(); } } diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index cd66c88caea..6d7a4ef7641 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -120,9 +120,11 @@ static SessionManagerPrivate *d = nullptr; static QString projectFolderId(Project *pro) { - return "P." + pro->displayName() + "." + pro->projectFilePath().toString(); + return pro->projectFilePath().toString(); } +const int PROJECT_SORT_VALUE = 100; + SessionManager::SessionManager(QObject *parent) : QObject(parent) { m_instance = this; @@ -392,8 +394,10 @@ void SessionManager::addProject(Project *pro) emit m_instance->projectAdded(pro); const auto updateFolderNavigation = [pro] { - FolderNavigationWidgetFactory::insertRootDirectory( - {projectFolderId(pro), pro->displayName(), pro->projectFilePath().parentDir()}); + FolderNavigationWidgetFactory::insertRootDirectory({projectFolderId(pro), + PROJECT_SORT_VALUE, + pro->displayName(), + pro->projectFilePath().parentDir()}); }; updateFolderNavigation(); configureEditors(pro); diff --git a/src/plugins/projectexplorer/subscription.cpp b/src/plugins/projectexplorer/subscription.cpp index 4ee9db21b1b..b878bdacdcf 100644 --- a/src/plugins/projectexplorer/subscription.cpp +++ b/src/plugins/projectexplorer/subscription.cpp @@ -54,6 +54,16 @@ void Subscription::subscribe(ProjectConfiguration *pc) QMetaObject::Connection conn = m_subscriber(pc); if (conn) m_connections.insert(pc, conn); + + if (auto p = qobject_cast(pc)) { + for (Target *t : p->targets()) { + for (ProjectConfiguration *pc : t->projectConfigurations()) + m_subscriber(pc); + } + } else if (auto t = qobject_cast(pc)) { + for (ProjectConfiguration *pc : t->projectConfigurations()) + m_subscriber(pc); + } } void Subscription::unsubscribe(ProjectConfiguration *pc) @@ -63,6 +73,16 @@ void Subscription::unsubscribe(ProjectConfiguration *pc) disconnect(c); m_connections.remove(pc); } + if (auto p = qobject_cast(pc)) { + for (Target *t : p->targets()) { + for (ProjectConfiguration *pc : t->projectConfigurations()) + unsubscribe(pc); + } + } else if (auto t = qobject_cast(pc)) { + for (ProjectConfiguration *pc : t->projectConfigurations()) + unsubscribe(pc); + } + } ProjectSubscription::ProjectSubscription(const Subscription::Connector &s, const QObject *r, diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index f9f212fcb08..1d0121eab0e 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -142,12 +142,12 @@ QbsProject::QbsProject(const FileName &fileName) : connect(this, &Project::removedTarget, this, &QbsProject::targetWasRemoved); subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() { if (static_cast(sender())->isActive()) - startParsing(); + delayParsing(); }); connect(this, &Project::activeProjectConfigurationChanged, this, [this](ProjectConfiguration *pc) { if (pc && pc->isActive()) - startParsing(); + delayParsing(); }); connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing); @@ -447,6 +447,7 @@ bool QbsProject::checkCancelStatus() qCDebug(qbsPmLog) << "Cancel request while parsing, starting re-parse"; m_qbsProjectParser->deleteLater(); m_qbsProjectParser = 0; + emitParsingFinished(false); parseCurrentBuildConfiguration(); return true; } @@ -537,7 +538,6 @@ void QbsProject::handleRuleExecutionDone() QTC_ASSERT(m_qbsProject.isValid(), return); m_projectData = m_qbsProject.projectData(); updateAfterParse(); - // finishParsing(true); } void QbsProject::targetWasAdded(Target *t) diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.h b/src/plugins/qmakeprojectmanager/addlibrarywizard.h index 6a0201c398b..0c4cb4b7601 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.h +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.h @@ -30,7 +30,6 @@ QT_BEGIN_NAMESPACE class QRadioButton; -class QCheckBox; class QLabel; QT_END_NAMESPACE diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.h b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.h index 2307a4ba779..a2ed5ef749a 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.h +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.h @@ -31,7 +31,6 @@ #include QT_BEGIN_NAMESPACE -class QWidget; QT_END_NAMESPACE namespace Core { class GeneratedFile; } diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index 706758038f4..5dde3c35349 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -42,7 +42,6 @@ QT_END_NAMESPACE namespace QmakeProjectManager { class QmakeProFile; -class QmakeProFileNode; class QmakeProject; namespace Internal { diff --git a/src/plugins/qmakeprojectmanager/externaleditors.h b/src/plugins/qmakeprojectmanager/externaleditors.h index 413b46a7d15..b7441501c41 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.h +++ b/src/plugins/qmakeprojectmanager/externaleditors.h @@ -33,7 +33,6 @@ #include QT_BEGIN_NAMESPACE -class QProcess; class QTcpSocket; QT_END_NAMESPACE diff --git a/src/plugins/qmakeprojectmanager/makefileparse.h b/src/plugins/qmakeprojectmanager/makefileparse.h index aefc81e1f57..9a2abeb00ee 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.h +++ b/src/plugins/qmakeprojectmanager/makefileparse.h @@ -29,10 +29,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QLogggingCategory; -QT_END_NAMESPACE - namespace QmakeProjectManager { namespace Internal { diff --git a/src/plugins/qmakeprojectmanager/makestep.h b/src/plugins/qmakeprojectmanager/makestep.h index 9f0abc91923..72a0b54e2ef 100644 --- a/src/plugins/qmakeprojectmanager/makestep.h +++ b/src/plugins/qmakeprojectmanager/makestep.h @@ -32,7 +32,6 @@ namespace ProjectExplorer { class BuildStep; class IBuildStepFactory; -class Task; } namespace QmakeProjectManager { diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.h b/src/plugins/qmakeprojectmanager/profilehoverhandler.h index 381329a93c3..cc9f91ef02b 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.h +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.h @@ -29,7 +29,6 @@ #include QT_BEGIN_NAMESPACE -class QUrl; QT_END_NAMESPACE namespace QmakeProjectManager { diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h index 31829d8acd2..a698653d7e7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h @@ -35,7 +35,6 @@ namespace Utils { class DetailsWidget; } namespace QmakeProjectManager { class QmakeBuildConfiguration; -class QmakeProFileNode; namespace Internal { namespace Ui { class QmakeProjectConfigWidget; } diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index a69db1113eb..caf12b129a0 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -38,7 +38,6 @@ class Abi; class BuildStep; class IBuildStepFactory; class Project; -class Kit; } // namespace ProjectExplorer namespace QtSupport { class BaseQtVersion; } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditortoolbutton.cpp b/src/plugins/qmldesigner/components/formeditor/formeditortoolbutton.cpp index c9d38985045..a4f2f3bff0c 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditortoolbutton.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditortoolbutton.cpp @@ -52,6 +52,7 @@ FormEditorToolButton::FormEditorToolButton(QAction *action, QGraphicsItem *paren setEnabled(m_action->isEnabled()); setVisible(m_action->isVisible()); + setCursor(Qt::ArrowCursor); } void FormEditorToolButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index 0785e704df2..6f7995a185f 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -118,7 +118,7 @@ QList NavigatorWidget::createToolBarWidgets() filter->setPopupMode(QToolButton::InstantPopup); filter->setProperty("noArrow", true); auto filterMenu = new QMenu(filter); - auto objectAction = new QAction(tr("Show only visible itmes.")); + auto objectAction = new QAction(tr("Show only visible items."), nullptr); objectAction->setCheckable(true); objectAction->setChecked( DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool()); diff --git a/src/plugins/qmldesigner/designercore/include/qmltimelinemutator.h b/src/plugins/qmldesigner/designercore/include/qmltimelinemutator.h index 44327fcb25c..10e00fc7b33 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimelinemutator.h +++ b/src/plugins/qmldesigner/designercore/include/qmltimelinemutator.h @@ -56,7 +56,7 @@ public: private: void addFramesIfNotExists(const ModelNode &node, const PropertyName &propertyName); bool hasFrames(const ModelNode &node, const PropertyName &propertyName) const; - QList frames() const; + QList allTimelineFrames() const; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmltimelinemutator.cpp b/src/plugins/qmldesigner/designercore/model/qmltimelinemutator.cpp index 7e22a615650..a028b61890d 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltimelinemutator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltimelinemutator.cpp @@ -142,7 +142,7 @@ void QmlTimelineMutator::addFramesIfNotExists(const ModelNode &node, const Prope bool QmlTimelineMutator::hasFrames(const ModelNode &node, const PropertyName &propertyName) const { - for (const QmlTimelineFrames &frames : frames()) { + for (const QmlTimelineFrames &frames : allTimelineFrames()) { if (frames.target().isValid() && frames.target() == node && frames.propertyName() == propertyName) @@ -152,7 +152,7 @@ bool QmlTimelineMutator::hasFrames(const ModelNode &node, const PropertyName &pr return false; } -QList QmlTimelineMutator::frames() const +QList QmlTimelineMutator::allTimelineFrames() const { QList returnList; diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 0af1d0a2344..47ce2bad158 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -71,7 +71,7 @@ static inline bool isSupportedAttachedProperties(const QString &propertyName) static inline QStringList supportedVersionsList() { static const QStringList list = { - "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9" + "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9", "2.10" }; return list; } diff --git a/src/plugins/qnx/images/qnx-target.png b/src/plugins/qnx/images/qnx-target.png deleted file mode 100644 index be59d15b821..00000000000 Binary files a/src/plugins/qnx/images/qnx-target.png and /dev/null differ diff --git a/src/plugins/qnx/images/qnxdevice.png b/src/plugins/qnx/images/qnxdevice.png new file mode 100644 index 00000000000..fedd002bf7d Binary files /dev/null and b/src/plugins/qnx/images/qnxdevice.png differ diff --git a/src/plugins/qnx/images/qnxdevice@2x.png b/src/plugins/qnx/images/qnxdevice@2x.png new file mode 100644 index 00000000000..0634693aa4e Binary files /dev/null and b/src/plugins/qnx/images/qnxdevice@2x.png differ diff --git a/src/plugins/qnx/images/qnxdevicesmall.png b/src/plugins/qnx/images/qnxdevicesmall.png new file mode 100644 index 00000000000..34a5ba9432c Binary files /dev/null and b/src/plugins/qnx/images/qnxdevicesmall.png differ diff --git a/src/plugins/qnx/images/qnxdevicesmall@2x.png b/src/plugins/qnx/images/qnxdevicesmall@2x.png new file mode 100644 index 00000000000..ab2100c1e9b Binary files /dev/null and b/src/plugins/qnx/images/qnxdevicesmall@2x.png differ diff --git a/src/plugins/qnx/qnx.qrc b/src/plugins/qnx/qnx.qrc index 97a16398cc7..7a7d425e8d2 100644 --- a/src/plugins/qnx/qnx.qrc +++ b/src/plugins/qnx/qnx.qrc @@ -1,5 +1,8 @@ - images/qnx-target.png + images/qnxdevice.png + images/qnxdevice@2x.png + images/qnxdevicesmall.png + images/qnxdevicesmall@2x.png diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index 22718c63851..282e5980854 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -320,7 +320,6 @@ ProjectExplorer::Kit *QnxConfiguration::createKit( "Kit for %1 (%2)") .arg(displayName()) .arg(target.shortDescription())); - kit->setIconPath(FileName::fromString(QLatin1String(Constants::QNX_CATEGORY_ICON))); kit->setAutoDetected(true); kit->setAutoDetectionSource(envFile().toString()); diff --git a/src/plugins/qnx/qnxconstants.h b/src/plugins/qnx/qnxconstants.h index 979aa1e94e8..63d9a2d50b4 100644 --- a/src/plugins/qnx/qnxconstants.h +++ b/src/plugins/qnx/qnxconstants.h @@ -48,7 +48,6 @@ const char QNX_DEBUG_EXECUTABLE[] = "pdebug"; const char QNX_TOOLCHAIN_ID[] = "Qnx.QccToolChain"; // QNX settings constants -const char QNX_CATEGORY_ICON[] = ":/qnx/images/qnx-target.png"; const char QNX_SETTINGS_ID[] = "DD.Qnx Configuration"; const char QNX_CONFIGS_FILENAME[] = "qnxconfigurations.xml"; diff --git a/src/plugins/qnx/qnxdevicefactory.cpp b/src/plugins/qnx/qnxdevicefactory.cpp index f489c10d740..1546171afd7 100644 --- a/src/plugins/qnx/qnxdevicefactory.cpp +++ b/src/plugins/qnx/qnxdevicefactory.cpp @@ -30,6 +30,7 @@ #include "qnxdevice.h" #include +#include #include @@ -55,7 +56,13 @@ QList QnxDeviceFactory::availableCreationIds() const QIcon QnxDeviceFactory::iconForId(Core::Id type) const { Q_UNUSED(type) - return QIcon(); + using namespace Utils; + static const QIcon icon = + Icon::combinedIcon({Icon({{":/qnx/images/qnxdevicesmall.png", + Theme::PanelTextColorDark}}, Icon::Tint), + Icon({{":/qnx/images/qnxdevice.png", + Theme::IconsBaseColor}})}); + return icon; } bool QnxDeviceFactory::canCreate() const diff --git a/src/plugins/resourceeditor/qrceditor/resourceview.h b/src/plugins/resourceeditor/qrceditor/resourceview.h index d53f9546858..d15a6389931 100644 --- a/src/plugins/resourceeditor/qrceditor/resourceview.h +++ b/src/plugins/resourceeditor/qrceditor/resourceview.h @@ -32,9 +32,6 @@ #include QT_BEGIN_NAMESPACE -class QAction; -class QMenu; -class QMouseEvent; class QUndoStack; QT_END_NAMESPACE diff --git a/src/plugins/resourceeditor/resourceeditorplugin.h b/src/plugins/resourceeditor/resourceeditorplugin.h index 0baf20f924b..6da00794635 100644 --- a/src/plugins/resourceeditor/resourceeditorplugin.h +++ b/src/plugins/resourceeditor/resourceeditorplugin.h @@ -38,8 +38,6 @@ namespace ResourceEditor { namespace Internal { class ResourceEditorW; -class ResourceWizard; -class ResourceEditorFactory; class ResourceEditorPlugin : public ExtensionSystem::IPlugin { diff --git a/src/plugins/texteditor/basefilefind.h b/src/plugins/texteditor/basefilefind.h index 56bbb4e5fd2..d921b4f2f05 100644 --- a/src/plugins/texteditor/basefilefind.h +++ b/src/plugins/texteditor/basefilefind.h @@ -33,15 +33,9 @@ #include -QT_BEGIN_NAMESPACE -class QLabel; -class QComboBox; -QT_END_NAMESPACE - namespace Utils { class FileIterator; } namespace Core { class IEditor; -class IFindSupport; class SearchResult; class SearchResultItem; } // namespace Core diff --git a/src/plugins/texteditor/codeassist/assistproposalitem.h b/src/plugins/texteditor/codeassist/assistproposalitem.h index 8d957a2f812..286eef67dc4 100644 --- a/src/plugins/texteditor/codeassist/assistproposalitem.h +++ b/src/plugins/texteditor/codeassist/assistproposalitem.h @@ -35,7 +35,6 @@ namespace TextEditor { -class TextEditorWidget; class TEXTEDITOR_EXPORT AssistProposalItem : public AssistProposalItemInterface { diff --git a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h index 69bc1d91e38..a4f925f4d90 100644 --- a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h +++ b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h @@ -32,14 +32,12 @@ QT_BEGIN_NAMESPACE class QIcon; class QString; -class QVariant; QT_END_NAMESPACE #include namespace TextEditor { -class TextEditorWidget; class TEXTEDITOR_EXPORT AssistProposalItemInterface { diff --git a/src/plugins/texteditor/codeassist/codeassistant.h b/src/plugins/texteditor/codeassist/codeassistant.h index 64e507f49b8..46ffa9a85c4 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.h +++ b/src/plugins/texteditor/codeassist/codeassistant.h @@ -34,7 +34,6 @@ namespace TextEditor { class CodeAssistantPrivate; -class CompletionSettings; class IAssistProvider; class TextEditorWidget; diff --git a/src/plugins/texteditor/codeassist/iassistprocessor.h b/src/plugins/texteditor/codeassist/iassistprocessor.h index d2c618ac4b2..a05c0bf8261 100644 --- a/src/plugins/texteditor/codeassist/iassistprocessor.h +++ b/src/plugins/texteditor/codeassist/iassistprocessor.h @@ -31,7 +31,6 @@ namespace TextEditor { -class IAssistProvider; class AssistInterface; class IAssistProposal; diff --git a/src/plugins/texteditor/codeassist/iassistproposalmodel.h b/src/plugins/texteditor/codeassist/iassistproposalmodel.h index 75196363934..fdb6289ce1e 100644 --- a/src/plugins/texteditor/codeassist/iassistproposalmodel.h +++ b/src/plugins/texteditor/codeassist/iassistproposalmodel.h @@ -31,7 +31,6 @@ QT_FORWARD_DECLARE_CLASS(QString) namespace TextEditor { -class AssistProposalItem; class TEXTEDITOR_EXPORT IAssistProposalModel { diff --git a/src/plugins/texteditor/codestyleselectorwidget.h b/src/plugins/texteditor/codestyleselectorwidget.h index 05ae0c41d8a..f498ecacd7f 100644 --- a/src/plugins/texteditor/codestyleselectorwidget.h +++ b/src/plugins/texteditor/codestyleselectorwidget.h @@ -29,14 +29,6 @@ #include -QT_BEGIN_NAMESPACE -class QHBoxLayout; -class QComboBox; -class QLabel; -class QCheckBox; -class QPushButton; -QT_END_NAMESPACE - namespace TextEditor { namespace Internal { namespace Ui { class CodeStyleSelectorWidget; } } diff --git a/src/plugins/texteditor/findinfiles.h b/src/plugins/texteditor/findinfiles.h index ab8d93bad78..f5df340ebd1 100644 --- a/src/plugins/texteditor/findinfiles.h +++ b/src/plugins/texteditor/findinfiles.h @@ -33,7 +33,7 @@ #include QT_BEGIN_NAMESPACE -class QLabel; +class QComboBox; class QStackedWidget; QT_END_NAMESPACE diff --git a/src/plugins/texteditor/generichighlighter/manager.h b/src/plugins/texteditor/generichighlighter/manager.h index 5b602d2e039..080e649e3ad 100644 --- a/src/plugins/texteditor/generichighlighter/manager.h +++ b/src/plugins/texteditor/generichighlighter/manager.h @@ -38,7 +38,6 @@ QT_BEGIN_NAMESPACE class QFileInfo; -class QStringList; class QIODevice; template class QFutureInterface; QT_END_NAMESPACE diff --git a/src/plugins/texteditor/icodestylepreferencesfactory.h b/src/plugins/texteditor/icodestylepreferencesfactory.h index 0e9b1b8d8f6..f9d534376fb 100644 --- a/src/plugins/texteditor/icodestylepreferencesfactory.h +++ b/src/plugins/texteditor/icodestylepreferencesfactory.h @@ -33,7 +33,6 @@ namespace Core { class Id; } namespace TextEditor { class ICodeStylePreferences; -class CodeStylePool; class Indenter; class SnippetProvider; diff --git a/src/plugins/texteditor/semantichighlighter.h b/src/plugins/texteditor/semantichighlighter.h index 1ffc03d76a1..f57b037957c 100644 --- a/src/plugins/texteditor/semantichighlighter.h +++ b/src/plugins/texteditor/semantichighlighter.h @@ -33,10 +33,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QTextDocument; -QT_END_NAMESPACE - namespace TextEditor { class SyntaxHighlighter; diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index b5365ad3279..b2f3d0a9fac 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -52,11 +52,9 @@ QT_END_NAMESPACE namespace TextEditor { class TextDocument; class BaseHoverHandler; -class TabSettings; class RefactorOverlay; struct RefactorMarker; class SyntaxHighlighter; -class IAssistMonitorInterface; class AssistInterface; class IAssistProvider; class ICodeStylePreferences; diff --git a/src/plugins/texteditor/texteditor_p.h b/src/plugins/texteditor/texteditor_p.h index ec2ad4ab7f8..09a9cf2a125 100644 --- a/src/plugins/texteditor/texteditor_p.h +++ b/src/plugins/texteditor/texteditor_p.h @@ -35,8 +35,6 @@ namespace TextEditor { class TextDocument; namespace Internal { -class TextEditorOverlay; -class ClipboardAssistProvider; class TEXTEDITOR_EXPORT TextBlockSelection { diff --git a/src/plugins/texteditor/texteditorsettings.h b/src/plugins/texteditor/texteditorsettings.h index 2c0ce20fabc..656d5856843 100644 --- a/src/plugins/texteditor/texteditorsettings.h +++ b/src/plugins/texteditor/texteditorsettings.h @@ -39,7 +39,6 @@ QT_END_NAMESPACE namespace TextEditor { class FontSettings; -class TabSettings; class TypingSettings; class StorageSettings; class BehaviorSettings; diff --git a/src/plugins/texteditor/textmark.h b/src/plugins/texteditor/textmark.h index f8cd36b1317..d9c09ee5133 100644 --- a/src/plugins/texteditor/textmark.h +++ b/src/plugins/texteditor/textmark.h @@ -42,7 +42,6 @@ QT_END_NAMESPACE namespace TextEditor { -class BaseTextEditor; class TextDocument; class TEXTEDITOR_EXPORT TextMark diff --git a/src/plugins/valgrind/callgrindvisualisation.h b/src/plugins/valgrind/callgrindvisualisation.h index cbb38ca6e51..f03b4775b58 100644 --- a/src/plugins/valgrind/callgrindvisualisation.h +++ b/src/plugins/valgrind/callgrindvisualisation.h @@ -29,7 +29,6 @@ QT_BEGIN_NAMESPACE class QAbstractItemModel; -class QModelIndex; QT_END_NAMESPACE namespace Valgrind { diff --git a/src/plugins/valgrind/xmlprotocol/error.h b/src/plugins/valgrind/xmlprotocol/error.h index f7b56f301f9..8a235348b1f 100644 --- a/src/plugins/valgrind/xmlprotocol/error.h +++ b/src/plugins/valgrind/xmlprotocol/error.h @@ -37,7 +37,6 @@ QT_END_NAMESPACE namespace Valgrind { namespace XmlProtocol { -class Frame; class Stack; class Suppression; diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index d82f71ae752..297f6aaff18 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -511,31 +511,38 @@ + id="guide2989" + inkscape:locked="false" /> + id="guide2991" + inkscape:locked="false" /> + id="guide3045" + inkscape:locked="false" /> + id="guide4261" + inkscape:locked="false" /> + id="guide4543" + inkscape:locked="false" /> + id="guide4545" + inkscape:locked="false" /> + id="guide4574" + inkscape:locked="false" /> @@ -8630,6 +8637,49 @@ width="100%" height="100%" /> + + + + + + + + + diff --git a/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp b/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp index 3777c7b755f..6884ee8d7b8 100644 --- a/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp +++ b/tests/auto/utils/camelhumpmatcher/tst_camelhumpmatcher.cpp @@ -77,6 +77,7 @@ void tst_CamelHumpMatcher::camelHumpMatcher_data() QTest::newRow("middle-after-underscore") << "CH" << "long_camel_hump" << 5; QTest::newRow("middle-after-underscore-uppercase") << "CH" << "LONG_CAMEL_HUMP" << 5; QTest::newRow("middle-continued") << "cahu" << "LongCamelHump" << 4; + QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp" << 4; } typedef QVector MatchStart; @@ -136,6 +137,8 @@ void tst_CamelHumpMatcher::highlighting_data() << MatchStart{4, 13} << MatchLength{2, 2}; QTest::newRow("wildcard-question") << "Lo?g" << "VeryLongCamelHump" << MatchStart{4, 7} << MatchLength{2, 1}; + QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp" + << MatchStart{4} << MatchLength{6}; } QTEST_APPLESS_MAIN(tst_CamelHumpMatcher)