diff options
38 files changed, 985 insertions, 287 deletions
diff --git a/src/libs/clangsupport/changedfilepathcompressor.h b/src/libs/clangsupport/changedfilepathcompressor.h index a6166c3d4f..2708e74c8a 100644 --- a/src/libs/clangsupport/changedfilepathcompressor.h +++ b/src/libs/clangsupport/changedfilepathcompressor.h @@ -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; }; diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h index 8a315f47e1..411e1b308d 100644 --- a/src/libs/clangsupport/clangpathwatcher.h +++ b/src/libs/clangsupport/clangpathwatcher.h @@ -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)); diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index 52e27bfde6..2e6130eedd 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -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 diff --git a/src/libs/clangsupport/filepath.h b/src/libs/clangsupport/filepath.h index 603f905397..968ab396a1 100644 --- a/src/libs/clangsupport/filepath.h +++ b/src/libs/clangsupport/filepath.h @@ -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 = view.slashIndex(); + } + + FilePath(FilePathView filePathView) + : m_path(filePathView.toStringView()), + m_slashIndex(filePathView.slashIndex()) + { + } - m_slashIndex = std::size_t(std::distance(m_path.begin(), found)); + 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>; diff --git a/src/libs/clangsupport/filepathcache.h b/src/libs/clangsupport/filepathcache.h index 157559a28b..7fa177e43a 100644 --- a/src/libs/clangsupport/filepathcache.h +++ b/src/libs/clangsupport/filepathcache.h @@ -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: diff --git a/src/libs/clangsupport/filepathcaching.cpp b/src/libs/clangsupport/filepathcaching.cpp index 1956a4718c..0a3fc6ee41 100644 --- a/src/libs/clangsupport/filepathcaching.cpp +++ b/src/libs/clangsupport/filepathcaching.cpp @@ -27,7 +27,7 @@ namespace ClangBackEnd { -FilePathId FilePathCaching::filePathId(Utils::SmallStringView filePath) const +FilePathId FilePathCaching::filePathId(FilePathView filePath) const { return m_cache.filePathId(filePath); } diff --git a/src/libs/clangsupport/filepathcaching.h b/src/libs/clangsupport/filepathcaching.h index 9f271e96de..d5e89fd7aa 100644 --- a/src/libs/clangsupport/filepathcaching.h +++ b/src/libs/clangsupport/filepathcaching.h @@ -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: diff --git a/src/libs/clangsupport/filepathcachinginterface.h b/src/libs/clangsupport/filepathcachinginterface.h index 9f53e57610..7ce357e09a 100644 --- a/src/libs/clangsupport/filepathcachinginterface.h +++ b/src/libs/clangsupport/filepathcachinginterface.h @@ -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> diff --git a/src/libs/clangsupport/filepathview.h b/src/libs/clangsupport/filepathview.h new file mode 100644 index 0000000000..5d62cec7ed --- /dev/null +++ b/src/libs/clangsupport/filepathview.h @@ -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; +}; + +} diff --git a/src/libs/clangsupport/nativefilepath.h b/src/libs/clangsupport/nativefilepath.h new file mode 100644 index 0000000000..bb7cdf4b01 --- /dev/null +++ b/src/libs/clangsupport/nativefilepath.h @@ -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 + diff --git a/src/libs/clangsupport/nativefilepathview.h b/src/libs/clangsupport/nativefilepathview.h new file mode 100644 index 0000000000..c2f2246c49 --- /dev/null +++ b/src/libs/clangsupport/nativefilepathview.h @@ -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; +}; + +} diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h index 39cb86b193..ce5e63292f 100644 --- a/src/libs/utils/smallstringview.h +++ b/src/libs/utils/smallstringview.h @@ -104,6 +104,18 @@ public: } 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 { return data(); diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp index 37ed6a871f..d76c5d61d6 100644 --- a/src/plugins/clangrefactoring/refactoringengine.cpp +++ b/src/plugins/clangrefactoring/refactoringengine.cpp @@ -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); } diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h index 4c7254145a..92b3bbe2a0 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h @@ -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: diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend_global.h b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend_global.h index 30d4b2e1a0..49796ef7b9 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend_global.h +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend_global.h @@ -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() ? '\\' : '/'; } diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h index 0f436a0e37..a6210afc22 100644 --- a/src/tools/clangrefactoringbackend/source/clangtool.h +++ b/src/tools/clangrefactoringbackend/source/clangtool.h @@ -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) {} diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h index f93f44a1cb..07fe19bd0f 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h @@ -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); diff --git a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp index 4699ec3818..a4e4c89863 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.cpp @@ -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; } } diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h index 3d5fb8d3e8..4ff84a0a7b 100644 --- a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h +++ b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h @@ -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(), diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp index d275cfe4e2..15dde240a4 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp +++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp @@ -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) diff --git a/tests/unit/unittest/changedfilepathcompressor-test.cpp b/tests/unit/unittest/changedfilepathcompressor-test.cpp index 9080e3f0f8..d65eac708c 100644 --- a/tests/unit/unittest/changedfilepathcompressor-test.cpp +++ b/tests/unit/unittest/changedfilepathcompressor-test.cpp @@ -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); }); } diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp index 960030ca99..f1a85f5f4b 100644 --- a/tests/unit/unittest/clangpathwatcher-test.cpp +++ b/tests/unit/unittest/clangpathwatcher-test.cpp @@ -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})); } } diff --git a/tests/unit/unittest/filepath-test.cpp b/tests/unit/unittest/filepath-test.cpp index d82e94f211..39c23470cc 100644 --- a/tests/unit/unittest/filepath-test.cpp +++ b/tests/unit/unittest/filepath-test.cpp @@ -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(), ""); +} + } diff --git a/tests/unit/unittest/filepathcache-test.cpp b/tests/unit/unittest/filepathcache-test.cpp index 9fe73faa63..a9cc33ba33 100644 --- a/tests/unit/unittest/filepathcache-test.cpp +++ b/tests/unit/unittest/filepathcache-test.cpp @@ -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() } } - diff --git a/tests/unit/unittest/filepathview-test.cpp b/tests/unit/unittest/filepathview-test.cpp new file mode 100644 index 0000000000..45d661dc37 --- /dev/null +++ b/tests/unit/unittest/filepathview-test.cpp @@ -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"); +} + +} diff --git a/tests/unit/unittest/filesystem-utilities.h b/tests/unit/unittest/filesystem-utilities.h index 0791c2b972..3bbafdf368 100644 --- a/tests/unit/unittest/filesystem-utilities.h +++ b/tests/unit/unittest/filesystem-utilities.h @@ -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; } diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h index c91c901efb..0b58af5423 100644 --- a/tests/unit/unittest/google-using-declarations.h +++ b/tests/unit/unittest/google-using-declarations.h @@ -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; diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp index 1bb51762ce..a9c925ef73 100644 --- a/tests/unit/unittest/includecollector-test.cpp +++ b/tests/unit/unittest/includecollector-test.cpp @@ -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}); } } diff --git a/tests/unit/unittest/mockchangedfilepathcompressor.h b/tests/unit/unittest/mockchangedfilepathcompressor.h index d7988d9920..f1b556ba2e 100644 --- a/tests/unit/unittest/mockchangedfilepathcompressor.h +++ b/tests/unit/unittest/mockchangedfilepathcompressor.h @@ -38,6 +38,6 @@ public: void ()); MOCK_METHOD1(callbackCalled, - void (const Utils::PathStringVector &filePaths)); + void (const ClangBackEnd::FilePaths &filePaths)); }; diff --git a/tests/unit/unittest/mockfilepathcaching.h b/tests/unit/unittest/mockfilepathcaching.h index f77287b4bb..1b22e910ee 100644 --- a/tests/unit/unittest/mockfilepathcaching.h +++ b/tests/unit/unittest/mockfilepathcaching.h @@ -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)); }; diff --git a/tests/unit/unittest/nativefilepath-test.cpp b/tests/unit/unittest/nativefilepath-test.cpp new file mode 100644 index 0000000000..864c91dc60 --- /dev/null +++ b/tests/unit/unittest/nativefilepath-test.cpp @@ -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(), ""); +} + +} diff --git a/tests/unit/unittest/nativefilepathview-test.cpp b/tests/unit/unittest/nativefilepathview-test.cpp new file mode 100644 index 0000000000..5209073217 --- /dev/null +++ b/tests/unit/unittest/nativefilepathview-test.cpp @@ -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"); +} + +} diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 9dccf204d1..b1812ddc36 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -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)); } } diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp index ca6534b558..69017f0d70 100644 --- a/tests/unit/unittest/smallstring-test.cpp +++ b/tests/unit/unittest/smallstring-test.cpp @@ -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; diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp index 79dc64dd46..b5e93e4d6c 100644 --- a/tests/unit/unittest/symbolindexing-test.cpp +++ b/tests/unit/unittest/symbolindexing-test.cpp @@ -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}); } + } diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index b57cc66f3c..792968d19c 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -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); diff --git a/tests/unit/unittest/unittest-matchers.h b/tests/unit/unittest/unittest-matchers.h index 4e9fc6568d..84ad863f14 100644 --- a/tests/unit/unittest/unittest-matchers.h +++ b/tests/unit/unittest/unittest-matchers.h @@ -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 { diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index f58f057240..fa69e7daac 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -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 += \ |