Merge remote-tracking branch 'origin/master' into 4.4

Change-Id: I00fe351ee5f2689366c63ba94b042609c47da777
This commit is contained in:
Eike Ziller
2017-07-04 13:55:35 +02:00
68 changed files with 733 additions and 389 deletions

View File

@@ -155,6 +155,7 @@ HEADERS += \
$$PWD/pchmanagerclientproxy.h \
$$PWD/projectpartpch.h \
$$PWD/precompiledheadersupdatedmessage.h \
$$PWD/stringcache.h \
$$PWD/removepchprojectpartsmessage.h \
$$PWD/clangcodemodelclientmessages.h \
$$PWD/clangcodemodelservermessages.h \

View File

@@ -37,66 +37,62 @@ class FilePath
{
public:
FilePath() = default;
explicit FilePath(Utils::SmallString &&filePath)
explicit FilePath(Utils::PathString &&filePath)
: m_path(std::move(filePath))
{
auto foundReverse = std::find(filePath.rbegin(), filePath.rend(), '/');
auto foundReverse = std::find(m_path.rbegin(), m_path.rend(), '/');
auto found = foundReverse.base();
--found;
Utils::SmallString fileName(found, filePath.end());
if (foundReverse != filePath.rend())
filePath.resize(std::size_t(std::distance(filePath.begin(), --found)));
m_slashIndex = std::size_t(std::distance(m_path.begin(), found));
}
directory_ = std::move(filePath);
name_ = std::move(fileName);
explicit FilePath(const Utils::PathString &filePath)
: FilePath(filePath.clone())
{
}
explicit FilePath(Utils::PathString &&filePath, std::size_t slashIndex)
: m_path(std::move(filePath)),
m_slashIndex(slashIndex)
{
}
explicit FilePath(const QString &filePath)
: FilePath(Utils::SmallString(filePath))
: FilePath(Utils::PathString(filePath))
{
}
FilePath(Utils::SmallString &&directory, Utils::SmallString &&name)
: directory_(std::move(directory)),
name_(std::move(name))
FilePath(const Utils::PathString &directory, const Utils::PathString &name)
: m_path({std::move(directory), "/", std::move(name)}),
m_slashIndex(directory.size())
{}
const Utils::SmallString &directory() const
Utils::SmallStringView directory() const
{
return directory_;
return m_path.mid(0, m_slashIndex);
}
Utils::SmallString takeDirectory()
Utils::SmallStringView name() const
{
return std::move(directory_);
return m_path.mid(m_slashIndex + 1, m_path.size() - m_slashIndex - 1);
}
const Utils::SmallString &name() const
const Utils::PathString &path() const
{
return name_;
}
Utils::SmallString takeName()
{
return std::move(name_);
}
Utils::PathString path() const
{
return {directory_, "/", name_};
return m_path;
}
friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath)
{
out << filePath.directory_;
out << filePath.name_;
out << filePath.m_path;
return out;
}
friend QDataStream &operator>>(QDataStream &in, FilePath &filePath)
{
in >> filePath.directory_;
in >> filePath.name_;
in >> filePath.m_path;
return in;
}
@@ -110,24 +106,22 @@ public:
friend bool operator==(const FilePath &first, const FilePath &second)
{
return first.name_ == second.name_
&& first.directory_ == second.directory_;
return first.m_path == second.m_path;
}
friend bool operator<(const FilePath &first, const FilePath &second)
{
return std::tie(first.name_, first.directory_)
< std::tie(second.name_, second.directory_);
return first.m_path < second.m_path;
}
FilePath clone() const
{
return FilePath(directory_.clone(), name_.clone());
return FilePath(m_path.clone(), m_slashIndex);
}
private:
Utils::SmallString directory_;
Utils::SmallString name_;
Utils::PathString m_path = "/";
std::size_t m_slashIndex = 0;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FilePath &filePath);

View File

@@ -42,13 +42,10 @@ public:
{
}
void insertFilePath(uint fileId, Utils::SmallString &&fileDirectory, Utils::SmallString &&fileName)
void insertFilePath(uint fileId, Utils::PathString &&filePath)
{
if (m_filePathHash.find(fileId) == m_filePathHash.end()) {
m_filePathHash.emplace(std::piecewise_construct,
std::forward_as_tuple(fileId),
std::forward_as_tuple(std::move(fileDirectory), std::move(fileName)));
}
if (m_filePathHash.find(fileId) == m_filePathHash.end())
m_filePathHash.emplace(fileId, FilePath(std::move(filePath)));
}
void reserve(std::size_t size)

View File

@@ -46,10 +46,10 @@ QDebug operator<<(QDebug debug, const SourceLocationContainer &container)
std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container)
{
os << "("
<< container.fileHash() << ", "
<< container.line() << ", "
<< container.column() << ", "
<< container.offset() << ", "
<< container.fileHash()
<< container.offset()
<< ")";
return os;

View File

@@ -47,6 +47,11 @@ public:
return sourceRangesContainer;
}
SourceRangesContainer &sourceRanges()
{
return sourceRangesContainer;
}
const std::vector<DynamicASTMatcherDiagnosticContainer> &diagnostics() const
{
return diagnosticContainers;

View File

@@ -54,6 +54,11 @@ public:
return m_sourceRangeWithTextContainers;
}
std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers()
{
return m_sourceRangeWithTextContainers;
}
std::vector<SourceRangeWithTextContainer> takeSourceRangeWithTextContainers()
{
return std::move(m_sourceRangeWithTextContainers);

View File

@@ -110,6 +110,25 @@ private:
Utils::SmallString m_text;
};
using SourceRangeWithTextContainers = std::vector<SourceRangeWithTextContainer>;
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer &container);
std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &container);
} // namespace ClangBackEnd
namespace std
{
template<> struct hash<ClangBackEnd::SourceRangeWithTextContainer>
{
using argument_type = ClangBackEnd::SourceRangeWithTextContainer;
using result_type = std::size_t;
result_type operator()(const argument_type &container) const
{
const result_type h1{std::hash<uint>{}(container.fileHash())};
const result_type h2{std::hash<uint>{}(container.start().offset())};
const result_type h3{std::hash<uint>{}(container.end().offset())};
return h1 ^ (h2 << 8) ^ (h3 << 16);
}
};
}

View File

@@ -25,16 +25,26 @@
#pragma once
#include "clangpchmanagerbackend_global.h"
#include <utils/smallstringview.h>
#include <algorithm>
#include <mutex>
#include <vector>
namespace ClangBackEnd {
template <typename StringType>
class NonLockingMutex
{
public:
constexpr NonLockingMutex() noexcept {}
NonLockingMutex(const NonLockingMutex&) = delete;
NonLockingMutex& operator=(const NonLockingMutex&) = delete;
void lock() {}
void unlock() {}
};
template <typename StringType,
typename Mutex = NonLockingMutex>
class StringCache
{
class StringCacheEntry
@@ -79,6 +89,8 @@ public:
uint stringId(Utils::SmallStringView stringView)
{
std::lock_guard<Mutex> lock(m_mutex);
Found found = find(stringView);
if (!found.wasFound)
@@ -89,6 +101,8 @@ public:
std::vector<uint> stringIds(const std::vector<StringType> &strings)
{
std::lock_guard<Mutex> lock(m_mutex);
std::vector<uint> ids;
ids.reserve(strings.size());
@@ -102,11 +116,15 @@ public:
const StringType &string(uint id) const
{
std::lock_guard<Mutex> lock(m_mutex);
return m_strings.at(m_indices.at(id)).string;
}
std::vector<StringType> strings(const std::vector<uint> &ids) const
{
std::lock_guard<Mutex> lock(m_mutex);
std::vector<StringType> strings;
strings.reserve(ids.size());
@@ -155,6 +173,7 @@ private:
private:
StringCacheEntries m_strings;
std::vector<uint> m_indices;
mutable Mutex m_mutex;
};
} // namespace ClangBackEnd

View File

@@ -395,18 +395,13 @@ FileSaverBase::FileSaverBase()
{
}
FileSaverBase::~FileSaverBase()
{
delete m_file;
}
FileSaverBase::~FileSaverBase() = default;
bool FileSaverBase::finalize()
{
m_file->close();
setResult(m_file->error() == QFile::NoError);
// We delete the object, so it is really closed even if it is a QTemporaryFile.
delete m_file;
m_file = 0;
m_file.reset();
return !m_hasError;
}
@@ -444,8 +439,13 @@ bool FileSaverBase::write(const QByteArray &bytes)
bool FileSaverBase::setResult(bool ok)
{
if (!ok && !m_hasError) {
m_errorString = tr("Cannot write file %1. Disk full?").arg(
QDir::toNativeSeparators(m_fileName));
if (!m_file->errorString().isEmpty()) {
m_errorString = tr("Cannot write file %1: %2").arg(
QDir::toNativeSeparators(m_fileName), m_file->errorString());
} else {
m_errorString = tr("Cannot write file %1. Disk full?").arg(
QDir::toNativeSeparators(m_fileName));
}
m_hasError = true;
}
return ok;
@@ -488,10 +488,10 @@ FileSaver::FileSaver(const QString &filename, QIODevice::OpenMode mode)
}
}
if (mode & (QIODevice::ReadOnly | QIODevice::Append)) {
m_file = new QFile(filename);
m_file.reset(new QFile{filename});
m_isSafe = false;
} else {
m_file = new SaveFile(filename);
m_file.reset(new SaveFile{filename});
m_isSafe = true;
}
if (!m_file->open(QIODevice::WriteOnly | mode)) {
@@ -507,22 +507,22 @@ bool FileSaver::finalize()
if (!m_isSafe)
return FileSaverBase::finalize();
SaveFile *sf = static_cast<SaveFile *>(m_file);
SaveFile *sf = static_cast<SaveFile *>(m_file.get());
if (m_hasError) {
if (sf->isOpen())
sf->rollback();
} else {
setResult(sf->commit());
}
delete sf;
m_file = 0;
m_file.reset();
return !m_hasError;
}
TempFileSaver::TempFileSaver(const QString &templ)
: m_autoRemove(true)
{
QTemporaryFile *tempFile = new QTemporaryFile();
m_file.reset(new QTemporaryFile{});
QTemporaryFile *tempFile = static_cast<QTemporaryFile *>(m_file.get());
if (!templ.isEmpty())
tempFile->setFileTemplate(templ);
tempFile->setAutoRemove(false);
@@ -532,14 +532,12 @@ TempFileSaver::TempFileSaver(const QString &templ)
tempFile->errorString());
m_hasError = true;
}
m_file = tempFile;
m_fileName = tempFile->fileName();
}
TempFileSaver::~TempFileSaver()
{
delete m_file;
m_file = 0;
m_file.reset();
if (m_autoRemove)
QFile::remove(m_fileName);
}

View File

@@ -35,6 +35,7 @@
#include <QStringList>
#include <functional>
#include <memory>
namespace Utils {class FileName; }
@@ -190,8 +191,10 @@ public:
bool setResult(QXmlStreamWriter *stream);
bool setResult(bool ok);
QFile *file() { return m_file.get(); }
protected:
QFile *m_file;
std::unique_ptr<QFile> m_file;
QString m_fileName;
QString m_errorString;
bool m_hasError;
@@ -208,7 +211,6 @@ public:
virtual bool finalize();
using FileSaverBase::finalize;
QFile *file() { return m_file; }
private:
bool m_isSafe;
@@ -221,8 +223,6 @@ public:
explicit TempFileSaver(const QString &templ = QString());
~TempFileSaver();
QTemporaryFile *file() { return reinterpret_cast<QTemporaryFile *>(m_file); }
void setAutoRemove(bool on) { m_autoRemove = on; }
private:

View File

@@ -113,10 +113,19 @@ bool SaveFile::commit()
QString finalFileName
= FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString();
QString bakname = finalFileName + QLatin1Char('~');
QFile::remove(bakname); // Kill old backup
QFile::rename(finalFileName, bakname); // Backup current file
if (QFile::exists(finalFileName)) {
QFile::remove(bakname); // Kill old backup
// Try to back up current file
if (!QFile::rename(finalFileName, bakname)) {
remove();
setErrorString(tr("File might be locked."));
return false;
}
}
if (!rename(finalFileName)) { // Replace current file
QFile::rename(bakname, finalFileName); // Rollback to current file
remove();
return false;
}
if (!m_backup)

View File

@@ -68,12 +68,12 @@ QDataStream &operator>>(QDataStream &in, BasicSmallString<Size> &string)
return in;
}
inline
QDebug &operator<<(QDebug &debug, const SmallString &string)
template <typename String>
QDebug &operator<<(QDebug &debug, const String &string)
{
using QT_PREPEND_NAMESPACE(operator<<);
debug.nospace() << "\"" << string.data() << "\"";
debug.nospace().quote() << QByteArray::fromRawData(string.data(), int(string.size()));
return debug;
}

View File

@@ -104,6 +104,11 @@ public:
return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
}
operator std::string() const
{
return std::string(data(), size());
}
private:
const char *m_pointer;
size_type m_size;

View File

@@ -67,6 +67,12 @@ QStringList QtTestConfiguration::argumentsForTestRunner() const
if (!metricsOption.isEmpty())
arguments << metricsOption;
if (qtSettings->verboseBench)
arguments << "-vb";
if (qtSettings->logSignalsSlots)
arguments << "-vs";
if (runMode() == DebuggableTestConfiguration::Debug) {
if (qtSettings->noCrashHandler)
arguments << "-nocrashhandler";

View File

@@ -319,7 +319,7 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine)
static QRegExp finish("^[*]{9} Finished testing of (.*) [*]{9}$");
static QRegExp result("^(PASS |FAIL! |XFAIL |XPASS |SKIP |BPASS |BFAIL |RESULT "
"|INFO |QWARN |WARNING|QDEBUG ): (.*)$");
"|INFO |QWARN |WARNING|QDEBUG ): (.*)$");
static QRegExp benchDetails("^\\s+([\\d,.]+ .* per iteration \\(total: [\\d,.]+, iterations: \\d+\\))$");
static QRegExp locationUnix("^ Loc: \\[(.*)\\]$");

View File

@@ -31,6 +31,8 @@ namespace Internal {
static const char metricsKey[] = "Metrics";
static const char noCrashhandlerKey[] = "NoCrashhandlerOnDebug";
static const char useXMLOutputKey[] = "UseXMLOutput";
static const char verboseBenchKey[] = "VerboseBench";
static const char logSignalsSlotsKey[] = "LogSignalsSlots";
static MetricsType intToMetrics(int value)
{
@@ -60,6 +62,8 @@ void QtTestSettings::fromFrameworkSettings(const QSettings *s)
metrics = intToMetrics(s->value(metricsKey, Walltime).toInt());
noCrashHandler = s->value(noCrashhandlerKey, true).toBool();
useXMLOutput = s->value(useXMLOutputKey, true).toBool();
verboseBench = s->value(verboseBenchKey, false).toBool();
logSignalsSlots = s->value(logSignalsSlotsKey, false).toBool();
}
void QtTestSettings::toFrameworkSettings(QSettings *s) const
@@ -67,6 +71,8 @@ void QtTestSettings::toFrameworkSettings(QSettings *s) const
s->setValue(metricsKey, metrics);
s->setValue(noCrashhandlerKey, noCrashHandler);
s->setValue(useXMLOutputKey, useXMLOutput);
s->setValue(verboseBenchKey, verboseBench);
s->setValue(logSignalsSlotsKey, logSignalsSlots);
}
QString QtTestSettings::metricsTypeToOption(const MetricsType type)

