Merge remote-tracking branch 'origin/4.5'

Change-Id: I919f3dac0bf44f18276e4f70309414bb22c74973
This commit is contained in:
Orgad Shaneh
2017-09-28 13:59:19 +03:00
165 changed files with 981 additions and 1466 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -154,7 +154,7 @@ struct MessageTrait<Message> \
using MixinHighlightingTypes = Utils::SizedArray<HighlightingType, 6>;
struct HighlightingTypes {
HighlightingType mainHighlightingType;
HighlightingType mainHighlightingType = HighlightingType::Invalid;
MixinHighlightingTypes mixinHighlightingTypes;
};

View File

@@ -35,8 +35,6 @@
namespace Timeline {
class TimelineRenderPass;
class TimelineRenderState;
class TIMELINE_EXPORT TimelineAbstractRenderer : public QQuickItem
{

View File

@@ -35,8 +35,6 @@
namespace Timeline {
class TimelineRenderPass;
class TimelineRenderState;
class TIMELINE_EXPORT TimelineRenderer : public TimelineAbstractRenderer
{

View File

@@ -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);
}

View File

@@ -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<int>(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<const TestTreeItem &>(*item);
return matches(treeItem);
});
return static_cast<const TestTreeItem *>(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

View File

@@ -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;
};

View File

@@ -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<const TestTreeItem &>(*item);
return matches(treeItem);
});
return static_cast<const TestTreeItem *>(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

View File

@@ -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;
};

View File

@@ -301,25 +301,7 @@ void TestNavigationWidget::onRunThisTestTriggered(TestRunMode runMode)
return;
TestTreeItem *item = static_cast<TestTreeItem *>(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()

View File

@@ -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")

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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());

View File

@@ -31,6 +31,7 @@
#include "testrunconfiguration.h"
#include "testsettings.h"
#include "testoutputreader.h"
#include "testtreeitem.h"
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/futureprogress.h>
@@ -106,6 +107,28 @@ void TestRunner::setSelectedTests(const QList<TestConfiguration *> &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(' '));

View File

@@ -55,6 +55,7 @@ public:
~TestRunner();
void setSelectedTests(const QList<TestConfiguration *> &selected);
void runTest(TestRunMode mode, const TestTreeItem *item);
bool isTestRunning() const { return m_executingTests; }
void prepareToRunTests(TestRunMode mode);

View File

@@ -39,7 +39,6 @@ namespace AutotoolsProjectManager {
namespace Internal {
class MakefileParserThread;
class AutotoolsTarget;
/**
* @brief Implementation of the ProjectExplorer::Project interface.

View File

@@ -313,125 +313,111 @@ void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message)
futureInterface.reportFinished();
}
class IpcSender : public IpcSenderInterface
{
public:
IpcSender(ClangBackEnd::ClangCodeModelConnectionClient &connectionClient)
IpcSender::IpcSender(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;
};
{}
void IpcSender::end()
{
QTC_CHECK(m_connection.isConnected());
QTC_CHECK(m_connection->isConnected());
qCDebug(log) << ">>>" << ClangBackEnd::EndMessage();
m_connection.sendEndMessage();
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;
}

View File

@@ -115,24 +115,30 @@ private:
QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> 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<IpcSenderInterface> m_ipcSender;
QScopedPointer<IpcSender> m_ipcSender;
int m_connectedCount = 0;
};

View File

@@ -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<QByteArray> &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<QByteArray> actualLines = actual.text.split('\n');
const QList<QByteArray> 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: <none>\n";
out << " expected: \"" << *expectedLineIt << "\"\n";
} else if (actualLineIt != actualLines.cend() && expectedLineIt == expectedLines.cend()) {
out << " line: " << line << '\n';
out << " actual: \"" << *actualLineIt << "\"\n";
out << " expected: <none>\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<FileContainer> &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<ProjectPartContainer> &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

View File

@@ -58,8 +58,6 @@ private slots:
void testCompleteAfterModifyingIncludedHeaderByRefactoringActions();
void testCompleteAfterChangingIncludedAndOpenHeaderExternally();
void testCompleteAfterChangingIncludedAndNotOpenHeaderExternally();
void testUpdateBackendAfterRestart();
};
} // namespace Tests

View File

@@ -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<ClangStaticAnalyzerToolRunner>
(Constants::CLANGSTATICANALYZER_RUN_MODE, constraint, /*priority*/ -1);
return true;
}

View File

@@ -35,6 +35,7 @@
#include <clangcodemodel/clangutils.h>
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h>
@@ -46,8 +47,10 @@
#include <projectexplorer/abi.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/target.h>
@@ -55,6 +58,7 @@
#include <projectexplorer/toolchain.h>
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/hostosinfo.h>
#include <utils/temporarydirectory.h>
@@ -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(
"<html><head/><body>"
"<p>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.</p>"
"<p>Do you want to continue and run the tool in %2 mode?</p>"
"</body></html>")
.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<Project> 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();
}

View File

@@ -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<ProjectExplorer::Target> m_target;
ProjectBuilder *m_projectBuilder;
CppTools::ProjectInfo m_projectInfoBeforeBuild;
CppTools::ProjectInfo m_projectInfo;
QString m_targetTriple;
Core::Id m_toolChainType;

View File

@@ -36,24 +36,19 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <cpptools/cppmodelmanager.h>
#include <debugger/analyzer/analyzermanager.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/target.h>
#include <projectexplorer/session.h>
#include <utils/checkablemessagebox.h>
#include <utils/fancymainwindow.h>
#include <utils/utilsicons.h>
#include <QAction>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QListView>
#include <QSortFilterProxyModel>
#include <QToolButton>
@@ -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(
"<html><head/><body>"
"<p>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.</p>"
"<p>Do you want to continue and run the tool in %2 mode?</p>"
"</body></html>")
.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<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
@@ -271,27 +202,12 @@ QList<Diagnostic> ClangStaticAnalyzerTool::diagnostics() const
return m_diagnosticModel->diagnostics();
}
void ClangStaticAnalyzerTool::onEngineIsStarting()
{
QTC_ASSERT(m_diagnosticModel, return);
}
void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &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"

View File

@@ -28,8 +28,6 @@
#include <projectexplorer/runconfiguration.h>
#include <cpptools/projectinfo.h>
#include <QHash>
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<Diagnostic> diagnostics() const;
void startTool();
void handleWorkerStart(ProjectExplorer::RunWorker *runWorker);
void onEngineIsStarting();
void onNewDiagnosticsAvailable(const QList<Diagnostic> &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<ProjectExplorer::Target *, DummyRunConfiguration *> m_runConfigs;
bool m_running = false;
bool m_toolBusy = false;
};

View File

@@ -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;
}

View File

@@ -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<Utils::TemporaryDirectory> m_tempDir = nullptr;
mutable CMakeConfig m_cmakeCache;
QTimer m_reparseTimer;
std::unique_ptr<BuildDirReader> m_reader;
mutable QList<CMakeBuildTarget> m_buildTargets;

View File

@@ -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<CMakeProject *>(project())->mustUpdateCMakeStateBeforeBuild();
}
void CMakeBuildConfiguration::runCMake()

View File

@@ -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);

View File

@@ -38,7 +38,6 @@
namespace ProjectExplorer {
class FileNode;
class Kit;
} // namespace ProjectExplorer
namespace CMakeProjectManager {

View File

@@ -32,7 +32,6 @@ namespace CMakeProjectManager {
namespace Internal {
class CMakeEditorWidget;
class CMakeSettingsPage;
class CMakeEditor : public TextEditor::BaseTextEditor
{

View File

@@ -31,7 +31,6 @@
namespace CMakeProjectManager {
namespace Internal {
class CMakeSettingsPage;
class CMakeFileCompletionAssist : public TextEditor::KeywordsCompletionAssistProcessor
{

View File

@@ -51,6 +51,7 @@
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/algorithm.h>
#include <utils/asconst.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <utils/hostosinfo.h>
@@ -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<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
if (isParsing())
return;
if (bc)
startParsingProject(PARSE);
}
void CMakeProject::runCMakeAndScanProjectTree()
{
if (isParsing())
return;
startParsingProject(static_cast<DataCollectionAction>(PARSE | SCAN));
}
void CMakeProject::startParsingProject(const CMakeProject::DataCollectionAction action)
{
const bool runParse = action & PARSE;
const bool runScan = action & SCAN;
CMakeBuildConfiguration *bc = activeTarget()
? qobject_cast<CMakeBuildConfiguration *>(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<CMakeBuildConfiguration *>(pc)) {
if (!bc->isActive())
return;
} else if (!qobject_cast<Target *>(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<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
foreach (Target *t, targets()) {
foreach (BuildConfiguration *bc, t->buildConfigurations()) {
for (Target *t : targets()) {
for (BuildConfiguration *bc : t->buildConfigurations()) {
auto i = qobject_cast<CMakeBuildConfiguration *>(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<CMakeBuildConfiguration*>(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<CMakeBuildConfiguration*>(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;
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);

View File

@@ -37,13 +37,10 @@
#include <QFuture>
#include <QHash>
#include <QTimer>
#include <memory>
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<CMakeBuildTarget> 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<CMakeBuildTarget> m_buildTargets;
@@ -134,10 +134,17 @@ private:
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
Internal::TreeScanner m_treeScanner;
bool m_waitingForScan = false;
bool m_waitingForParse = false;
bool m_combinedScanAndParseResult = false;
QHash<QString, bool> m_mimeBinaryCache;
QList<const ProjectExplorer::FileNode *> m_allFiles;
mutable std::unique_ptr<Internal::CMakeProjectImporter> m_projectImporter;
QTimer m_delayedParsingTimer;
friend class Internal::CMakeBuildConfiguration;
friend class Internal::CMakeBuildSettingsWidget;
};

View File

@@ -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
}

View File

@@ -34,7 +34,6 @@ QT_END_NAMESPACE
namespace CMakeProjectManager {
namespace Internal {
class CMakeSettingsPage;
class CMakeManager : public QObject
{

View File

@@ -34,7 +34,6 @@ namespace Utils { class ParameterAction; }
namespace CMakeProjectManager {
class CMakeProject;
class CMakeToolManager;
namespace Internal {

View File

@@ -36,7 +36,6 @@
namespace CMakeProjectManager {
namespace Internal {
class CMakeListsNode;
class ServerModeReader : public BuildDirReader
{

View File

@@ -35,7 +35,6 @@
QT_BEGIN_NAMESPACE
class QAction;
class QSettings;
class QString;
QT_END_NAMESPACE

View File

@@ -34,18 +34,12 @@
#include <QMultiHash>
#include <QTimer>
QT_BEGIN_NAMESPACE
class QLabel;
class QSettings;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
class Action;
class ActionContainerPrivate;
class MainWindow;
class ActionManagerPrivate : public QObject
{

View File

@@ -30,7 +30,6 @@
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLineEdit;
class QTreeWidget;
class QTreeWidgetItem;
QT_END_NAMESPACE

View File

@@ -34,10 +34,8 @@
#include <QVariantMap>
QT_BEGIN_NAMESPACE
class QIcon;
class QWizard;
class QWizardPage;
class QDebug;
QT_END_NAMESPACE
namespace Utils { class Wizard; }

View File

@@ -35,7 +35,6 @@ QT_END_NAMESPACE
namespace Utils {
class PathChooser;
class Theme;
}
namespace Core {

View File

@@ -39,7 +39,6 @@ class QSortFilterProxyModel;
class QPushButton;
class QStandardItem;
class QStandardItemModel;
class QStringList;
QT_END_NAMESPACE
namespace Core {

View File

@@ -30,7 +30,6 @@
namespace Core {
class ICore;
namespace Internal {

View File

@@ -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
{

View File

@@ -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
{

View File

@@ -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 {

View File

@@ -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

View File

@@ -41,8 +41,6 @@
#include <functional>
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 {

View File

@@ -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
{

View File

@@ -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

View File

@@ -44,9 +44,7 @@ namespace Core {
class IWizardFactory;
class Context;
class IContext;
class ProgressManager;
class SettingsDatabase;
class VcsManager;
namespace Internal { class MainWindow; }

View File

@@ -34,7 +34,6 @@
#include <QPointer>
QT_BEGIN_NAMESPACE
class QListWidgetItem;
class QSortFilterProxyModel;
QT_END_NAMESPACE

View File

@@ -34,10 +34,7 @@
QT_BEGIN_NAMESPACE
class QAction;
class QLabel;
class QLineEdit;
class QMenu;
class QTreeView;
QT_END_NAMESPACE
namespace Utils { class FancyLineEdit; }

View File

@@ -37,7 +37,6 @@
#include <functional>
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;

View File

@@ -33,7 +33,6 @@
QT_BEGIN_NAMESPACE
class QSettings;
class QAbstractItemModel;
class QStandardItemModel;
QT_END_NAMESPACE
namespace Core {

View File

@@ -32,9 +32,7 @@
QT_BEGIN_NAMESPACE
class QAction;
class QComboBox;
class QLabel;
class QSplitter;
class QStackedWidget;
class QTimeLine;
class QLabel;

View File

@@ -36,7 +36,6 @@ QT_END_NAMESPACE
namespace Core {
class IMode;
class RightPaneWidget;
class CORE_EXPORT RightPanePlaceHolder : public QWidget

View File

@@ -28,10 +28,8 @@
#include <QWidget>
QT_BEGIN_NAMESPACE
class QSettings;
class QToolBar;
class QAction;
class QToolButton;
QT_END_NAMESPACE
namespace Core {

View File

@@ -37,8 +37,6 @@ class QAction;
QT_END_NAMESPACE
namespace CodePaster {
class CustomFetcher;
class CustomPoster;
class Settings;
class Protocol;

View File

@@ -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

View File

@@ -46,7 +46,6 @@ namespace CppTools { class CppModelManager; }
namespace CppEditor {
namespace Internal {
class CppEditorWidget;
class CppElement;
class CppElementEvaluator

View File

@@ -35,7 +35,6 @@ namespace CppEditor {
namespace Internal {
class CppEditorWidget;
class CppHighlighter : public TextEditor::SyntaxHighlighter
{

View File

@@ -37,12 +37,9 @@ class QLabel;
class QModelIndex;
class QStackedLayout;
class QStandardItem;
template <class> class QVector;
template <class> 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
{

View File

@@ -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(),

View File

@@ -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);

View File

@@ -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 &)

View File

@@ -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);

View File

@@ -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<DebuggerEngine> m_previouslyActiveEngine;
QPointer<DebuggerRunTool> 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 &sections)
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<StandardRunnable>());
debugger->setTestCase(TestNoBoundsOfCurrentFunction);

View File

@@ -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> 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<StandardRunnable>(), reportFailure(); return);
m_runParameters.inferior = runnable.as<StandardRunnable>();
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<StandardRunnable>()) {
m_runParameters.inferior = r.as<StandardRunnable>();
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<DebuggerRunConfigurationAspect>() : 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<Task> 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)

View File

@@ -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<Internal::DebuggerEngine> m_engine; // Master engine
Internal::DebuggerRunParameters m_runParameters;
bool m_isDying = false;

View File

@@ -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,12 +1215,14 @@ 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())
if (m_expectTerminalTrap) {
m_expectTerminalTrap = false;
if ((!data.isValid() || !data["reason"].isValid())
&& Abi::hostAbi().os() == Abi::WindowsOS) {
m_terminalTrap = false;
showMessage("IGNORING TERMINAL SIGTRAP", LogMisc);
return;
}
}
if (isDying()) {
notifyInferiorStopOk();
@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -32,6 +32,7 @@
#include <debugger/debuggermainwindow.h>
#include <debugger/debuggerprotocol.h>
#include <debugger/debuggertooltipmanager.h>
#include <debugger/terminal.h>
#include <debugger/breakhandler.h>
#include <debugger/disassemblerlines.h>
@@ -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

View File

@@ -154,12 +154,6 @@ private:
QHash<int, DebuggerCommand> m_commandForToken;
DebuggerCommandSequence m_onStop;
// Console handling.
void stubError(const QString &msg);
void stubExited();
void stubStarted();
Utils::ConsoleProcess m_stubProc;
};
} // namespace Internal

View File

@@ -25,11 +25,16 @@
#include "terminal.h"
#include "debuggerruncontrol.h"
#include <QDebug>
#include <QIODevice>
#include <QSocketNotifier>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/hostosinfo.h>
#ifdef Q_OS_UNIX
# define DEBUGGER_USE_TERMINAL
@@ -45,6 +50,10 @@
# include <sys/stat.h>
#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

View File

@@ -28,7 +28,15 @@
#include <QCoreApplication>
#include <QSocketNotifier>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <utils/consoleprocess.h>
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

View File

@@ -35,7 +35,6 @@ QT_BEGIN_NAMESPACE
class QComboBox;
class QSpinBox;
class QToolBar;
class QToolButton;
class QStackedWidget;
QT_END_NAMESPACE

View File

@@ -37,7 +37,6 @@ namespace TextEditor { class TextEditorWidget; }
namespace DiffEditor {
class DiffEditorController;
class FileData;
namespace Internal {

View File

@@ -44,7 +44,6 @@ QT_END_NAMESPACE
namespace DiffEditor {
class DiffEditorController;
class FileData;
namespace Internal {

View File

@@ -35,11 +35,6 @@ class DisplaySettings;
class FontSettings;
}
QT_BEGIN_NAMESPACE
class QSplitter;
class QTextCharFormat;
QT_END_NAMESPACE
namespace DiffEditor {
class ChunkData;

View File

@@ -36,7 +36,6 @@ namespace Internal {
namespace Ui { class BranchDialog; }
class BranchAddDialog;
class BranchModel;
/**

View File

@@ -33,10 +33,6 @@
#include <QProcessEnvironment>
QT_BEGIN_NAMESPACE
class QPushButton;
class QLabel;
class QLineEdit;
class QPlainTextEdit;
class QProcess;
class QStringListModel;
QT_END_NAMESPACE

View File

@@ -32,10 +32,6 @@
#include <QSharedPointer>
#include <QDateTime>
QT_BEGIN_NAMESPACE
class QUrl;
QT_END_NAMESPACE
namespace Gerrit {
namespace Internal {
class QueryContext;

View File

@@ -32,10 +32,6 @@
#include <QSharedPointer>
#include <QPair>
QT_BEGIN_NAMESPACE
class QAction;
QT_END_NAMESPACE
namespace Core {
class ActionContainer;
class Command;

View File

@@ -53,7 +53,6 @@ namespace VcsBase {
}
namespace DiffEditor {
class DiffEditorDocument;
class DiffEditorController;
}

View File

@@ -29,10 +29,6 @@
#include <QRegExp>
QT_BEGIN_NAMESPACE
class QVariant;
QT_END_NAMESPACE
namespace Git {
namespace Internal {

View File

@@ -39,9 +39,7 @@
#include <functional>
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;

View File

@@ -37,7 +37,6 @@ namespace VcsBase { class SubmitFileModel; }
namespace Git {
namespace Internal {
class GitClient;
class GitSubmitEditorWidget;
class GitSubmitEditorPanelData;

View File

@@ -36,8 +36,6 @@ QT_END_NAMESPACE
namespace Git {
namespace Internal {
class GitClient;
class MergeTool : public QObject
{
Q_OBJECT

View File

@@ -32,8 +32,6 @@
namespace Git {
namespace Internal {
class GitClient;
class RemoteModel : public QAbstractTableModel {
Q_OBJECT
public:

View File

@@ -32,10 +32,6 @@
#include <QPointer>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace VcsBase {
class VcsBaseClientSettings;
} // namespace VcsBase

View File

@@ -30,7 +30,6 @@
QT_BEGIN_NAMESPACE
class QSortFilterProxyModel;
class QPushButton;
class QModelIndex;
QT_END_NAMESPACE
namespace Git {

View File

@@ -32,8 +32,6 @@
namespace Help {
namespace Internal {
class HelpViewer;
class PrintHelper;
class CentralWidget : public HelpWidget
{

View File

@@ -33,7 +33,6 @@
namespace Help {
namespace Internal {
class CentralWidget;
class GeneralSettingsPage : public Core::IOptionsPage
{

View File

@@ -35,16 +35,11 @@
#include <QStringList>
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

Some files were not shown because too many files have changed in this diff Show More