forked from qt-creator/qt-creator
Clang: Use FilePathId in ChangedFilePathCompressor
Change-Id: I622d9196ec12c6fe6e07ef9c953586f2f40b9a5c Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -27,10 +27,13 @@
|
|||||||
|
|
||||||
#include "clangsupport_global.h"
|
#include "clangsupport_global.h"
|
||||||
|
|
||||||
#include <filepath.h>
|
#include <filepathid.h>
|
||||||
|
#include <filepathcache.h>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <filepathcachinginterface.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -39,7 +42,8 @@ template <typename Timer>
|
|||||||
class ChangedFilePathCompressor
|
class ChangedFilePathCompressor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChangedFilePathCompressor()
|
ChangedFilePathCompressor(FilePathCachingInterface &filePathCache)
|
||||||
|
: m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
m_timer.setSingleShot(true);
|
m_timer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
@@ -50,21 +54,26 @@ public:
|
|||||||
|
|
||||||
void addFilePath(const QString &filePath)
|
void addFilePath(const QString &filePath)
|
||||||
{
|
{
|
||||||
m_filePaths.emplace_back(filePath);
|
FilePathId filePathId = m_filePathCache.filePathId(FilePath(filePath));
|
||||||
|
|
||||||
|
auto found = std::lower_bound(m_filePaths.begin(), m_filePaths.end(), filePathId);
|
||||||
|
|
||||||
|
if (found == m_filePaths.end() || *found != filePathId)
|
||||||
|
m_filePaths.insert(found, filePathId);
|
||||||
|
|
||||||
restartTimer();
|
restartTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePaths takeFilePaths()
|
FilePathIds takeFilePathIds()
|
||||||
{
|
{
|
||||||
return std::move(m_filePaths);
|
return std::move(m_filePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setCallback(std::function<void(ClangBackEnd::FilePaths &&)> &&callback)
|
virtual void setCallback(std::function<void(ClangBackEnd::FilePathIds &&)> &&callback)
|
||||||
{
|
{
|
||||||
QObject::connect(&m_timer,
|
QObject::connect(&m_timer,
|
||||||
&Timer::timeout,
|
&Timer::timeout,
|
||||||
[this, callback=std::move(callback)] { callback(takeFilePaths()); });
|
[this, callback=std::move(callback)] { callback(takeFilePathIds()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest_public:
|
unittest_public:
|
||||||
@@ -79,8 +88,9 @@ unittest_public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilePaths m_filePaths;
|
FilePathIds m_filePaths;
|
||||||
Timer m_timer;
|
Timer m_timer;
|
||||||
|
FilePathCachingInterface &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -77,21 +77,22 @@ class ClangPathWatcher : public ClangPathWatcherInterface
|
|||||||
public:
|
public:
|
||||||
ClangPathWatcher(FilePathCachingInterface &pathCache,
|
ClangPathWatcher(FilePathCachingInterface &pathCache,
|
||||||
ClangPathWatcherNotifier *notifier=nullptr)
|
ClangPathWatcherNotifier *notifier=nullptr)
|
||||||
: m_pathCache(pathCache),
|
: m_changedFilePathCompressor(pathCache),
|
||||||
|
m_pathCache(pathCache),
|
||||||
m_notifier(notifier)
|
m_notifier(notifier)
|
||||||
{
|
{
|
||||||
QObject::connect(&m_fileSystemWatcher,
|
QObject::connect(&m_fileSystemWatcher,
|
||||||
&FileSystemWatcher::fileChanged,
|
&FileSystemWatcher::fileChanged,
|
||||||
[&] (const QString &filePath) { compressChangedFilePath(filePath); });
|
[&] (const QString &filePath) { compressChangedFilePath(filePath); });
|
||||||
|
|
||||||
m_changedFilePathCompressor.setCallback([&] (ClangBackEnd::FilePaths &&filePaths) {
|
m_changedFilePathCompressor.setCallback([&] (ClangBackEnd::FilePathIds &&filePathIds) {
|
||||||
addChangedPathForFilePath(std::move(filePaths));
|
addChangedPathForFilePath(std::move(filePathIds));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
~ClangPathWatcher()
|
~ClangPathWatcher()
|
||||||
{
|
{
|
||||||
m_changedFilePathCompressor.setCallback([&] (FilePaths &&) {});
|
m_changedFilePathCompressor.setCallback([&] (FilePathIds &&) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateIdPaths(const std::vector<IdPaths> &idPaths) override
|
void updateIdPaths(const std::vector<IdPaths> &idPaths) override
|
||||||
@@ -376,14 +377,12 @@ unittest_public:
|
|||||||
m_changedFilePathCompressor.addFilePath(filePath);
|
m_changedFilePathCompressor.addFilePath(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
WatcherEntries watchedEntriesForPaths(ClangBackEnd::FilePaths &&filePaths)
|
WatcherEntries watchedEntriesForPaths(ClangBackEnd::FilePathIds &&filePathIds)
|
||||||
{
|
{
|
||||||
FilePathIds pathIds = m_pathCache.filePathIds(filePaths);
|
|
||||||
|
|
||||||
WatcherEntries foundEntries;
|
WatcherEntries foundEntries;
|
||||||
foundEntries.reserve(pathIds.size());
|
foundEntries.reserve(filePathIds.size());
|
||||||
|
|
||||||
for (FilePathId pathId : pathIds) {
|
for (FilePathId pathId : filePathIds) {
|
||||||
auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId);
|
auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId);
|
||||||
foundEntries.insert(foundEntries.end(), range.first, range.second);
|
foundEntries.insert(foundEntries.end(), range.first, range.second);
|
||||||
}
|
}
|
||||||
@@ -415,10 +414,10 @@ unittest_public:
|
|||||||
return std::move(ids);
|
return std::move(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addChangedPathForFilePath(ClangBackEnd::FilePaths &&filePaths)
|
void addChangedPathForFilePath(ClangBackEnd::FilePathIds &&filePathIds)
|
||||||
{
|
{
|
||||||
if (m_notifier) {
|
if (m_notifier) {
|
||||||
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePaths));
|
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePathIds));
|
||||||
|
|
||||||
Utils::SmallStringVector changedIds = idsForWatcherEntries(foundEntries);
|
Utils::SmallStringVector changedIds = idsForWatcherEntries(foundEntries);
|
||||||
|
|
||||||
@@ -439,7 +438,7 @@ unittest_public:
|
|||||||
private:
|
private:
|
||||||
IdCache m_idCache;
|
IdCache m_idCache;
|
||||||
WatcherEntries m_watchedEntries;
|
WatcherEntries m_watchedEntries;
|
||||||
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
|
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor{};
|
||||||
FileSystemWatcher m_fileSystemWatcher;
|
FileSystemWatcher m_fileSystemWatcher;
|
||||||
FilePathCachingInterface &m_pathCache;
|
FilePathCachingInterface &m_pathCache;
|
||||||
ClangPathWatcherNotifier *m_notifier;
|
ClangPathWatcherNotifier *m_notifier;
|
||||||
|
@@ -25,7 +25,11 @@
|
|||||||
|
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
#include <mockchangedfilepathcompressor.h>
|
#include "mocktimer.h"
|
||||||
|
|
||||||
|
#include <changedfilepathcompressor.h>
|
||||||
|
#include <filepathcaching.h>
|
||||||
|
#include <refactoringdatabaseinitializer.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -35,56 +39,65 @@ using testing::IsEmpty;
|
|||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
|
|
||||||
using ClangBackEnd::FilePath;
|
using ClangBackEnd::FilePath;
|
||||||
|
using ClangBackEnd::FilePathId;
|
||||||
|
|
||||||
class ChangedFilePathCompressor : public testing::Test
|
class ChangedFilePathCompressor : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void SetUp();
|
void SetUp()
|
||||||
|
{
|
||||||
|
compressor.setCallback(mockCompressor.AsStdFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePathId filePathId(const QString &filePath)
|
||||||
|
{
|
||||||
|
Utils::SmallString utf8FilePath{filePath};
|
||||||
|
|
||||||
|
return filePathCache.filePathId(ClangBackEnd::FilePathView{utf8FilePath});
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NiceMock<MockChangedFilePathCompressor> mockCompressor;
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
ClangBackEnd::ChangedFilePathCompressor<FakeTimer> compressor;
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
||||||
|
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||||
|
NiceMock<MockFunction<void (const ClangBackEnd::FilePathIds &filePathIds)>> mockCompressor;
|
||||||
|
ClangBackEnd::ChangedFilePathCompressor<NiceMock<MockTimer>> compressor{filePathCache};
|
||||||
|
NiceMock<MockTimer> &mockTimer = compressor.timer();
|
||||||
QString filePath1{"filePath1"};
|
QString filePath1{"filePath1"};
|
||||||
QString filePath2{"filePath2"};
|
QString filePath2{"filePath2"};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ChangedFilePathCompressor, AddFilePath)
|
TEST_F(ChangedFilePathCompressor, AddFilePath)
|
||||||
{
|
{
|
||||||
mockCompressor.addFilePath(filePath1);
|
compressor.addFilePath(filePath1);
|
||||||
|
|
||||||
ASSERT_THAT(mockCompressor.takeFilePaths(), ElementsAre(FilePath{filePath1}));
|
ASSERT_THAT(compressor.takeFilePathIds(), ElementsAre(filePathId(filePath1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ChangedFilePathCompressor, NoFilePathsAferTakenThem)
|
TEST_F(ChangedFilePathCompressor, NoFilePathsAferTakenThem)
|
||||||
{
|
{
|
||||||
mockCompressor.addFilePath(filePath1);
|
compressor.addFilePath(filePath1);
|
||||||
|
|
||||||
mockCompressor.takeFilePaths();
|
compressor.takeFilePathIds();
|
||||||
|
|
||||||
ASSERT_THAT(mockCompressor.takeFilePaths(), IsEmpty());
|
ASSERT_THAT(compressor.takeFilePathIds(), IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ChangedFilePathCompressor, CallRestartTimerAfterAddingPath)
|
TEST_F(ChangedFilePathCompressor, CallRestartTimerAfterAddingPath)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(mockCompressor, restartTimer());
|
EXPECT_CALL(mockTimer, start(20));
|
||||||
|
|
||||||
mockCompressor.addFilePath(filePath1);
|
compressor.addFilePath(filePath1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ChangedFilePathCompressor, CallTimeOutAfterAddingPath)
|
TEST_F(ChangedFilePathCompressor, CallTimeOutAfterAddingPath)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(mockCompressor, callbackCalled(ElementsAre(FilePath{filePath1}, FilePath{filePath2})));
|
auto id1 = filePathId(filePath1);
|
||||||
|
auto id2 = filePathId(filePath2);
|
||||||
|
EXPECT_CALL(mockCompressor, Call(ElementsAre(id1, id2)));
|
||||||
|
|
||||||
compressor.addFilePath(filePath1);
|
compressor.addFilePath(filePath1);
|
||||||
compressor.addFilePath(filePath2);
|
compressor.addFilePath(filePath2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangedFilePathCompressor::SetUp()
|
|
||||||
{
|
|
||||||
compressor.setCallback([&] (ClangBackEnd::FilePaths &&filePaths) {
|
|
||||||
mockCompressor.callbackCalled(filePaths);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
#include "faketimer.h"
|
#include "mocktimer.h"
|
||||||
#include "mockfilepathcaching.h"
|
#include "mockfilepathcaching.h"
|
||||||
#include "mockqfilesystemwatcher.h"
|
#include "mockqfilesystemwatcher.h"
|
||||||
#include "mockclangpathwatchernotifier.h"
|
#include "mockclangpathwatchernotifier.h"
|
||||||
@@ -42,7 +42,7 @@ using testing::IsEmpty;
|
|||||||
using testing::SizeIs;
|
using testing::SizeIs;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
|
|
||||||
using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, FakeTimer>;
|
using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, NiceMock<MockTimer>>;
|
||||||
using ClangBackEnd::WatcherEntry;
|
using ClangBackEnd::WatcherEntry;
|
||||||
using ClangBackEnd::FilePath;
|
using ClangBackEnd::FilePath;
|
||||||
using ClangBackEnd::FilePathView;
|
using ClangBackEnd::FilePathView;
|
||||||
|
@@ -31,6 +31,7 @@ using testing::_;
|
|||||||
using testing::AllOf;
|
using testing::AllOf;
|
||||||
using testing::AnyNumber;
|
using testing::AnyNumber;
|
||||||
using testing::AnyOf;
|
using testing::AnyOf;
|
||||||
|
using testing::Assign;
|
||||||
using testing::Contains;
|
using testing::Contains;
|
||||||
using testing::ElementsAre;
|
using testing::ElementsAre;
|
||||||
using testing::Field;
|
using testing::Field;
|
||||||
@@ -38,6 +39,7 @@ using testing::HasSubstr;
|
|||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
using testing::IsEmpty;
|
using testing::IsEmpty;
|
||||||
using testing::Mock;
|
using testing::Mock;
|
||||||
|
using testing::MockFunction;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
using testing::Not;
|
using testing::Not;
|
||||||
using testing::Pair;
|
using testing::Pair;
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 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.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "googletest.h"
|
|
||||||
|
|
||||||
#include "faketimer.h"
|
|
||||||
|
|
||||||
#include <changedfilepathcompressor.h>
|
|
||||||
|
|
||||||
class MockChangedFilePathCompressor : public ClangBackEnd::ChangedFilePathCompressor<FakeTimer>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MOCK_METHOD0(restartTimer,
|
|
||||||
void ());
|
|
||||||
|
|
||||||
MOCK_METHOD1(callbackCalled,
|
|
||||||
void (const ClangBackEnd::FilePaths &filePaths));
|
|
||||||
};
|
|
||||||
|
|
@@ -23,23 +23,23 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "faketimer.h"
|
#include "mocktimer.h"
|
||||||
|
|
||||||
FakeTimer::~FakeTimer()
|
MockTimer::MockTimer()
|
||||||
|
{
|
||||||
|
ON_CALL(*this, start(_)).WillByDefault(Assign(&m_isStarted, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
MockTimer::~MockTimer()
|
||||||
{
|
{
|
||||||
emitTimoutIfStarted();
|
emitTimoutIfStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeTimer::start(int)
|
void MockTimer::setSingleShot(bool)
|
||||||
{
|
|
||||||
m_isStarted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeTimer::setSingleShot(bool)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeTimer::emitTimoutIfStarted()
|
void MockTimer::emitTimoutIfStarted()
|
||||||
{
|
{
|
||||||
if (m_isStarted)
|
if (m_isStarted)
|
||||||
emit timeout();
|
emit timeout();
|
@@ -24,16 +24,21 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "googletest.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class FakeTimer : public QObject
|
class MockTimer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~FakeTimer();
|
MockTimer();
|
||||||
|
~MockTimer();
|
||||||
|
|
||||||
|
MOCK_METHOD1(start,
|
||||||
|
void (int));
|
||||||
|
|
||||||
void start(int interval);
|
|
||||||
void setSingleShot(bool);
|
void setSingleShot(bool);
|
||||||
|
|
||||||
void emitTimoutIfStarted();
|
void emitTimoutIfStarted();
|
@@ -48,7 +48,6 @@ SOURCES += \
|
|||||||
cppprojectinfogenerator-test.cpp \
|
cppprojectinfogenerator-test.cpp \
|
||||||
cppprojectpartchooser-test.cpp \
|
cppprojectpartchooser-test.cpp \
|
||||||
fakeprocess.cpp \
|
fakeprocess.cpp \
|
||||||
faketimer.cpp \
|
|
||||||
filepath-test.cpp \
|
filepath-test.cpp \
|
||||||
filepathview-test.cpp \
|
filepathview-test.cpp \
|
||||||
gtest-creator-printing.cpp \
|
gtest-creator-printing.cpp \
|
||||||
@@ -85,7 +84,8 @@ SOURCES += \
|
|||||||
filepathstoragesqlitestatementfactory-test.cpp \
|
filepathstoragesqlitestatementfactory-test.cpp \
|
||||||
processcreator-test.cpp \
|
processcreator-test.cpp \
|
||||||
nativefilepath-test.cpp \
|
nativefilepath-test.cpp \
|
||||||
nativefilepathview-test.cpp
|
nativefilepathview-test.cpp \
|
||||||
|
mocktimer.cpp
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -180,13 +180,11 @@ HEADERS += \
|
|||||||
dynamicastmatcherdiagnosticcontainer-matcher.h \
|
dynamicastmatcherdiagnosticcontainer-matcher.h \
|
||||||
eventspy.h \
|
eventspy.h \
|
||||||
fakeprocess.h \
|
fakeprocess.h \
|
||||||
faketimer.h \
|
|
||||||
filesystem-utilities.h \
|
filesystem-utilities.h \
|
||||||
googletest.h \
|
googletest.h \
|
||||||
gtest-creator-printing.h \
|
gtest-creator-printing.h \
|
||||||
gtest-qt-printing.h \
|
gtest-qt-printing.h \
|
||||||
mimedatabase-utilities.h \
|
mimedatabase-utilities.h \
|
||||||
mockchangedfilepathcompressor.h \
|
|
||||||
mockclangcodemodelclient.h \
|
mockclangcodemodelclient.h \
|
||||||
mockclangcodemodelserver.h \
|
mockclangcodemodelserver.h \
|
||||||
mockclangpathwatcher.h \
|
mockclangpathwatcher.h \
|
||||||
@@ -221,7 +219,8 @@ HEADERS += \
|
|||||||
unittest-utility-functions.h \
|
unittest-utility-functions.h \
|
||||||
mocksymbolquery.h \
|
mocksymbolquery.h \
|
||||||
runprojectcreateorupdate-utility.h \
|
runprojectcreateorupdate-utility.h \
|
||||||
rundocumentparse-utility.h
|
rundocumentparse-utility.h \
|
||||||
|
mocktimer.h
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
chunksreportedmonitor.h \
|
chunksreportedmonitor.h \
|
||||||
|
Reference in New Issue
Block a user