View File

@@ -49,6 +49,8 @@ public:
MetricsType metrics = Walltime;
bool noCrashHandler = true;
bool useXMLOutput = true;
bool verboseBench = false;
bool logSignalsSlots = false;
protected:
void fromFrameworkSettings(const QSettings *s) override;

View File

@@ -47,6 +47,8 @@ void QtTestSettingsWidget::setSettings(const QtTestSettings &settings)
{
m_ui.disableCrashhandlerCB->setChecked(settings.noCrashHandler);
m_ui.useXMLOutputCB->setChecked(settings.useXMLOutput);
m_ui.verboseBenchmarksCB->setChecked(settings.verboseBench);
m_ui.logSignalsAndSlotsCB->setChecked(settings.logSignalsSlots);
switch (settings.metrics) {
case MetricsType::Walltime:
m_ui.walltimeRB->setChecked(true);
@@ -74,6 +76,8 @@ QtTestSettings QtTestSettingsWidget::settings() const
result.noCrashHandler = m_ui.disableCrashhandlerCB->isChecked();
result.useXMLOutput = m_ui.useXMLOutputCB->isChecked();
result.verboseBench = m_ui.verboseBenchmarksCB->isChecked();
result.logSignalsSlots = m_ui.logSignalsAndSlotsCB->isChecked();
if (m_ui.walltimeRB->isChecked())
result.metrics = MetricsType::Walltime;
else if (m_ui.tickcounterRB->isChecked())

View File

@@ -46,6 +46,23 @@ Warning: Plain text output is missing some information (e.g. duration)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="verboseBenchmarksCB">
<property name="text">
<string>Verbose benchmarks</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="logSignalsAndSlotsCB">
<property name="toolTip">
<string>Log every signal emission and resulting slot invocations.</string>
</property>
<property name="text">
<string>Log signals and slots</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">

View File

@@ -104,19 +104,6 @@ void RefactoringClient::setRefactoringConnectionClient(
this->connectionClient = connectionClient;
}
namespace {
Utils::SmallString concatenateFilePath(const ClangBackEnd::FilePath &filePath)
{
Utils::SmallString concatenatedFilePath = filePath.directory().clone();
concatenatedFilePath.append("/");
concatenatedFilePath.append(filePath.name().clone());
return concatenatedFilePath;
}
}
std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
const ClangBackEnd::FilePathDict &filePaths)
{
@@ -126,7 +113,7 @@ std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
auto convertFilePath = [] (const ClangBackEnd::FilePathDict::value_type &dictonaryEntry) {
return std::make_pair(dictonaryEntry.first,
concatenateFilePath(dictonaryEntry.second).toQString());
dictonaryEntry.second.path().toQString());
};
std::transform(filePaths.begin(),

View File

@@ -55,7 +55,7 @@
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="searchLabel">
<property name="text">
<string>Sear&amp;ch for:</string>
</property>
@@ -73,7 +73,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -103,9 +112,18 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="widget" native="true">
<widget class="QWidget" name="optionsWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>

View File

@@ -147,6 +147,13 @@ void FindToolWindow::updateButtonStates()
if (m_configWidget)
m_configWidget->setEnabled(filterEnabled);
if (m_currentFilter) {
m_ui.searchTerm->setVisible(m_currentFilter->showSearchTermInput());
m_ui.searchLabel->setVisible(m_currentFilter->showSearchTermInput());
m_ui.optionsWidget->setVisible(m_currentFilter->supportedFindFlags()
& (FindCaseSensitively | FindWholeWords | FindRegularExpression));
}
m_ui.matchCase->setEnabled(filterEnabled
&& (m_currentFilter->supportedFindFlags() & FindCaseSensitively));
m_ui.wholeWords->setEnabled(filterEnabled

View File

@@ -142,6 +142,14 @@
your find filter supports global search and replace.
*/
/*!
\fn bool showSearchTermInput() const
Returns whether the find filter wants to show the search term line edit.
The default value is \c true, override this function to return \c false, if
your find filter does not want to show the search term line edit.
*/
/*!
\fn void IFindFilter::findAll(const QString &txt, Core::FindFlags findFlags)
This function is called when the user selected this find scope and
@@ -227,7 +235,8 @@ QKeySequence IFindFilter::defaultShortcut() const
FindFlags IFindFilter::supportedFindFlags() const
{
return FindCaseSensitively
| FindRegularExpression | FindWholeWords;
| FindRegularExpression
| FindWholeWords;
}
QPixmap IFindFilter::pixmapForFindFlags(FindFlags flags)

View File

@@ -50,6 +50,7 @@ public:
virtual bool isValid() const { return true; }
virtual QKeySequence defaultShortcut() const;
virtual bool isReplaceSupported() const { return false; }
virtual bool showSearchTermInput() const { return true; }
virtual FindFlags supportedFindFlags() const;
virtual void findAll(const QString &txt, FindFlags findFlags) = 0;

View File

@@ -100,11 +100,6 @@ void SymbolsFindFilter::setPaused(bool paused)
watcher->setPaused(paused);
}
FindFlags SymbolsFindFilter::supportedFindFlags() const
{
return FindCaseSensitively | FindRegularExpression | FindWholeWords;
}
void SymbolsFindFilter::findAll(const QString &txt, FindFlags findFlags)
{
SearchResultWindow *window = SearchResultWindow::instance();

View File

@@ -56,7 +56,6 @@ public:
QString id() const;
QString displayName() const;
bool isEnabled() const;
Core::FindFlags supportedFindFlags() const;
void findAll(const QString &txt, Core::FindFlags findFlags);

View File

@@ -30,11 +30,7 @@
#include "../debuggermainwindow.h"
#include <coreplugin/id.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/runconfiguration.h>
#include <QWidget>
#include <QCoreApplication>

View File

@@ -3416,19 +3416,10 @@ static bool buildTypeAccepted(QFlags<ToolMode> toolMode, BuildConfiguration::Bui
return false;
}
RunConfiguration *startupRunConfiguration()
{
if (Project *pro = SessionManager::startupProject()) {
if (const Target *target = pro->activeTarget())
return target->activeRunConfiguration();
}
return nullptr;
}
static BuildConfiguration::BuildType startupBuildType()
{
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
if (RunConfiguration *runConfig = startupRunConfiguration()) {
if (RunConfiguration *runConfig = RunConfiguration::startupRunConfiguration()) {
if (const BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration())
buildType = buildConfig->buildType();
}

View File

@@ -33,6 +33,7 @@
#include "environmentaspect.h"
#include "kitinformation.h"
#include "runnables.h"
#include "session.h"
#include <extensionsystem/pluginmanager.h>
@@ -243,6 +244,20 @@ void RunConfiguration::ctor()
[this] { return displayName(); }, false);
}
/*!
* Returns the RunConfiguration of the currently active target
* of the startup project, if such exists, or \c nullptr otherwise.
*/
RunConfiguration *RunConfiguration::startupRunConfiguration()
{
if (Project *pro = SessionManager::startupProject()) {
if (const Target *target = pro->activeTarget())
return target->activeRunConfiguration();
}
return nullptr;
}
/*!
Checks whether a run configuration is enabled.
*/

View File

@@ -281,6 +281,8 @@ public:
void addExtraAspect(IRunConfigurationAspect *aspect);
static RunConfiguration *startupRunConfiguration();
signals:
void enabledChanged();
void requestRunActionsUpdate();

View File

@@ -587,8 +587,8 @@ void QmlProfilerTool::attachToWaitingApplication()
Debugger::selectPerspective(Constants::QmlProfilerPerspectiveId);
RunConfiguration *rc = Debugger::startupRunConfiguration();
auto runControl = new RunControl(rc, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
auto runConfig = RunConfiguration::startupRunConfiguration();
auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
auto profiler = new QmlProfilerRunner(runControl);
profiler->setServerUrl(serverUrl);

View File

@@ -8,7 +8,6 @@ SOURCES += qnxplugin.cpp \
qnxdevicefactory.cpp \
qnxdevicewizard.cpp \
qnxrunconfiguration.cpp \
qnxruncontrolfactory.cpp \
qnxanalyzesupport.cpp \
qnxdebugsupport.cpp \
qnxdeploystepfactory.cpp \
@@ -41,7 +40,6 @@ HEADERS += qnxplugin.h\
qnxdevicefactory.h \
qnxdevicewizard.h \
qnxrunconfiguration.h \
qnxruncontrolfactory.h \
qnxanalyzesupport.h \
qnxdebugsupport.h \
qnxdeploystepfactory.h \

View File

@@ -76,8 +76,6 @@ QtcPlugin {
"qnxrunconfiguration.h",
"qnxrunconfigurationfactory.cpp",
"qnxrunconfigurationfactory.h",
"qnxruncontrolfactory.cpp",
"qnxruncontrolfactory.h",
"qnxutils.cpp",
"qnxutils.h",
"qnx_export.h",

View File

@@ -75,9 +75,11 @@ private:
// QnxDebugSupport
QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
QnxQmlProfilerSupport::QnxQmlProfilerSupport(RunControl *runControl)
: RunWorker(runControl)
{
runControl->createWorker(runControl->runMode());
setDisplayName("QnxAnalyzeSupport");
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
@@ -99,7 +101,7 @@ QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
// m_outputParser.processOutput(msg);
}
void QnxAnalyzeSupport::start()
void QnxQmlProfilerSupport::start()
{
// runControl()->notifyRemoteSetupDone(m_qmlPort);
reportStarted();

View File

@@ -30,14 +30,12 @@
namespace Qnx {
namespace Internal {
class Slog2InfoRunner;
class QnxAnalyzeSupport : public ProjectExplorer::RunWorker
class QnxQmlProfilerSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
explicit QnxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
explicit QnxQmlProfilerSupport(ProjectExplorer::RunControl *runControl);
private:
void start() override;

View File

@@ -25,38 +25,49 @@
#include "qnxplugin.h"
#include "qnxconstants.h"
#include "qnxanalyzesupport.h"
#include "qnxattachdebugsupport.h"
#include "qnxdevicefactory.h"
#include "qnxruncontrolfactory.h"
#include "qnxdeploystepfactory.h"
#include "qnxdeployconfigurationfactory.h"
#include "qnxrunconfigurationfactory.h"
#include "qnxqtversionfactory.h"
#include "qnxsettingspage.h"
#include "qnxconfigurationmanager.h"
#include "qnxconstants.h"
#include "qnxdebugsupport.h"
#include "qnxdeployconfigurationfactory.h"
#include "qnxdeploystepfactory.h"
#include "qnxdevice.h"
#include "qnxdevicefactory.h"
#include "qnxqtversion.h"
#include "qnxqtversionfactory.h"
#include "qnxrunconfiguration.h"
#include "qnxrunconfigurationfactory.h"
#include "qnxsettingspage.h"
#include "qnxtoolchain.h"
#include "qnxattachdebugsupport.h"
#include "qnxutils.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <qtsupport/qtkitinformation.h>
#include <QAction>
#include <QtPlugin>
using namespace ProjectExplorer;
using namespace Qnx::Internal;
QnxPlugin::QnxPlugin() : m_debugSeparator(0) , m_attachToQnxApplication(0)
{ }
namespace Qnx {
namespace Internal {
bool QnxPlugin::initialize(const QStringList &arguments, QString *errorString)
{
@@ -67,13 +78,29 @@ bool QnxPlugin::initialize(const QStringList &arguments, QString *errorString)
addAutoReleasedObject(new QnxConfigurationManager);
addAutoReleasedObject(new QnxQtVersionFactory);
addAutoReleasedObject(new QnxDeviceFactory);
addAutoReleasedObject(new QnxRunControlFactory);
addAutoReleasedObject(new QnxDeployStepFactory);
addAutoReleasedObject(new QnxDeployConfigurationFactory);
addAutoReleasedObject(new QnxRunConfigurationFactory);
addAutoReleasedObject(new QnxSettingsPage);
// Handle Qcc Compiler
auto constraint = [](RunConfiguration *runConfig) {
if (!runConfig->isEnabled()
|| !runConfig->id().name().startsWith(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX)) {
return false;
}
auto dev = DeviceKitInformation::device(runConfig->target()->kit())
.dynamicCast<const QnxDevice>();
return !dev.isNull();
};
RunControl::registerWorker<SimpleTargetRunner>
(ProjectExplorer::Constants::NORMAL_RUN_MODE, constraint);
RunControl::registerWorker<QnxDebugSupport>
(ProjectExplorer::Constants::DEBUG_RUN_MODE, constraint);
RunControl::registerWorker<QnxQmlProfilerSupport>
(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, constraint);
addAutoReleasedObject(new QnxToolChainFactory);
return true;
@@ -118,3 +145,6 @@ void QnxPlugin::updateDebuggerActions()
m_attachToQnxApplication->setVisible(false && hasValidQnxKit); // FIXME
m_debugSeparator->setVisible(false && hasValidQnxKit); // FIXME QTCREATORBUG-16608
}
} // Internal
} // Qnx

View File

@@ -40,18 +40,17 @@ class QnxPlugin : public ExtensionSystem::IPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Qnx.json")
public:
QnxPlugin();
QnxPlugin() {}
bool initialize(const QStringList &arguments, QString *errorString);
void extensionsInitialized();
ShutdownFlag aboutToShutdown();
private slots:
private:
void updateDebuggerActions();
private:
QAction *m_debugSeparator;
QAction *m_attachToQnxApplication;
QAction *m_debugSeparator = nullptr;
QAction *m_attachToQnxApplication = nullptr;
};
} // namespace Internal

View File

@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "qnxruncontrolfactory.h"
#include "qnxconstants.h"
#include "qnxrunconfiguration.h"
#include "qnxdebugsupport.h"
#include "qnxdevice.h"
#include "qnxanalyzesupport.h"
#include "qnxqtversion.h"
#include "slog2inforunner.h"
#include "qnxutils.h"
#include <debugger/debuggerruncontrol.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerkitinformation.h>
#include <debugger/analyzer/analyzermanager.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/portlist.h>
using namespace Debugger;
using namespace ProjectExplorer;
namespace Qnx {
namespace Internal {
QnxRunControlFactory::QnxRunControlFactory(QObject *parent)
: IRunControlFactory(parent)
{
}
bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const
{
if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE
&& mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
return false;
}
if (!runConfiguration->isEnabled()
|| !runConfiguration->id().name().startsWith(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX)) {
return false;
}
const QnxDevice::ConstPtr dev = DeviceKitInformation::device(runConfiguration->target()->kit())
.dynamicCast<const QnxDevice>();
if (dev.isNull())
return false;
return true;
}
RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *)
{
QTC_ASSERT(canRun(runConfig, mode), return 0);
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
auto runControl = new RunControl(runConfig, mode);
(void) new SimpleTargetRunner(runControl);
return runControl;
}
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE) {
auto runControl = new RunControl(runConfig, mode);
(void) new QnxDebugSupport(runControl);
return runControl;
}
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
RunControl *runControl = new RunControl(runConfig, mode);
runControl->createWorker(mode);
(void) new QnxAnalyzeSupport(runControl);
return runControl;
}
QTC_CHECK(false);
return 0;
}
} // namespace Internal
} // namespace Qnx

View File

@@ -37,6 +37,7 @@ QT_END_NAMESPACE
namespace TextEditor {
namespace Convenience {
// line is 1-based, column is 0-based
TEXTEDITOR_EXPORT bool convertPosition(const QTextDocument *document,
int pos,
int *line, int *column);

View File

@@ -6316,7 +6316,8 @@ void TextEditorWidgetPrivate::autocompleterHighlight(const QTextCursor &cursor)
m_autoCompleteHighlightPos.clear();
} else if (m_highlightAutoComplete) {
m_autoCompleteHighlightPos.push_back(cursor);
} else if (m_animateAutoComplete) {
}
if (m_animateAutoComplete) {
const QTextCharFormat &matchFormat
= q->textDocument()->fontSettings().toTextCharFormat(C_AUTOCOMPLETE);
cancelCurrentAnimations();// one animation is enough

View File

@@ -272,7 +272,7 @@ CallgrindTool::CallgrindTool()
menu->addAction(ActionManager::registerAction(action, CallgrindRemoteActionId),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
QObject::connect(action, &QAction::triggered, this, [this, action] {
RunConfiguration *runConfig = startupRunConfiguration();
auto runConfig = RunConfiguration::startupRunConfiguration();
if (!runConfig) {
showCannotStartDialog(action->text());
return;

View File

@@ -435,7 +435,7 @@ MemcheckTool::MemcheckTool()
menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
QObject::connect(action, &QAction::triggered, this, [this, action] {
RunConfiguration *runConfig = startupRunConfiguration();
auto runConfig = RunConfiguration::startupRunConfiguration();
if (!runConfig) {
showCannotStartDialog(action->text());
return;

View File

@@ -19,7 +19,6 @@ HEADERS += \
$$PWD/environment.h \
$$PWD/clangpathwatcher.h \
$$PWD/projectparts.h \
$$PWD/stringcache.h \
$$PWD/idpaths.h \
$$PWD/pchcreatorinterface.h \
$$PWD/clangpathwatcherinterface.h \

View File

@@ -30,27 +30,15 @@
#include <sourcerangescontainer.h>
#include <QTime>
#include <stringcache.h>
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <QTime>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/Dynamic/Diagnostics.h>
#include <clang/ASTMatchers/Dynamic/Parser.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
using clang::ast_matchers::dynamic::Diagnostics;
using clang::ast_matchers::dynamic::Parser;
using clang::ast_matchers::BoundNodes;
@@ -66,8 +54,10 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
}
};
ClangQuery::ClangQuery(Utils::SmallString &&query)
: query(std::move(query))
ClangQuery::ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache,
Utils::SmallString &&query)
: query(std::move(query)),
filePathCache(filePathCache)
{
}
@@ -226,6 +216,7 @@ void ClangQuery::matchLocation(
SourceRangeExtractor extractor(ast->getSourceManager(),
ast->getLangOpts(),
filePathCache,
sourceRangesContainer);
extractor.addSourceRanges(sourceRanges);

View File

@@ -30,6 +30,8 @@
#include <sourcerangescontainer.h>
#include <dynamicastmatcherdiagnosticcontainer.h>
#include <stringcache.h>
namespace clang {
namespace ast_matchers {
namespace dynamic {
@@ -49,7 +51,7 @@ namespace ClangBackEnd {
class ClangQuery : public ClangTool
{
public:
ClangQuery(Utils::SmallString &&query={});
ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache, Utils::SmallString &&query={});
void setQuery(Utils::SmallString &&query);
@@ -67,6 +69,7 @@ private:
SourceRangesContainer sourceRangesContainer;
Utils::SmallString query;
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_;
StringCache<Utils::PathString, std::mutex> &filePathCache;
};
} // namespace ClangBackEnd

View File

@@ -29,10 +29,13 @@
namespace ClangBackEnd {
ClangQueryGatherer::ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query)
: m_sources(std::move(sources)),
: m_filePathCache(filePathCache),
m_sourceRangeFilter(sources.size()),
m_sources(std::move(sources)),
m_unsaved(std::move(unsaved)),
m_query(std::move(query))
{
@@ -40,11 +43,12 @@ ClangQueryGatherer::ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
SourceRangesAndDiagnosticsForQueryMessage
ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource(
StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query)
{
ClangQuery clangQuery(std::move(query));
ClangQuery clangQuery(*filePathCache, std::move(query));
clangQuery.addFile(source.filePath().directory(),
source.filePath().name(),
@@ -65,7 +69,8 @@ bool ClangQueryGatherer::canCreateSourceRangesAndDiagnostics() const
SourceRangesAndDiagnosticsForQueryMessage ClangQueryGatherer::createNextSourceRangesAndDiagnostics()
{
auto message = createSourceRangesAndDiagnosticsForSource(std::move(m_sources.back()),
auto message = createSourceRangesAndDiagnosticsForSource(m_filePathCache,
std::move(m_sources.back()),
m_unsaved,
m_query.clone());
m_sources.pop_back();
@@ -77,6 +82,7 @@ ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDia
{
Future future = std::async(std::launch::async,
createSourceRangesAndDiagnosticsForSource,
m_filePathCache,
std::move(m_sources.back()),
m_unsaved,
m_query.clone());
@@ -120,7 +126,7 @@ std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::allCu
std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages;
for (Future &future : m_sourceFutures)
messages.push_back(future.get());
messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get()));
return messages;
}
@@ -130,7 +136,7 @@ std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::finis
std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages;
for (auto &&future : finishedFutures())
messages.push_back(future.get());
messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get()));
return messages;
}

View File

@@ -25,8 +25,11 @@
#pragma once
#include "sourcerangefilter.h"
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <filecontainerv2.h>
#include <stringcache.h>
#include <future>
@@ -38,16 +41,16 @@ public:
using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>;
ClangQueryGatherer() = default;
ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query);
static
SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource(
static SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource(
StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query);
bool canCreateSourceRangesAndDiagnostics() const;
SourceRangesAndDiagnosticsForQueryMessage createNextSourceRangesAndDiagnostics();
Future startCreateNextSourceRangesAndDiagnosticsMessage();
@@ -66,6 +69,8 @@ protected:
std::vector<Future> finishedFutures();
private:
StringCache<Utils::PathString, std::mutex> *m_filePathCache = nullptr;
SourceRangeFilter m_sourceRangeFilter;
std::vector<V2::FileContainer> m_sources;
std::vector<V2::FileContainer> m_unsaved;
Utils::SmallString m_query;

View File

@@ -1,7 +1,8 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/clangrefactoringbackend_global.h
$$PWD/clangrefactoringbackend_global.h \
$$PWD/sourcerangefilter.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
@@ -33,3 +34,6 @@ HEADERS += \
$$PWD/locationsourcefilecallbacks.h \
$$PWD/clangquerygatherer.h
}
SOURCES += \
$$PWD/sourcerangefilter.cpp

View File

@@ -84,23 +84,12 @@ template
void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector &filePaths,
const Utils::SmallStringVector &arguments);
namespace {
Utils::SmallString toNativeFilePath(const FilePath &filePath)
{
Utils::SmallString filePathString = filePath.directory().clone();
filePathString.append("/");
filePathString.append(filePath.name());
return toNativePath(std::move(filePathString));
}
}
void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
{
unsavedFileContents.reserve(unsavedFileContents.size() + unsavedFiles.size());
auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) {
return UnsavedFileContent{toNativeFilePath(unsavedFile.filePath()),
return UnsavedFileContent{toNativePath(unsavedFile.filePath().path().clone()),
unsavedFile.unsavedFileContent().clone()};
};
@@ -111,7 +100,8 @@ void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
}
namespace {
llvm::StringRef toStringRef(const Utils::SmallString &string)
template <typename String>
llvm::StringRef toStringRef(const String &string)
{
return llvm::StringRef(string.data(), string.size());
}

View File

@@ -77,13 +77,13 @@ struct FileContent
struct UnsavedFileContent
{
UnsavedFileContent(Utils::SmallString &&filePath,
UnsavedFileContent(Utils::PathString &&filePath,
Utils::SmallString &&content)
: filePath(std::move(filePath)),
content(std::move(content))
{}
Utils::SmallString filePath;
Utils::PathString filePath;
Utils::SmallString content;
};

View File

@@ -37,6 +37,7 @@
#include <QCoreApplication>
#include <functional>
#include <atomic>
namespace ClangBackEnd {
@@ -114,6 +115,11 @@ bool RefactoringServer::pollTimerIsActive() const
return m_pollTimer.isActive();
}
void RefactoringServer::setGathererProcessingSlotCount(uint count)
{
m_gatherer.setProcessingSlotCount(count);
}
void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessages(
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
@@ -125,7 +131,7 @@ void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessages(
uint freeProcessors = std::thread::hardware_concurrency();
#endif
m_gatherer = ClangQueryGatherer(std::move(sources), std::move(unsaved), std::move(query));
m_gatherer = ClangQueryGatherer(&m_filePathCache, std::move(sources), std::move(unsaved), std::move(query));
m_gatherer.setProcessingSlotCount(freeProcessors);
m_pollTimer.start();

View File

@@ -30,7 +30,12 @@
#include <refactoringserverinterface.h>
#include <QTimer>
#include <stringcache.h>
#include <utils/smallstring.h>
#include <future>
#include <mutex>
#include <vector>
namespace ClangBackEnd {
@@ -59,12 +64,15 @@ public:
bool pollTimerIsActive() const;
void setGathererProcessingSlotCount(uint count);
private:
void gatherSourceRangesAndDiagnosticsForQueryMessages(std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query);
private:
StringCache<Utils::PathString, std::mutex> m_filePathCache;
ClangQueryGatherer m_gatherer;
QTimer m_pollTimer;
};

View File

@@ -53,7 +53,7 @@
namespace ClangBackEnd {
inline
llvm::SmallString<256> absolutePath(const llvm::StringRef &path)
llvm::SmallString<256> absolutePath(clang::StringRef path)
{
llvm::SmallString<256> absolutePath(path);
@@ -64,9 +64,9 @@ llvm::SmallString<256> absolutePath(const llvm::StringRef &path)
}
template <typename Container>
Utils::SmallString fromNativePath(Container container)
Utils::PathString fromNativePath(Container container)
{
Utils::SmallString path(container.data(), container.size());
Utils::PathString path(container.data(), container.size());
#ifdef _WIN32
std::replace(path.begin(), path.end(), '\\', '/');
@@ -89,13 +89,9 @@ void appendSourceLocationsToSourceLocationsContainer(
const auto fileId = decomposedLoction.first;
const auto offset = decomposedLoction.second;
const auto fileEntry = sourceManager.getFileEntryForID(fileId);
auto filePath = absolutePath(fileEntry->getName());
const auto fileName = llvm::sys::path::filename(filePath);
llvm::sys::path::remove_filename(filePath);
sourceLocationsContainer.insertFilePath(fileId.getHashValue(),
fromNativePath(filePath),
fromNativePath(fileName));
fromNativePath(fileEntry->tryGetRealPathName()));
sourceLocationsContainer.insertSourceLocation(fileId.getHashValue(),
fullSourceLocation.getSpellingLineNumber(),
fullSourceLocation.getSpellingColumnNumber(),

View File

@@ -51,11 +51,14 @@
namespace ClangBackEnd {
SourceRangeExtractor::SourceRangeExtractor(const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
SourceRangesContainer &sourceRangesContainer)
SourceRangeExtractor::SourceRangeExtractor(
const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
SourceRangesContainer &sourceRangesContainer)
: sourceManager(sourceManager),
languageOptions(languageOptions),
filePathCache(filePathCache),
sourceRangesContainer(sourceRangesContainer)
{
}
@@ -123,19 +126,16 @@ const clang::SourceRange SourceRangeExtractor::extendSourceRangeToLastTokenEnd(c
return {sourceRange.getBegin(), endLocation};
}
void SourceRangeExtractor::insertSourceRange(uint fileHash,
Utils::SmallString &&directoryPath,
Utils::SmallString &&fileName,
void SourceRangeExtractor::insertSourceRange(uint fileId,
Utils::PathString &&filePath,
const clang::FullSourceLoc &startLocation,
uint startOffset,
const clang::FullSourceLoc &endLocation,
uint endOffset,
Utils::SmallString &&lineSnippet)
{
sourceRangesContainer.insertFilePath(fileHash,
std::move(directoryPath),
std::move(fileName));
sourceRangesContainer.insertSourceRange(fileHash,
sourceRangesContainer.insertFilePath(fileId, std::move(filePath));
sourceRangesContainer.insertSourceRange(fileId,
startLocation.getSpellingLineNumber(),
startLocation.getSpellingColumnNumber(),
startOffset,
@@ -145,6 +145,17 @@ void SourceRangeExtractor::insertSourceRange(uint fileHash,
std::move(lineSnippet));
}
uint SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const
{
auto found = m_fileIdMapping.find(fileId.getHashValue());
if (found != m_fileIdMapping.end()) {
return found->second;
}
auto filePath = absolutePath(fileEntry->tryGetRealPathName());
return filePathCache.stringId(fromNativePath(filePath));
}
void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)
{
auto extendedSourceRange = extendSourceRangeToLastTokenEnd(sourceRange);
@@ -158,15 +169,13 @@ void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)
const auto startOffset = startDecomposedLoction.second;
const auto endOffset = endDecomposedLoction.second;
const auto fileEntry = sourceManager.getFileEntryForID(fileId);
auto filePath = absolutePath(fileEntry->getName());
const auto fileName = llvm::sys::path::filename(filePath);
llvm::sys::path::remove_filename(filePath);
Utils::SmallString lineSnippet = getExpandedText(startSourceLocation.getBufferData(),
startOffset,
endOffset);
insertSourceRange(fileId.getHashValue(),
fromNativePath(filePath),
{fileName.data(), fileName.size()},
insertSourceRange(findFileId(fileId, fileEntry),
fromNativePath(fileEntry->tryGetRealPathName()),
startSourceLocation,
startOffset,
endSourceLocation,

View File

@@ -25,9 +25,14 @@
#pragma once
#include <stringcache.h>
#include <filepath.h>
#include <utils/smallstringfwd.h>
#include <vector>
#include <unordered_map>
using uint = unsigned int;
@@ -40,6 +45,8 @@ class SourceManager;
class LangOptions;
class SourceRange;
class FullSourceLoc;
class FileID;
class FileEntry;
}
namespace ClangBackEnd {
@@ -52,6 +59,7 @@ class SourceRangeExtractor
public:
SourceRangeExtractor(const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
SourceRangesContainer &sourceRangesContainer);
void addSourceRange(const clang::SourceRange &sourceRange);
@@ -66,18 +74,21 @@ public:
const clang::SourceRange extendSourceRangeToLastTokenEnd(const clang::SourceRange sourceRange);
private:
void insertSourceRange(uint fileHash,
Utils::SmallString &&directoryPath,
Utils::SmallString &&fileName,
void insertSourceRange(uint fileId,
Utils::PathString &&filePath,
const clang::FullSourceLoc &startLocation,
uint startOffset,
const clang::FullSourceLoc &endLocation,
uint endOffset,
Utils::SmallString &&lineSnippet);
uint findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
private:
mutable std::unordered_map<uint, uint> m_fileIdMapping;
const clang::SourceManager &sourceManager;
const clang::LangOptions &languageOptions;
ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache;
SourceRangesContainer &sourceRangesContainer;
};

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "sourcerangefilter.h"
#include <algorithm>
namespace ClangBackEnd {
SourceRangeFilter::SourceRangeFilter(std::size_t sourcesCount)
{
m_collectedSourceRanges.reserve(sourcesCount);
}
SourceRangesAndDiagnosticsForQueryMessage SourceRangeFilter::removeDuplicates(SourceRangesAndDiagnosticsForQueryMessage &&message)
{
removeDuplicates(message.sourceRanges().sourceRangeWithTextContainers());
return std::move(message);
}
void SourceRangeFilter::removeDuplicates(SourceRangeWithTextContainers &sourceRanges)
{
auto partitionPoint = std::stable_partition(sourceRanges.begin(),
sourceRanges.end(),
[&] (const SourceRangeWithTextContainer &sourceRange) {
return m_collectedSourceRanges.find(sourceRange) == m_collectedSourceRanges.end();
});
sourceRanges.erase(partitionPoint, sourceRanges.end());
std::copy(sourceRanges.begin(),
sourceRanges.end(),
std::inserter(m_collectedSourceRanges, m_collectedSourceRanges.end()));
}
} // namespace ClangBackEnd

View File

@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: KDAB (info@kdab.com)
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
@@ -25,23 +25,23 @@
#pragma once
#include <projectexplorer/runconfiguration.h>
#include <unordered_set>
namespace Qnx {
namespace Internal {
#include <sourcerangesanddiagnosticsforquerymessage.h>
class QnxRunControlFactory : public ProjectExplorer::IRunControlFactory
namespace ClangBackEnd {
class SourceRangeFilter
{
Q_OBJECT
public:
explicit QnxRunControlFactory(QObject *parent = 0);
SourceRangeFilter(std::size_t sourcesCount = 0);
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration,
Core::Id mode) const override;
ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration,
Core::Id mode, QString *errorMessage) override;
SourceRangesAndDiagnosticsForQueryMessage
removeDuplicates(SourceRangesAndDiagnosticsForQueryMessage &&message);
void removeDuplicates(SourceRangeWithTextContainers &sourceRanges);
private:
std::unordered_set<SourceRangeWithTextContainer> m_collectedSourceRanges;
};
} // namespace Internal
} // namespace Qnx
} // namespace ClangBackEnd

View File

@@ -29,7 +29,10 @@
#include <clangquery.h>
#include <mutex>
using ClangBackEnd::ClangQuery;
using ClangBackEnd::StringCache;
using testing::IsEmpty;
using testing::Not;
@@ -43,8 +46,9 @@ protected:
void SetUp() override;
protected:
::ClangQuery simpleFunctionQuery;
::ClangQuery simpleClassQuery;
StringCache<Utils::PathString, std::mutex> filePathCache;
::ClangQuery simpleFunctionQuery{filePathCache};
::ClangQuery simpleClassQuery{filePathCache};
};
using ClangQuerySlowTest = ClangQuery;
@@ -77,7 +81,7 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange)
TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
{
::ClangQuery query;
::ClangQuery query(filePathCache);
query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", "query_simplefunction.cpp", "-std=c++14"});
query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}};
@@ -91,7 +95,7 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang
{
::ClangQuery query;
::ClangQuery query(filePathCache);
query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", "query_simplefunction.cpp", "-std=c++14"});
query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}};

View File

@@ -25,6 +25,8 @@
#include "googletest.h"
#include "filesystem-utilities.h"
#include "sourcerangecontainer-matcher.h"
#include <filecontainerv2.h>
@@ -38,6 +40,7 @@ using testing::AtLeast;
using testing::AtMost;
using testing::Contains;
using testing::Each;
using testing::ElementsAre;
using testing::Eq;
using testing::Ge;
using testing::IsEmpty;
@@ -47,6 +50,7 @@ using testing::Pair;
using testing::PrintToString;
using testing::Property;
using testing::SizeIs;
using testing::UnorderedElementsAre;
using testing::_;
using ClangBackEnd::V2::FileContainer;
@@ -71,34 +75,42 @@ protected:
void SetUp() override;
protected:
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f()\n {}"};
ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
sourceContent.clone(),
{"cc", "query_simplefunction.cpp"}};
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-I", TESTDATA_DIR}};
FileContainer source2{{TESTDATA_DIR, "query_simplefunction2.cpp"},
{},
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction2.cpp"), "-I", TESTDATA_DIR}};
FileContainer source3{{TESTDATA_DIR, "query_simplefunction3.cpp"},
{},
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction3.cpp"), "-I", TESTDATA_DIR}};
Utils::SmallString unsavedContent{"void f();"};
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
unsavedContent.clone(),
{}};
Utils::SmallString query{"functionDecl()"};
ClangBackEnd::ClangQueryGatherer gatherer{{source.clone()}, {unsaved.clone()}, query.clone()};
ClangBackEnd::ClangQueryGatherer manyGatherer{{source.clone(), source.clone(), source.clone()},
ClangBackEnd::ClangQueryGatherer gatherer{&filePathCache, {source.clone()}, {unsaved.clone()}, query.clone()};
ClangBackEnd::ClangQueryGatherer manyGatherer{&filePathCache,
{source3.clone(), source2.clone(), source.clone()},
{unsaved.clone()},
query.clone()};
};
TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnostics)
{
auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(source.clone(), {}, query.clone());
auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {unsaved}, query.clone());
ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(2, 1, 3, 4, "void f()\n {}")))));
Contains(IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))));
}
TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnosticssWithUnsavedContent)
{
auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(source.clone(), {unsaved}, query.clone());
auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {unsaved}, query.clone());
ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
@@ -113,7 +125,7 @@ TEST_F(ClangQueryGatherer, CanCreateSourceRangesAndDiagnosticsIfItHasSources)
TEST_F(ClangQueryGatherer, CanNotCreateSourceRangesAndDiagnosticsIfItHasNoSources)
{
ClangBackEnd::ClangQueryGatherer empthyGatherer{{}, {unsaved.clone()}, query.clone()};
ClangBackEnd::ClangQueryGatherer empthyGatherer{&filePathCache, {}, {unsaved.clone()}, query.clone()};
ASSERT_FALSE(empthyGatherer.canCreateSourceRangesAndDiagnostics());
}
@@ -174,14 +186,18 @@ TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesGet
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages();
ASSERT_THAT(manyGatherer.allCurrentProcessedMessages(),
Each(
UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))));
UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))));
}
TEST_F(ClangQueryGatherer, GetFinishedMessages)
{
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages();
@@ -191,10 +207,17 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages)
ASSERT_THAT(messages,
AllOf(SizeIs(2),
Each(
UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();")))))));
UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))));
}
TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass)
@@ -209,10 +232,38 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass)
ASSERT_THAT(messages,
AllOf(SizeIs(1),
Each(
ElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();")))))));
UnorderedElementsAre(
IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))));
}
TEST_F(ClangQueryGatherer, FilterDuplicates)
{
manyGatherer.setProcessingSlotCount(3);
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages();
manyGatherer.waitForFinished();
auto messages = manyGatherer.finishedMessages();
ASSERT_THAT(messages,
AllOf(SizeIs(3),
UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
IsSourceRangeWithText(3, 1, 3, 15, "int function();")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(
IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))));
}
TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced)

View File

@@ -0,0 +1,4 @@
#include "query_simplefunction2.h"
int function();

View File

@@ -0,0 +1,2 @@
int header();

View File

@@ -0,0 +1,4 @@
#include "query_simplefunction2.h"
int function();

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "googletest.h"
#include <filepath.h>
namespace {
TEST(FilePath, CreateFromPathString)
{
ClangBackEnd::FilePath filePath{Utils::PathString{"/file/pathOne"}};
ASSERT_THAT(filePath.directory(), "/file");
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, CreateFromQString)
{
ClangBackEnd::FilePath filePath{QString{"/file/pathOne"}};
ASSERT_THAT(filePath.directory(), "/file");
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, EmptyFilePath)
{
ClangBackEnd::FilePath filePath;
ASSERT_THAT(filePath.directory(), "");
ASSERT_THAT(filePath.name(), "");
}
}

View File

@@ -73,7 +73,7 @@ protected:
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
PathString header2Path = TESTDATA_DIR "/includecollector_header2.h";
SmallString generatedFileName = "includecollector_generated_file.h";
PathString generatedFileName = "includecollector_generated_file.h";
PathString generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h";
ProjectPartContainer projectPart1{"project1",
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},

View File

@@ -25,6 +25,7 @@
#include "googletest.h"
#include "filesystem-utilities.h"
#include "mockrefactoringclient.h"
#include "sourcerangecontainer-matcher.h"
@@ -40,6 +41,7 @@ namespace {
using testing::AllOf;
using testing::Contains;
using testing::NiceMock;
using testing::Not;
using testing::Pair;
using testing::PrintToString;
using testing::Property;
@@ -77,7 +79,8 @@ protected:
Utils::SmallString sourceContent{"void f()\n {}"};
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
sourceContent.clone(),
{"cc", "query_simplefunction.cpp"}};
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}};
int processingSlotCount = 2;
};
using RefactoringServerSlowTest = RefactoringServer;
@@ -153,8 +156,12 @@ TEST_F(RefactoringServerSlowTest, RequestTwoSourceRangesAndDiagnosticsForQueryMe
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))
.Times(2);
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))));
EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))));
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
}
@@ -163,7 +170,7 @@ TEST_F(RefactoringServerVerySlowTest, RequestManySourceRangesAndDiagnosticsForQu
{
std::vector<FileContainer> sources;
std::fill_n(std::back_inserter(sources),
std::thread::hardware_concurrency() + 3,
processingSlotCount + 3,
source.clone());
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()",
std::move(sources),
@@ -173,8 +180,13 @@ TEST_F(RefactoringServerVerySlowTest, RequestManySourceRangesAndDiagnosticsForQu
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))
.Times(std::thread::hardware_concurrency() + 3);
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))));
EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))))
.Times(processingSlotCount + 2);
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
}
@@ -237,6 +249,7 @@ void RefactoringServer::SetUp()
void RefactoringServer::TearDown()
{
refactoringServer.setGathererProcessingSlotCount(uint(processingSlotCount));
refactoringServer.waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished();
}

View File

@@ -28,23 +28,12 @@
#include <sourcerangeextractor.h>
#include <sourcerangescontainer.h>
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning( disable : 4100 )
#endif
#include <stringcache.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Lex/Lexer.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif
#include <mutex>
using testing::Contains;
using ::testing::Eq;
@@ -65,7 +54,8 @@ protected:
TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}};
ClangBackEnd::SourceRangesContainer sourceRangesContainer;
const clang::SourceManager &sourceManager{clangTool.sourceManager()};
ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), sourceRangesContainer};
ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer};
clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID());
clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4);
clang::SourceRange sourceRange{startLocation, endLocation};
@@ -76,7 +66,7 @@ using SourceRangeExtractorSlowTest = SourceRangeExtractor;
TEST_F(SourceRangeExtractorSlowTest, ExtractSourceRangeContainer)
{
SourceRangeWithTextContainer sourceRangeContainer{1, 1, 1, 0, 1, 10, 9, Utils::SmallString("int value;")};
SourceRangeWithTextContainer sourceRangeContainer{0, 1, 1, 0, 1, 10, 9, Utils::SmallString("int value;")};
extractor.addSourceRange(sourceRange);

View File

@@ -0,0 +1,106 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "googletest.h"
#include <sourcerangefilter.h>
namespace {
using testing::ContainerEq;
using testing::IsEmpty;
using ClangBackEnd::SourceRangeWithTextContainer;
using ClangBackEnd::SourceRangeWithTextContainers;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
class SourceRangeFilter : public ::testing::Test
{
protected:
protected:
SourceRangeWithTextContainers sourceRanges1{{1, 1, 1, 1, 2, 1, 4, "foo"},
{2, 1, 1, 1, 2, 1, 4, "foo"},
{1, 1, 1, 1, 2, 2, 5, "foo"}};
SourceRangeWithTextContainers sourceRanges2{{1, 1, 1, 1, 2, 1, 4, "foo"},
{3, 1, 1, 1, 2, 1, 4, "foo"},
{1, 1, 1, 1, 2, 2, 6, "foo"}};
SourceRangeWithTextContainers sourceRanges3{{3, 1, 1, 1, 2, 1, 4, "foo"},
{1, 1, 1, 1, 2, 2, 6, "foo"}};
SourceRangesAndDiagnosticsForQueryMessage message1{{{}, Utils::clone(sourceRanges1)}, {}};
SourceRangesAndDiagnosticsForQueryMessage message2{{{}, Utils::clone(sourceRanges2)}, {}};
ClangBackEnd::SourceRangeFilter filter{3};
};
TEST_F(SourceRangeFilter, DontChangeForFirstTime)
{
auto expectedSourceRanges = sourceRanges1;
filter.removeDuplicates(sourceRanges1);
ASSERT_THAT(sourceRanges1, ContainerEq(expectedSourceRanges));
}
TEST_F(SourceRangeFilter, DoNotFilterNonDuplicates)
{
SourceRangeWithTextContainers expectedSourceRanges = sourceRanges3;
filter.removeDuplicates(sourceRanges1);
filter.removeDuplicates(sourceRanges3);
ASSERT_THAT(sourceRanges3, ContainerEq(expectedSourceRanges));
}
TEST_F(SourceRangeFilter, FilterDuplicates)
{
filter.removeDuplicates(sourceRanges1);
filter.removeDuplicates(sourceRanges2);
ASSERT_THAT(sourceRanges2, ContainerEq(sourceRanges3));
}
TEST_F(SourceRangeFilter, FilterMoreDuplicates)
{
filter.removeDuplicates(sourceRanges1);
filter.removeDuplicates(sourceRanges2);
filter.removeDuplicates(sourceRanges3);
ASSERT_THAT(sourceRanges3, IsEmpty());
}
TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage)
{
filter.removeDuplicates(std::move(message1));
auto filteredMessage = filter.removeDuplicates(std::move(message2));
ASSERT_THAT(filteredMessage.sourceRanges().sourceRangeWithTextContainers(),
ContainerEq(sourceRanges3));
}
}

View File

@@ -63,6 +63,8 @@ SOURCES += \
projectupdater-test.cpp \
pchmanagerserver-test.cpp \
pchmanagerclientserverinprocess-test.cpp \
filepath-test.cpp \
sourcerangefilter-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \