Clang: Handle native file in the file cache

Different types are introduced for normalized and native file path. So the
compiler is warning you if you try the wrong format.

Change-Id: I1da0686b142cbf9bb7578468c2b50f90a94cebf9
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-11-16 17:48:53 +01:00
parent bb2f9574b4
commit a15250051d
38 changed files with 985 additions and 287 deletions

View File

@@ -27,7 +27,7 @@
#include "clangsupport_global.h"
#include <utils/smallstringvector.h>
#include <filepath.h>
#include <QTimer>
@@ -50,17 +50,17 @@ public:
void addFilePath(const QString &filePath)
{
m_filePaths.push_back(filePath);
m_filePaths.emplace_back(filePath);
restartTimer();
}
Utils::PathStringVector takeFilePaths()
FilePaths takeFilePaths()
{
return std::move(m_filePaths);
}
virtual void setCallback(std::function<void(Utils::PathStringVector &&)> &&callback)
virtual void setCallback(std::function<void(ClangBackEnd::FilePaths &&)> &&callback)
{
QObject::connect(&m_timer,
&Timer::timeout,
@@ -79,7 +79,7 @@ unittest_public:
}
private:
Utils::PathStringVector m_filePaths;
FilePaths m_filePaths;
Timer m_timer;
};

View File

@@ -84,14 +84,14 @@ public:
&FileSystemWatcher::fileChanged,
[&] (const QString &filePath) { compressChangedFilePath(filePath); });
m_changedFilePathCompressor.setCallback([&] (Utils::PathStringVector &&filePaths) {
m_changedFilePathCompressor.setCallback([&] (ClangBackEnd::FilePaths &&filePaths) {
addChangedPathForFilePath(std::move(filePaths));
});
}
~ClangPathWatcher()
{
m_changedFilePathCompressor.setCallback([&] (Utils::PathStringVector &&) {});
m_changedFilePathCompressor.setCallback([&] (FilePaths &&) {});
}
void updateIdPaths(const std::vector<IdPaths> &idPaths) override
@@ -376,7 +376,7 @@ unittest_public:
m_changedFilePathCompressor.addFilePath(filePath);
}
WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths)
WatcherEntries watchedEntriesForPaths(ClangBackEnd::FilePaths &&filePaths)
{
FilePathIds pathIds = m_pathCache.filePathIds(filePaths);
@@ -415,7 +415,7 @@ unittest_public:
return std::move(ids);
}
void addChangedPathForFilePath(Utils::PathStringVector &&filePaths)
void addChangedPathForFilePath(ClangBackEnd::FilePaths &&filePaths)
{
if (m_notifier) {
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePaths));

View File

@@ -125,7 +125,6 @@ HEADERS += \
$$PWD/dynamicmatcherdiagnostics.h \
$$PWD/filecontainer.h \
$$PWD/filecontainerv2.h \
$$PWD/filepath.h \
$$PWD/fixitcontainer.h \
$$PWD/followsymbolmessage.h \
$$PWD/highlightingmarkcontainer.h \
@@ -187,6 +186,10 @@ HEADERS += \
$$PWD/filepathexceptions.h \
$$PWD/filepathcachinginterface.h \
$$PWD/filepathcaching.h \
$$PWD/filepathcachingfwd.h
$$PWD/filepathcachingfwd.h \
$$PWD/nativefilepathview.h \
$$PWD/filepath.h \
$$PWD/nativefilepath.h \
$$PWD/filepathview.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -27,6 +27,10 @@
#include "clangsupport_global.h"
#include "filepathview.h"
#include "nativefilepathview.h"
#include <utils/hostosinfo.h>
#include <utils/smallstringio.h>
#include <QDataStream>
@@ -35,16 +39,29 @@ namespace ClangBackEnd {
class FilePath
{
using size_type = Utils::PathString::size_type;
public:
FilePath() = default;
explicit FilePath(Utils::PathString &&filePath)
: m_path(std::move(filePath))
{
auto foundReverse = std::find(m_path.rbegin(), m_path.rend(), '/');
auto found = foundReverse.base();
--found;
FilePathView view{m_path};
m_slashIndex = std::size_t(std::distance(m_path.begin(), found));
m_slashIndex = view.slashIndex();
}
FilePath(FilePathView filePathView)
: m_path(filePathView.toStringView()),
m_slashIndex(filePathView.slashIndex())
{
}
template<size_type Size>
FilePath(const char(&string)[Size]) noexcept
: FilePath(FilePathView(string, Size - 1))
{
static_assert(Size >= 1, "Invalid string literal! Length is zero!");
}
explicit FilePath(const Utils::PathString &filePath)
@@ -52,7 +69,7 @@ public:
{
}
explicit FilePath(Utils::PathString &&filePath, std::size_t slashIndex)
explicit FilePath(Utils::PathString &&filePath, std::ptrdiff_t slashIndex)
: m_path(std::move(filePath)),
m_slashIndex(slashIndex)
{
@@ -65,17 +82,23 @@ public:
FilePath(Utils::SmallStringView directory, Utils::SmallStringView name)
: m_path({directory, "/", name}),
m_slashIndex(directory.size())
m_slashIndex(std::ptrdiff_t(directory.size()))
{}
Utils::SmallStringView directory() const noexcept
{
return m_path.mid(0, m_slashIndex);
return m_path.mid(0, std::size_t(std::max(std::ptrdiff_t(0), m_slashIndex)));
}
Utils::SmallStringView name() const noexcept
{
return m_path.mid(m_slashIndex + 1, m_path.size() - m_slashIndex - 1);
return m_path.mid(std::size_t(m_slashIndex + 1),
std::size_t(std::ptrdiff_t(m_path.size()) - m_slashIndex - std::ptrdiff_t(1)));
}
bool empty() const
{
return m_path.empty();
}
const Utils::PathString &path() const noexcept
@@ -83,11 +106,16 @@ public:
return m_path;
}
operator Utils::PathString() const noexcept
operator const Utils::PathString&() const noexcept
{
return m_path;
}
operator FilePathView() const noexcept
{
return FilePathView(Utils::SmallStringView(m_path));
}
friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath)
{
out << filePath.m_path;
@@ -118,12 +146,12 @@ public:
return first.m_path == second.m_path;
}
friend bool operator==(const FilePath &first, const Utils::SmallStringView &second)
friend bool operator==(const FilePath &first, const FilePathView &second)
{
return first.path() == second;
return first.path() == second.toStringView();
}
friend bool operator==(const Utils::SmallStringView &first, const FilePath&second)
friend bool operator==(const FilePathView &first, const FilePath &second)
{
return second == first;
}
@@ -138,14 +166,25 @@ public:
return *this;
}
std::size_t slashIndex() const
std::ptrdiff_t slashIndex() const
{
return m_slashIndex;
}
template<typename String>
static FilePath fromNativeFilePath(String filePath)
{
Utils::PathString nativePath{filePath.data(), filePath.size()};
if (Utils::HostOsInfo::isWindowsHost())
nativePath.replace('\\', '/');
return FilePath(std::move(nativePath));
}
private:
Utils::PathString m_path = "/";
std::size_t m_slashIndex = 0;
Utils::PathString m_path;
std::ptrdiff_t m_slashIndex = -1;
};
using FilePaths = std::vector<FilePath>;

