forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.5'
Change-Id: I919f3dac0bf44f18276e4f70309414bb22c74973
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -154,7 +154,7 @@ struct MessageTrait<Message> \
|
||||
using MixinHighlightingTypes = Utils::SizedArray<HighlightingType, 6>;
|
||||
|
||||
struct HighlightingTypes {
|
||||
HighlightingType mainHighlightingType;
|
||||
HighlightingType mainHighlightingType = HighlightingType::Invalid;
|
||||
MixinHighlightingTypes mixinHighlightingTypes;
|
||||
};
|
||||
|
||||
|
@@ -35,8 +35,6 @@
|
||||
|
||||
namespace Timeline {
|
||||
|
||||
class TimelineRenderPass;
|
||||
class TimelineRenderState;
|
||||
|
||||
class TIMELINE_EXPORT TimelineAbstractRenderer : public QQuickItem
|
||||
{
|
||||
|
@@ -35,8 +35,6 @@
|
||||
|
||||
namespace Timeline {
|
||||
|
||||
class TimelineRenderPass;
|
||||
class TimelineRenderState;
|
||||
|
||||
class TIMELINE_EXPORT TimelineRenderer : public TimelineAbstractRenderer
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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")
|
||||
|
@@ -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; }
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
|
||||
|
@@ -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(' '));
|
||||
|
@@ -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);
|
||||
|
@@ -39,7 +39,6 @@ namespace AutotoolsProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class MakefileParserThread;
|
||||
class AutotoolsTarget;
|
||||
|
||||
/**
|
||||
* @brief Implementation of the ProjectExplorer::Project interface.
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -58,8 +58,6 @@ private slots:
|
||||
void testCompleteAfterModifyingIncludedHeaderByRefactoringActions();
|
||||
void testCompleteAfterChangingIncludedAndOpenHeaderExternally();
|
||||
void testCompleteAfterChangingIncludedAndNotOpenHeaderExternally();
|
||||
|
||||
void testUpdateBackendAfterRestart();
|
||||
};
|
||||
|
||||
} // namespace Tests
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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,72 +67,75 @@
|
||||
|
||||
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);
|
||||
public:
|
||||
ProjectBuilder(RunControl *runControl, Project *project)
|
||||
: RunWorker(runControl), m_project(project)
|
||||
{
|
||||
setDisplayName("ProjectBuilder");
|
||||
}
|
||||
|
||||
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);
|
||||
bool success() const { return m_success; }
|
||||
|
||||
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
|
||||
QTC_ASSERT(projectInfoBeforeBuild.isValid(), return);
|
||||
private:
|
||||
void start() final
|
||||
{
|
||||
Target *target = m_project->activeTarget();
|
||||
QTC_ASSERT(target, reportFailure(); return);
|
||||
|
||||
QTC_ASSERT(runConfiguration, return);
|
||||
Target * const target = runConfiguration->target();
|
||||
QTC_ASSERT(target, return);
|
||||
Project * const project = target->project();
|
||||
QTC_ASSERT(project, return);
|
||||
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
|
||||
if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration())
|
||||
buildType = buildConfig->buildType();
|
||||
|
||||
// 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."));
|
||||
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;
|
||||
}
|
||||
|
||||
// Some projects provides CompilerCallData once a build is finished,
|
||||
QTC_ASSERT(!projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild),
|
||||
return);
|
||||
|
||||
m_projectInfo = projectInfoAfterBuild;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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"
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -38,7 +38,6 @@
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class FileNode;
|
||||
class Kit;
|
||||
} // namespace ProjectExplorer
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
|
@@ -32,7 +32,6 @@ namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class CMakeEditorWidget;
|
||||
class CMakeSettingsPage;
|
||||
|
||||
class CMakeEditor : public TextEditor::BaseTextEditor
|
||||
{
|
||||
|
@@ -31,7 +31,6 @@
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class CMakeSettingsPage;
|
||||
|
||||
class CMakeFileCompletionAssist : public TextEditor::KeywordsCompletionAssistProcessor
|
||||
{
|
||||
|
@@ -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;
|
||||
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())
|
||||
} else if (!qobject_cast<Target *>(pc)) {
|
||||
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);
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -34,7 +34,6 @@ QT_END_NAMESPACE
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class CMakeSettingsPage;
|
||||
|
||||
class CMakeManager : public QObject
|
||||
{
|
||||
|
@@ -34,7 +34,6 @@ namespace Utils { class ParameterAction; }
|
||||
namespace CMakeProjectManager {
|
||||
|
||||
class CMakeProject;
|
||||
class CMakeToolManager;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
|
@@ -36,7 +36,6 @@
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class CMakeListsNode;
|
||||
|
||||
class ServerModeReader : public BuildDirReader
|
||||
{
|
||||
|
@@ -35,7 +35,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QSettings;
|
||||
class QString;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLineEdit;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
QT_END_NAMESPACE
|
||||
|
@@ -34,10 +34,8 @@
|
||||
#include <QVariantMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QIcon;
|
||||
class QWizard;
|
||||
class QWizardPage;
|
||||
class QDebug;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { class Wizard; }
|
||||
|
@@ -35,7 +35,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class PathChooser;
|
||||
class Theme;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
@@ -39,7 +39,6 @@ class QSortFilterProxyModel;
|
||||
class QPushButton;
|
||||
class QStandardItem;
|
||||
class QStandardItemModel;
|
||||
class QStringList;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
@@ -30,7 +30,6 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
class ICore;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -44,9 +44,7 @@ namespace Core {
|
||||
class IWizardFactory;
|
||||
class Context;
|
||||
class IContext;
|
||||
class ProgressManager;
|
||||
class SettingsDatabase;
|
||||
class VcsManager;
|
||||
|
||||
namespace Internal { class MainWindow; }
|
||||
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#include <QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QListWidgetItem;
|
||||
class QSortFilterProxyModel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@@ -34,10 +34,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QMenu;
|
||||
class QTreeView;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { class FancyLineEdit; }
|
||||
|
@@ -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;
|
||||
|
@@ -33,7 +33,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
class QAbstractItemModel;
|
||||
class QStandardItemModel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
@@ -32,9 +32,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QSplitter;
|
||||
class QStackedWidget;
|
||||
class QTimeLine;
|
||||
class QLabel;
|
||||
|
@@ -36,7 +36,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IMode;
|
||||
class RightPaneWidget;
|
||||
|
||||
class CORE_EXPORT RightPanePlaceHolder : public QWidget
|
||||
|
@@ -28,10 +28,8 @@
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
class QToolBar;
|
||||
class QAction;
|
||||
class QToolButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
@@ -37,8 +37,6 @@ class QAction;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CodePaster {
|
||||
class CustomFetcher;
|
||||
class CustomPoster;
|
||||
class Settings;
|
||||
class Protocol;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -46,7 +46,6 @@ namespace CppTools { class CppModelManager; }
|
||||
namespace CppEditor {
|
||||
namespace Internal {
|
||||
|
||||
class CppEditorWidget;
|
||||
class CppElement;
|
||||
|
||||
class CppElementEvaluator
|
||||
|
@@ -35,7 +35,6 @@ namespace CppEditor {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class CppEditorWidget;
|
||||
|
||||
class CppHighlighter : public TextEditor::SyntaxHighlighter
|
||||
{
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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(),
|
||||
|
@@ -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);
|
||||
|
@@ -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 &)
|
||||
|
@@ -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);
|
||||
|
@@ -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,14 +2786,24 @@ void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
|
||||
m_mainWindow->showStatusMessage(msg, timeout);
|
||||
}
|
||||
|
||||
void DebuggerPluginPrivate::coreShutdown()
|
||||
void DebuggerPluginPrivate::aboutToShutdown()
|
||||
{
|
||||
m_shuttingDown = true;
|
||||
if (currentEngine()) {
|
||||
if (currentEngine()->state() != Debugger::DebuggerNotReady)
|
||||
currentEngine()->abortDebugger();
|
||||
|
||||
disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr);
|
||||
|
||||
m_mainWindow->saveCurrentPerspective();
|
||||
m_shutdownTimer.setInterval(0);
|
||||
m_shutdownTimer.setSingleShot(true);
|
||||
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
|
||||
if (DebuggerEngine *engine = currentEngine()) {
|
||||
if (engine->state() != Debugger::DebuggerNotReady) {
|
||||
engine->abortDebugger();
|
||||
m_shutdownTimer.setInterval(3000);
|
||||
}
|
||||
}
|
||||
m_shutdownTimer.start();
|
||||
}
|
||||
|
||||
const CPlusPlus::Snapshot &cppCodeModelSnapshot()
|
||||
{
|
||||
@@ -2878,8 +2878,9 @@ static void createNewDock(QWidget *widget)
|
||||
dockWidget->show();
|
||||
}
|
||||
|
||||
static QString formatStartParameters(const DebuggerRunParameters &sp)
|
||||
static QString formatStartParameters(const DebuggerRunTool *debugger)
|
||||
{
|
||||
const DebuggerRunParameters &sp = debugger->runParameters();
|
||||
QString rc;
|
||||
QTextStream str(&rc);
|
||||
str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
|
||||
@@ -2893,7 +2894,7 @@ static QString formatStartParameters(const DebuggerRunParameters &sp)
|
||||
if (!sp.inferior.executable.isEmpty()) {
|
||||
str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
|
||||
<< ' ' << sp.inferior.commandLineArguments;
|
||||
if (sp.useTerminal)
|
||||
if (debugger->terminalRunner())
|
||||
str << " [terminal]";
|
||||
str << '\n';
|
||||
if (!sp.inferior.workingDirectory.isEmpty())
|
||||
@@ -2928,7 +2929,7 @@ void DebuggerPluginPrivate::runControlStarted(DebuggerRunTool *runTool)
|
||||
.arg(runTool->engine()->objectName())
|
||||
.arg(runTool->runParameters().toolChainAbi.toString());
|
||||
showStatusMessage(message);
|
||||
showMessage(formatStartParameters(runTool->runParameters()), LogDebug);
|
||||
showMessage(formatStartParameters(runTool), LogDebug);
|
||||
showMessage(m_debuggerSettings->dump(), LogDebug);
|
||||
m_snapshotHandler->appendSnapshot(runTool);
|
||||
connectEngine(runTool);
|
||||
@@ -2938,11 +2939,13 @@ void DebuggerPluginPrivate::runControlFinished(DebuggerRunTool *runTool)
|
||||
{
|
||||
if (runTool && runTool->engine())
|
||||
runTool->engine()->handleFinished();
|
||||
if (m_shuttingDown)
|
||||
return;
|
||||
showStatusMessage(tr("Debugger finished."));
|
||||
m_snapshotHandler->removeSnapshot(runTool);
|
||||
if (m_snapshotHandler->size() == 0) {
|
||||
if (m_shuttingDown) {
|
||||
doShutdown();
|
||||
return;
|
||||
}
|
||||
// Last engine quits.
|
||||
disconnectEngine();
|
||||
if (boolSetting(SwitchModeOnExit))
|
||||
@@ -3120,11 +3123,9 @@ void showModuleSections(const QString &moduleName, const Sections §ions)
|
||||
createNewDock(w);
|
||||
}
|
||||
|
||||
void DebuggerPluginPrivate::aboutToShutdown()
|
||||
void DebuggerPluginPrivate::doShutdown()
|
||||
{
|
||||
disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr);
|
||||
|
||||
m_mainWindow->saveCurrentPerspective();
|
||||
m_shutdownTimer.stop();
|
||||
delete m_mainWindow;
|
||||
m_mainWindow = 0;
|
||||
|
||||
@@ -3140,6 +3141,7 @@ void DebuggerPluginPrivate::aboutToShutdown()
|
||||
|
||||
delete m_mode;
|
||||
m_mode = 0;
|
||||
emit m_plugin->asynchronousShutdownFinished();
|
||||
}
|
||||
|
||||
void updateState(DebuggerRunTool *runTool)
|
||||
@@ -3302,7 +3304,7 @@ IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
|
||||
{
|
||||
removeObject(this);
|
||||
dd->aboutToShutdown();
|
||||
return SynchronousShutdown;
|
||||
return AsynchronousShutdown;
|
||||
}
|
||||
|
||||
QObject *DebuggerPlugin::remoteCommand(const QStringList &options,
|
||||
@@ -3648,7 +3650,9 @@ void DebuggerUnitTests::testStateMachine()
|
||||
RunConfiguration *rc = t->activeRunConfiguration();
|
||||
QVERIFY(rc);
|
||||
|
||||
auto debugger = DebuggerRunTool::createFromRunConfiguration(rc);
|
||||
auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||
auto debugger = new DebuggerRunTool(runControl);
|
||||
|
||||
debugger->setInferior(rc->runnable().as<StandardRunnable>());
|
||||
debugger->setTestCase(TestNoBoundsOfCurrentFunction);
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -35,7 +35,6 @@ QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QSpinBox;
|
||||
class QToolBar;
|
||||
class QToolButton;
|
||||
class QStackedWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@@ -37,7 +37,6 @@ namespace TextEditor { class TextEditorWidget; }
|
||||
|
||||
namespace DiffEditor {
|
||||
|
||||
class DiffEditorController;
|
||||
class FileData;
|
||||
|
||||
namespace Internal {
|
||||
|
@@ -44,7 +44,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace DiffEditor {
|
||||
|
||||
class DiffEditorController;
|
||||
class FileData;
|
||||
|
||||
namespace Internal {
|
||||
|
@@ -35,11 +35,6 @@ class DisplaySettings;
|
||||
class FontSettings;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSplitter;
|
||||
class QTextCharFormat;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DiffEditor {
|
||||
|
||||
class ChunkData;
|
||||
|
@@ -36,7 +36,6 @@ namespace Internal {
|
||||
|
||||
namespace Ui { class BranchDialog; }
|
||||
|
||||
class BranchAddDialog;
|
||||
class BranchModel;
|
||||
|
||||
/**
|
||||
|
@@ -33,10 +33,6 @@
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPlainTextEdit;
|
||||
class QProcess;
|
||||
class QStringListModel;
|
||||
QT_END_NAMESPACE
|
||||
|
@@ -32,10 +32,6 @@
|
||||
#include <QSharedPointer>
|
||||
#include <QDateTime>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QUrl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Gerrit {
|
||||
namespace Internal {
|
||||
class QueryContext;
|
||||
|
@@ -32,10 +32,6 @@
|
||||
#include <QSharedPointer>
|
||||
#include <QPair>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
class ActionContainer;
|
||||
class Command;
|
||||
|
@@ -53,7 +53,6 @@ namespace VcsBase {
|
||||
}
|
||||
|
||||
namespace DiffEditor {
|
||||
class DiffEditorDocument;
|
||||
class DiffEditorController;
|
||||
}
|
||||
|
||||
|
@@ -29,10 +29,6 @@
|
||||
|
||||
#include <QRegExp>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QVariant;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -37,7 +37,6 @@ namespace VcsBase { class SubmitFileModel; }
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class GitClient;
|
||||
class GitSubmitEditorWidget;
|
||||
class GitSubmitEditorPanelData;
|
||||
|
||||
|
@@ -36,8 +36,6 @@ QT_END_NAMESPACE
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class GitClient;
|
||||
|
||||
class MergeTool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@@ -32,8 +32,6 @@
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class GitClient;
|
||||
|
||||
class RemoteModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@@ -32,10 +32,6 @@
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace VcsBase {
|
||||
class VcsBaseClientSettings;
|
||||
} // namespace VcsBase
|
||||
|
@@ -30,7 +30,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSortFilterProxyModel;
|
||||
class QPushButton;
|
||||
class QModelIndex;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Git {
|
||||
|
@@ -32,8 +32,6 @@
|
||||
namespace Help {
|
||||
namespace Internal {
|
||||
|
||||
class HelpViewer;
|
||||
class PrintHelper;
|
||||
|
||||
class CentralWidget : public HelpWidget
|
||||
{
|
||||
|
@@ -33,7 +33,6 @@
|
||||
namespace Help {
|
||||
namespace Internal {
|
||||
|
||||
class CentralWidget;
|
||||
|
||||
class GeneralSettingsPage : public Core::IOptionsPage
|
||||
{
|
||||
|
@@ -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
Reference in New Issue
Block a user