View File

@@ -28,42 +28,15 @@
#include "filepathexceptions.h"
#include "filepathid.h"
#include "filepath.h"
#include "nativefilepathview.h"
#include "stringcache.h"
#include <utils/smallstringview.h>
#include <algorithm>
namespace ClangBackEnd {
class FilePathCacheBase
{
public:
static
std::ptrdiff_t lastSlashIndex(Utils::SmallStringView filePath)
{
auto foundReverse = std::find(filePath.rbegin(), filePath.rend(), '/');
auto found = foundReverse.base();
--found;
return std::distance(filePath.begin(), found);
}
static
Utils::SmallStringView directoryPath(Utils::SmallStringView filePath, std::ptrdiff_t slashIndex)
{
return {filePath.data(), std::size_t(std::max(std::ptrdiff_t(0), slashIndex))};
}
static
Utils::SmallStringView fileName(Utils::SmallStringView filePath, std::ptrdiff_t slashIndex)
{
return {filePath.data() + slashIndex + 1, filePath.size() - std::size_t(slashIndex) - 1};
}
};
template <typename FilePathStorage>
class FilePathCache final : private FilePathCacheBase
class FilePathCache
{
using DirectoryPathCache = StringCache<Utils::PathString,
int,
@@ -80,17 +53,16 @@ public:
: m_filePathStorage(filePathStorage)
{}
FilePathId filePathId(Utils::SmallStringView filePath) const
FilePathId filePathId(FilePathView filePath) const
{
std::ptrdiff_t slashIndex = lastSlashIndex(filePath);
Utils::SmallStringView directoryPath = filePath.directory();
Utils::SmallStringView directoryPath = this->directoryPath(filePath, slashIndex);
int directoryId = m_directyPathCache.stringId(directoryPath,
[&] (const Utils::SmallStringView) {
return m_filePathStorage.fetchDirectoryId(directoryPath);
});
Utils::SmallStringView fileName = this->fileName(filePath, slashIndex);
Utils::SmallStringView fileName = filePath.name();
int fileNameId = m_fileNameCache.stringId(fileName,
[&] (const Utils::SmallStringView) {
@@ -116,7 +88,7 @@ public:
Utils::SmallString fileName = m_fileNameCache.string(filePathId.fileNameId,
fetchSoureName);
return {directoryPath, fileName};
return FilePath{directoryPath, fileName};
}
private:

View File

@@ -27,7 +27,7 @@
namespace ClangBackEnd {
FilePathId FilePathCaching::filePathId(Utils::SmallStringView filePath) const
FilePathId FilePathCaching::filePathId(FilePathView filePath) const
{
return m_cache.filePathId(filePath);
}

View File

@@ -50,7 +50,7 @@ public:
: m_factory(database)
{}
FilePathId filePathId(Utils::SmallStringView filePath) const override;
FilePathId filePathId(FilePathView filePath) const override;
FilePath filePath(FilePathId filePathId) const override;
private:

View File

@@ -27,13 +27,14 @@
#include "filepath.h"
#include "filepathid.h"
#include "filepathview.h"
namespace ClangBackEnd {
class FilePathCachingInterface
{
public:
virtual FilePathId filePathId(Utils::SmallStringView filePath) const = 0;
virtual FilePathId filePathId(FilePathView filePath) const = 0;
virtual FilePath filePath(FilePathId filePathId) const = 0;
template <typename Container>

View File

@@ -0,0 +1,101 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include <utils/smallstringview.h>
#include <algorithm>
namespace ClangBackEnd {
class FilePathView : protected Utils::SmallStringView
{
public:
explicit FilePathView(const char *const string, const size_type size) noexcept
: Utils::SmallStringView(string, size),
m_slashIndex(lastSlashIndex(*this))
{
}
explicit FilePathView(Utils::SmallStringView filePath)
: Utils::SmallStringView(filePath),
m_slashIndex(lastSlashIndex(filePath))
{
}
template <typename String>
explicit FilePathView(String filePath)
: FilePathView(filePath.data(), filePath.size())
{
}
template<size_type Size>
FilePathView(const char(&string)[Size]) noexcept
: FilePathView(string, Size - 1)
{
static_assert(Size >= 1, "Invalid string literal! Length is zero!");
}
Utils::SmallStringView toStringView() const
{
return *this;
}
std::ptrdiff_t slashIndex() const
{
return m_slashIndex;
}
Utils::SmallStringView directory() const noexcept
{
return mid(0, std::size_t(std::max(std::ptrdiff_t(0), m_slashIndex)));
}
Utils::SmallStringView name() const noexcept
{
return mid(std::size_t(m_slashIndex + 1),
std::size_t(std::ptrdiff_t(size()) - m_slashIndex - std::ptrdiff_t(1)));
}
static
std::ptrdiff_t lastSlashIndex(Utils::SmallStringView filePath)
{
auto foundReverse = std::find(filePath.rbegin(), filePath.rend(), '/');
auto found = foundReverse.base();
--found;
return std::distance(filePath.begin(), found);
}
friend bool operator==(const FilePathView &first, const FilePathView &second)
{
return first.toStringView() == second.toStringView();
}
private:
std::ptrdiff_t m_slashIndex = -1;
};
}

View File

@@ -0,0 +1,187 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include "filepathview.h"
#include "nativefilepathview.h"
#include <utils/hostosinfo.h>
#include <utils/smallstringio.h>
namespace ClangBackEnd {
class NativeFilePath
{
using size_type = Utils::PathString::size_type;
public:
NativeFilePath() = default;
explicit NativeFilePath(Utils::PathString &&filePath)
: m_path(std::move(filePath))
{
NativeFilePathView view{m_path};
m_slashIndex = view.slashIndex();
}
NativeFilePath(NativeFilePathView filePathView)
: m_path(filePathView.toStringView()),
m_slashIndex(filePathView.slashIndex())
{
}
template<size_type Size>
NativeFilePath(const char(&string)[Size]) noexcept
: NativeFilePath(NativeFilePathView(string, Size - 1))
{
static_assert(Size >= 1, "Invalid string literal! Length is zero!");
}
explicit NativeFilePath(const Utils::PathString &filePath)
: NativeFilePath(filePath.clone())
{
}
explicit NativeFilePath(Utils::PathString &&filePath, std::ptrdiff_t slashIndex)
: m_path(std::move(filePath)),
m_slashIndex(slashIndex)
{
}
explicit NativeFilePath(const QString &filePath)
: NativeFilePath(Utils::PathString(filePath))
{
}
NativeFilePath(Utils::SmallStringView directory, Utils::SmallStringView name)
: m_path({directory, Utils::HostOsInfo::isWindowsHost() ? "\\" : "/", name}),
m_slashIndex(directory.size())
{}
Utils::SmallStringView directory() const noexcept
{
return m_path.mid(0, std::size_t(std::max(std::ptrdiff_t(0), m_slashIndex))); }
Utils::SmallStringView name() const noexcept
{
return m_path.mid(std::size_t(m_slashIndex + 1),
std::size_t(std::ptrdiff_t(m_path.size()) - m_slashIndex - std::ptrdiff_t(1)));
}
bool empty() const
{
return m_path.empty();
}
const Utils::PathString &path() const noexcept
{
return m_path;
}
operator const Utils::PathString&() const noexcept
{
return m_path;
}
operator NativeFilePathView() const noexcept
{
return NativeFilePathView(Utils::SmallStringView(m_path));
}
friend QDataStream &operator<<(QDataStream &out, const NativeFilePath &filePath)
{
out << filePath.m_path;
out << uint(filePath.m_slashIndex);
return out;
}
friend QDataStream &operator>>(QDataStream &in, NativeFilePath &filePath)
{
uint slashIndex;
in >> filePath.m_path;
in >> slashIndex;
filePath.m_slashIndex = slashIndex;
return in;
}
friend std::ostream &operator<<(std::ostream &out, const NativeFilePath &filePath)
{
return out << "(" << filePath.path() << ", " << filePath.slashIndex() << ")";
}
friend bool operator==(const NativeFilePath &first, const NativeFilePath &second)
{
return first.m_path == second.m_path;
}
friend bool operator==(const NativeFilePath &first, const NativeFilePathView &second)
{
return first.path() == second.toStringView();
}
friend bool operator==(const NativeFilePathView &first, const NativeFilePath &second)
{
return second == first;
}
friend bool operator<(const NativeFilePath &first, const NativeFilePath &second)
{
return first.m_path < second.m_path;
}
NativeFilePath clone() const
{
return *this;
}
std::ptrdiff_t slashIndex() const
{
return m_slashIndex;
}
template<typename String>
static NativeFilePath fromFilePath(String filePath)
{
Utils::PathString nativePath{filePath.data(), filePath.size()};
if (Utils::HostOsInfo::isWindowsHost())
nativePath.replace('/', '\\');
return NativeFilePath(std::move(nativePath));
}
private:
Utils::PathString m_path;
std::ptrdiff_t m_slashIndex = -1;
};
using NativeFilePaths = std::vector<NativeFilePath>;
} // namespace ClangBackEnd

View File

@@ -0,0 +1,101 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include <utils/hostosinfo.h>
#include <utils/smallstringview.h>
namespace ClangBackEnd {
class NativeFilePathView : protected Utils::SmallStringView
{
public:
explicit NativeFilePathView(const char *const string, const size_type size) noexcept
: Utils::SmallStringView(string, size),
m_slashIndex(lastSlashIndex(*this))
{
}
explicit NativeFilePathView(Utils::SmallStringView filePath)
: Utils::SmallStringView(filePath),
m_slashIndex(lastSlashIndex(filePath))
{
}
template <typename String>
explicit NativeFilePathView(String filePath)
: NativeFilePathView(filePath.data(), filePath.size())
{
}
template<size_type Size>
NativeFilePathView(const char(&string)[Size]) noexcept
: NativeFilePathView(string, Size - 1)
{
static_assert(Size >= 1, "Invalid string literal! Length is zero!");
}
Utils::SmallStringView toStringView() const
{
return *this;
}
std::ptrdiff_t slashIndex() const
{
return m_slashIndex;
}
Utils::SmallStringView directory() const noexcept
{
return mid(0, std::size_t(std::max(std::ptrdiff_t(0), m_slashIndex)));
}
Utils::SmallStringView name() const noexcept
{
return mid(std::size_t(m_slashIndex + 1),
std::size_t(std::ptrdiff_t(size()) - m_slashIndex - std::ptrdiff_t(1)));
}
static
std::ptrdiff_t lastSlashIndex(Utils::SmallStringView filePath)
{
const char separator = Utils::HostOsInfo::isWindowsHost() ? '\\' : '/';
auto foundReverse = std::find(filePath.rbegin(), filePath.rend(), separator);
auto found = foundReverse.base();
--found;
return std::distance(filePath.begin(), found);
}
friend bool operator==(const NativeFilePathView &first, const NativeFilePathView &second)
{
return first.toStringView() == second.toStringView();
}
private:
std::ptrdiff_t m_slashIndex = -1;
};
}

View File

@@ -103,6 +103,18 @@ public:
return m_size == 0;
}
constexpr
SmallStringView mid(size_type position) const noexcept
{
return SmallStringView(data() + position, size() - position);
}
constexpr
SmallStringView mid(size_type position, size_type length) const noexcept
{
return SmallStringView(data() + position, length);
}
constexpr
const_iterator begin() const noexcept
{

View File

@@ -26,6 +26,7 @@
#include "refactoringengine.h"
#include "projectpartutilities.h"
#include <filepath.h>
#include <refactoringserverinterface.h>
#include <requestsourcelocationforrenamingmessage.h>
@@ -96,8 +97,8 @@ CppTools::Usages RefactoringEngine::locationsAt(const CppTools::CursorInEditor &
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
Utils::Text::convertPosition(cursor.document(), cursor.position(), &line, &column);
const QByteArray filePath = data.filePath().toString().toLatin1();
const ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(filePath.constData());
const QByteArray filePath = data.filePath().toString().toUtf8();
const ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(ClangBackEnd::FilePathView(filePath));
return m_symbolQuery.sourceUsagesAt(filePathId, line, column + 1);
}

View File

@@ -81,8 +81,8 @@ public:
auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
if (notAlreadyIncluded.first) {
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
Utils::PathString filePath = filePathFromFile(file);
if (!filePath.isEmpty()) {
FilePath filePath = filePathFromFile(file);
if (!filePath.empty()) {
FilePathId includeId = m_filePathCache.filePathId(filePath);
m_includeIds.emplace_back(includeId);
}
@@ -146,13 +146,9 @@ public:
return {range.first == range.second, range.first};
}
static Utils::PathString filePathFromFile(const clang::FileEntry *file)
static FilePath filePathFromFile(const clang::FileEntry *file)
{
clang::StringRef realPath = file->tryGetRealPathName();
if (!realPath.empty())
return fromNativePath(realPath);
return fromNativePath(absolutePath(file->getName()));
return FilePath::fromNativeFilePath(absolutePath(file->getName()));
}
private:

View File

@@ -25,6 +25,8 @@
#pragma once
#include <utils/hostosinfo.h>
namespace llvm {
template <typename T, unsigned N>
class SmallVector;
@@ -35,10 +37,7 @@ namespace ClangBackEnd {
using USRName = llvm::SmallVector<char, 128>;
// use std::filesystem::path if it is supported by all compilers
#ifdef _WIN32
const char nativeSeperator = '\\';
#else
const char nativeSeperator = '/';
#endif
static const char nativeSeparator = Utils::HostOsInfo::isWindowsHost() ? '\\' : '/';
}

View File

@@ -63,7 +63,7 @@ struct FileContent
const std::vector<std::string> &commandLine)
: directory(directory),
fileName(fileName),
filePath(directory + nativeSeperator + fileName),
filePath(directory + nativeSeparator + fileName),
content(content),
commandLine(commandLine)
{}

View File

@@ -40,11 +40,6 @@
namespace ClangBackEnd {
Utils::SmallStringView toStringView(clang::StringRef stringReference)
{
return Utils::SmallStringView(stringReference.data(), stringReference.size());
}
class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbolsASTVisitor>
{
public:
@@ -111,7 +106,7 @@ public:
auto filePath = m_sourceManager.getFilename(sourceLocation);
FilePathId filePathId = m_filePathCache.filePathId(toStringView(filePath));
FilePathId filePathId = m_filePathCache.filePathId(FilePath::fromNativeFilePath(filePath));
m_filePathIndices.emplace(clangFileId, filePathId);

View File

@@ -37,7 +37,7 @@ namespace {
std::string concatFilePath(const clang::tooling::CompileCommand &compileCommand)
{
return compileCommand.Directory + nativeSeperator + compileCommand.Filename;
return compileCommand.Directory + nativeSeparator + compileCommand.Filename;
}
}

View File

@@ -79,7 +79,7 @@ void appendSourceLocationsToSourceLocationsContainer(
const auto fileId = decomposedLoction.first;
const auto offset = decomposedLoction.second;
const auto fileEntry = sourceManager.getFileEntryForID(fileId);
auto filePath = fromNativePath(absolutePath(fileEntry->getName()));
auto filePath = FilePath::fromNativeFilePath(absolutePath(fileEntry->getName()));
sourceLocationsContainer.insertSourceLocation(filePathCache.filePathId(filePath),
fullSourceLocation.getSpellingLineNumber(),

View File

@@ -139,7 +139,7 @@ FilePathId SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::F
}
auto filePath = absolutePath(fileEntry->getName());
return filePathCache.filePathId(fromNativePath(filePath));
return filePathCache.filePathId(FilePath::fromNativeFilePath(filePath));
}
void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)

View File

@@ -34,6 +34,9 @@ using testing::Invoke;
using testing::IsEmpty;
using testing::NiceMock;
using ClangBackEnd::FilePath;
class ChangedFilePathCompressor : public testing::Test
{
protected:
@@ -50,7 +53,7 @@ TEST_F(ChangedFilePathCompressor, AddFilePath)
{
mockCompressor.addFilePath(filePath1);
ASSERT_THAT(mockCompressor.takeFilePaths(), ElementsAre(filePath1));
ASSERT_THAT(mockCompressor.takeFilePaths(), ElementsAre(FilePath{filePath1}));
}
TEST_F(ChangedFilePathCompressor, NoFilePathsAferTakenThem)
@@ -71,7 +74,7 @@ TEST_F(ChangedFilePathCompressor, CallRestartTimerAfterAddingPath)
TEST_F(ChangedFilePathCompressor, CallTimeOutAfterAddingPath)
{
EXPECT_CALL(mockCompressor, callbackCalled(ElementsAre(filePath1, filePath2)));
EXPECT_CALL(mockCompressor, callbackCalled(ElementsAre(FilePath{filePath1}, FilePath{filePath2})));
compressor.addFilePath(filePath1);
compressor.addFilePath(filePath2);
@@ -79,7 +82,7 @@ TEST_F(ChangedFilePathCompressor, CallTimeOutAfterAddingPath)
void ChangedFilePathCompressor::SetUp()
{
compressor.setCallback([&] (Utils::PathStringVector &&filePaths) {
compressor.setCallback([&] (ClangBackEnd::FilePaths &&filePaths) {
mockCompressor.callbackCalled(filePaths);
});
}

View File

@@ -45,6 +45,7 @@ using testing::NiceMock;
using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, FakeTimer>;
using ClangBackEnd::WatcherEntry;
using ClangBackEnd::FilePath;
using ClangBackEnd::FilePathView;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathIds;
@@ -61,10 +62,10 @@ protected:
Utils::SmallString id1{"id4"};
Utils::SmallString id2{"id2"};
Utils::SmallString id3{"id3"};
FilePath path1{Utils::PathString{"/path/path1"}};
FilePath path2{Utils::PathString{"/path/path2"}};
QString path1QString = QString(path1.path());
QString path2QString = QString(path2.path());
FilePathView path1{"/path/path1"};
FilePathView path2{"/path/path2"};
QString path1QString = QString(path1.toStringView());
QString path2QString = QString(path2.toStringView());
FilePathIds pathIds = {{1, 1}, {1, 2}};
std::vector<int> ids{watcher.idCache().stringIds({id1, id2, id3})};
WatcherEntry watcherEntry1{ids[0], pathIds[0]};
@@ -338,8 +339,8 @@ void ClangPathWatcher::SetUp()
ON_CALL(filePathCache, filePathId(Eq(path2)))
.WillByDefault(Return(pathIds[1]));
ON_CALL(filePathCache, filePath(pathIds[0]))
.WillByDefault(Return(path1));
.WillByDefault(Return(FilePath{path1}));
ON_CALL(filePathCache, filePath(Eq(pathIds[1])))
.WillByDefault(Return(path2));
.WillByDefault(Return(FilePath{path2}));
}
}

View File

@@ -37,6 +37,31 @@ TEST(FilePath, CreateFromPathString)
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, CreateFromDirectoryAndFileName)
{
ClangBackEnd::FilePath filePath{Utils::PathString{"/file"}, Utils::PathString{"pathOne"}};
ASSERT_THAT(filePath.directory(), "/file");
ASSERT_THAT(filePath.name(), "pathOne");
ASSERT_THAT(filePath.path(), "/file/pathOne");
}
TEST(FilePath, CreateFromCString)
{
ClangBackEnd::FilePath filePath{"/file/pathOne"};
ASSERT_THAT(filePath.directory(), "/file");
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, CreateFromFilePathView)
{
ClangBackEnd::FilePath filePath{ClangBackEnd::FilePathView{"/file/pathOne"}};
ASSERT_THAT(filePath.directory(), "/file");
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, CreateFromQString)
{
ClangBackEnd::FilePath filePath{QString{"/file/pathOne"}};
@@ -45,7 +70,7 @@ TEST(FilePath, CreateFromQString)
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(FilePath, EmptyFilePath)
TEST(FilePath, DefaultFilePath)
{
ClangBackEnd::FilePath filePath;
@@ -53,4 +78,12 @@ TEST(FilePath, EmptyFilePath)
ASSERT_THAT(filePath.name(), "");
}
TEST(FilePath, EmptyFilePath)
{
ClangBackEnd::FilePath filePath("");
ASSERT_THAT(filePath.directory(), "");
ASSERT_THAT(filePath.name(), "");
}
}

View File

@@ -32,9 +32,10 @@
namespace {
using ClangBackEnd::FilePathId;
using FPCB = ClangBackEnd::FilePathCacheBase;
using Cache = ClangBackEnd::FilePathCache<NiceMock<MockFilePathStorage>>;
using ClangBackEnd::FilePathId;
using NFP = ClangBackEnd::FilePath;
using ClangBackEnd::FilePathView;
class FilePathCache : public testing::Test
{
@@ -46,199 +47,86 @@ protected:
Cache cache{mockStorage};
};
TEST_F(FilePathCache, FilePathSlashForEmptyPath)
{
auto slashIndex = FPCB::lastSlashIndex("");
ASSERT_THAT(slashIndex, -1);
}
TEST_F(FilePathCache, FilePathSlashForSingleSlash)
{
auto slashIndex = FPCB::lastSlashIndex("/");
ASSERT_THAT(slashIndex, 0);
}
TEST_F(FilePathCache, FilePathSlashForFileInRoot)
{
auto slashIndex = FPCB::lastSlashIndex("/file.h");
ASSERT_THAT(slashIndex, 0);
}
TEST_F(FilePathCache, FilePathSlashForSomeLongerPath)
{
auto slashIndex = FPCB::lastSlashIndex("/path/to/some/file.h");
ASSERT_THAT(slashIndex, 13);
}
TEST_F(FilePathCache, FilePathSlashForFileNameOnly)
{
auto slashIndex = FPCB::lastSlashIndex("file.h");
ASSERT_THAT(slashIndex, -1);
}
TEST_F(FilePathCache, DirectoryPathForEmptyPath)
{
auto slashIndex = FPCB::lastSlashIndex("");
auto directoryPath = FPCB::directoryPath("", slashIndex);
ASSERT_THAT(directoryPath, "");
}
TEST_F(FilePathCache, DirectoryPathForSingleSlashPath)
{
Utils::SmallStringView singleSlashPath{"/"};
auto slashIndex = FPCB::lastSlashIndex(singleSlashPath);
auto directoryPath = FPCB::directoryPath(singleSlashPath, slashIndex);
ASSERT_THAT(directoryPath, "");
}
TEST_F(FilePathCache, DirectoryPathForLongerPath)
{
Utils::SmallStringView longerPath{"/path/to/some/file.h"};
auto slashIndex = FPCB::lastSlashIndex(longerPath);
auto directoryPath = FPCB::directoryPath(longerPath, slashIndex);
ASSERT_THAT(directoryPath, "/path/to/some");
}
TEST_F(FilePathCache, DirectoryPathForFileNameOnly)
{
Utils::SmallStringView longerPath{"file.h"};
auto slashIndex = FPCB::lastSlashIndex(longerPath);
auto directoryPath = FPCB::directoryPath(longerPath, slashIndex);
ASSERT_THAT(directoryPath, IsEmpty());
}
TEST_F(FilePathCache, FileNameForEmptyPath)
{
auto slashIndex = FPCB::lastSlashIndex("");
auto fileName = FPCB::fileName("", slashIndex);
ASSERT_THAT(fileName, "");
}
TEST_F(FilePathCache, FileNameForSingleSlashPath)
{
Utils::SmallStringView singleSlashPath{"/"};
auto slashIndex = FPCB::lastSlashIndex(singleSlashPath);
auto fileName = FPCB::fileName(singleSlashPath, slashIndex);
ASSERT_THAT(fileName, "");
}
TEST_F(FilePathCache, FileNameForLongerPath)
{
Utils::SmallStringView longerPath{"/path/to/some/file.h"};
auto slashIndex = FPCB::lastSlashIndex(longerPath);
auto fileName = FPCB::fileName(longerPath, slashIndex);
ASSERT_THAT(fileName, "file.h");
}
TEST_F(FilePathCache, FileNameForFileNameOnly)
{
Utils::SmallStringView longerPath{"file.h"};
auto slashIndex = FPCB::lastSlashIndex(longerPath);
auto fileName = FPCB::fileName(longerPath, slashIndex);
ASSERT_THAT(fileName, "file.h");
}
TEST_F(FilePathCache, FilePathIdWithOutAnyEntryCallDirectoryId)
{
EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to")));
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
}
TEST_F(FilePathCache, FilePathIdWithOutAnyEntryCalls)
{
EXPECT_CALL(mockStorage, fetchSourceId(5, Eq("file.cpp")));
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
}
TEST_F(FilePathCache, DirectoryIdOfFilePathIdWithOutAnyEntry)
{
auto filePathId = cache.filePathId("/path/to/file.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file.cpp"));
ASSERT_THAT(filePathId.directoryId, 5);
}
TEST_F(FilePathCache, FileNameIdOfFilePathIdWithOutAnyEntry)
{
auto filePathId = cache.filePathId("/path/to/file.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file.cpp"));
ASSERT_THAT(filePathId.fileNameId, 42);
}
TEST_F(FilePathCache, IfEntryExistsDontCallInStrorage)
{
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to"))).Times(0);
EXPECT_CALL(mockStorage, fetchSourceId(5, Eq("file.cpp"))).Times(0);
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
}
TEST_F(FilePathCache, IfDirectoryEntryExistsDontCallFetchDirectoryIdButStillCallFetchSourceId)
{
cache.filePathId("/path/to/file2.cpp");
cache.filePathId(FilePathView("/path/to/file2.cpp"));
EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to"))).Times(0);
EXPECT_CALL(mockStorage, fetchSourceId(5, Eq("file.cpp")));
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
}
TEST_F(FilePathCache, GetFileNameIdWithCachedValue)
{
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
auto filePathId = cache.filePathId("/path/to/file.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file.cpp"));
ASSERT_THAT(filePathId.fileNameId, 42);
}
TEST_F(FilePathCache, GetFileNameIdWithDirectoryIdCached)
{
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
auto filePathId = cache.filePathId("/path/to/file2.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file2.cpp"));
ASSERT_THAT(filePathId.fileNameId, 63);
}
TEST_F(FilePathCache, GetDirectyIdWithCachedValue)
{
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
auto filePathId = cache.filePathId("/path/to/file2.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file2.cpp"));
ASSERT_THAT(filePathId.directoryId, 5);
}
TEST_F(FilePathCache, GetDirectyIdWithDirectoryIdCached)
{
cache.filePathId("/path/to/file.cpp");
cache.filePathId(FilePathView("/path/to/file.cpp"));
auto filePathId = cache.filePathId("/path/to/file2.cpp");
auto filePathId = cache.filePathId(FilePathView("/path/to/file2.cpp"));
ASSERT_THAT(filePathId.directoryId, 5);
}
@@ -252,11 +140,11 @@ TEST_F(FilePathCache, ThrowForGettingAFilePathWithAnInvalidId)
TEST_F(FilePathCache, GetAFilePath)
{
FilePathId filePathId = cache.filePathId("/path/to/file.cpp");
FilePathId filePathId = cache.filePathId(FilePathView("/path/to/file.cpp"));
auto filePath = cache.filePath(filePathId);
ASSERT_THAT(filePath, Eq("/path/to/file.cpp"));
ASSERT_THAT(filePath, Eq(FilePathView{"/path/to/file.cpp"}));
}
TEST_F(FilePathCache, GetAFilePathWithCachedFilePathId)
@@ -265,7 +153,7 @@ TEST_F(FilePathCache, GetAFilePathWithCachedFilePathId)
auto filePath = cache.filePath(filePathId);
ASSERT_THAT(filePath, Eq("/path/to/file.cpp"));
ASSERT_THAT(filePath, Eq(FilePathView{"/path/to/file.cpp"}));
}
void FilePathCache::SetUp()
@@ -283,4 +171,3 @@ void FilePathCache::SetUp()
}
}

View File

@@ -0,0 +1,125 @@
/****************************************************************************
**
** 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 <filepathview.h>
namespace {
using ClangBackEnd::FilePathView;
TEST(FilePathView, FilePathSlashForEmptyPath)
{
FilePathView filePath("");
ASSERT_THAT(filePath.slashIndex(), -1);
}
TEST(FilePathView, FilePathSlashForSingleSlash)
{
FilePathView filePath("/");
ASSERT_THAT(filePath.slashIndex(), 0);
}
TEST(FilePathView, FilePathSlashForFileInRoot)
{
FilePathView filePath("/file.h");
ASSERT_THAT(filePath.slashIndex(), 0);
}
TEST(FilePathView, FilePathSlashForSomeLongerPath)
{
FilePathView filePath("/path/to/some/file.h");
ASSERT_THAT(filePath.slashIndex(), 13);
}
TEST(FilePathView, FilePathSlashForFileNameOnly)
{
FilePathView filePath("file.h");
ASSERT_THAT(filePath.slashIndex(), -1);
}
TEST(FilePathView, DirectoryPathForEmptyPath)
{
FilePathView filePath("");
ASSERT_THAT(filePath.directory(), "");
}
TEST(FilePathView, DirectoryPathForSingleSlashPath)
{
FilePathView filePath{"/"};
ASSERT_THAT(filePath.directory(), "");
}
TEST(FilePathView, DirectoryPathForLongerPath)
{
FilePathView filePath{"/path/to/some/file.h"};
ASSERT_THAT(filePath.directory(), "/path/to/some");
}
TEST(FilePathView, DirectoryPathForFileNameOnly)
{
FilePathView filePath{"file.h"};
ASSERT_THAT(filePath.directory(), IsEmpty());
}
TEST(FilePathView, FileNameForEmptyPath)
{
FilePathView filePath("");
ASSERT_THAT(filePath.name(), "");
}
TEST(FilePathView, FileNameForSingleSlashPath)
{
FilePathView filePath{"/"};
ASSERT_THAT(filePath.name(), "");
}
TEST(FilePathView, FileNameForLongerPath)
{
FilePathView filePath{"/path/to/some/file.h"};
ASSERT_THAT(filePath.name(), "file.h");
}
TEST(FilePathView, FileNameForFileNameOnly)
{
FilePathView filePath{"file.h"};
ASSERT_THAT(filePath.name(), "file.h");
}
}

View File

@@ -25,25 +25,22 @@
#pragma once
#include <utils/hostosinfo.h>
#include <utils/smallstring.h>
#include <string>
// use std::filesystem::path if it is supported by all compilers
#ifdef _WIN32
const char nativeSeperator = '\\';
#else
const char nativeSeperator = '/';
#endif
static const char nativeSeparator = Utils::HostOsInfo::isWindowsHost() ? '\\' : '/';
template <std::size_t Size>
std::string toNativePath(const char (&text)[Size])
{
std::string path = text;
#ifdef _WIN32
std::replace(path.begin(), path.end(), '/', '\\');
#endif
if (Utils::HostOsInfo::isWindowsHost())
std::replace(path.begin(), path.end(), '/', '\\');
return path;
}
@@ -52,9 +49,9 @@ inline
std::string toNativePath(const QString &qStringPath)
{
auto path = qStringPath.toStdString();
#ifdef _WIN32
std::replace(path.begin(), path.end(), '/', '\\');
#endif
if (Utils::HostOsInfo::isWindowsHost())
std::replace(path.begin(), path.end(), '/', '\\');
return path;
}

View File

@@ -35,6 +35,7 @@ using testing::Contains;
using testing::ElementsAre;
using testing::Eq;
using testing::Field;
using testing::HasSubstr;
using testing::InSequence;
using testing::IsEmpty;
using testing::Mock;

View File

@@ -40,6 +40,7 @@ using testing::ElementsAre;
using testing::UnorderedElementsAre;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathView;
namespace {
@@ -47,7 +48,7 @@ class IncludeCollector : public ::testing::Test
{
protected:
void SetUp();
FilePathId id(const Utils::SmallString &path);
FilePathId id(const Utils::SmallStringView &path);
protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
@@ -139,9 +140,9 @@ void IncludeCollector::SetUp()
emptyCollector.setExcludedIncludes(excludePaths.clone());
}
FilePathId IncludeCollector::id(const Utils::SmallString &path)
FilePathId IncludeCollector::id(const Utils::SmallStringView &path)
{
return filePathCache.filePathId(path);
return filePathCache.filePathId(FilePathView{path});
}
}

View File

@@ -38,6 +38,6 @@ public:
void ());
MOCK_METHOD1(callbackCalled,
void (const Utils::PathStringVector &filePaths));
void (const ClangBackEnd::FilePaths &filePaths));
};

View File

@@ -33,7 +33,7 @@ class MockFilePathCaching : public ClangBackEnd::FilePathCachingInterface
{
public:
MOCK_CONST_METHOD1(filePathId,
ClangBackEnd::FilePathId (Utils::SmallStringView filePath));
ClangBackEnd::FilePathId (ClangBackEnd::FilePathView filePath));
MOCK_CONST_METHOD1(filePath,
ClangBackEnd::FilePath (ClangBackEnd::FilePathId filePathId));
};

View File

@@ -0,0 +1,99 @@
/****************************************************************************
**
** 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 <nativefilepath.h>
namespace {
Utils::PathString native(Utils::PathString path)
{
if (Utils::HostOsInfo::isWindowsHost())
path.replace('/', '\\');
return path;
}
TEST(NativeFilePath, CreateFromPathString)
{
ClangBackEnd::NativeFilePath filePath{native("/file/pathOne")};
ASSERT_THAT(filePath.directory(), native("/file"));
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(NativeFilePath, CreateFromDirectoryAndFileName)
{
ClangBackEnd::NativeFilePath filePath{Utils::PathString{native("/file")}, Utils::PathString{"pathOne"}};
ASSERT_THAT(filePath.directory(), native("/file"));
ASSERT_THAT(filePath.name(), "pathOne");
ASSERT_THAT(filePath.path(), native("/file/pathOne"));
}
TEST(NativeFilePath, CreateFromCString)
{
ClangBackEnd::NativeFilePath filePath{"/file/pathOne"};
if (Utils::HostOsInfo::isWindowsHost())
filePath = ClangBackEnd::NativeFilePath{"\\file\\pathOne"};
ASSERT_THAT(filePath.directory(), native("/file"));
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(NativeFilePath, CreateFromFilePathView)
{
ClangBackEnd::NativeFilePath filePath{ClangBackEnd::NativeFilePathView{native("/file/pathOne")}};
ASSERT_THAT(filePath.directory(), native("/file"));
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(NativeFilePath, CreateFromQString)
{
ClangBackEnd::NativeFilePath filePath{QString{native("/file/pathOne")}};
ASSERT_THAT(filePath.directory(), native("/file"));
ASSERT_THAT(filePath.name(), "pathOne");
}
TEST(NativeFilePath, DefaultNativeFilePath)
{
ClangBackEnd::NativeFilePath filePath;
ASSERT_THAT(filePath.directory(), "");
ASSERT_THAT(filePath.name(), "");
}
TEST(NativeFilePath, EmptyNativeFilePath)
{
ClangBackEnd::NativeFilePath filePath{""};
ASSERT_THAT(filePath.directory(), "");
ASSERT_THAT(filePath.name(), "");
}
}

View File

@@ -0,0 +1,135 @@
/****************************************************************************
**
** 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 <nativefilepathview.h>
#include <utils/hostosinfo.h>
namespace {
using ClangBackEnd::NativeFilePathView;
Utils::PathString native(Utils::PathString path)
{
if (Utils::HostOsInfo::isWindowsHost())
path.replace('/', '\\');
return path;
}
TEST(NativeFilePathView, FilePathSlashForEmptyPath)
{
NativeFilePathView filePath("");
ASSERT_THAT(filePath.slashIndex(), -1);
}
TEST(NativeFilePathView, FilePathSlashForSingleSlash)
{
NativeFilePathView filePath(native("/"));
ASSERT_THAT(filePath.slashIndex(), 0);
}
TEST(NativeFilePathView, FilePathSlashForFileInRoot)
{
NativeFilePathView filePath(native("/file.h"));
ASSERT_THAT(filePath.slashIndex(), 0);
}
TEST(NativeFilePathView, FilePathSlashForSomeLongerPath)
{
NativeFilePathView filePath(native("/path/to/some/file.h"));
ASSERT_THAT(filePath.slashIndex(), 13);
}
TEST(NativeFilePathView, FilePathSlashForFileNameOnly)
{
NativeFilePathView filePath(native("file.h"));
ASSERT_THAT(filePath.slashIndex(), -1);
}
TEST(NativeFilePathView, DirectoryPathForEmptyPath)
{
NativeFilePathView filePath("");
ASSERT_THAT(filePath.directory(), "");
}
TEST(NativeFilePathView, DirectoryPathForSingleSlashPath)
{
NativeFilePathView filePath{native("/")};
ASSERT_THAT(filePath.directory(), "");
}
TEST(NativeFilePathView, DirectoryPathForLongerPath)
{
NativeFilePathView filePath{native("/path/to/some/file.h")};
ASSERT_THAT(filePath.directory(), native("/path/to/some"));
}
TEST(NativeFilePathView, DirectoryPathForFileNameOnly)
{
NativeFilePathView filePath{"file.h"};
ASSERT_THAT(filePath.directory(), IsEmpty());
}
TEST(NativeFilePathView, FileNameForEmptyPath)
{
NativeFilePathView filePath("");
ASSERT_THAT(filePath.name(), "");
}
TEST(NativeFilePathView, FileNameForSingleSlashPath)
{
NativeFilePathView filePath{native("/")};
ASSERT_THAT(filePath.name(), "");
}
TEST(NativeFilePathView, FileNameForLongerPath)
{
NativeFilePathView filePath{native("/path/to/some/file.h")};
ASSERT_THAT(filePath.name(), "file.h");
}
TEST(NativeFilePathView, FileNameForFileNameOnly)
{
NativeFilePathView filePath{"file.h"};
ASSERT_THAT(filePath.name(), "file.h");
}
}

View File

@@ -43,50 +43,37 @@ using ClangBackEnd::ProjectPartPch;
using ClangBackEnd::V2::ProjectPartContainer;
using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::FilePath;
using ClangBackEnd::FilePathView;
using Utils::PathString;
using Utils::SmallString;
using testing::_;
using testing::AllOf;
using testing::AtLeast;
using testing::ContainerEq;
using testing::Contains;
using testing::ElementsAre;
using testing::Eq;
using testing::Field;
using testing::HasSubstr;
using testing::IsEmpty;
using testing::NiceMock;
using testing::Not;
using testing::Property;
using testing::SizeIs;
using testing::UnorderedElementsAre;
using UnitTests::EndsWith;
class PchCreator: public ::testing::Test
{
protected:
void SetUp();
ClangBackEnd::FilePathId id(const Utils::PathString &path);
ClangBackEnd::FilePathId id(Utils::SmallStringView path);
protected:
NiceMock<MockFilePathCaching> filePathCache;
PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
PathString header2Path = TESTDATA_DIR "/includecollector_header2.h";
PathString generatedFileName = "includecollector_generated_file.h";
PathString generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h";
FilePath main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
FilePath main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
FilePath header1Path = TESTDATA_DIR "/includecollector_header1.h";
FilePath header2Path = TESTDATA_DIR "/includecollector_header2.h";
Utils::SmallStringView generatedFileName = "includecollector_generated_file.h";
FilePath generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h";
ProjectPartContainer projectPart1{"project1",
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
{header1Path.clone()},
{main1Path.clone()}};
{header1Path},
{main1Path}};
ProjectPartContainer projectPart2{"project2",
{"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"},
{header2Path.clone()},
{main2Path.clone()}};
{header2Path},
{main2Path}};
TestEnvironment environment;
FileContainer generatedFile{{TESTDATA_DIR, generatedFileName.clone()}, "#pragma once", {}};
FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}};
NiceMock<MockPchGeneratorNotifier> mockPchGeneratorNotifier;
ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockPchGeneratorNotifier};
ClangBackEnd::PchCreator creator{{projectPart1.clone(),projectPart2.clone()},
@@ -347,30 +334,30 @@ TEST_F(PchCreator, CreateProjectPartHeaderAndSourcesContent)
void PchCreator::SetUp()
{
ON_CALL(filePathCache, filePathId(Eq(TESTDATA_DIR "/includecollector_external1.h")))
ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external1.h"})))
.WillByDefault(Return(FilePathId{1, 1}));
ON_CALL(filePathCache, filePathId(Eq(TESTDATA_DIR "/includecollector_external2.h")))
ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external2.h"})))
.WillByDefault(Return(FilePathId{1, 2}));
ON_CALL(filePathCache, filePathId(Eq(TESTDATA_DIR "/includecollector_external3.h")))
ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external3.h"})))
.WillByDefault(Return(FilePathId{1, 3}));
ON_CALL(filePathCache, filePathId(Eq(header1Path)))
.WillByDefault(Return(FilePathId{1, 4}));
ON_CALL(filePathCache, filePathId(Eq(header2Path)))
.WillByDefault(Return(FilePathId{1, 5}));
ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 1})))
.WillByDefault(Return(FilePath{PathString{TESTDATA_DIR "/includecollector_external1.h"}}));
.WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external1.h"}));
ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 2})))
.WillByDefault(Return(FilePath{PathString{TESTDATA_DIR "/includecollector_external2.h"}}));
.WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external2.h"}));
ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 3})))
.WillByDefault(Return(FilePath{PathString{TESTDATA_DIR "/includecollector_external3.h"}}));
.WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external3.h"}));
ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 4})))
.WillByDefault(Return(FilePath{header1Path}));
ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 5})))
.WillByDefault(Return(FilePath{header2Path}));
}
ClangBackEnd::FilePathId PchCreator::id(const Utils::PathString &path)
ClangBackEnd::FilePathId PchCreator::id(Utils::SmallStringView path)
{
return filePathCache.filePathId(path);
return filePathCache.filePathId(ClangBackEnd::FilePathView(path));
}
}

View File

@@ -677,6 +677,24 @@ TEST(SmallString, MidTwoParameter)
ASSERT_THAT(midString, Eq(SmallString("text")));
}
TEST(SmallString, SmallStringViewMidOneParameter)
{
SmallStringView text("some text");
auto midString = text.mid(5);
ASSERT_THAT(midString, Eq(SmallStringView("text")));
}
TEST(SmallString, SmallStringViewMidTwoParameter)
{
SmallStringView text("some text and more");
auto midString = text.mid(5, 4);
ASSERT_THAT(midString, Eq(SmallStringView("text")));
}
TEST(SmallString, SizeOfEmptyStringl)
{
SmallString emptyString;

View File

@@ -112,6 +112,7 @@ TEST_F(SymbolIndexing, DISABLED_TemplateFunction)
ClangBackEnd::FilePathId SymbolIndexing::filePathId(Utils::SmallString filePath)
{
return filePathCache.filePathId(filePath);
return filePathCache.filePathId(ClangBackEnd::FilePathView{filePath});
}
}

View File

@@ -61,7 +61,7 @@ class SymbolsCollector : public testing::Test
protected:
FilePathId filePathId(Utils::SmallStringView string)
{
return filePathCache.filePathId(string);
return filePathCache.filePathId(ClangBackEnd::FilePathView{string});
}
SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName);

View File

@@ -37,7 +37,6 @@ class EndsWithMatcher
public:
explicit EndsWithMatcher(const StringType& suffix) : m_suffix(suffix) {}
template <typename CharType>
bool MatchAndExplain(CharType *s, testing::MatchResultListener *listener) const
{

View File

@@ -50,6 +50,7 @@ SOURCES += \
fakeprocess.cpp \
faketimer.cpp \
filepath-test.cpp \
filepathview-test.cpp \
gtest-creator-printing.cpp \
gtest-qt-printing.cpp \
lineprefixer-test.cpp \
@@ -80,7 +81,10 @@ SOURCES += \
refactoringdatabaseinitializer-test.cpp \
filepathcache-test.cpp \
filepathstorage-test.cpp \
filepathstoragesqlitestatementfactory-test.cpp
filepathstoragesqlitestatementfactory-test.cpp \
nativefilepath-test.cpp \
nativefilepathview-test.cpp \
filepathview-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \