diff options
Diffstat (limited to 'src')
87 files changed, 1534 insertions, 975 deletions
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index 25b48dfc07..30c1d03446 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -67,7 +67,6 @@ SOURCES += \ $$PWD/requestsourcelocationforrenamingmessage.cpp \ $$PWD/requestsourcerangesanddiagnosticsforquerymessage.cpp \ $$PWD/requestsourcerangesforquerymessage.cpp \ - $$PWD/sourcefilepathcontainerbase.cpp \ $$PWD/sourcelocationcontainer.cpp \ $$PWD/sourcelocationcontainerv2.cpp \ $$PWD/sourcelocationscontainer.cpp \ @@ -82,7 +81,9 @@ SOURCES += \ $$PWD/updatepchprojectpartsmessage.cpp \ $$PWD/updatetranslationunitsforeditormessage.cpp \ $$PWD/updatevisibletranslationunitsmessage.cpp \ - $$PWD/writemessageblock.cpp + $$PWD/writemessageblock.cpp \ + $$PWD/filepathcaching.cpp \ + $$PWD/filepathid.cpp HEADERS += \ $$PWD/cancelmessage.h \ @@ -150,7 +151,6 @@ HEADERS += \ $$PWD/requestsourcelocationforrenamingmessage.h \ $$PWD/requestsourcerangesanddiagnosticsforquerymessage.h \ $$PWD/requestsourcerangesforquerymessage.h \ - $$PWD/sourcefilepathcontainerbase.h \ $$PWD/sourcelocationcontainer.h \ $$PWD/sourcelocationcontainerv2.h \ $$PWD/sourcelocationscontainer.h \ @@ -172,6 +172,15 @@ HEADERS += \ $$PWD/stringcachefwd.h \ $$PWD/stringcachealgorithms.h \ $$PWD/projectmanagementserverinterface.h \ - $$PWD/refactoringdatabaseinitializer.h + $$PWD/refactoringdatabaseinitializer.h \ + $$PWD/filepathcache.h \ + $$PWD/filepathid.h \ + $$PWD/filepathstorage.h \ + $$PWD/filepathstoragesqlitestatementfactory.h \ + $$PWD/filepathstoragesources.h \ + $$PWD/filepathexceptions.h \ + $$PWD/filepathcachinginterface.h \ + $$PWD/filepathcaching.h \ + $$PWD/filepathcachingfwd.h contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols diff --git a/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h index 07a21af605..51e1f12949 100644 --- a/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h +++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h @@ -94,9 +94,7 @@ public: DynamicASTMatcherDiagnosticMessageContainer clone() const { - return DynamicASTMatcherDiagnosticMessageContainer(m_sourceRange.clone(), - m_errorType, - m_arguments.clone()); + return *this; } private: diff --git a/src/libs/clangsupport/filepath.h b/src/libs/clangsupport/filepath.h index c57da408bc..96387412c1 100644 --- a/src/libs/clangsupport/filepath.h +++ b/src/libs/clangsupport/filepath.h @@ -63,22 +63,27 @@ public: { } - FilePath(const Utils::PathString &directory, const Utils::PathString &name) - : m_path({std::move(directory), "/", std::move(name)}), + FilePath(Utils::SmallStringView directory, Utils::SmallStringView name) + : m_path({directory, "/", name}), m_slashIndex(directory.size()) {} - Utils::SmallStringView directory() const + Utils::SmallStringView directory() const noexcept { return m_path.mid(0, m_slashIndex); } - Utils::SmallStringView name() const + Utils::SmallStringView name() const noexcept { return m_path.mid(m_slashIndex + 1, m_path.size() - m_slashIndex - 1); } - const Utils::PathString &path() const + const Utils::PathString &path() const noexcept + { + return m_path; + } + + operator Utils::PathString() const noexcept { return m_path; } @@ -105,9 +110,7 @@ public: friend std::ostream &operator<<(std::ostream &out, const FilePath &filePath) { - out << filePath.directory() << "/" << filePath.name(); - - return out; + return out << "(" << filePath.path() << ", " << filePath.slashIndex() << ")"; } friend bool operator==(const FilePath &first, const FilePath &second) @@ -115,6 +118,16 @@ public: return first.m_path == second.m_path; } + friend bool operator==(const FilePath &first, const Utils::SmallStringView &second) + { + return first.path() == second; + } + + friend bool operator==(const Utils::SmallStringView &first, const FilePath&second) + { + return second == first; + } + friend bool operator<(const FilePath &first, const FilePath &second) { return first.m_path < second.m_path; @@ -125,11 +138,18 @@ public: return *this; } + std::size_t slashIndex() const + { + return m_slashIndex; + } + private: Utils::PathString m_path = "/"; std::size_t m_slashIndex = 0; }; +using FilePaths = std::vector<FilePath>; + CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FilePath &filePath); } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/filepathcache.h b/src/libs/clangsupport/filepathcache.h new file mode 100644 index 0000000000..61e8680965 --- /dev/null +++ b/src/libs/clangsupport/filepathcache.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** 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 "filepathexceptions.h" +#include "filepathid.h" +#include "filepath.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 +{ + using DirectoryPathCache = StringCache<Utils::PathString, + int, + std::mutex, + decltype(&Utils::reverseCompare), + Utils::reverseCompare>; + using FileNameCache = StringCache<Utils::SmallString, + int, + std::mutex, + decltype(&Utils::compare), + Utils::compare>; +public: + FilePathCache(FilePathStorage &filePathStorage) + : m_filePathStorage(filePathStorage) + {} + + FilePathId filePathId(Utils::SmallStringView filePath) const + { + std::ptrdiff_t slashIndex = lastSlashIndex(filePath); + + 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); + + int fileNameId = m_fileNameCache.stringId(fileName, + [&] (const Utils::SmallStringView) { + return m_filePathStorage.fetchSourceId(directoryId, fileName); + }); + + return {directoryId, fileNameId}; + } + + FilePath filePath(FilePathId filePathId) const + { + if (Q_UNLIKELY(!filePathId.isValid())) + throw NoFilePathForInvalidFilePathId(); + + auto fetchFilePath = [&] (int id) { return m_filePathStorage.fetchDirectoryPath(id); }; + + Utils::PathString directoryPath = m_directyPathCache.string(filePathId.directoryId, + fetchFilePath); + + + auto fetchSoureName = [&] (int id) { return m_filePathStorage.fetchSourceName(id); }; + + Utils::SmallString fileName = m_fileNameCache.string(filePathId.fileNameId, + fetchSoureName); + + return {directoryPath, fileName}; + } + +private: + mutable DirectoryPathCache m_directyPathCache; + mutable FileNameCache m_fileNameCache; + FilePathStorage &m_filePathStorage; +}; + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp b/src/libs/clangsupport/filepathcaching.cpp index 9cea242fa8..1956a4718c 100644 --- a/src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp +++ b/src/libs/clangsupport/filepathcaching.cpp @@ -23,20 +23,18 @@ ** ****************************************************************************/ -#include "sourcelocationentry.h" - -#include <utils/smallstringio.h> +#include "filepathcaching.h" namespace ClangBackEnd { -std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry) +FilePathId FilePathCaching::filePathId(Utils::SmallStringView filePath) const { - out << "(" - << entry.fileId << ", " - << entry.line << ", " - << entry.column << ")"; + return m_cache.filePathId(filePath); +} - return out; +FilePath FilePathCaching::filePath(FilePathId filePathId) const +{ + return m_cache.filePath(filePathId); } } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/filepathcaching.h b/src/libs/clangsupport/filepathcaching.h new file mode 100644 index 0000000000..573ce81610 --- /dev/null +++ b/src/libs/clangsupport/filepathcaching.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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 "clangsupport_global.h" + +#include "filepathcachinginterface.h" +#include "filepathcache.h" +#include "filepathstoragesqlitestatementfactory.h" +#include "filepathstorage.h" + +#include <sqlitedatabase.h> +#include <sqlitereadstatement.h> +#include <sqlitewritestatement.h> + +namespace ClangBackEnd { + +class CMBIPC_EXPORT FilePathCaching final : public FilePathCachingInterface +{ + using Factory = FilePathStorageSqliteStatementFactory<Sqlite::Database, + Sqlite::ReadStatement, + Sqlite::WriteStatement>; + using Storage = FilePathStorage<Factory>; + using Cache = FilePathCache<Storage>; +public: + FilePathCaching(Sqlite::Database &database) + : m_factory(database) + {} + + FilePathId filePathId(Utils::SmallStringView filePath) const override; + FilePath filePath(FilePathId filePathId) const override; + +private: + Factory m_factory; + Storage m_storage{m_factory}; + Cache m_cache{m_storage}; +}; + +} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/sourcefilepathcontainerbase.cpp b/src/libs/clangsupport/filepathcachingfwd.h index 66d44d8827..7519dde634 100644 --- a/src/libs/clangsupport/sourcefilepathcontainerbase.cpp +++ b/src/libs/clangsupport/filepathcachingfwd.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -23,10 +23,10 @@ ** ****************************************************************************/ -#include "sourcefilepathcontainerbase.h" +#pragma once namespace ClangBackEnd { - +class FilePathCachingInterface; } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/filepathcachinginterface.h b/src/libs/clangsupport/filepathcachinginterface.h new file mode 100644 index 0000000000..9f53e57610 --- /dev/null +++ b/src/libs/clangsupport/filepathcachinginterface.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 "filepath.h" +#include "filepathid.h" + +namespace ClangBackEnd { + +class FilePathCachingInterface +{ +public: + virtual FilePathId filePathId(Utils::SmallStringView filePath) const = 0; + virtual FilePath filePath(FilePathId filePathId) const = 0; + + template <typename Container> + FilePathIds filePathIds(Container &&filePaths) const + { + FilePathIds filePathIds; + filePathIds.reserve(filePaths.size()); + + std::transform(filePaths.begin(), + filePaths.end(), + std::back_inserter(filePathIds), + [&] (const auto &filePath) { return this->filePathId(filePath); }); + + return filePathIds; + } + + template <typename Element> + FilePathIds filePathIds(std::initializer_list<Element> filePaths) const + { + return filePathIds(std::vector<Element>(filePaths)); + } + + FilePaths filePaths(const FilePathIds &filePathIds) const + { + FilePaths filePaths; + filePaths.reserve(filePathIds.size()); + + std::transform(filePathIds.begin(), + filePathIds.end(), + std::back_inserter(filePaths), + [&] (auto filePathId) { return this->filePath(filePathId); }); + + return filePaths; + } +}; + +} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp b/src/libs/clangsupport/filepathexceptions.h index 1647fa7943..32142c084c 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp +++ b/src/libs/clangsupport/filepathexceptions.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -23,20 +23,37 @@ ** ****************************************************************************/ -#include "clangpathwatcher.h" +#pragma once -#include <utils/smallstringio.h> +#include <exception> namespace ClangBackEnd { -std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry) +class NoFilePathForInvalidFilePathId : std::exception { - out << "(" - << entry.id << ", " - << entry.path - << ")"; +public: + const char *what() const noexcept override + { + return "You cannot get a file path for an invalid file path id!"; + } +}; - return out; -} +class SourceNameIdDoesNotExists : std::exception +{ +public: + const char *what() const noexcept override + { + return "The source name id does not exists in the database!"; + } +}; + +class DirectoryPathIdDoesNotExists : std::exception +{ +public: + const char *what() const noexcept override + { + return "The directory path id does not exists in the database!"; + } +}; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.cpp b/src/libs/clangsupport/filepathid.cpp index f1dba02e4e..0ed77ef77a 100644 --- a/src/tools/clangpchmanagerbackend/source/idpaths.cpp +++ b/src/libs/clangsupport/filepathid.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -23,19 +23,17 @@ ** ****************************************************************************/ -#include "idpaths.h" +#include "filepathid.h" -#include <utils/smallstringio.h> +#include <QDebug> namespace ClangBackEnd { -std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths) +QDebug operator<<(QDebug debug, const FilePathId &filePathId) { - out << "(" - << idPaths.id << ", " - << idPaths.paths << ")"; + debug.nospace() << "(" << filePathId.directoryId << ", " << filePathId.fileNameId << ")"; - return out; + return debug; } } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/filepathid.h b/src/libs/clangsupport/filepathid.h new file mode 100644 index 0000000000..34bd66dbe3 --- /dev/null +++ b/src/libs/clangsupport/filepathid.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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 "clangsupport_global.h" + +#include <QDataStream> + +#include <cstdint> +#include <tuple> +#include <vector> + +namespace ClangBackEnd { + +class FilePathId +{ +public: + FilePathId() = default; + FilePathId(int directoryId, int fileNameId) + : directoryId(directoryId), + fileNameId(fileNameId) + {} + + bool isValid() const + { + return directoryId >= 0 && fileNameId >= 0; + } + + friend bool operator==(FilePathId first, FilePathId second) + { + return first.isValid() + && second.isValid() + && first.directoryId == second.directoryId + && first.fileNameId == second.fileNameId; + } + + friend bool operator!=(FilePathId first, FilePathId second) + { + return !(first==second); + } + + friend bool operator<(FilePathId first, FilePathId second) + { + return std::tie(first.directoryId, first.fileNameId) + < std::tie(second.directoryId, second.fileNameId); + } + + friend QDataStream &operator<<(QDataStream &out, const FilePathId &filePathId) + { + out << filePathId.directoryId; + out << filePathId.fileNameId; + + return out; + } + + friend QDataStream &operator>>(QDataStream &in, FilePathId &filePathId) + { + in >> filePathId.directoryId; + in >> filePathId.fileNameId; + + return in; + } + + +public: + int directoryId = -1; + int fileNameId = -1; +}; + +using FilePathIds = std::vector<FilePathId>; + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FilePathId &filePathId); +} // namespace ClangBackEnd + +namespace std { +template<> struct hash<ClangBackEnd::FilePathId> +{ + using argument_type = ClangBackEnd::FilePathId; + using result_type = std::size_t; + result_type operator()(const argument_type& filePathId) const + { + long long hash = filePathId.directoryId; + hash = hash << 32; + hash += filePathId.fileNameId; + + return std::hash<long long>{}(hash); + } +}; + +} // namespace std diff --git a/src/libs/clangsupport/filepathstorage.h b/src/libs/clangsupport/filepathstorage.h new file mode 100644 index 0000000000..d8279c9c0b --- /dev/null +++ b/src/libs/clangsupport/filepathstorage.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 "filepathexceptions.h" +#include "filepathid.h" +#include "filepathstoragesources.h" + +#include <sqliteexception.h> +#include <sqlitetransaction.h> + +#include <utils/optional.h> + +namespace ClangBackEnd { + +template <typename StatementFactory> +class FilePathStorage +{ + using DeferredTransaction = Sqlite::DeferredTransaction<typename StatementFactory::DatabaseType>; + using ImmediateTransaction = Sqlite::ImmediateTransaction<typename StatementFactory::DatabaseType>; + using ReadStatement = typename StatementFactory::ReadStatementType; + using WriteStatement = typename StatementFactory::WriteStatementType; + using Database = typename StatementFactory::DatabaseType; + +public: + FilePathStorage(StatementFactory &statementFactory) + : m_statementFactory(statementFactory) + {} + + int fetchDirectoryId(Utils::SmallStringView directoryPath) + try { + DeferredTransaction transaction{m_statementFactory.database}; + + Utils::optional<int> optionalDirectoryId = readDirectoryId(directoryPath); + + int directoryId = -1; + + if (optionalDirectoryId) + directoryId = optionalDirectoryId.value(); + else + directoryId = writeDirectoryId(directoryPath); + + transaction.commit(); + + return directoryId; + } catch (Sqlite::StatementIsBusy &) { + return fetchDirectoryId(directoryPath); + } + + Utils::optional<int> readDirectoryId(Utils::SmallStringView directoryPath) + { + ReadStatement &statement = m_statementFactory.selectDirectoryIdFromDirectoriesByDirectoryPath; + + return statement.template value<int>(directoryPath); + } + + int writeDirectoryId(Utils::SmallStringView directoryPath) + { + WriteStatement &statement = m_statementFactory.insertIntoDirectories; + + statement.write(directoryPath); + + return int(m_statementFactory.database.lastInsertedRowId()); + } + + Utils::PathString fetchDirectoryPath(int directoryPathId) + { + DeferredTransaction transaction{m_statementFactory.database}; + + ReadStatement &statement = m_statementFactory.selectDirectoryPathFromDirectoriesByDirectoryId; + + auto optionalDirectoryPath = statement.template value<Utils::PathString>(directoryPathId); + + if (!optionalDirectoryPath) + throw DirectoryPathIdDoesNotExists(); + + transaction.commit(); + + return optionalDirectoryPath.value(); + } + + std::vector<Sources::Directory> fetchAllDirectories() + { + DeferredTransaction transaction{m_statementFactory.database}; + + ReadStatement &statement = m_statementFactory.selectAllDirectories; + + auto directories = statement.template values<Sources::Directory, 2>(256); + + transaction.commit(); + + return directories; + } + + int fetchSourceId(int directoryId, Utils::SmallStringView sourceName) + try { + DeferredTransaction transaction{m_statementFactory.database}; + + Utils::optional<int> optionalSourceId = readSourceId(directoryId, sourceName); + + int sourceId = -1; + + if (optionalSourceId) + sourceId = optionalSourceId.value(); + else + sourceId = writeSourceId(directoryId, sourceName); + + transaction.commit(); + + return sourceId; + } catch (Sqlite::StatementIsBusy &) { + return fetchSourceId(directoryId, sourceName); + } + + int writeSourceId(int directoryId, Utils::SmallStringView sourceName) + { + WriteStatement &statement = m_statementFactory.insertIntoSources; + + statement.write(directoryId, sourceName); + + return int(m_statementFactory.database.lastInsertedRowId()); + } + + Utils::optional<int> readSourceId(int directoryId, Utils::SmallStringView sourceName) + { + ReadStatement &statement = m_statementFactory.selectSourceIdFromSourcesByDirectoryIdAndSourceName; + + return statement.template value<int>(directoryId, sourceName); + } + + Utils::SmallString fetchSourceName(int sourceId) + { + DeferredTransaction transaction{m_statementFactory.database}; + + ReadStatement &statement = m_statementFactory.selectSourceNameFromSourcesBySourceId; + + auto optionalSourceName = statement.template value<Utils::SmallString>(sourceId); + + if (!optionalSourceName) + throw SourceNameIdDoesNotExists(); + + transaction.commit(); + + return optionalSourceName.value(); + } + + std::vector<Sources::Source> fetchAllSources() + { + DeferredTransaction transaction{m_statementFactory.database}; + + ReadStatement &statement = m_statementFactory.selectAllSources; + + auto sources = statement.template values<Sources::Source, 2>(8192); + + transaction.commit(); + + return sources; + } + +private: + StatementFactory &m_statementFactory; +}; + +} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/sourcefilepathcontainerbase.h b/src/libs/clangsupport/filepathstoragesources.h index ebf717f15e..7561aca908 100644 --- a/src/libs/clangsupport/sourcefilepathcontainerbase.h +++ b/src/libs/clangsupport/filepathstoragesources.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,41 +25,50 @@ #pragma once -#include "filepath.h" +#include <utils/smallstring.h> +#include <cstdint> +#include <vector> +#include <tuple> #include <unordered_map> namespace ClangBackEnd { - -using FilePathDict = std::unordered_map<uint, FilePath>; - -class SourceFilePathContainerBase +namespace Sources { +class Directory { public: - SourceFilePathContainerBase() = default; - SourceFilePathContainerBase(std::unordered_map<uint, FilePath> &&filePathHash) - : m_filePathHash(std::move(filePathHash)) - { - } + Directory(int directoryId, Utils::PathString &&directoryPath) + : directoryId(directoryId), directoryPath(std::move(directoryPath)) + {} - void insertFilePath(uint fileId, Utils::PathString &&filePath) + friend + bool operator==(const Directory &first, const Directory &second) { - if (m_filePathHash.find(fileId) == m_filePathHash.end()) - m_filePathHash.emplace(fileId, FilePath(std::move(filePath))); + return first.directoryId == second.directoryId && first.directoryPath == second.directoryPath; } - void reserve(std::size_t size) - { - m_filePathHash.reserve(size / 3); - } +public: + int directoryId; + Utils::PathString directoryPath; +}; + +class Source +{ +public: + Source(int sourceId, Utils::PathString &&sourceName) + : sourceId(sourceId), sourceName(std::move(sourceName)) + {} - const FilePathDict &filePaths() const + friend + bool operator==(const Source &first, const Source &second) { - return m_filePathHash; + return first.sourceId == second.sourceId && first.sourceName == second.sourceName; } -protected: - FilePathDict m_filePathHash; +public: + int sourceId; + Utils::PathString sourceName; }; +} // namespace ClangBackEnd } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h new file mode 100644 index 0000000000..6c4c48302a --- /dev/null +++ b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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 <sqlitetransaction.h> +#include <sqlitetable.h> + +namespace ClangBackEnd { + +template<typename Database, + typename ReadStatement, + typename WriteStatement> +class FilePathStorageSqliteStatementFactory +{ +public: + using DatabaseType = Database; + using ReadStatementType = ReadStatement; + using WriteStatementType = WriteStatement; + + FilePathStorageSqliteStatementFactory(Database &database) + : database(database) + { + } + +public: + Database &database; + ReadStatement selectDirectoryIdFromDirectoriesByDirectoryPath{ + "SELECT directoryId FROM directories WHERE directoryPath = ?", + database + }; + ReadStatement selectDirectoryPathFromDirectoriesByDirectoryId{ + "SELECT directoryPath FROM directories WHERE directoryId = ?", + database + }; + ReadStatement selectAllDirectories{ + "SELECT directoryId, directoryPath FROM directories", + database + }; + WriteStatement insertIntoDirectories{ + "INSERT INTO directories(directoryPath) VALUES (?)", + database + }; + ReadStatement selectSourceIdFromSourcesByDirectoryIdAndSourceName{ + "SELECT sourceId FROM sources WHERE directoryId = ? AND sourceName = ?", + database + }; + ReadStatement selectSourceNameFromSourcesBySourceId{ + "SELECT sourceName FROM sources WHERE sourceId = ?", + database + }; + WriteStatement insertIntoSources{ + "INSERT INTO sources(directoryId, sourceName) VALUES (?,?)", + database + }; + ReadStatement selectAllSources{ + "SELECT sourceId, sourceName FROM sources", + database + }; +}; + +} // namespace ClangBackEnd + diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h index 29f41d621e..c1696d0ecf 100644 --- a/src/libs/clangsupport/refactoringdatabaseinitializer.h +++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h @@ -44,6 +44,7 @@ public: createSymbolsTable(); createLocationsTable(); createSourcesTable(); + createDirectoriesTable(); transaction.commit(); } @@ -67,10 +68,10 @@ public: table.setUseIfNotExists(true); table.setName("locations"); table.addColumn("symbolId", Sqlite::ColumnType::Integer); - table.addColumn("line", Sqlite::ColumnType::Integer); - table.addColumn("column", Sqlite::ColumnType::Integer); + const Sqlite::Column &lineColumn = table.addColumn("line", Sqlite::ColumnType::Integer); + const Sqlite::Column &columnColumn = table.addColumn("column", Sqlite::ColumnType::Integer); const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer); - table.addIndex({sourceIdColumn}); + table.addIndex({sourceIdColumn, lineColumn, columnColumn}); table.initialize(database); } @@ -81,7 +82,22 @@ public: table.setUseIfNotExists(true); table.setName("sources"); table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey); - table.addColumn("sourcePath", Sqlite::ColumnType::Text); + table.addColumn("directoryId", Sqlite::ColumnType::Integer); + const Sqlite::Column &sourceNameColumn = table.addColumn("sourceName", Sqlite::ColumnType::Text); + table.addColumn("sourceType", Sqlite::ColumnType::Integer); + table.addIndex({sourceNameColumn}); + + table.initialize(database); + } + + void createDirectoriesTable() + { + Sqlite::Table table; + table.setUseIfNotExists(true); + table.setName("directories"); + table.addColumn("directoryId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey); + const Sqlite::Column &directoryPathColumn = table.addColumn("directoryPath", Sqlite::ColumnType::Text); + table.addIndex({directoryPathColumn}); table.initialize(database); } diff --git a/src/libs/clangsupport/sourcelocationcontainerv2.cpp b/src/libs/clangsupport/sourcelocationcontainerv2.cpp index 3206daf2b5..2aa2d1a3cf 100644 --- a/src/libs/clangsupport/sourcelocationcontainerv2.cpp +++ b/src/libs/clangsupport/sourcelocationcontainerv2.cpp @@ -38,15 +38,15 @@ QDebug operator<<(QDebug debug, const SourceLocationContainer &container) << container.line() << ", " << container.column() << ", " << container.offset() << ", " - << container.fileHash() + << container.filePathId().fileNameId << ")"; return debug; } std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container) { - os << "(" - << container.fileHash() << ", " + os << "((" + << container.filePathId().directoryId << ", " << container.filePathId().fileNameId << "), " << container.line() << ", " << container.column() << ", " << container.offset() diff --git a/src/libs/clangsupport/sourcelocationcontainerv2.h b/src/libs/clangsupport/sourcelocationcontainerv2.h index def1c389fa..70327f371a 100644 --- a/src/libs/clangsupport/sourcelocationcontainerv2.h +++ b/src/libs/clangsupport/sourcelocationcontainerv2.h @@ -26,6 +26,7 @@ #pragma once #include "clangsupport_global.h" +#include "filepathid.h" #include <QDataStream> @@ -37,20 +38,20 @@ class SourceLocationContainer { public: SourceLocationContainer() = default; - SourceLocationContainer(uint fileHash, + SourceLocationContainer(FilePathId filePathId, uint line, uint column, uint offset) - : m_fileHash(fileHash), + : m_filePathId(filePathId), m_line(line), m_column(column), m_offset(offset) { } - uint fileHash() const + FilePathId filePathId() const { - return m_fileHash; + return m_filePathId; } uint line() const @@ -70,7 +71,7 @@ public: friend QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container) { - out << container.m_fileHash; + out << container.m_filePathId; out << container.m_line; out << container.m_column; out << container.m_offset; @@ -80,7 +81,7 @@ public: friend QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container) { - in >> container.m_fileHash; + in >> container.m_filePathId; in >> container.m_line; in >> container.m_column; in >> container.m_offset; @@ -97,23 +98,23 @@ public: { return first.m_line != second.m_line || first.m_column != second.m_column - || first.m_fileHash != second.m_fileHash; + || first.m_filePathId != second.m_filePathId; } friend bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second) { - return std::tie(first.m_fileHash, first.m_line, first.m_column) - < std::tie(second.m_fileHash, second.m_line, second.m_column); + return std::tie(first.m_filePathId, first.m_line, first.m_column) + < std::tie(second.m_filePathId, second.m_line, second.m_column); } SourceLocationContainer clone() const { - return SourceLocationContainer(m_fileHash, m_line, m_column, m_offset); + return *this; } private: - uint m_fileHash = 0; + FilePathId m_filePathId; uint m_line = 1; uint m_column = 1; uint m_offset = 0; diff --git a/src/libs/clangsupport/sourcelocationscontainer.cpp b/src/libs/clangsupport/sourcelocationscontainer.cpp index c5775e6a76..7e4bc79a5b 100644 --- a/src/libs/clangsupport/sourcelocationscontainer.cpp +++ b/src/libs/clangsupport/sourcelocationscontainer.cpp @@ -33,10 +33,10 @@ QDebug operator<<(QDebug debug, const SourceLocationsContainer &container) { debug.nospace() << "SourceLocationsContainer(["; for (const auto &sourceLocation: container.sourceLocationContainers()) { - debug.nospace() << "[" - << container.filePathForSourceLocation(sourceLocation).name() << "," + debug.nospace() << "(" + << sourceLocation.filePathId() << "," << sourceLocation.line() << "," - << sourceLocation.column() << "], "; + << sourceLocation.column() << "), "; } debug.nospace() << "])"; diff --git a/src/libs/clangsupport/sourcelocationscontainer.h b/src/libs/clangsupport/sourcelocationscontainer.h index 731ad16906..c33564c304 100644 --- a/src/libs/clangsupport/sourcelocationscontainer.h +++ b/src/libs/clangsupport/sourcelocationscontainer.h @@ -25,30 +25,20 @@ #pragma once -#include "sourcefilepathcontainerbase.h" #include "sourcelocationcontainerv2.h" -#include <utils/smallstringvector.h> +#include <utils/smallstringio.h> namespace ClangBackEnd { -class SourceLocationsContainer : public SourceFilePathContainerBase +class SourceLocationsContainer { public: SourceLocationsContainer() = default; - SourceLocationsContainer(std::unordered_map<uint, FilePath> &&filePathHash, - std::vector<V2::SourceLocationContainer> &&sourceLocationContainers) - : SourceFilePathContainerBase(std::move(filePathHash)), - m_sourceLocationContainers(std::move(sourceLocationContainers)) + SourceLocationsContainer(std::vector<V2::SourceLocationContainer> &&sourceLocationContainers) + : m_sourceLocationContainers(std::move(sourceLocationContainers)) {} - const FilePath &filePathForSourceLocation(const V2::SourceLocationContainer &sourceLocation) const - { - auto found = m_filePathHash.find(sourceLocation.fileHash()); - - return found->second; - } - const std::vector<V2::SourceLocationContainer> &sourceLocationContainers() const { return m_sourceLocationContainers; @@ -59,20 +49,18 @@ public: return !m_sourceLocationContainers.empty(); } - void insertSourceLocation(uint fileId, uint line, uint column, uint offset) + void insertSourceLocation(FilePathId filePathId, uint line, uint column, uint offset) { - m_sourceLocationContainers.emplace_back(fileId, line, column, offset); + m_sourceLocationContainers.emplace_back(filePathId, line, column, offset); } void reserve(std::size_t size) { - SourceFilePathContainerBase::reserve(size); m_sourceLocationContainers.reserve(size); } friend QDataStream &operator<<(QDataStream &out, const SourceLocationsContainer &container) { - out << container.m_filePathHash; out << container.m_sourceLocationContainers; return out; @@ -80,7 +68,6 @@ public: friend QDataStream &operator>>(QDataStream &in, SourceLocationsContainer &container) { - in >> container.m_filePathHash; in >> container.m_sourceLocationContainers; return in; @@ -93,7 +80,7 @@ public: SourceLocationsContainer clone() const { - return SourceLocationsContainer(Utils::clone(m_filePathHash), Utils::clone(m_sourceLocationContainers)); + return *this; } std::vector<V2::SourceLocationContainer> m_sourceLocationContainers; diff --git a/src/libs/clangsupport/sourcerangecontainerv2.h b/src/libs/clangsupport/sourcerangecontainerv2.h index a5dba3ddf1..50d0b96682 100644 --- a/src/libs/clangsupport/sourcerangecontainerv2.h +++ b/src/libs/clangsupport/sourcerangecontainerv2.h @@ -43,15 +43,15 @@ public: { } - SourceRangeContainer(uint fileHash, + SourceRangeContainer(FilePathId filePathId, uint startLine, uint startColumn, uint startOffset, uint endLine, uint endColumn, uint endOffset) - : m_start(fileHash, startLine, startColumn, startOffset), - m_end(fileHash, endLine, endColumn, endOffset) + : m_start(filePathId, startLine, startColumn, startOffset), + m_end(filePathId, endLine, endColumn, endOffset) { } @@ -65,9 +65,9 @@ public: return m_end; } - uint fileHash() const + FilePathId filePathId() const { - return m_start.fileHash(); + return m_start.filePathId(); } friend QDataStream &operator<<(QDataStream &out, const SourceRangeContainer &container) @@ -99,7 +99,7 @@ public: SourceRangeContainer clone() const { - return SourceRangeContainer(m_start.clone(), m_end.clone()); + return *this; } private: diff --git a/src/libs/clangsupport/sourcerangescontainer.cpp b/src/libs/clangsupport/sourcerangescontainer.cpp index ff833be874..9f2752f286 100644 --- a/src/libs/clangsupport/sourcerangescontainer.cpp +++ b/src/libs/clangsupport/sourcerangescontainer.cpp @@ -31,12 +31,11 @@ QDebug operator<<(QDebug debug, const SourceRangesContainer &container) { debug.nospace() << "SourceRangesContainer(["; for (const auto &sourceRangeWithText: container.sourceRangeWithTextContainers()) { - debug.nospace() << "[" - << container.filePathForSourceRange(sourceRangeWithText).name() << ", (" + debug.nospace() << "(" << sourceRangeWithText.start().line() << "," << sourceRangeWithText.start().column() << "), (" << sourceRangeWithText.end().line() << "," - << sourceRangeWithText.end().column() << ")], "; + << sourceRangeWithText.end().column() << "), "; } debug.nospace() << "])"; diff --git a/src/libs/clangsupport/sourcerangescontainer.h b/src/libs/clangsupport/sourcerangescontainer.h index 6968830a6d..dfb5d44bd4 100644 --- a/src/libs/clangsupport/sourcerangescontainer.h +++ b/src/libs/clangsupport/sourcerangescontainer.h @@ -25,30 +25,20 @@ #pragma once -#include "sourcefilepathcontainerbase.h" #include "sourcerangewithtextcontainer.h" #include <utils/smallstringvector.h> namespace ClangBackEnd { -class SourceRangesContainer : public SourceFilePathContainerBase +class SourceRangesContainer { public: SourceRangesContainer() = default; - SourceRangesContainer(std::unordered_map<uint, FilePath> &&filePathHash, - SourceRangeWithTextContainers &&sourceRangeWithTextContainers) - : SourceFilePathContainerBase(std::move(filePathHash)), - m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers)) + SourceRangesContainer(SourceRangeWithTextContainers &&sourceRangeWithTextContainers) + : m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers)) {} - const FilePath &filePathForSourceRange(const SourceRangeWithTextContainer &sourceRange) const - { - auto found = m_filePathHash.find(sourceRange.fileHash()); - - return found->second; - } - const SourceRangeWithTextContainers &sourceRangeWithTextContainers() const { return m_sourceRangeWithTextContainers; @@ -69,7 +59,7 @@ public: return !m_sourceRangeWithTextContainers.empty(); } - void insertSourceRange(uint fileId, + void insertSourceRange(FilePathId filePathId, uint startLine, uint startColumn, uint startOffset, @@ -78,7 +68,7 @@ public: uint endOffset, Utils::SmallString &&text) { - m_sourceRangeWithTextContainers.emplace_back(fileId, + m_sourceRangeWithTextContainers.emplace_back(filePathId, startLine, startColumn, startOffset, @@ -90,13 +80,11 @@ public: void reserve(std::size_t size) { - SourceFilePathContainerBase::reserve(size); m_sourceRangeWithTextContainers.reserve(size); } friend QDataStream &operator<<(QDataStream &out, const SourceRangesContainer &container) { - out << container.m_filePathHash; out << container.m_sourceRangeWithTextContainers; return out; @@ -104,7 +92,6 @@ public: friend QDataStream &operator>>(QDataStream &in, SourceRangesContainer &container) { - in >> container.m_filePathHash; in >> container.m_sourceRangeWithTextContainers; return in; diff --git a/src/libs/clangsupport/sourcerangewithtextcontainer.h b/src/libs/clangsupport/sourcerangewithtextcontainer.h index 4edb231550..dd2d66cb7e 100644 --- a/src/libs/clangsupport/sourcerangewithtextcontainer.h +++ b/src/libs/clangsupport/sourcerangewithtextcontainer.h @@ -35,7 +35,7 @@ class SourceRangeWithTextContainer : public V2::SourceRangeContainer { public: SourceRangeWithTextContainer() = default; - SourceRangeWithTextContainer(uint fileHash, + SourceRangeWithTextContainer(FilePathId filePathId, uint startLine, uint startColumn, uint startOffset, @@ -43,7 +43,7 @@ public: uint endColumn, uint endOffset, Utils::SmallString &&text) - : V2::SourceRangeContainer(fileHash, + : V2::SourceRangeContainer(filePathId, startLine, startColumn, startOffset, @@ -67,7 +67,7 @@ public: using V2::SourceRangeContainer::start; using V2::SourceRangeContainer::end; - using V2::SourceRangeContainer::fileHash; + using V2::SourceRangeContainer::filePathId; friend QDataStream &operator<<(QDataStream &out, const SourceRangeWithTextContainer &container) { diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h index 6d5f4e986b..d3de7fe4dd 100644 --- a/src/libs/clangsupport/stringcache.h +++ b/src/libs/clangsupport/stringcache.h @@ -28,6 +28,7 @@ #include "stringcachealgorithms.h" #include "stringcachefwd.h" +#include <utils/optional.h> #include <utils/smallstringview.h> #include <utils/smallstringfwd.h> @@ -70,15 +71,12 @@ public: } StringType string; - uint id; + IndexType id; }; template <typename StringType, typename IndexType> using StringCacheEntries = std::vector<StringCacheEntry<StringType, IndexType>>; -using FileCacheCacheEntry = StringCacheEntry<Utils::PathString, FilePathIndex>; -using FileCacheCacheEntries = std::vector<FileCacheCacheEntry>; - template <typename StringType, typename IndexType, typename Mutex, @@ -86,25 +84,26 @@ template <typename StringType, Compare compare = Utils::compare> class StringCache { +public: using CacheEntry = StringCacheEntry<StringType, IndexType>; - using CacheEnties = StringCacheEntries<StringType, IndexType>; - using const_iterator = typename CacheEnties::const_iterator; + using CacheEntries = StringCacheEntries<StringType, IndexType>; + using const_iterator = typename CacheEntries::const_iterator; using Found = ClangBackEnd::Found<const_iterator>; -public: - StringCache() + + StringCache(std::size_t reserveSize = 1024) { - m_strings.reserve(1024); - m_indices.reserve(1024); + m_strings.reserve(reserveSize); + m_indices.reserve(reserveSize); } - void populate(CacheEnties &&entries) + void populate(CacheEntries &&entries) { uncheckedPopulate(std::move(entries)); checkEntries(); } - void uncheckedPopulate(CacheEnties &&entries) + void uncheckedPopulate(CacheEntries &&entries) { std::sort(entries.begin(), entries.end(), @@ -149,13 +148,35 @@ public: return stringIds<std::initializer_list<StringType>>(strings); } - Utils::SmallStringView string(IndexType id) const + StringType string(IndexType id) const { std::lock_guard<Mutex> lock(m_mutex); return m_strings.at(m_indices.at(id)).string; } + template<typename Function> + StringType string(IndexType id, Function storageFunction) + { + std::lock_guard<Mutex> lock(m_mutex); + + IndexType index; + + if (IndexType(m_indices.size()) <= id) { + StringType string{storageFunction(id)}; + index = insertString(find(string).iterator, string, id); + } else { + index = m_indices.at(id); + + if (index < 0) { + StringType string{storageFunction(id)}; + index = insertString(find(string).iterator, string, id); + } + } + + return m_strings.at(index).string; + } + std::vector<StringType> strings(const std::vector<IndexType> &ids) const { std::lock_guard<Mutex> lock(m_mutex); @@ -176,13 +197,31 @@ public: return m_strings.empty() && m_indices.empty(); } + template<typename Function> + IndexType stringId(Utils::SmallStringView stringView, Function storageFunction) + { + std::lock_guard<Mutex> lock(m_mutex); + + Found found = find(stringView); + + if (!found.wasFound) + insertString(found.iterator, stringView, storageFunction(stringView)); + + return found.iterator->id; + } + + Mutex &mutex() const + { + return m_mutex; + } + private: IndexType ungardedStringId(Utils::SmallStringView stringView) { Found found = find(stringView); if (!found.wasFound) - return insertString(found.iterator, stringView); + insertString(found.iterator, stringView, IndexType(m_indices.size())); return found.iterator->id; } @@ -202,20 +241,26 @@ private: }); } - IndexType insertString(const_iterator beforeIterator, - Utils::SmallStringView stringView) + void ensureSize(IndexType id) { - auto id = IndexType(m_indices.size()); + if (m_indices.size() <= std::size_t(id)) + m_indices.resize(id + 1, -1); + } + IndexType insertString(const_iterator beforeIterator, + Utils::SmallStringView stringView, + IndexType id) + { auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id); auto newIndex = IndexType(std::distance(m_strings.begin(), inserted)); incrementLargerOrEqualIndicesByOne(newIndex); - m_indices.push_back(newIndex); + ensureSize(id); + m_indices.at(id) = newIndex; - return id; + return newIndex; } void checkEntries() @@ -227,11 +272,9 @@ private: } private: - CacheEnties m_strings; + CacheEntries m_strings; std::vector<IndexType> m_indices; mutable Mutex m_mutex; }; -using FilePathIndices = std::vector<FilePathIndex>; - } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/stringcachefwd.h b/src/libs/clangsupport/stringcachefwd.h index 66448411e1..75f03056b2 100644 --- a/src/libs/clangsupport/stringcachefwd.h +++ b/src/libs/clangsupport/stringcachefwd.h @@ -29,8 +29,6 @@ namespace ClangBackEnd { -using FilePathIndex = long long int; - class NonLockingMutex; template <typename StringType, @@ -39,13 +37,5 @@ template <typename StringType, typename Compare, Compare compare> class StringCache; - -template <typename Mutex = NonLockingMutex> -using FilePathCache = StringCache<Utils::PathString, - FilePathIndex, - Mutex, - decltype(&Utils::reverseCompare), - Utils::reverseCompare>; - } // namespace ClangBackEnd diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri index 67c8c6b937..28f159a0d5 100644 --- a/src/libs/sqlite/sqlite-lib.pri +++ b/src/libs/sqlite/sqlite-lib.pri @@ -17,7 +17,6 @@ SOURCES += \ $$PWD/sqliteglobal.cpp \ $$PWD/sqlitereadstatement.cpp \ $$PWD/sqlitereadwritestatement.cpp \ - $$PWD/sqlitestatement.cpp \ $$PWD/sqlitetransaction.cpp \ $$PWD/sqlitewritestatement.cpp \ $$PWD/sqlstatementbuilder.cpp \ @@ -26,7 +25,8 @@ SOURCES += \ $$PWD/utf8stringvector.cpp \ $$PWD/sqlitedatabase.cpp \ $$PWD/sqlitetable.cpp \ - $$PWD/sqlitecolumn.cpp + $$PWD/sqlitecolumn.cpp \ + $$PWD/sqlitebasestatement.cpp HEADERS += \ $$PWD/createtablesqlstatementbuilder.h \ $$PWD/sqlitedatabasebackend.h \ @@ -34,7 +34,6 @@ HEADERS += \ $$PWD/sqliteglobal.h \ $$PWD/sqlitereadstatement.h \ $$PWD/sqlitereadwritestatement.h \ - $$PWD/sqlitestatement.h \ $$PWD/sqlitetransaction.h \ $$PWD/sqlitewritestatement.h \ $$PWD/sqlstatementbuilder.h \ @@ -44,7 +43,8 @@ HEADERS += \ $$PWD/sqlitedatabase.h \ $$PWD/sqlitetable.h \ $$PWD/sqlitecolumn.h \ - $$PWD/sqliteindex.h + $$PWD/sqliteindex.h \ + $$PWD/sqlitebasestatement.h DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA diff --git a/src/libs/sqlite/sqlitestatement.cpp b/src/libs/sqlite/sqlitebasestatement.cpp index 0e70b5aaca..3f41c04a11 100644 --- a/src/libs/sqlite/sqlitestatement.cpp +++ b/src/libs/sqlite/sqlitebasestatement.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ -#include "sqlitestatement.h" +#include "sqlitebasestatement.h" #include "sqlitedatabase.h" #include "sqlitedatabasebackend.h" @@ -40,7 +40,7 @@ namespace Sqlite { -Statement::Statement(Utils::SmallStringView sqlStatement, Database &database) +BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database) : m_compiledStatement(nullptr, deleteCompiledStatement), m_database(database), m_bindingParameterCount(0), @@ -49,11 +49,10 @@ Statement::Statement(Utils::SmallStringView sqlStatement, Database &database) { prepare(sqlStatement); setBindingParameterCount(); - setBindingColumnNamesFromStatement(); setColumnCount(); } -void Statement::deleteCompiledStatement(sqlite3_stmt *compiledStatement) +void BaseStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement) { if (compiledStatement) sqlite3_finalize(compiledStatement); @@ -92,7 +91,7 @@ private: std::mutex m_mutex; }; -void Statement::waitForUnlockNotify() const +void BaseStatement::waitForUnlockNotify() const { UnlockNotification unlockNotification; int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(), @@ -105,7 +104,7 @@ void Statement::waitForUnlockNotify() const unlockNotification.wait(); } -void Statement::reset() const +void BaseStatement::reset() const { int resultCode = sqlite3_reset(m_compiledStatement.get()); switch (resultCode) { @@ -119,7 +118,7 @@ void Statement::reset() const m_isReadyToFetchValues = false; } -bool Statement::next() const +bool BaseStatement::next() const { int resultCode; @@ -137,26 +136,26 @@ bool Statement::next() const return checkForStepError(resultCode); } -void Statement::step() const +void BaseStatement::step() const { next(); } -void Statement::execute() const +void BaseStatement::execute() const { next(); reset(); } -int Statement::columnCount() const +int BaseStatement::columnCount() const { return m_columnCount; } -Utils::SmallStringVector Statement::columnNames() const +Utils::SmallStringVector BaseStatement::columnNames() const { Utils::SmallStringVector columnNames; - int columnCount = Statement::columnCount(); + int columnCount = BaseStatement::columnCount(); columnNames.reserve(std::size_t(columnCount)); for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) columnNames.emplace_back(sqlite3_column_origin_name(m_compiledStatement.get(), columnIndex)); @@ -164,25 +163,25 @@ Utils::SmallStringVector Statement::columnNames() const return columnNames; } -void Statement::bind(int index, int value) +void BaseStatement::bind(int index, int value) { int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value); checkForBindingError(resultCode); } -void Statement::bind(int index, long long value) +void BaseStatement::bind(int index, long long value) { int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value); checkForBindingError(resultCode); } -void Statement::bind(int index, double value) +void BaseStatement::bind(int index, double value) { int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value); checkForBindingError(resultCode); } -void Statement::bind(int index, Utils::SmallStringView text) +void BaseStatement::bind(int index, Utils::SmallStringView text) { int resultCode = sqlite3_bind_text(m_compiledStatement.get(), index, @@ -193,35 +192,25 @@ void Statement::bind(int index, Utils::SmallStringView text) } template <typename Type> -void Statement::bind(Utils::SmallStringView name, Type value) +void BaseStatement::bind(Utils::SmallStringView name, Type value) { int index = bindingIndexForName(name); checkBindingName(index); bind(index, value); } -template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, int value); -template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long value); -template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long long value); -template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, double value); -template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, Utils::SmallStringView text); +template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, int value); +template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, long value); +template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, long long value); +template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, double value); +template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, Utils::SmallStringView text); -int Statement::bindingIndexForName(Utils::SmallStringView name) const +int BaseStatement::bindingIndexForName(Utils::SmallStringView name) const { return sqlite3_bind_parameter_index(m_compiledStatement.get(), name.data()); } -void Statement::setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames) -{ - m_bindingColumnNames = bindingColumnNames; -} - -const Utils::SmallStringVector &Statement::bindingColumnNames() const -{ - return m_bindingColumnNames; -} - -void Statement::prepare(Utils::SmallStringView sqlStatement) +void BaseStatement::prepare(Utils::SmallStringView sqlStatement) { int resultCode; @@ -242,17 +231,17 @@ void Statement::prepare(Utils::SmallStringView sqlStatement) checkForPrepareError(resultCode); } -sqlite3 *Statement::sqliteDatabaseHandle() const +sqlite3 *BaseStatement::sqliteDatabaseHandle() const { return m_database.backend().sqliteDatabaseHandle(); } -TextEncoding Statement::databaseTextEncoding() +TextEncoding BaseStatement::databaseTextEncoding() { return m_database.backend().textEncoding(); } -bool Statement::checkForStepError(int resultCode) const +bool BaseStatement::checkForStepError(int resultCode) const { switch (resultCode) { case SQLITE_ROW: return true; @@ -268,7 +257,7 @@ bool Statement::checkForStepError(int resultCode) const Q_UNREACHABLE(); } -void Statement::checkForPrepareError(int resultCode) const +void BaseStatement::checkForPrepareError(int resultCode) const { switch (resultCode) { case SQLITE_OK: return; @@ -280,7 +269,7 @@ void Statement::checkForPrepareError(int resultCode) const throwUnknowError("SqliteStatement::prepareStatement: unknown error has happened"); } -void Statement::checkForBindingError(int resultCode) const +void BaseStatement::checkForBindingError(int resultCode) const { switch (resultCode) { case SQLITE_OK: return; @@ -292,7 +281,7 @@ void Statement::checkForBindingError(int resultCode) const throwUnknowError("SqliteStatement::bind: unknown error has happened"); } -void Statement::setIfIsReadyToFetchValues(int resultCode) const +void BaseStatement::setIfIsReadyToFetchValues(int resultCode) const { if (resultCode == SQLITE_ROW) m_isReadyToFetchValues = true; @@ -301,13 +290,13 @@ void Statement::setIfIsReadyToFetchValues(int resultCode) const } -void Statement::checkIfIsReadyToFetchValues() const +void BaseStatement::checkIfIsReadyToFetchValues() const { if (!m_isReadyToFetchValues) throwNoValuesToFetch("SqliteStatement::value: there are no values to fetch!"); } -void Statement::checkColumnsAreValid(const std::vector<int> &columns) const +void BaseStatement::checkColumnsAreValid(const std::vector<int> &columns) const { for (int column : columns) { if (column < 0 || column >= m_columnCount) @@ -315,19 +304,19 @@ void Statement::checkColumnsAreValid(const std::vector<int> &columns) const } } -void Statement::checkColumnIsValid(int column) const +void BaseStatement::checkColumnIsValid(int column) const { if (column < 0 || column >= m_columnCount) throwInvalidColumnFetched("SqliteStatement::values: column index out of bound!"); } -void Statement::checkBindingName(int index) const +void BaseStatement::checkBindingName(int index) const { if (index <= 0 || index > m_bindingParameterCount) throwWrongBingingName("SqliteStatement::bind: binding name are not exists in this statement!"); } -void Statement::setBindingParameterCount() +void BaseStatement::setBindingParameterCount() { m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get()); } @@ -340,65 +329,57 @@ Utils::SmallStringView chopFirstLetter(const char *rawBindingName) return Utils::SmallStringView(""); } -void Statement::setBindingColumnNamesFromStatement() -{ - for (int index = 1; index <= m_bindingParameterCount; index++) { - Utils::SmallStringView bindingName = chopFirstLetter(sqlite3_bind_parameter_name(m_compiledStatement.get(), index)); - m_bindingColumnNames.push_back(Utils::SmallString(bindingName)); - } -} - -void Statement::setColumnCount() +void BaseStatement::setColumnCount() { m_columnCount = sqlite3_column_count(m_compiledStatement.get()); } -bool Statement::isReadOnlyStatement() const +bool BaseStatement::isReadOnlyStatement() const { return sqlite3_stmt_readonly(m_compiledStatement.get()); } -void Statement::throwStatementIsBusy(const char *whatHasHappened) const +void BaseStatement::throwStatementIsBusy(const char *whatHasHappened) const { throw StatementIsBusy(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void Statement::throwStatementHasError(const char *whatHasHappened) const +void BaseStatement::throwStatementHasError(const char *whatHasHappened) const { throw StatementHasError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void Statement::throwStatementIsMisused(const char *whatHasHappened) const +void BaseStatement::throwStatementIsMisused(const char *whatHasHappened) const { throw StatementIsMisused(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void Statement::throwConstraintPreventsModification(const char *whatHasHappened) const +void BaseStatement::throwConstraintPreventsModification(const char *whatHasHappened) const { throw ContraintPreventsModification(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void Statement::throwNoValuesToFetch(const char *whatHasHappened) const +void BaseStatement::throwNoValuesToFetch(const char *whatHasHappened) const { throw NoValuesToFetch(whatHasHappened); } -void Statement::throwInvalidColumnFetched(const char *whatHasHappened) const +void BaseStatement::throwInvalidColumnFetched(const char *whatHasHappened) const { throw InvalidColumnFetched(whatHasHappened); } -void Statement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) const +void BaseStatement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) const { throw BindingIndexIsOutOfRange(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void Statement::throwWrongBingingName(const char *whatHasHappened) const +void BaseStatement::throwWrongBingingName(const char *whatHasHappened) const { - throw WrongBingingName(whatHasHappened); + throw WrongBindingName(whatHasHappened); } -void Statement::throwUnknowError(const char *whatHasHappened) const +void BaseStatement::throwUnknowError(const char *whatHasHappened) const { if (sqliteDatabaseHandle()) throw UnknowError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); @@ -406,17 +387,17 @@ void Statement::throwUnknowError(const char *whatHasHappened) const throw UnknowError(whatHasHappened); } -void Statement::throwBingingTooBig(const char *whatHasHappened) const +void BaseStatement::throwBingingTooBig(const char *whatHasHappened) const { throw BindingTooBig(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -QString Statement::columnName(int column) const +QString BaseStatement::columnName(int column) const { return QString::fromUtf8(sqlite3_column_name(m_compiledStatement.get(), column)); } -Database &Statement::database() const +Database &BaseStatement::database() const { return m_database; } @@ -445,7 +426,7 @@ static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column) Q_UNREACHABLE(); } -int Statement::fetchIntValue(int column) const +int BaseStatement::fetchIntValue(int column) const { checkIfIsReadyToFetchValues(); checkColumnIsValid(column); @@ -453,23 +434,23 @@ int Statement::fetchIntValue(int column) const } template<> -int Statement::fetchValue<int>(int column) const +int BaseStatement::fetchValue<int>(int column) const { return fetchIntValue(column); } -long Statement::fetchLongValue(int column) const +long BaseStatement::fetchLongValue(int column) const { return long(fetchValue<long long>(column)); } template<> -long Statement::fetchValue<long>(int column) const +long BaseStatement::fetchValue<long>(int column) const { return fetchLongValue(column); } -long long Statement::fetchLongLongValue(int column) const +long long BaseStatement::fetchLongLongValue(int column) const { checkIfIsReadyToFetchValues(); checkColumnIsValid(column); @@ -477,12 +458,12 @@ long long Statement::fetchLongLongValue(int column) const } template<> -long long Statement::fetchValue<long long>(int column) const +long long BaseStatement::fetchValue<long long>(int column) const { return fetchLongLongValue(column); } -double Statement::fetchDoubleValue(int column) const +double BaseStatement::fetchDoubleValue(int column) const { checkIfIsReadyToFetchValues(); checkColumnIsValid(column); @@ -490,62 +471,30 @@ double Statement::fetchDoubleValue(int column) const } template<> -double Statement::fetchValue<double>(int column) const +double BaseStatement::fetchValue<double>(int column) const { return fetchDoubleValue(column); } template<typename StringType> -StringType Statement::fetchValue(int column) const +StringType BaseStatement::fetchValue(int column) const { checkIfIsReadyToFetchValues(); checkColumnIsValid(column); return convertToTextForColumn<StringType>(m_compiledStatement.get(), column); } -Utils::SmallString Statement::fetchSmallStringValue(int column) const +Utils::SmallString BaseStatement::fetchSmallStringValue(int column) const { return fetchValue<Utils::SmallString>(column); } -Utils::PathString Statement::fetchPathStringValue(int column) const +Utils::PathString BaseStatement::fetchPathStringValue(int column) const { return fetchValue<Utils::PathString>(column); } -template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const; -template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const; - -Utils::SmallString Statement::text(int column) const -{ - return fetchValue<Utils::SmallString>(column); -} - -template <typename ContainerType> -ContainerType Statement::columnValues(const std::vector<int> &columnIndices) const -{ - using ElementType = typename ContainerType::value_type; - ContainerType valueContainer; - valueContainer.reserve(columnIndices.size()); - for (int columnIndex : columnIndices) - valueContainer.push_back(fetchValue<ElementType>(columnIndex)); - - return valueContainer; -} - -template <typename Type> -Type Statement::toValue(Utils::SmallStringView sqlStatement, Database &database) -{ - Statement statement(sqlStatement, database); - - statement.next(); - - return statement.fetchValue<Type>(0); -} - -template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database); -template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::SmallStringView sqlStatement, Database &database); -template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database); -template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database); +template SQLITE_EXPORT Utils::SmallString BaseStatement::fetchValue<Utils::SmallString>(int column) const; +template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue<Utils::PathString>(int column) const; } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitebasestatement.h index 3e93b7ba8d..bf6dfd4e5e 100644 --- a/src/libs/sqlite/sqlitestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -48,10 +48,10 @@ namespace Sqlite { class Database; class DatabaseBackend; -class SQLITE_EXPORT Statement +class SQLITE_EXPORT BaseStatement { -protected: - explicit Statement(Utils::SmallStringView sqlStatement, Database &database); +public: + explicit BaseStatement(Utils::SmallStringView sqlStatement, Database &database); static void deleteCompiledStatement(sqlite3_stmt *m_compiledStatement); @@ -68,7 +68,6 @@ protected: Utils::PathString fetchPathStringValue(int column) const; template<typename Type> Type fetchValue(int column) const; - Utils::SmallString text(int column) const; int columnCount() const; Utils::SmallStringVector columnNames() const; @@ -87,6 +86,71 @@ protected: bind(index, static_cast<long long>(value)); } + template <typename Type> + void bind(Utils::SmallStringView name, Type fetchValue); + + int bindingIndexForName(Utils::SmallStringView name) const; + + void prepare(Utils::SmallStringView sqlStatement); + void waitForUnlockNotify() const; + + sqlite3 *sqliteDatabaseHandle() const; + TextEncoding databaseTextEncoding(); + + bool checkForStepError(int resultCode) const; + void checkForPrepareError(int resultCode) const; + void checkForBindingError(int resultCode) const; + void setIfIsReadyToFetchValues(int resultCode) const; + void checkIfIsReadyToFetchValues() const; + void checkColumnsAreValid(const std::vector<int> &columns) const; + void checkColumnIsValid(int column) const; + void checkBindingName(int index) const; + void setBindingParameterCount(); + void setColumnCount(); + bool isReadOnlyStatement() const; + [[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const; + [[noreturn]] void throwStatementHasError(const char *whatHasHappened) const; + [[noreturn]] void throwStatementIsMisused(const char *whatHasHappened) const; + [[noreturn]] void throwConstraintPreventsModification(const char *whatHasHappened) const; + [[noreturn]] void throwNoValuesToFetch(const char *whatHasHappened) const; + [[noreturn]] void throwInvalidColumnFetched(const char *whatHasHappened) const; + [[noreturn]] void throwBindingIndexIsOutOfRange(const char *whatHasHappened) const; + [[noreturn]] void throwWrongBingingName(const char *whatHasHappened) const; + [[noreturn]] void throwUnknowError(const char *whatHasHappened) const; + [[noreturn]] void throwBingingTooBig(const char *whatHasHappened) const; + + QString columnName(int column) const; + + Database &database() const; + +private: + std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement; + Database &m_database; + int m_bindingParameterCount; + int m_columnCount; + mutable bool m_isReadyToFetchValues; +}; + +extern template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, int value); +extern template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, long value); +extern template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, long long value); +extern template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, double value); +extern template SQLITE_EXPORT void BaseStatement::bind(Utils::SmallStringView name, Utils::SmallStringView text); + +template <> SQLITE_EXPORT int BaseStatement::fetchValue<int>(int column) const; +template <> SQLITE_EXPORT long BaseStatement::fetchValue<long>(int column) const; +template <> SQLITE_EXPORT long long BaseStatement::fetchValue<long long>(int column) const; +template <> SQLITE_EXPORT double BaseStatement::fetchValue<double>(int column) const; +extern template SQLITE_EXPORT Utils::SmallString BaseStatement::fetchValue<Utils::SmallString>(int column) const; +extern template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue<Utils::PathString>(int column) const; + +template <typename BaseStatement> +class SQLITE_EXPORT StatementImplementation : public BaseStatement +{ + +public: + using BaseStatement::BaseStatement; + void bindValues() { } @@ -101,7 +165,7 @@ protected: void write(const ValueType&... values) { bindValuesByIndex(1, values...); - execute(); + BaseStatement::execute(); } template<typename... ValueType> @@ -114,29 +178,20 @@ protected: void writeNamed(const ValueType&... values) { bindValuesByName(values...); - execute(); + BaseStatement::execute(); } - template <typename Type> - void bind(Utils::SmallStringView name, Type fetchValue); - - int bindingIndexForName(Utils::SmallStringView name) const; - - void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames); - const Utils::SmallStringVector &bindingColumnNames() const; - template <typename ResultType, int ResultTypeCount = 1> std::vector<ResultType> values(std::size_t reserveSize) { + Resetter resetter{*this}; std::vector<ResultType> resultValues; resultValues.reserve(reserveSize); - while (next()) + while (BaseStatement::next()) emplaceBackValues<ResultTypeCount>(resultValues); - reset(); - return resultValues; } @@ -145,16 +200,15 @@ protected: typename... QueryTypes> std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues) { + Resetter resetter{*this}; std::vector<ResultType> resultValues; resultValues.reserve(reserveSize); bindValues(queryValues...); - while (next()) + while (BaseStatement::next()) emplaceBackValues<ResultTypeCount>(resultValues); - reset(); - return resultValues; } @@ -162,18 +216,17 @@ protected: int ResultTypeCount = 1, typename QueryElementType> std::vector<ResultType> values(std::size_t reserveSize, - const std::vector<QueryElementType> &queryValues) + const std::vector<QueryElementType> &queryValues) { std::vector<ResultType> resultValues; resultValues.reserve(reserveSize); for (const QueryElementType &queryValue : queryValues) { + Resetter resetter{*this}; bindValues(queryValue); - while (next()) + while (BaseStatement::next()) emplaceBackValues<ResultTypeCount>(resultValues); - - reset(); } return resultValues; @@ -183,19 +236,18 @@ protected: int ResultTypeCount = 1, typename... QueryElementTypes> std::vector<ResultType> values(std::size_t reserveSize, - const std::vector<std::tuple<QueryElementTypes...>> &queryTuples) + const std::vector<std::tuple<QueryElementTypes...>> &queryTuples) { using Container = std::vector<ResultType>; Container resultValues; resultValues.reserve(reserveSize); for (const auto &queryTuple : queryTuples) { + Resetter resetter{*this}; bindTupleValues(queryTuple); - while (next()) + while (BaseStatement::next()) emplaceBackValues<ResultTypeCount>(resultValues); - - reset(); } return resultValues; @@ -204,68 +256,48 @@ protected: template <typename ResultType, int ResultTypeCount = 1, typename... QueryTypes> - Utils::optional<ResultType> value( const QueryTypes&... queryValues) + Utils::optional<ResultType> value(const QueryTypes&... queryValues) { + Resetter resetter{*this}; Utils::optional<ResultType> resultValue; bindValues(queryValues...); - if (next()) + if (BaseStatement::next()) resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>(); - reset(); - return resultValue; } template <typename Type> - static Type toValue(Utils::SmallStringView sqlStatement, Database &database); - - void prepare(Utils::SmallStringView sqlStatement); - void waitForUnlockNotify() const; + static Type toValue(Utils::SmallStringView sqlStatement, Database &database) + { + StatementImplementation statement(sqlStatement, database); - sqlite3 *sqliteDatabaseHandle() const; - TextEncoding databaseTextEncoding(); + statement.next(); - bool checkForStepError(int resultCode) const; - void checkForPrepareError(int resultCode) const; - void checkForBindingError(int resultCode) const; - void setIfIsReadyToFetchValues(int resultCode) const; - void checkIfIsReadyToFetchValues() const; - void checkColumnsAreValid(const std::vector<int> &columns) const; - void checkColumnIsValid(int column) const; - void checkBindingName(int index) const; - void setBindingParameterCount(); - void setBindingColumnNamesFromStatement(); - void setColumnCount(); - bool isReadOnlyStatement() const; - [[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const; - [[noreturn]] void throwStatementHasError(const char *whatHasHappened) const; - [[noreturn]] void throwStatementIsMisused(const char *whatHasHappened) const; - [[noreturn]] void throwConstraintPreventsModification(const char *whatHasHappened) const; - [[noreturn]] void throwNoValuesToFetch(const char *whatHasHappened) const; - [[noreturn]] void throwInvalidColumnFetched(const char *whatHasHappened) const; - [[noreturn]] void throwBindingIndexIsOutOfRange(const char *whatHasHappened) const; - [[noreturn]] void throwWrongBingingName(const char *whatHasHappened) const; - [[noreturn]] void throwUnknowError(const char *whatHasHappened) const; - [[noreturn]] void throwBingingTooBig(const char *whatHasHappened) const; + return statement.template fetchValue<Type>(0); + } - template <typename ContainerType> - ContainerType columnValues(const std::vector<int> &columnIndices) const; - QString columnName(int column) const; +private: + struct Resetter + { + Resetter(StatementImplementation &statement) + : statement(statement) + {} - Database &database() const; + ~Resetter() + { + statement.reset(); + } -protected: - explicit Statement(Utils::SmallStringView sqlStatement, - DatabaseBackend &databaseBackend); + StatementImplementation &statement; + }; -private: - class ValueGetter + struct ValueGetter { - public: - ValueGetter(Statement &statement, int column) + ValueGetter(StatementImplementation &statement, int column) : statement(statement), column(column) {} @@ -300,7 +332,7 @@ private: return statement.fetchPathStringValue(column); } - Statement &statement; + StatementImplementation &statement; int column; }; @@ -335,26 +367,26 @@ private: template<typename ValueType> void bindValuesByIndex(int index, const ValueType &value) { - bind(index, value); + BaseStatement::bind(index, value); } template<typename ValueType, typename... ValueTypes> void bindValuesByIndex(int index, const ValueType &value, const ValueTypes&... values) { - bind(index, value); + BaseStatement::bind(index, value); bindValuesByIndex(index + 1, values...); } template<typename ValueType> void bindValuesByName(Utils::SmallStringView name, const ValueType &value) { - bind(bindingIndexForName(name), value); + BaseStatement::bind(BaseStatement::bindingIndexForName(name), value); } template<typename ValueType, typename... ValueTypes> void bindValuesByName(Utils::SmallStringView name, const ValueType &value, const ValueTypes&... values) { - bind(bindingIndexForName(name), value); + BaseStatement::bind(BaseStatement::bindingIndexForName(name), value); bindValuesByName(values...); } @@ -371,30 +403,6 @@ private: bindTupleValuesElement(element, ColumnIndices()); } -private: - std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement; - Utils::SmallStringVector m_bindingColumnNames; - Database &m_database; - int m_bindingParameterCount; - int m_columnCount; - mutable bool m_isReadyToFetchValues; }; -extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, int value); -extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long value); -extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long long value); -extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, double value); -extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, Utils::SmallStringView text); - -extern template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database); -extern template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::SmallStringView sqlStatement, Database &database); -extern template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database); -extern template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database); - -template <> SQLITE_EXPORT int Statement::fetchValue<int>(int column) const; -template <> SQLITE_EXPORT long Statement::fetchValue<long>(int column) const; -template <> SQLITE_EXPORT long long Statement::fetchValue<long long>(int column) const; -template <> SQLITE_EXPORT double Statement::fetchValue<double>(int column) const; -extern template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const; -extern template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const; } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp index 5c4fc95e73..928eb2b1d1 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.cpp +++ b/src/libs/sqlite/sqlitedatabasebackend.cpp @@ -28,7 +28,7 @@ #include "sqliteexception.h" #include "sqlitereadstatement.h" #include "sqlitereadwritestatement.h" -#include "sqlitestatement.h" +#include "sqlitebasestatement.h" #include "sqlitewritestatement.h" #include <QFileInfo> diff --git a/src/libs/sqlite/sqliteexception.h b/src/libs/sqlite/sqliteexception.h index 319141d257..3d6dfb5129 100644 --- a/src/libs/sqlite/sqliteexception.h +++ b/src/libs/sqlite/sqliteexception.h @@ -125,10 +125,10 @@ public: } }; -class WrongBingingName : public Exception +class WrongBindingName : public Exception { public: - WrongBingingName(const char *whatErrorHasHappen) + WrongBindingName(const char *whatErrorHasHappen) : Exception(whatErrorHasHappen) { } diff --git a/src/libs/sqlite/sqlitereadstatement.cpp b/src/libs/sqlite/sqlitereadstatement.cpp index 9af95f1cff..91e672985b 100644 --- a/src/libs/sqlite/sqlitereadstatement.cpp +++ b/src/libs/sqlite/sqlitereadstatement.cpp @@ -31,7 +31,7 @@ namespace Sqlite { ReadStatement::ReadStatement(Utils::SmallStringView sqlStatement, Database &database) - : Statement(sqlStatement, database) + : StatementImplementation(sqlStatement, database) { checkIsReadOnlyStatement(); } diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h index 828d1f7c37..310f91fbc9 100644 --- a/src/libs/sqlite/sqlitereadstatement.h +++ b/src/libs/sqlite/sqlitereadstatement.h @@ -25,19 +25,18 @@ #pragma once -#include "sqlitestatement.h" +#include "sqlitebasestatement.h" namespace Sqlite { -class SQLITE_EXPORT ReadStatement final : private Statement +class SQLITE_EXPORT ReadStatement final : protected StatementImplementation<BaseStatement> { public: explicit ReadStatement(Utils::SmallStringView sqlStatement, Database &database); - using Statement::value; - using Statement::values; - using Statement::toValue; - using Statement::database; + using StatementImplementation::value; + using StatementImplementation::values; + using StatementImplementation::toValue; protected: void checkIsReadOnlyStatement(); diff --git a/src/libs/sqlite/sqlitereadwritestatement.cpp b/src/libs/sqlite/sqlitereadwritestatement.cpp index 74190deae1..8910ffd7f0 100644 --- a/src/libs/sqlite/sqlitereadwritestatement.cpp +++ b/src/libs/sqlite/sqlitereadwritestatement.cpp @@ -29,7 +29,7 @@ namespace Sqlite { ReadWriteStatement::ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database) - : Statement(sqlStatement, database) + : StatementImplementation(sqlStatement, database) { } diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h index 8645a6eae8..c81ed628b2 100644 --- a/src/libs/sqlite/sqlitereadwritestatement.h +++ b/src/libs/sqlite/sqlitereadwritestatement.h @@ -25,24 +25,23 @@ #pragma once -#include "sqlitestatement.h" +#include "sqlitebasestatement.h" namespace Sqlite { -class SQLITE_EXPORT ReadWriteStatement final : private Statement +class SQLITE_EXPORT ReadWriteStatement final : protected StatementImplementation<BaseStatement> { friend class DatabaseBackend; public: ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database); - using Statement::execute; - using Statement::value; - using Statement::values; - using Statement::toValue; - using Statement::database; - using Statement::write; - using Statement::writeNamed; + using StatementImplementation::execute; + using StatementImplementation::value; + using StatementImplementation::values; + using StatementImplementation::toValue; + using StatementImplementation::write; + using StatementImplementation::writeNamed; }; } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitewritestatement.cpp b/src/libs/sqlite/sqlitewritestatement.cpp index 26c8522b8a..89fce7abf3 100644 --- a/src/libs/sqlite/sqlitewritestatement.cpp +++ b/src/libs/sqlite/sqlitewritestatement.cpp @@ -29,7 +29,7 @@ namespace Sqlite { WriteStatement::WriteStatement(Utils::SmallStringView sqlStatement, Database &database) - : Statement(sqlStatement, database) + : StatementImplementation(sqlStatement, database) { checkIsWritableStatement(); } diff --git a/src/libs/sqlite/sqlitewritestatement.h b/src/libs/sqlite/sqlitewritestatement.h index ec00ae4e8f..24cf5a8742 100644 --- a/src/libs/sqlite/sqlitewritestatement.h +++ b/src/libs/sqlite/sqlitewritestatement.h @@ -25,19 +25,19 @@ #pragma once -#include "sqlitestatement.h" +#include "sqlitebasestatement.h" namespace Sqlite { -class SQLITE_EXPORT WriteStatement : private Statement +class SQLITE_EXPORT WriteStatement : protected StatementImplementation<BaseStatement> { public: explicit WriteStatement(Utils::SmallStringView sqlStatement, Database &database); - using Statement::execute; - using Statement::database; - using Statement::write; - using Statement::writeNamed; + using StatementImplementation::execute; + using StatementImplementation::database; + using StatementImplementation::write; + using StatementImplementation::writeNamed; protected: void checkIsWritableStatement(); diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index 5b30662592..f358609258 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -145,25 +145,7 @@ public: BasicSmallString(std::initializer_list<Utils::SmallStringView> list) : m_data(Internal::StringDataLayout<Size>()) { - std::size_t size = std::accumulate(list.begin(), - list.end(), - std::size_t(0), - [] (std::size_t size, Utils::SmallStringView string) { - return size + string.size(); - }); - - reserve(size); - setSize(size); - - char *currentData = data(); - - for (Utils::SmallStringView string : list) { - std::memcpy(currentData, string.data(), string.size()); - - currentData += string.size(); - } - - at(size) = 0; + appendInitializerList(list, 0); } ~BasicSmallString() noexcept @@ -478,6 +460,13 @@ public: return *this; } + BasicSmallString &operator+=(std::initializer_list<SmallStringView> list) + { + appendInitializerList(list, size()); + + return *this; + } + void replace(SmallStringView fromText, SmallStringView toText) { if (toText.size() == fromText.size()) @@ -690,6 +679,27 @@ private: { } + void appendInitializerList(std::initializer_list<SmallStringView> list, std::size_t initialSize) + { + auto addSize = [] (std::size_t size, Utils::SmallStringView string) { + return size + string.size(); + }; + + std::size_t size = std::accumulate(list.begin(), list.end(), initialSize, addSize); + + reserve(size); + setSize(size); + + char *currentData = data() + initialSize; + + for (Utils::SmallStringView string : list) { + std::memcpy(currentData, string.data(), string.size()); + currentData += string.size(); + } + + at(size) = 0; + } + void initializeLongString(size_type size, size_type capacity) { m_data.allocated.data.pointer[size] = 0; diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h index 3d479195f1..39cb86b193 100644 --- a/src/libs/utils/smallstringview.h +++ b/src/libs/utils/smallstringview.h @@ -193,15 +193,16 @@ inline int reverse_memcmp(const char *first, const char *second, size_t n) { - const char *currentFirst = first + n; - const char *currentSecond = second + n; + const char *currentFirst = first + n - 1; + const char *currentSecond = second + n - 1; while (n > 0) { // If the current characters differ, return an appropriately signed // value; otherwise, keep searching backwards - if (*currentFirst != *currentSecond) - return *currentFirst - *currentSecond; + int difference = *currentFirst - *currentSecond; + if (difference != 0) + return difference; --currentFirst; --currentSecond; diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp index a2638212d6..ac5a96ee88 100644 --- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp +++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp @@ -33,8 +33,15 @@ #include <coreplugin/find/searchresultwindow.h> #include <extensionsystem/pluginmanager.h> +#include <refactoringdatabaseinitializer.h> +#include <filepathcaching.h> + +#include <sqlitedatabase.h> + #include <utils/hostosinfo.h> +#include <QDir> + namespace ClangRefactoring { namespace { @@ -54,9 +61,12 @@ class ClangRefactoringPluginData { using ProjectUpdater = ClangPchManager::QtCreatorProjectUpdater<ClangPchManager::ProjectUpdater>; public: + Sqlite::Database database{Utils::PathString{QDir::tempPath() + "/symbol.db"}}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; RefactoringClient refactoringClient; ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient}; - RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient}; + RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient, filePathCache}; QtCreatorSearch qtCreatorSearch{*Core::SearchResultWindow::instance()}; QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(), qtCreatorSearch, diff --git a/src/plugins/clangrefactoring/querysqlitestatementfactory.h b/src/plugins/clangrefactoring/querysqlitestatementfactory.h index dec404f89b..b2a7f97cb8 100644 --- a/src/plugins/clangrefactoring/querysqlitestatementfactory.h +++ b/src/plugins/clangrefactoring/querysqlitestatementfactory.h @@ -40,14 +40,9 @@ public: {} Database &database; ReadStatement selectLocationsForSymbolLocation{ - "SELECT sourceId, line, column FROM locations WHERE symbolId = " - " (SELECT symbolId FROM locations WHERE sourceId=" - " (SELECT sourceId FROM sources WHERE sourcePath =?)" - " AND line=? AND column=?) " + "SELECT directoryId, sourceId, line, column FROM locations JOIN sources USING(sourceId) WHERE symbolId = " + " (SELECT symbolId FROM locations WHERE sourceId=? AND line=? AND column=?) " "ORDER BY sourceId, line, column", - database}; // alternatively SELECT l2.symbolid, l2.sourceId, l2.line, l2.column FROM locations AS l2, sources, locations AS l1 ON sources.sourceId = l1.sourceId AND l2.symbolId=l1.symbolId WHERE sourcePath = ? AND l1.line=? AND l1.column=? ORDER BY l2.sourceId, l2.line, l2.column - ReadStatement selectSourcePathForId{ - "SELECT sourceId, sourcePath FROM sources WHERE sourceId = ?", database}; }; diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp index 189e2bd480..5c544e5a22 100644 --- a/src/plugins/clangrefactoring/refactoringclient.cpp +++ b/src/plugins/clangrefactoring/refactoringclient.cpp @@ -28,8 +28,9 @@ #include "clangqueryhighlighter.h" #include "clangqueryexamplehighlighter.h" -#include <refactoringconnectionclient.h> #include <clangrefactoringmessages.h> +#include <filepathcachinginterface.h> +#include <refactoringconnectionclient.h> namespace ClangRefactoring { @@ -43,8 +44,8 @@ void RefactoringClient::sourceLocationsForRenamingMessage( ClangBackEnd::SourceLocationsForRenamingMessage &&message) { m_localRenamingCallback(message.symbolName().toQString(), - message.sourceLocations(), - message.textDocumentRevision()); + message.sourceLocations(), + message.textDocumentRevision()); m_refactoringEngine->setUsable(true); } @@ -122,45 +123,24 @@ void RefactoringClient::setRefactoringConnectionClient( m_connectionClient = connectionClient; } -std::unordered_map<uint, QString> RefactoringClient::convertFilePaths( - const ClangBackEnd::FilePathDict &filePaths) -{ - using Dict = std::unordered_map<uint, QString>; - Dict qstringFilePaths; - qstringFilePaths.reserve(filePaths.size()); - - auto convertFilePath = [] (const ClangBackEnd::FilePathDict::value_type &dictonaryEntry) { - return std::make_pair(dictonaryEntry.first, - dictonaryEntry.second.path().toQString()); - }; - - std::transform(filePaths.begin(), - filePaths.end(), - std::inserter(qstringFilePaths, qstringFilePaths.begin()), - convertFilePath); - - return qstringFilePaths; -} - void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContainer &sourceRanges) { - auto filePaths = convertFilePaths(sourceRanges.filePaths()); - for (const auto &sourceRangeWithText : sourceRanges.sourceRangeWithTextContainers()) - addSearchResult(sourceRangeWithText, filePaths); + addSearchResult(sourceRangeWithText); } -void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText, - std::unordered_map<uint, QString> &filePaths) +void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText) { - m_searchHandle->addResult(filePaths[sourceRangeWithText.fileHash()], - QString(sourceRangeWithText.text()), - {{int(sourceRangeWithText.start().line()), - int(sourceRangeWithText.start().column() - 1), - int(sourceRangeWithText.start().offset())}, - {int(sourceRangeWithText.end().line()), - int(sourceRangeWithText.end().column() - 1), - int(sourceRangeWithText.end().offset())}}); + auto &filePathCache = m_refactoringEngine->filePathCache(); + + m_searchHandle->addResult(QString(filePathCache.filePath(sourceRangeWithText.filePathId()).path()), + QString(sourceRangeWithText.text()), + {{int(sourceRangeWithText.start().line()), + int(sourceRangeWithText.start().column() - 1), + int(sourceRangeWithText.start().offset())}, + {int(sourceRangeWithText.end().line()), + int(sourceRangeWithText.end().column() - 1), + int(sourceRangeWithText.end().offset())}}); } void RefactoringClient::setResultCounterAndSendSearchIsFinishedIfFinished() diff --git a/src/plugins/clangrefactoring/refactoringclient.h b/src/plugins/clangrefactoring/refactoringclient.h index 09524f314f..d504538b3e 100644 --- a/src/plugins/clangrefactoring/refactoringclient.h +++ b/src/plugins/clangrefactoring/refactoringclient.h @@ -66,9 +66,6 @@ public: bool hasValidLocalRenamingCallback() const; - static std::unordered_map<uint, QString> convertFilePaths( - const std::unordered_map<uint, ClangBackEnd::FilePath> &filePaths); - void setExpectedResultCount(uint count); uint expectedResultCount() const; uint resultCounter() const; @@ -76,8 +73,7 @@ public: void setRefactoringConnectionClient(ClangBackEnd::RefactoringConnectionClient *connectionClient); unittest_public: - void addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRange, - std::unordered_map<uint, QString> &filePaths); + void addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRange); private: void addSearchResults(const ClangBackEnd::SourceRangesContainer &sourceRanges); diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp index 696e38c468..bc9ec9ab68 100644 --- a/src/plugins/clangrefactoring/refactoringengine.cpp +++ b/src/plugins/clangrefactoring/refactoringengine.cpp @@ -46,9 +46,11 @@ namespace ClangRefactoring { using ClangBackEnd::RequestSourceLocationsForRenamingMessage; RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server, - ClangBackEnd::RefactoringClientInterface &client) - : server(server), - client(client) + ClangBackEnd::RefactoringClientInterface &client, + ClangBackEnd::FilePathCachingInterface &filePathCache) + : m_server(server), + m_client(client), + m_filePathCache(filePathCache) { } @@ -60,7 +62,7 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data, setUsable(false); - client.setLocalRenamingCallback(std::move(renameSymbolsCallback)); + m_client.setLocalRenamingCallback(std::move(renameSymbolsCallback)); QString filePath = data.filePath().toString(); QTextCursor textCursor = data.cursor(); @@ -79,7 +81,7 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data, textCursor.document()->revision()); - server.requestSourceLocationsForRenamingMessage(std::move(message)); + m_server.requestSourceLocationsForRenamingMessage(std::move(message)); } void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &) @@ -89,12 +91,12 @@ void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &) bool RefactoringEngine::isUsable() const { - return server.isUsable(); + return m_server.isUsable(); } void RefactoringEngine::setUsable(bool isUsable) { - server.setUsable(isUsable); + m_server.setUsable(isUsable); } } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/refactoringengine.h b/src/plugins/clangrefactoring/refactoringengine.h index 83e67bfe27..b64a2c8eeb 100644 --- a/src/plugins/clangrefactoring/refactoringengine.h +++ b/src/plugins/clangrefactoring/refactoringengine.h @@ -25,6 +25,8 @@ #pragma once +#include <filepathcachingfwd.h> + #include <cpptools/refactoringengineinterface.h> namespace ClangBackEnd { @@ -37,8 +39,10 @@ namespace ClangRefactoring { class RefactoringEngine : public CppTools::RefactoringEngineInterface { public: - RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server, - ClangBackEnd::RefactoringClientInterface &client); + RefactoringEngine(ClangBackEnd::RefactoringServerInterface &m_server, + ClangBackEnd::RefactoringClientInterface &m_client, + ClangBackEnd::FilePathCachingInterface &filePathCache); + void startLocalRenaming(const CppTools::CursorInEditor &data, CppTools::ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) override; @@ -47,9 +51,15 @@ public: bool isUsable() const override; void setUsable(bool isUsable); + ClangBackEnd::FilePathCachingInterface &filePathCache() + { + return m_filePathCache; + } + private: - ClangBackEnd::RefactoringServerInterface &server; - ClangBackEnd::RefactoringClientInterface &client; + ClangBackEnd::RefactoringServerInterface &m_server; + ClangBackEnd::RefactoringClientInterface &m_client; + ClangBackEnd::FilePathCachingInterface &m_filePathCache; }; } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/sourcelocations.h b/src/plugins/clangrefactoring/sourcelocations.h index 9ae4241c01..1eaf3fe3af 100644 --- a/src/plugins/clangrefactoring/sourcelocations.h +++ b/src/plugins/clangrefactoring/sourcelocations.h @@ -27,39 +27,26 @@ #include <utils/smallstring.h> -#include <cstdint> +#include <filepathid.h> + #include <vector> -#include <tuple> -#include <unordered_map> namespace ClangRefactoring { -class SourceLocations +struct SourceLocation { -public: - struct Location - { - Location(qint64 sourceId, qint64 line, qint64 column) - : sourceId(sourceId), line(line), column(column) - {} - - qint64 sourceId; - qint64 line; - qint64 column; - }; - - struct Source - { - Source(qint64 sourceId, Utils::PathString &&sourcePath) - : sourceId(sourceId), sourcePath(std::move(sourcePath)) - {} - - qint64 sourceId; - Utils::PathString sourcePath; - }; - - std::vector<Location> locations; - std::unordered_map<qint64, Utils::PathString> sources; + SourceLocation(ClangBackEnd::FilePathId filePathId, int line, int column) + : filePathId(filePathId), line(line), column(column) + {} + SourceLocation(int directoryId, int sourceId, int line, int column) + : filePathId{directoryId, sourceId}, line(line), column(column) + {} + + ClangBackEnd::FilePathId filePathId; + int line; + int column; }; +using SourceLocations = std::vector<SourceLocation>; + } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/symbolquery.h b/src/plugins/clangrefactoring/symbolquery.h index 19faf97229..75c110eb76 100644 --- a/src/plugins/clangrefactoring/symbolquery.h +++ b/src/plugins/clangrefactoring/symbolquery.h @@ -27,6 +27,7 @@ #include <utils/smallstring.h> +#include <filepathid.h> #include <sourcelocations.h> #include <algorithm> @@ -39,68 +40,20 @@ class SymbolQuery using ReadStatement = typename StatementFactory::ReadStatementType; public: - using Location = SourceLocations::Location; - using Source = SourceLocations::Source; - SymbolQuery(StatementFactory &statementFactory) : m_statementFactory(statementFactory) {} - SourceLocations locationsAt(const Utils::PathString &filePath, uint line, uint utf8Column) + SourceLocations locationsAt(ClangBackEnd::FilePathId filePathId, int line, int utf8Column) { ReadStatement &locationsStatement = m_statementFactory.selectLocationsForSymbolLocation; const std::size_t reserveSize = 128; - auto locations = locationsStatement.template values<Location, 3>( - reserveSize, - filePath, - line, - utf8Column); - - const std::vector<qint64> sourceIds = uniqueSourceIds(locations); - - ReadStatement &sourcesStatement = m_statementFactory.selectSourcePathForId; - - auto sources = sourcesStatement.template values<Source, 2>( - reserveSize, - sourceIds); - - return {locations, sourcesToHashMap(sources)}; - } - - static - qint64 sourceId(const Location &location) - { - return location.sourceId; - } - - static - std::vector<qint64> uniqueSourceIds(const std::vector<Location> &locations) - { - std::vector<qint64> ids; - ids.reserve(locations.size()); - - std::transform(locations.begin(), - locations.end(), - std::back_inserter(ids), - sourceId); - - auto newEnd = std::unique(ids.begin(), ids.end()); - ids.erase(newEnd, ids.end()); - - return ids; - } - - static - std::unordered_map<qint64, Utils::PathString> sourcesToHashMap(const std::vector<Source> &sources) - { - std::unordered_map<qint64, Utils::PathString> dictonary; - - for (const Source &source : sources) - dictonary.emplace(source.sourceId, std::move(source.sourcePath)); - - return dictonary; + return locationsStatement.template values<SourceLocation, 4>(reserveSize, + filePathId.fileNameId, + line, + utf8Column); } private: diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index 5622179272..d17fbd2bd9 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -31,7 +31,9 @@ #include <pchmanagerserver.h> #include <pchmanagerclientproxy.h> #include <projectparts.h> -#include <stringcache.h> +#include <filepathcaching.h> +#include <refactoringdatabaseinitializer.h> +#include <sqlitedatabase.h> #include <QCommandLineParser> #include <QCoreApplication> @@ -103,15 +105,16 @@ int main(int argc, char *argv[]) const QString connection = processArguments(application); - FilePathCache<> filePathCache; + Sqlite::Database database{Utils::PathString{QDir::tempPath() + "/symbol.db"}}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache); ApplicationEnvironment environment; PchGenerator<QProcess> pchGenerator(environment); PchCreator pchCreator(environment, filePathCache); pchCreator.setGenerator(&pchGenerator); ProjectParts projectParts; - PchManagerServer clangPchManagerServer(filePathCache, - includeWatcher, + PchManagerServer clangPchManagerServer(includeWatcher, pchCreator, projectParts); includeWatcher.setNotifier(&clangPchManagerServer); diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h index 85ad8bbd63..e37668d7a7 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h +++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h @@ -28,7 +28,9 @@ #include "clangpathwatcherinterface.h" #include "clangpathwatchernotifier.h" #include "changedfilepathcompressor.h" -#include "stringcache.h" + +#include <filepathcachinginterface.h> +#include <stringcache.h> #include <QTimer> @@ -37,34 +39,34 @@ namespace ClangBackEnd { class WatcherEntry { public: - FilePathIndex id; - FilePathIndex path; + int id; + FilePathId pathId; friend bool operator==(const WatcherEntry &first, const WatcherEntry &second) { - return first.id == second.id && first.path == second.path; + return first.id == second.id && first.pathId == second.pathId; } friend bool operator<(const WatcherEntry &first, const WatcherEntry &second) { - return std::tie(first.path, first.id) < std::tie(second.path, second.id); + return std::tie(first.pathId, first.id) < std::tie(second.pathId, second.id); } - friend bool operator<(const WatcherEntry &entry, FilePathIndex path) + friend bool operator<(const WatcherEntry &entry, FilePathId pathId) { - return entry.path < path; + return entry.pathId < pathId; } - friend bool operator<(FilePathIndex path, const WatcherEntry &entry) + friend bool operator<(FilePathId pathId, const WatcherEntry &entry) { - return path < entry.path; + return pathId < entry.pathId; } }; using WatcherEntries = std::vector<WatcherEntry>; using IdCache = StringCache<Utils::SmallString, - FilePathIndex, + int, NonLockingMutex, decltype(&Utils::compare), Utils::compare>; @@ -74,7 +76,7 @@ template <typename FileSystemWatcher, class ClangPathWatcher : public ClangPathWatcherInterface { public: - ClangPathWatcher(FilePathCache<> &pathCache, + ClangPathWatcher(FilePathCachingInterface &pathCache, ClangPathWatcherNotifier *notifier=nullptr) : m_pathCache(pathCache), m_notifier(notifier) @@ -136,9 +138,9 @@ unittest_public: return ids; } - std::vector<FilePathIndex> convertToIdNumbers(const Utils::SmallStringVector &ids) + std::vector<int> convertToIdNumbers(const Utils::SmallStringVector &ids) { - std::vector<FilePathIndex> idNumbers = m_idCache.stringIds(ids); + std::vector<int> idNumbers = m_idCache.stringIds(ids); std::sort(idNumbers.begin(), idNumbers.end()); @@ -148,33 +150,33 @@ unittest_public: std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths) { auto sumSize = [] (std::size_t size, const IdPaths &idPath) { - return size + idPath.paths.size(); + return size + idPath.filePathIds.size(); }; return std::accumulate(idPaths.begin(), idPaths.end(), std::size_t(0), sumSize); } - std::pair<WatcherEntries,std::vector<FilePathIndex>> + std::pair<WatcherEntries, std::vector<int>> convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths) { WatcherEntries entries; entries.reserve(sizeOfIdPaths(idPaths)); - std::vector<FilePathIndex> ids; + std::vector<int> ids; ids.reserve(ids.size()); auto outputIterator = std::back_inserter(entries); for (const IdPaths &idPath : idPaths) { - FilePathIndex id = m_idCache.stringId(idPath.id); + int id = m_idCache.stringId(idPath.id); ids.push_back(id); - outputIterator = std::transform(idPath.paths.begin(), - idPath.paths.end(), + outputIterator = std::transform(idPath.filePathIds.begin(), + idPath.filePathIds.end(), outputIterator, - [&] (uint path) { return WatcherEntry{id, path}; }); + [&] (FilePathId pathId) { return WatcherEntry{id, pathId}; }); } std::sort(entries.begin(), entries.end()); @@ -196,7 +198,7 @@ unittest_public: } void removeUnusedEntries(const WatcherEntries &entries, - const std::vector<FilePathIndex> &ids) + const std::vector<int> &ids) { auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids); @@ -222,7 +224,9 @@ unittest_public: std::transform(watcherEntries.begin(), watcherEntries.end(), std::back_inserter(paths), - [&] (const WatcherEntry &entry) { return QString(m_pathCache.string(entry.path)); }); + [&] (const WatcherEntry &entry) { + return QString(m_pathCache.filePath(entry.pathId).path()); + }); return paths; } @@ -252,7 +256,7 @@ unittest_public: WatcherEntries notWatchedPaths(const WatcherEntries &entries) const { auto compare = [] (const WatcherEntry &first, const WatcherEntry &second) { - return first.path < second.path; + return first.pathId < second.pathId; }; return notWatchedEntries(entries, compare); @@ -278,7 +282,7 @@ unittest_public: WatcherEntries notAnymoreWatchedEntriesWithIds( const WatcherEntries &newEntries, - const std::vector<FilePathIndex> &ids) const + const std::vector<int> &ids) const { auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>()); @@ -313,7 +317,7 @@ unittest_public: WatcherEntries uniqueEntries; auto compare = [] (const WatcherEntry &first, const WatcherEntry &second) { - return first.path == second.path; + return first.pathId == second.pathId; }; std::unique_copy(pathEntries.begin(), @@ -334,7 +338,7 @@ unittest_public: return m_watchedEntries; } - WatcherEntries removeIdsFromWatchedEntries(const std::vector<FilePathIndex> &ids) + WatcherEntries removeIdsFromWatchedEntries(const std::vector<int> &ids) { auto keep = [&] (const WatcherEntry &entry) { @@ -374,11 +378,11 @@ unittest_public: WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths) { - std::vector<FilePathIndex> pathIds = m_pathCache.stringIds(filePaths); + FilePathIds pathIds = m_pathCache.filePathIds(filePaths); WatcherEntries foundEntries; - for (uint pathId : pathIds) { + for (FilePathId pathId : pathIds) { auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId); foundEntries.insert(foundEntries.end(), range.first, range.second); } @@ -420,7 +424,7 @@ unittest_public: } } - FilePathCache<> &pathCache() + FilePathCachingInterface &pathCache() { return m_pathCache; } @@ -435,10 +439,8 @@ private: WatcherEntries m_watchedEntries; ChangedFilePathCompressor<Timer> m_changedFilePathCompressor; FileSystemWatcher m_fileSystemWatcher; - FilePathCache<> &m_pathCache; + FilePathCachingInterface &m_pathCache; ClangPathWatcherNotifier *m_notifier; }; -std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry); - } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri index 926280a5fa..686d9a5d18 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri +++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri @@ -2,9 +2,7 @@ INCLUDEPATH += $$PWD SOURCES += \ $$PWD/pchmanagerserver.cpp \ - $$PWD/clangpathwatcher.cpp \ $$PWD/projectparts.cpp \ - $$PWD/idpaths.cpp \ $$PWD/pchcreatorinterface.cpp \ $$PWD/clangpathwatcherinterface.cpp \ $$PWD/projectpartsinterface.cpp \ diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h index 339d491848..c61dfecb61 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h @@ -25,10 +25,11 @@ #pragma once -#include "stringcache.h" - #include <collectincludespreprocessorcallbacks.h> +#include <filepathcachingfwd.h> +#include <filepathid.h> + #include <clang/Frontend/FrontendActions.h> #include <clang/Frontend/CompilerInstance.h> #include <clang/Lex/Preprocessor.h> @@ -38,10 +39,10 @@ namespace ClangBackEnd { class CollectIncludesAction final : public clang::PreprocessOnlyAction { public: - CollectIncludesAction(FilePathIndices &includeIds, - FilePathCache<> &filePathCache, - FilePathIndices &excludedIncludeUID, - FilePathIndices &alreadyIncludedFileUIDs) + CollectIncludesAction(FilePathIds &includeIds, + FilePathCachingInterface &filePathCache, + std::vector<uint> &excludedIncludeUID, + std::vector<uint> &alreadyIncludedFileUIDs) : m_includeIds(includeIds), m_filePathCache(filePathCache), m_excludedIncludeUID(excludedIncludeUID), @@ -78,10 +79,10 @@ public: } private: - FilePathIndices &m_includeIds; - FilePathCache<> &m_filePathCache; - FilePathIndices &m_excludedIncludeUID; - FilePathIndices &m_alreadyIncludedFileUIDs; + FilePathIds &m_includeIds; + FilePathCachingInterface &m_filePathCache; + std::vector<uint> &m_excludedIncludeUID; + std::vector<uint> &m_alreadyIncludedFileUIDs; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h index a57d72adfc..dff1dc39ce 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h @@ -25,7 +25,10 @@ #pragma once -#include "stringcache.h" +#include <filepathcachinginterface.h> +#include <filepathid.h> + +#include <utils/smallstringvector.h> #include <clang/Basic/SourceManager.h> #include <clang/Lex/MacroInfo.h> @@ -33,8 +36,6 @@ #include <clang/Lex/PPCallbacks.h> #include <clang/Lex/Preprocessor.h> -#include <utils/smallstringvector.h> - #include <QFile> #include <QDir> #include <QTemporaryDir> @@ -47,10 +48,10 @@ class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks { public: CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch, - std::vector<FilePathIndex> &includeIds, - FilePathCache<> &filePathCache, - const std::vector<FilePathIndex> &excludedIncludeUID, - std::vector<FilePathIndex> &alreadyIncludedFileUIDs) + FilePathIds &includeIds, + FilePathCachingInterface &filePathCache, + const std::vector<uint> &excludedIncludeUID, + std::vector<uint> &alreadyIncludedFileUIDs) : m_headerSearch(headerSearch), m_includeIds(includeIds), m_filePathCache(filePathCache), @@ -78,7 +79,7 @@ public: m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); Utils::PathString filePath = filePathFromFile(file); if (!filePath.isEmpty()) { - FilePathIndex includeId = m_filePathCache.stringId(filePath); + FilePathId includeId = m_filePathCache.filePathId(filePath); m_includeIds.emplace_back(includeId); } } @@ -132,7 +133,7 @@ public: uid); } - std::pair<bool, std::vector<FilePathIndex>::iterator> isNotAlreadyIncluded(FilePathIndex uid) const + std::pair<bool, std::vector<uint>::iterator> isNotAlreadyIncluded(uint uid) const { auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(), m_alreadyIncludedFileUIDs.end(), @@ -174,10 +175,10 @@ public: private: clang::HeaderSearch &m_headerSearch; - std::vector<FilePathIndex> &m_includeIds; - FilePathCache<> &m_filePathCache; - const std::vector<FilePathIndex> &m_excludedIncludeUID; - std::vector<FilePathIndex> &m_alreadyIncludedFileUIDs; + FilePathIds &m_includeIds; + FilePathCachingInterface &m_filePathCache; + const std::vector<uint> &m_excludedIncludeUID; + std::vector<uint> &m_alreadyIncludedFileUIDs; bool m_skipInclude = false; }; diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h index 42b8a62cea..969a8ddb8b 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h @@ -25,10 +25,11 @@ #pragma once -#include "stringcache.h" - #include "collectincludesaction.h" +#include <filepathcachingfwd.h> +#include <filepathid.h> + #include <clang/Tooling/Tooling.h> namespace ClangBackEnd { @@ -36,8 +37,8 @@ namespace ClangBackEnd { class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory { public: - CollectIncludesToolAction(std::vector<FilePathIndex> &includeIds, - FilePathCache<> &filePathCache, + CollectIncludesToolAction(FilePathIds &includeIds, + FilePathCachingInterface &filePathCache, const Utils::PathStringVector &excludedIncludes) : m_includeIds(includeIds), m_filePathCache(filePathCache), @@ -72,9 +73,9 @@ public: m_alreadyIncludedFileUIDs); } - std::vector<FilePathIndex> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const + std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const { - std::vector<FilePathIndex> fileUIDs; + std::vector<uint> fileUIDs; fileUIDs.reserve(m_excludedIncludes.size()); for (const Utils::PathString &filePath : m_excludedIncludes) { @@ -90,10 +91,10 @@ public: } private: - std::vector<FilePathIndex> m_alreadyIncludedFileUIDs; - std::vector<FilePathIndex> m_excludedIncludeUIDs; - std::vector<FilePathIndex> &m_includeIds; - FilePathCache<> &m_filePathCache; + std::vector<uint> m_alreadyIncludedFileUIDs; + std::vector<uint> m_excludedIncludeUIDs; + FilePathIds &m_includeIds; + FilePathCachingInterface &m_filePathCache; const Utils::PathStringVector &m_excludedIncludes; }; diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.h b/src/tools/clangpchmanagerbackend/source/idpaths.h index a407e24530..3b24ba7538 100644 --- a/src/tools/clangpchmanagerbackend/source/idpaths.h +++ b/src/tools/clangpchmanagerbackend/source/idpaths.h @@ -27,9 +27,7 @@ #include <utils/smallstring.h> -#include <iosfwd> - -#include <stringcachefwd.h> +#include <filepathid.h> namespace ClangBackEnd { @@ -37,14 +35,12 @@ class IdPaths { public: Utils::SmallString id; - std::vector<FilePathIndex> paths; + FilePathIds filePathIds; friend bool operator==(const IdPaths &first, const IdPaths &second) { - return first.id == second.id && first.paths == second.paths; + return first.id == second.id && first.filePathIds == second.filePathIds; } }; -std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); - } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp index 421123b3a7..6ac142e22b 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp +++ b/src/tools/clangpchmanagerbackend/source/includecollector.cpp @@ -33,7 +33,7 @@ namespace ClangBackEnd { -IncludeCollector::IncludeCollector(FilePathCache<> &filePathCache) +IncludeCollector::IncludeCollector(FilePathCachingInterface &filePathCache) : m_filePathCache(filePathCache) { } @@ -69,7 +69,7 @@ void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedInc #endif } -std::vector<FilePathIndex> IncludeCollector::takeIncludeIds() +FilePathIds IncludeCollector::takeIncludeIds() { std::sort(m_includeIds.begin(), m_includeIds.end()); diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/includecollector.h index 73f9b948af..52e6e560db 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.h +++ b/src/tools/clangpchmanagerbackend/source/includecollector.h @@ -25,28 +25,28 @@ #pragma once -#include "stringcache.h" - #include <clangtool.h> +#include <filepathcachingfwd.h> + namespace ClangBackEnd { class IncludeCollector : public ClangTool { public: - IncludeCollector(FilePathCache<> &filePathCache); + IncludeCollector(FilePathCachingInterface &filePathCache); void collectIncludes(); void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes); - std::vector<FilePathIndex> takeIncludeIds(); + FilePathIds takeIncludeIds(); private: Utils::PathStringVector m_excludedIncludes; - std::vector<FilePathIndex> m_includeIds; + FilePathIds m_includeIds; Utils::SmallStringVector m_directories; - FilePathCache<> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index fd6da58012..645e266db0 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -29,6 +29,7 @@ #include "includecollector.h" #include "pchnotcreatederror.h" +#include <filepathcachinginterface.h> #include <projectpartpch.h> #include <QCryptographicHash> @@ -37,7 +38,7 @@ namespace ClangBackEnd { -PchCreator::PchCreator(Environment &environment, FilePathCache<> &filePathCache) +PchCreator::PchCreator(Environment &environment, FilePathCachingInterface &filePathCache) : m_environment(environment), m_filePathCache(filePathCache) { @@ -45,7 +46,7 @@ PchCreator::PchCreator(Environment &environment, FilePathCache<> &filePathCache) PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts, Environment &environment, - FilePathCache<> &filePathCache, + FilePathCachingInterface &filePathCache, PchGeneratorInterface *pchGenerator, V2::FileContainers &&generatedFiles) : m_projectParts(std::move(projectsParts)), @@ -239,7 +240,7 @@ Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() cons return compilerArguments; } -std::vector<FilePathIndex> PchCreator::generateGlobalPchIncludeIds() const +FilePathIds PchCreator::generateGlobalPchIncludeIds() const { IncludeCollector collector(m_filePathCache); @@ -256,7 +257,7 @@ std::vector<FilePathIndex> PchCreator::generateGlobalPchIncludeIds() const namespace { -std::size_t contentSize(const std::vector<Utils::PathString> &includes) +std::size_t contentSize(const FilePaths &includes) { auto countIncludeSize = [] (std::size_t size, const Utils::PathString &include) { return size + include.size(); @@ -266,20 +267,16 @@ std::size_t contentSize(const std::vector<Utils::PathString> &includes) } } -Utils::SmallString PchCreator::generatePchIncludeFileContent( - const std::vector<FilePathIndex> &includeIds) const +Utils::SmallString PchCreator::generatePchIncludeFileContent(const FilePathIds &includeIds) const { Utils::SmallString fileContent; const std::size_t lineTemplateSize = 12; - auto includes = m_filePathCache.strings(includeIds); + auto includes = m_filePathCache.filePaths(includeIds); fileContent.reserve(includes.size() * lineTemplateSize + contentSize(includes)); - for (const Utils::PathString &include : includes) { - fileContent += "#include \""; - fileContent += include; - fileContent += "\"\n"; - } + for (const Utils::PathString &include : includes) + fileContent += {"#include \"", include, "\"\n"}; return fileContent; } @@ -461,7 +458,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaderAndSourcePaths( return includeAndSources; } -std::vector<FilePathIndex> PchCreator::generateProjectPartPchIncludes( +FilePathIds PchCreator::generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const { Utils::SmallString jointedFileContent = generateProjectPartHeaderAndSourcesContent(projectPart); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 5548ec7acd..26e591302f 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -28,9 +28,9 @@ #include "pchcreatorinterface.h" #include "pchgeneratorinterface.h" -#include "stringcache.h" #include "idpaths.h" +#include <filepathcachingfwd.h> #include <projectpartpch.h> #include <projectpartcontainerv2.h> @@ -48,10 +48,10 @@ class PchCreator final : public PchCreatorInterface { public: PchCreator(Environment &environment, - FilePathCache<> &filePathCache); + FilePathCachingInterface &filePathCache); PchCreator(V2::ProjectPartContainers &&projectsParts, Environment &environment, - FilePathCache<> &filePathCache, + FilePathCachingInterface &filePathCache, PchGeneratorInterface *pchGenerator, V2::FileContainers &&generatedFiles); @@ -70,9 +70,9 @@ unittest_public: Utils::SmallStringVector generateGlobalPchCompilerArguments() const; Utils::SmallStringVector generateGlobalClangCompilerArguments() const; - std::vector<FilePathIndex> generateGlobalPchIncludeIds() const; + FilePathIds generateGlobalPchIncludeIds() const; - Utils::SmallString generatePchIncludeFileContent(const std::vector<FilePathIndex> &includeIds) const; + Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const; Utils::SmallString generateGlobalPchHeaderFileContent() const; std::unique_ptr<QFile> generateGlobalPchHeaderFile(); void generatePch(Utils::SmallStringVector &&commandLineArguments, @@ -97,7 +97,7 @@ unittest_public: const V2::ProjectPartContainer &projectPart); static Utils::PathStringVector generateProjectPartHeaderAndSourcePaths( const V2::ProjectPartContainer &projectPart); - std::vector<FilePathIndex> generateProjectPartPchIncludes( + FilePathIds generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPathPchHeaderFilePath( const V2::ProjectPartContainer &projectPart) const; @@ -127,7 +127,7 @@ private: std::vector<ProjectPartPch> m_projectPartPchs; std::vector<IdPaths> m_projectsIncludeIds; Environment &m_environment; - FilePathCache<> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; PchGeneratorInterface *m_pchGenerator = nullptr; }; diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp index 03261ae164..8abcda8d65 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp @@ -36,12 +36,10 @@ namespace ClangBackEnd { -PchManagerServer::PchManagerServer(FilePathCache<> &filePathCache, - ClangPathWatcherInterface &fileSystemWatcher, +PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher, PchCreatorInterface &pchCreator, ProjectPartsInterface &projectParts) - : m_filePathCache(filePathCache), - m_fileSystemWatcher(fileSystemWatcher), + : m_fileSystemWatcher(fileSystemWatcher), m_pchCreator(pchCreator), m_projectParts(projectParts) { diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h index 7be9c75966..bac2dcd00f 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h @@ -31,7 +31,6 @@ #include "pchgeneratornotifierinterface.h" #include "pchmanagerserverinterface.h" #include "projectpartsinterface.h" -#include "stringcache.h" #include <ipcclientprovider.h> @@ -46,8 +45,7 @@ class PchManagerServer : public PchManagerServerInterface, { public: - PchManagerServer(FilePathCache<> &filePathCache, - ClangPathWatcherInterface &fileSystemWatcher, + PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher, PchCreatorInterface &pchCreator, ProjectPartsInterface &projectParts); @@ -60,7 +58,6 @@ public: void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override; private: - FilePathCache<> &m_filePathCache; ClangPathWatcherInterface &m_fileSystemWatcher; PchCreatorInterface &m_pchCreator; ProjectPartsInterface &m_projectParts; diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp index 8c5fe3f751..7c628fa376 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp @@ -29,14 +29,15 @@ #include <QDir> #include <connectionserver.h> -#include <stringcache.h> +#include <filepathcaching.h> #include <refactoringserver.h> #include <refactoringclientproxy.h> #include <symbolindexing.h> -using ClangBackEnd::FilePathCache; +using ClangBackEnd::FilePathCaching; using ClangBackEnd::RefactoringClientProxy; using ClangBackEnd::RefactoringServer; +using ClangBackEnd::RefactoringDatabaseInitializer; using ClangBackEnd::ConnectionServer; using ClangBackEnd::SymbolIndexing; @@ -69,8 +70,10 @@ try { const QString connection = processArguments(application); - FilePathCache<std::mutex> filePathCache; - SymbolIndexing symbolIndexing{filePathCache, Utils::PathString{QDir::tempPath() + "/symbol.db"}}; + Sqlite::Database database{Utils::PathString{QDir::tempPath() + "/symbol.db"}}; + RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + FilePathCaching filePathCache{database}; + SymbolIndexing symbolIndexing{database, filePathCache}; RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache}; ConnectionServer<RefactoringServer, RefactoringClientProxy> connectionServer(connection); connectionServer.start(); diff --git a/src/tools/clangrefactoringbackend/source/clangquery.cpp b/src/tools/clangrefactoringbackend/source/clangquery.cpp index 620a7ebaab..fc9dd868c0 100644 --- a/src/tools/clangrefactoringbackend/source/clangquery.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquery.cpp @@ -54,16 +54,16 @@ struct CollectBoundNodes : MatchFinder::MatchCallback { } }; -ClangQuery::ClangQuery(FilePathCache<std::mutex> &filePathCache, +ClangQuery::ClangQuery(FilePathCachingInterface &filePathCache, Utils::SmallString &&query) - : query(std::move(query)), - filePathCache(filePathCache) + : m_query(std::move(query)), + m_filePathCache(filePathCache) { } void ClangQuery::setQuery(Utils::SmallString &&query) { - this->query = std::move(query); + this->m_query = std::move(query); } void ClangQuery::findLocations() @@ -78,7 +78,7 @@ void ClangQuery::findLocations() std::make_move_iterator(asts.end()), [&] (std::unique_ptr<clang::ASTUnit> &&ast) { Diagnostics diagnostics; - auto optionalMatcher = Parser::parseMatcherExpression({query.data(), query.size()}, + auto optionalMatcher = Parser::parseMatcherExpression({m_query.data(), m_query.size()}, nullptr, &diagnostics); parseDiagnostics(diagnostics); @@ -89,19 +89,19 @@ void ClangQuery::findLocations() SourceRangesContainer ClangQuery::takeSourceRanges() { - return std::move(sourceRangesContainer); + return std::move(m_sourceRangesContainer); } DynamicASTMatcherDiagnosticContainers ClangQuery::takeDiagnosticContainers() { - return std::move(diagnosticContainers_); + return std::move(m_diagnosticContainers_); } namespace { V2::SourceRangeContainer convertToContainer(const clang::ast_matchers::dynamic::SourceRange sourceRange) { - return V2::SourceRangeContainer(0, + return V2::SourceRangeContainer({1, 0}, sourceRange.Start.Line, sourceRange.Start.Column, 0, @@ -159,8 +159,8 @@ void ClangQuery::parseDiagnostics(const clang::ast_matchers::dynamic::Diagnostic auto errors = diagnostics.errors(); for (const auto &errorContent : errors) { - diagnosticContainers_.emplace_back(); - DynamicASTMatcherDiagnosticContainer &diagnosticContainer = diagnosticContainers_.back(); + m_diagnosticContainers_.emplace_back(); + DynamicASTMatcherDiagnosticContainer &diagnosticContainer = m_diagnosticContainers_.back(); for (const auto &message : errorContent.Messages) { diagnosticContainer.insertMessage(convertToContainer(message.Range), @@ -216,8 +216,8 @@ void ClangQuery::matchLocation( SourceRangeExtractor extractor(ast->getSourceManager(), ast->getLangOpts(), - filePathCache, - sourceRangesContainer); + m_filePathCache, + m_sourceRangesContainer); extractor.addSourceRanges(sourceRanges); } diff --git a/src/tools/clangrefactoringbackend/source/clangquery.h b/src/tools/clangrefactoringbackend/source/clangquery.h index 7d99766008..daccd8335e 100644 --- a/src/tools/clangrefactoringbackend/source/clangquery.h +++ b/src/tools/clangrefactoringbackend/source/clangquery.h @@ -30,7 +30,7 @@ #include <sourcerangescontainer.h> #include <dynamicastmatcherdiagnosticcontainer.h> -#include <stringcache.h> +#include <filepathcachingfwd.h> namespace clang { namespace ast_matchers { @@ -51,9 +51,9 @@ namespace ClangBackEnd { class ClangQuery : public ClangTool { public: - ClangQuery(FilePathCache<std::mutex> &filePathCache, Utils::SmallString &&query={}); + ClangQuery(FilePathCachingInterface &m_filePathCache, Utils::SmallString &&m_query={}); - void setQuery(Utils::SmallString &&query); + void setQuery(Utils::SmallString &&m_query); void findLocations(); @@ -66,10 +66,10 @@ private: std::unique_ptr<clang::ASTUnit> ast); private: - SourceRangesContainer sourceRangesContainer; - Utils::SmallString query; - std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_; - FilePathCache<std::mutex> &filePathCache; + SourceRangesContainer m_sourceRangesContainer; + Utils::SmallString m_query; + std::vector<DynamicASTMatcherDiagnosticContainer> m_diagnosticContainers_; + ClangBackEnd::FilePathCachingInterface &m_filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp index 692065a9e7..0ac42d6ef1 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp @@ -29,7 +29,7 @@ namespace ClangBackEnd { -ClangQueryGatherer::ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache, +ClangQueryGatherer::ClangQueryGatherer(FilePathCachingInterface *filePathCache, std::vector<V2::FileContainer> &&sources, std::vector<V2::FileContainer> &&unsaved, Utils::SmallString &&query) @@ -43,7 +43,7 @@ ClangQueryGatherer::ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache, SourceRangesForQueryMessage ClangQueryGatherer::createSourceRangesForSource( - FilePathCache<std::mutex> *filePathCache, + FilePathCachingInterface *filePathCache, V2::FileContainer &&source, const std::vector<V2::FileContainer> &unsaved, Utils::SmallString &&query) diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h index c1fd6341fa..f0e0e181f2 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h @@ -29,7 +29,7 @@ #include <sourcerangesforquerymessage.h> #include <filecontainerv2.h> -#include <stringcache.h> +#include <filepathcachingfwd.h> #include <future> @@ -41,13 +41,13 @@ public: using Future = std::future<SourceRangesForQueryMessage>; ClangQueryGatherer() = default; - ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache, + ClangQueryGatherer(FilePathCachingInterface *filePathCache, std::vector<V2::FileContainer> &&sources, std::vector<V2::FileContainer> &&unsaved, Utils::SmallString &&query); static SourceRangesForQueryMessage createSourceRangesForSource( - FilePathCache<std::mutex> *filePathCache, + FilePathCachingInterface *filePathCache, V2::FileContainer &&source, const std::vector<V2::FileContainer> &unsaved, Utils::SmallString &&query); @@ -69,7 +69,7 @@ protected: std::vector<Future> finishedFutures(); private: - FilePathCache<std::mutex> *m_filePathCache = nullptr; + FilePathCachingInterface *m_filePathCache = nullptr; SourceRangeFilter m_sourceRangeFilter; std::vector<V2::FileContainer> m_sources; std::vector<V2::FileContainer> m_unsaved; diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index 50041e596a..e95981a4a3 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -57,5 +57,4 @@ HEADERS += \ SOURCES += \ $$PWD/sourcerangefilter.cpp \ $$PWD/symbolindexer.cpp \ - $$PWD/symbolentry.cpp \ - $$PWD/sourcelocationentry.cpp + $$PWD/symbolentry.cpp diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h index 1ddd34b595..2c8a93e940 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h @@ -31,7 +31,7 @@ #include <utils/smallstring.h> -#include <stringcachefwd.h> +#include <filepathcachingfwd.h> #include <clang/Frontend/FrontendAction.h> @@ -42,7 +42,7 @@ namespace ClangBackEnd { class CollectSymbolsAction { public: - CollectSymbolsAction(FilePathCache<std::mutex> &filePathCache) + CollectSymbolsAction(FilePathCachingInterface &filePathCache) : m_filePathCache(filePathCache) {} @@ -66,7 +66,7 @@ public: private: SymbolEntries m_symbolEntries; SourceLocationEntries m_sourceLocationEntries; - FilePathCache<std::mutex> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; }; diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h index fcedd6a6d0..f93f44a1cb 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h @@ -28,7 +28,7 @@ #include "symbolentry.h" #include "sourcelocationentry.h" -#include <stringcache.h> +#include <filepathcachinginterface.h> #include <clang/AST/AST.h> #include <clang/AST/ASTContext.h> @@ -50,7 +50,7 @@ class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbol public: CollectSymbolsASTVisitor(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, - FilePathCache<std::mutex> &filePathCache, + FilePathCachingInterface &filePathCache, const clang::SourceManager &sourceManager) : m_symbolEntries(symbolEntries), m_sourceLocationEntries(sourceLocationEntries), @@ -100,7 +100,7 @@ public: return true; } - FilePathIndex filePathId(clang::SourceLocation sourceLocation) + FilePathId filePathId(clang::SourceLocation sourceLocation) { uint clangFileId = m_sourceManager.getFileID(sourceLocation).getHashValue(); @@ -111,11 +111,11 @@ public: auto filePath = m_sourceManager.getFilename(sourceLocation); - FilePathIndex index = m_filePathCache.stringId(toStringView(filePath)); + FilePathId filePathId = m_filePathCache.filePathId(toStringView(filePath)); - m_filePathIndices.emplace(clangFileId, index); + m_filePathIndices.emplace(clangFileId, filePathId); - return index; + return filePathId; } LineColumn lineColum(clang::SourceLocation sourceLocation) @@ -147,9 +147,9 @@ public: private: SymbolEntries &m_symbolEntries; - std::unordered_map<uint, FilePathIndex> m_filePathIndices; + std::unordered_map<uint, FilePathId> m_filePathIndices; SourceLocationEntries &m_sourceLocationEntries; - FilePathCache<std::mutex> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; const clang::SourceManager &m_sourceManager; }; diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h index 0eeb7a73f2..55822ab091 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h @@ -31,7 +31,7 @@ #include <clang/AST/ASTConsumer.h> #include <clang/AST/ASTContext.h> -#include <stringcachefwd.h> +#include <filepathcachingfwd.h> namespace ClangBackEnd { @@ -40,7 +40,7 @@ class CollectSymbolsConsumer : public clang::ASTConsumer public: CollectSymbolsConsumer(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, - FilePathCache<std::mutex> &filePathCache) + FilePathCachingInterface &filePathCache) : m_symbolEntries(symbolEntries), m_sourceLocationEntries(sourceLocationEntries), m_filePathCache(filePathCache) @@ -69,6 +69,6 @@ public: private: SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; - FilePathCache<std::mutex> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; }; } diff --git a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp index cc6e8e609a..3dd43976a0 100644 --- a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp +++ b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp @@ -48,9 +48,12 @@ namespace ClangBackEnd { -LocationSourceFileCallbacks::LocationSourceFileCallbacks(uint line, uint column) - : line(line), - column(column) +LocationSourceFileCallbacks::LocationSourceFileCallbacks(uint line, + uint column, + FilePathCachingInterface &filePathCache) + : m_filePathCache(filePathCache), + m_line(line), + m_column(column) { } @@ -58,30 +61,31 @@ bool LocationSourceFileCallbacks::handleBeginSource(clang::CompilerInstance &com { auto &preprocessor = compilerInstance.getPreprocessor(); - macroPreprocessorCallbacks = new MacroPreprocessorCallbacks(sourceLocationsContainer, - symbolName, - preprocessor, - line, - column); + m_macroPreprocessorCallbacks = new MacroPreprocessorCallbacks(m_sourceLocationsContainer, + m_symbolName, + preprocessor, + m_filePathCache, + m_line, + m_column); - preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks)); + preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(m_macroPreprocessorCallbacks)); return true; } SourceLocationsContainer LocationSourceFileCallbacks::takeSourceLocations() { - return std::move(sourceLocationsContainer); + return std::move(m_sourceLocationsContainer); } Utils::SmallString LocationSourceFileCallbacks::takeSymbolName() { - return std::move(symbolName); + return std::move(m_symbolName); } bool LocationSourceFileCallbacks::hasSourceLocations() const { - return sourceLocationsContainer.hasContent(); + return m_sourceLocationsContainer.hasContent(); } diff --git a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h index cb9560ae7d..5b7fe2af4a 100644 --- a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h +++ b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h @@ -25,6 +25,7 @@ #pragma once +#include <filepathcachingfwd.h> #include <sourcelocationscontainer.h> #include <clang/Tooling/Tooling.h> @@ -45,7 +46,7 @@ class SourceLocationsContainer; class LocationSourceFileCallbacks : public clang::tooling::SourceFileCallbacks { public: - LocationSourceFileCallbacks(uint line, uint column); + LocationSourceFileCallbacks(uint line, uint column, FilePathCachingInterface &filePathCache); bool handleBeginSource(clang::CompilerInstance &compilerInstance, llvm::StringRef fileName) override; @@ -56,11 +57,12 @@ public: bool hasSourceLocations() const; private: - SourceLocationsContainer sourceLocationsContainer; - Utils::SmallString symbolName; - MacroPreprocessorCallbacks *macroPreprocessorCallbacks; - uint line; - uint column; + SourceLocationsContainer m_sourceLocationsContainer; + Utils::SmallString m_symbolName; + MacroPreprocessorCallbacks *m_macroPreprocessorCallbacks; + FilePathCachingInterface &m_filePathCache; + uint m_line; + uint m_column; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.cpp b/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.cpp index c0015f867d..2d46efed28 100644 --- a/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.cpp +++ b/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.cpp @@ -30,13 +30,15 @@ namespace ClangBackEnd { MacroPreprocessorCallbacks::MacroPreprocessorCallbacks(SourceLocationsContainer &sourceLocationsContainer, Utils::SmallString &symbolName, clang::Preprocessor &preprocessor, + FilePathCachingInterface &filePathCache, uint line, uint column) - : sourceLocationsContainer(sourceLocationsContainer), - symbolName(symbolName), - preprocessor(preprocessor), - line(line), - column(column) + : m_sourceLocationsContainer(sourceLocationsContainer), + m_symbolName(symbolName), + m_preprocessor(preprocessor), + m_filePathCache(filePathCache), + m_line(line), + m_column(column) { } diff --git a/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.h b/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.h index 6c6010b2bb..f94d993ef2 100644 --- a/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.h +++ b/src/tools/clangrefactoringbackend/source/macropreprocessorcallbacks.h @@ -27,27 +27,14 @@ #include "sourcelocationsutils.h" +#include <filepathcachingfwd.h> #include <sourcelocationscontainer.h> -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-parameter" -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning( disable : 4100 ) -#endif - #include <clang/Basic/SourceManager.h> #include <clang/Lex/PPCallbacks.h> #include <clang/Lex/Preprocessor.h> #include <clang/Lex/MacroInfo.h> -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - #include <QDebug> namespace ClangBackEnd { @@ -67,18 +54,19 @@ struct MacroDirectiveToken class MacroPreprocessorCallbacks : public clang::PPCallbacks { public: - MacroPreprocessorCallbacks(SourceLocationsContainer &sourceLocationsContainer, - Utils::SmallString &symbolName, - clang::Preprocessor &preprocessor, - uint line, - uint column); + MacroPreprocessorCallbacks(SourceLocationsContainer &m_sourceLocationsContainer, + Utils::SmallString &m_symbolName, + clang::Preprocessor &m_preprocessor, + FilePathCachingInterface &filePathCache, + uint m_line, + uint m_column); void FileChanged(clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind /*fileType*/, clang::FileID /*previousFileIdentifier*/) final { - if (!isMainFileEntered) { + if (!m_isMainFileEntered) { updateLocations(); updateIsMainFileEntered(location, reason); } @@ -88,9 +76,9 @@ public: { if (isInMainFile(token)) { if (includesCursorPosition(token)) { - sourceLocations.push_back(token.getLocation()); - cursorMacroDirective = macroDirective; - symbolName = Utils::SmallString(token.getIdentifierInfo()->getNameStart(), + m_sourceLocations.push_back(token.getLocation()); + m_cursorMacroDirective = macroDirective; + m_symbolName = Utils::SmallString(token.getIdentifierInfo()->getNameStart(), token.getIdentifierInfo()->getLength()); } } @@ -103,59 +91,60 @@ public: { if (includesCursorPosition(token)) { appendSourceLocations(token, macroDefinition); - cursorMacroDirective = macroDefinition.getLocalDirective(); - symbolName = Utils::SmallString(token.getIdentifierInfo()->getNameStart(), + m_cursorMacroDirective = macroDefinition.getLocalDirective(); + m_symbolName = Utils::SmallString(token.getIdentifierInfo()->getNameStart(), token.getIdentifierInfo()->getLength()); } else if (isCurrentTokenExpansion(macroDefinition)) { - sourceLocations.push_back(token.getLocation()); + m_sourceLocations.push_back(token.getLocation()); } else if (isBeforeCursorSourceLocation()) { - preCursorMacroDirectiveTokens.emplace_back(macroDefinition.getLocalDirective(), token); + m_preCursorMacroDirectiveTokens.emplace_back(macroDefinition.getLocalDirective(), token); } } void EndOfMainFile() final { - appendSourceLocationsToSourceLocationsContainer(sourceLocationsContainer, - sourceLocations, - sourceManager()); + appendSourceLocationsToSourceLocationsContainer(m_sourceLocationsContainer, + m_sourceLocations, + sourceManager(), + m_filePathCache); } private: void appendSourceLocations(const clang::Token &token, const clang::MacroDefinition ¯oDefinition) { - sourceLocations.push_back(macroDefinition.getLocalDirective()->getLocation()); - for (const auto ¯oDirectiveToken : preCursorMacroDirectiveTokens) { + m_sourceLocations.push_back(macroDefinition.getLocalDirective()->getLocation()); + for (const auto ¯oDirectiveToken : m_preCursorMacroDirectiveTokens) { if (macroDirectiveToken.macroDirective == macroDefinition.getLocalDirective()) - sourceLocations.push_back(macroDirectiveToken.token.getLocation()); + m_sourceLocations.push_back(macroDirectiveToken.token.getLocation()); } - sourceLocations.push_back(token.getLocation()); + m_sourceLocations.push_back(token.getLocation()); } void updateLocations() { - if (mainFileSourceLocation.isInvalid()) { - mainFileSourceLocation = sourceManager().getLocForStartOfFile(sourceManager().getMainFileID()); - cursorSourceLocation = sourceManager().translateLineCol(sourceManager().getMainFileID(), - line, - column); + if (m_mainFileSourceLocation.isInvalid()) { + m_mainFileSourceLocation = sourceManager().getLocForStartOfFile(sourceManager().getMainFileID()); + m_cursorSourceLocation = sourceManager().translateLineCol(sourceManager().getMainFileID(), + m_line, + m_column); } } void updateIsMainFileEntered(clang::SourceLocation location, FileChangeReason reason) { - if (location == mainFileSourceLocation && reason == PPCallbacks::EnterFile) - isMainFileEntered = true; + if (location == m_mainFileSourceLocation && reason == PPCallbacks::EnterFile) + m_isMainFileEntered = true; } const clang::SourceManager &sourceManager() const { - return preprocessor.getSourceManager(); + return m_preprocessor.getSourceManager(); } bool isInMainFile(const clang::Token &token) { - return isMainFileEntered && sourceManager().isWrittenInMainFile(token.getLocation()); + return m_isMainFileEntered && sourceManager().isWrittenInMainFile(token.getLocation()); } bool includesCursorPosition(const clang::Token &token) @@ -163,35 +152,36 @@ private: auto start = token.getLocation(); auto end = token.getEndLoc(); - return cursorSourceLocation == start - || cursorSourceLocation == end - || (sourceManager().isBeforeInTranslationUnit(start, cursorSourceLocation) && - sourceManager().isBeforeInTranslationUnit(cursorSourceLocation, end)); + return m_cursorSourceLocation == start + || m_cursorSourceLocation == end + || (sourceManager().isBeforeInTranslationUnit(start, m_cursorSourceLocation) && + sourceManager().isBeforeInTranslationUnit(m_cursorSourceLocation, end)); } bool isCurrentTokenExpansion(const clang::MacroDefinition ¯oDefinition) { - return cursorMacroDirective - && cursorMacroDirective == macroDefinition.getLocalDirective(); + return m_cursorMacroDirective + && m_cursorMacroDirective == macroDefinition.getLocalDirective(); } bool isBeforeCursorSourceLocation() const { - return !cursorMacroDirective; + return !m_cursorMacroDirective; } private: - std::vector<clang::SourceLocation> sourceLocations; - std::vector<MacroDirectiveToken> preCursorMacroDirectiveTokens; - SourceLocationsContainer &sourceLocationsContainer; - Utils::SmallString &symbolName; - clang::Preprocessor &preprocessor; - const clang::MacroDirective *cursorMacroDirective = nullptr; - clang::SourceLocation mainFileSourceLocation; - clang::SourceLocation cursorSourceLocation; - uint line; - uint column; - bool isMainFileEntered = false; + std::vector<clang::SourceLocation> m_sourceLocations; + std::vector<MacroDirectiveToken> m_preCursorMacroDirectiveTokens; + SourceLocationsContainer &m_sourceLocationsContainer; + Utils::SmallString &m_symbolName; + clang::Preprocessor &m_preprocessor; + const clang::MacroDirective *m_cursorMacroDirective = nullptr; + clang::SourceLocation m_mainFileSourceLocation; + clang::SourceLocation m_cursorSourceLocation; + FilePathCachingInterface &m_filePathCache; + uint m_line; + uint m_column; + bool m_isMainFileEntered = false; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp index 84b588118e..da16f5bdc4 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp @@ -40,7 +40,7 @@ namespace ClangBackEnd { RefactoringServer::RefactoringServer(SymbolIndexingInterface &symbolIndexing, - FilePathCache<std::mutex> &filePathCache) + FilePathCachingInterface &filePathCache) : m_symbolIndexing(symbolIndexing), m_filePathCache(filePathCache) { @@ -58,7 +58,7 @@ void RefactoringServer::end() void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) { - SymbolFinder symbolFinder(message.line(), message.column()); + SymbolFinder symbolFinder(message.line(), message.column(), m_filePathCache); symbolFinder.addFile(std::string(message.filePath().directory()), std::string(message.filePath().name()), diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h index b11cf3fc21..e0a1f23ce9 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.h +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h @@ -29,12 +29,13 @@ #include <refactoringserverinterface.h> -#include <QTimer> #include <ipcclientprovider.h> -#include <stringcache.h> +#include <filepathcachinginterface.h> #include <utils/smallstring.h> +#include <QTimer> + #include <future> #include <mutex> #include <vector> @@ -54,7 +55,7 @@ class RefactoringServer : public RefactoringServerInterface, using Future = std::future<SourceRangesForQueryMessage>; public: RefactoringServer(SymbolIndexingInterface &symbolIndexing, - FilePathCache<std::mutex> &filePathCache); + FilePathCachingInterface &filePathCache); void end() override; void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; @@ -82,7 +83,7 @@ private: ClangQueryGatherer m_gatherer; QTimer m_pollTimer; SymbolIndexingInterface &m_symbolIndexing; - FilePathCache<std::mutex> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationentry.h b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h index dbe7012388..1a7d89efcf 100644 --- a/src/tools/clangrefactoringbackend/source/sourcelocationentry.h +++ b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h @@ -25,11 +25,10 @@ #pragma once -#include <stringcachefwd.h> +#include <filepathid.h> #include <limits> #include <vector> -#include <iosfwd> using uint = unsigned int; @@ -59,18 +58,18 @@ class SourceLocationEntry { public: SourceLocationEntry(SymbolIndex symbolId, - FilePathIndex fileId, + FilePathId filePathId, LineColumn lineColumn, SymbolType symbolType) : symbolId(symbolId), - fileId(fileId), + filePathId(filePathId), line(lineColumn.line), column(lineColumn.column), symbolType(symbolType) {} SymbolIndex symbolId = 0; - FilePathIndex fileId = std::numeric_limits<uint>::max(); + FilePathId filePathId; uint line = 0; uint column = 0; SymbolType symbolType; @@ -78,7 +77,7 @@ public: friend bool operator==(const SourceLocationEntry &first, const SourceLocationEntry &second) { return first.symbolId == second.symbolId - && first.fileId == second.fileId + && first.filePathId == second.filePathId && first.line == second.line && first.column == second.column && first.symbolType == second.symbolType; @@ -87,6 +86,4 @@ public: using SourceLocationEntries = std::vector<SourceLocationEntry>; -std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); - } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h index 82dfcf2b40..c7d11da517 100644 --- a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h +++ b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h @@ -25,28 +25,15 @@ #pragma once +#include <filepathcachinginterface.h> #include <sourcelocationscontainer.h> #include <sourcerangescontainer.h> -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-parameter" -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning( disable : 4100 ) -#endif - #include <clang/Basic/SourceManager.h> #include <clang/Lex/Lexer.h> #include <llvm/Support/FileSystem.h> #include <llvm/Support/FileUtilities.h> -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - #include <iterator> #include <cctype> @@ -79,7 +66,8 @@ inline void appendSourceLocationsToSourceLocationsContainer( ClangBackEnd::SourceLocationsContainer &sourceLocationsContainer, const std::vector<clang::SourceLocation> &sourceLocations, - const clang::SourceManager &sourceManager) + const clang::SourceManager &sourceManager, + FilePathCachingInterface &filePathCache) { sourceLocationsContainer.reserve(sourceLocations.size()); @@ -89,10 +77,9 @@ void appendSourceLocationsToSourceLocationsContainer( const auto fileId = decomposedLoction.first; const auto offset = decomposedLoction.second; const auto fileEntry = sourceManager.getFileEntryForID(fileId); + auto filePath = fromNativePath(absolutePath(fileEntry->getName())); - sourceLocationsContainer.insertFilePath(fileId.getHashValue(), - fromNativePath(absolutePath(fileEntry->getName()))); - sourceLocationsContainer.insertSourceLocation(fileId.getHashValue(), + sourceLocationsContainer.insertSourceLocation(filePathCache.filePathId(filePath), fullSourceLocation.getSpellingLineNumber(), fullSourceLocation.getSpellingColumnNumber(), offset); diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp index 399a7353f3..d275cfe4e2 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp +++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp @@ -28,14 +28,7 @@ #include "sourcelocationsutils.h" #include <sourcerangescontainer.h> - -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-parameter" -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning( disable : 4100 ) -#endif +#include <filepathcachinginterface.h> #include <clang/Basic/SourceManager.h> #include <clang/Lex/Lexer.h> @@ -43,18 +36,12 @@ #include <llvm/Support/FileUtilities.h> #include <llvm/ADT/SmallVector.h> -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - namespace ClangBackEnd { SourceRangeExtractor::SourceRangeExtractor( const clang::SourceManager &sourceManager, const clang::LangOptions &languageOptions, - ClangBackEnd::FilePathCache<std::mutex> &filePathCache, + FilePathCachingInterface &filePathCache, SourceRangesContainer &sourceRangesContainer) : sourceManager(sourceManager), languageOptions(languageOptions), @@ -127,16 +114,14 @@ const clang::SourceRange SourceRangeExtractor::extendSourceRangeToLastTokenEnd(c return {sourceRange.getBegin(), endLocation}; } -void SourceRangeExtractor::insertSourceRange(uint fileId, - Utils::PathString &&filePath, +void SourceRangeExtractor::insertSourceRange(FilePathId filePathId, const clang::FullSourceLoc &startLocation, uint startOffset, const clang::FullSourceLoc &endLocation, uint endOffset, Utils::SmallString &&lineSnippet) { - sourceRangesContainer.insertFilePath(fileId, std::move(filePath)); - sourceRangesContainer.insertSourceRange(fileId, + sourceRangesContainer.insertSourceRange(filePathId, startLocation.getSpellingLineNumber(), startLocation.getSpellingColumnNumber(), startOffset, @@ -146,7 +131,7 @@ void SourceRangeExtractor::insertSourceRange(uint fileId, std::move(lineSnippet)); } -FilePathIndex SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const +FilePathId SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const { auto found = m_fileIdMapping.find(fileId.getHashValue()); if (found != m_fileIdMapping.end()) { @@ -154,7 +139,7 @@ FilePathIndex SourceRangeExtractor::findFileId(clang::FileID fileId, const clang } auto filePath = absolutePath(fileEntry->getName()); - return filePathCache.stringId(fromNativePath(filePath)); + return filePathCache.filePathId(fromNativePath(filePath)); } void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange) @@ -176,13 +161,11 @@ void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange) endOffset); insertSourceRange(findFileId(fileId, fileEntry), - fromNativePath(absolutePath(fileEntry->getName())), startSourceLocation, startOffset, endSourceLocation, endOffset, std::move(lineSnippet)); - } } diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h index 3064642974..85c277265d 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h +++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h @@ -25,9 +25,10 @@ #pragma once -#include <stringcache.h> +#include <filepathcachingfwd.h> #include <filepath.h> +#include <filepathid.h> #include <utils/smallstringfwd.h> @@ -59,7 +60,7 @@ class SourceRangeExtractor public: SourceRangeExtractor(const clang::SourceManager &sourceManager, const clang::LangOptions &languageOptions, - ClangBackEnd::FilePathCache<std::mutex> &filePathCache, + FilePathCachingInterface &filePathCache, SourceRangesContainer &sourceRangesContainer); void addSourceRange(const clang::SourceRange &sourceRange); @@ -74,21 +75,20 @@ public: const clang::SourceRange extendSourceRangeToLastTokenEnd(const clang::SourceRange sourceRange); private: - void insertSourceRange(uint fileId, - Utils::PathString &&filePath, + void insertSourceRange(FilePathId filePathId, const clang::FullSourceLoc &startLocation, uint startOffset, const clang::FullSourceLoc &endLocation, uint endOffset, Utils::SmallString &&lineSnippet); - FilePathIndex findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const; + FilePathId findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const; private: - mutable std::unordered_map<uint, uint> m_fileIdMapping; + mutable std::unordered_map<uint, FilePathId> m_fileIdMapping; const clang::SourceManager &sourceManager; const clang::LangOptions &languageOptions; - ClangBackEnd::FilePathCache<std::mutex> &filePathCache; + FilePathCachingInterface &filePathCache; SourceRangesContainer &sourceRangesContainer; }; diff --git a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h index c144c7a9c5..5a103fd233 100644 --- a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h +++ b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h @@ -25,8 +25,6 @@ #pragma once -#include <createtablesqlstatementbuilder.h> - #include <sqlitetransaction.h> #include <sqlitetable.h> @@ -96,9 +94,6 @@ public: "INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)", database }; -// WriteStatement syncNewLocationsToLocationsStatement{ -// "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations", -// database}; ReadStatement selectNewSourceIdsStatement{ "SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)", database @@ -109,10 +104,6 @@ public: "(SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)", database }; - WriteStatement insertSourcesStatement{ - "INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)", - database - }; WriteStatement syncNewSymbolsFromSymbolsStatement{ "UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)", database diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp b/src/tools/clangrefactoringbackend/source/symbolfinder.cpp index 02f727b614..8f002f10a1 100644 --- a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolfinder.cpp @@ -30,9 +30,10 @@ namespace ClangBackEnd { -SymbolFinder::SymbolFinder(uint line, uint column) - : usrFindingAction(line, column), - sourceFileCallbacks(line, column) +SymbolFinder::SymbolFinder(uint line, uint column, FilePathCachingInterface &filePathCache) + : m_usrFindingAction(line, column), + m_symbolLocationFinderAction(filePathCache), + m_sourceFileCallbacks(line, column, filePathCache) { } @@ -40,39 +41,39 @@ void SymbolFinder::findSymbol() { clang::tooling::ClangTool tool = createTool(); - tool.run(clang::tooling::newFrontendActionFactory(&usrFindingAction, &sourceFileCallbacks).get()); + tool.run(clang::tooling::newFrontendActionFactory(&m_usrFindingAction, &m_sourceFileCallbacks).get()); - if (sourceFileCallbacks.hasSourceLocations()) { - sourceLocations_ = sourceFileCallbacks.takeSourceLocations(); - symbolName = sourceFileCallbacks.takeSymbolName(); + if (m_sourceFileCallbacks.hasSourceLocations()) { + m_sourceLocations_ = m_sourceFileCallbacks.takeSourceLocations(); + m_symbolName = m_sourceFileCallbacks.takeSymbolName(); } else { - symbolLocationFinderAction.setUnifiedSymbolResolutions(usrFindingAction.takeUnifiedSymbolResolutions()); + m_symbolLocationFinderAction.setUnifiedSymbolResolutions(m_usrFindingAction.takeUnifiedSymbolResolutions()); - tool.run(clang::tooling::newFrontendActionFactory(&symbolLocationFinderAction).get()); + tool.run(clang::tooling::newFrontendActionFactory(&m_symbolLocationFinderAction).get()); - sourceLocations_ = symbolLocationFinderAction.takeSourceLocations(); - symbolName = usrFindingAction.takeSymbolName(); + m_sourceLocations_ = m_symbolLocationFinderAction.takeSourceLocations(); + m_symbolName = m_usrFindingAction.takeSymbolName(); } } Utils::SmallString SymbolFinder::takeSymbolName() { - return std::move(symbolName); + return std::move(m_symbolName); } const std::vector<USRName> &SymbolFinder::unifiedSymbolResolutions() { - return symbolLocationFinderAction.unifiedSymbolResolutions(); + return m_symbolLocationFinderAction.unifiedSymbolResolutions(); } const SourceLocationsContainer &SymbolFinder::sourceLocations() const { - return sourceLocations_; + return m_sourceLocations_; } SourceLocationsContainer SymbolFinder::takeSourceLocations() { - return std::move(sourceLocations_); + return std::move(m_sourceLocations_); } } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.h b/src/tools/clangrefactoringbackend/source/symbolfinder.h index a76639aa26..a3c9659032 100644 --- a/src/tools/clangrefactoringbackend/source/symbolfinder.h +++ b/src/tools/clangrefactoringbackend/source/symbolfinder.h @@ -30,6 +30,7 @@ #include "symbollocationfinderaction.h" #include "locationsourcefilecallbacks.h" +#include <filepathcachingfwd.h> #include <sourcelocationscontainer.h> namespace ClangBackEnd { @@ -37,7 +38,7 @@ namespace ClangBackEnd { class SymbolFinder : public ClangTool { public: - SymbolFinder(uint line, uint column); + SymbolFinder(uint line, uint column, FilePathCachingInterface &filePathCache); void findSymbol(); @@ -47,12 +48,11 @@ public: SourceLocationsContainer takeSourceLocations(); private: - Utils::SmallString symbolName; - USRFindingAction usrFindingAction; - SymbolLocationFinderAction symbolLocationFinderAction; - LocationSourceFileCallbacks sourceFileCallbacks; - - ClangBackEnd::SourceLocationsContainer sourceLocations_; + Utils::SmallString m_symbolName; + USRFindingAction m_usrFindingAction; + SymbolLocationFinderAction m_symbolLocationFinderAction; + LocationSourceFileCallbacks m_sourceFileCallbacks; + ClangBackEnd::SourceLocationsContainer m_sourceLocations_; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index 4dd173e1bf..24957eb7bf 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -33,7 +33,7 @@ #include "symbolstorage.h" #include <refactoringdatabaseinitializer.h> -#include <stringcache.h> +#include <filepathcachingfwd.h> #include <sqlitedatabase.h> #include <sqlitereadstatement.h> @@ -48,13 +48,11 @@ public: Sqlite::ReadStatement, Sqlite::WriteStatement>; using Storage = ClangBackEnd::SymbolStorage<StatementFactory>; - using DatabaseInitializer = RefactoringDatabaseInitializer<Sqlite::Database>; - SymbolIndexing(FilePathCache<std::mutex> &filePathCache, - Utils::PathString &&databaseFilePath) + SymbolIndexing(Sqlite::Database &database, + FilePathCachingInterface &filePathCache) : m_filePathCache(filePathCache), - m_database(std::move(databaseFilePath)), - m_databaseInitializer(m_database) + m_statementFactory(database) { } @@ -63,11 +61,6 @@ public: return m_indexer; } - Sqlite::Database &database() - { - return m_database; - } - void updateProjectParts(V2::ProjectPartContainers &&projectParts, V2::FileContainers &&generatedFiles) { @@ -75,11 +68,9 @@ public: } private: - FilePathCache<std::mutex> &m_filePathCache; - Sqlite::Database m_database; - DatabaseInitializer m_databaseInitializer; + FilePathCachingInterface &m_filePathCache; SymbolsCollector m_collector{m_filePathCache}; - StatementFactory m_statementFactory{m_database}; + StatementFactory m_statementFactory; Storage m_symbolStorage{m_statementFactory, m_filePathCache}; SymbolIndexer m_indexer{m_collector, m_symbolStorage}; }; diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp index 2b07e893f5..f8782b405b 100644 --- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp +++ b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp @@ -28,6 +28,8 @@ #include "sourcelocationsutils.h" #include "findlocationsofusrs.h" +#include <filepathcachingfwd.h> + #include <clang/AST/ASTConsumer.h> #include <clang/AST/ASTContext.h> @@ -38,8 +40,10 @@ namespace ClangBackEnd { class FindingSymbolsASTConsumer : public clang::ASTConsumer { public: - FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions) - : m_unifiedSymbolResolutions(unifiedSymbolResolutions) + FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions, + FilePathCachingInterface &filePathCache) + : m_unifiedSymbolResolutions(unifiedSymbolResolutions), + m_filePathCache(filePathCache) { } @@ -65,7 +69,10 @@ public: void updateSourceLocations(const std::vector<clang::SourceLocation> &sourceLocations, const clang::SourceManager &sourceManager) { - appendSourceLocationsToSourceLocationsContainer(*m_sourceLocationsContainer, sourceLocations, sourceManager); + appendSourceLocationsToSourceLocationsContainer(*m_sourceLocationsContainer, + sourceLocations, + sourceManager, + m_filePathCache); } void setSourceLocations(ClangBackEnd::SourceLocationsContainer *sourceLocations) @@ -76,11 +83,13 @@ public: private: ClangBackEnd::SourceLocationsContainer *m_sourceLocationsContainer = nullptr; std::vector<USRName> &m_unifiedSymbolResolutions; + FilePathCachingInterface &m_filePathCache; }; std::unique_ptr<clang::ASTConsumer> SymbolLocationFinderAction::newASTConsumer() { - auto consumer = std::unique_ptr<FindingSymbolsASTConsumer>(new FindingSymbolsASTConsumer(m_unifiedSymbolResolutions_)); + auto consumer = std::make_unique<FindingSymbolsASTConsumer>(m_unifiedSymbolResolutions_, + m_filePathCache); consumer->setSourceLocations(&m_sourceLocations); diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h index ae601d8219..e3f4c4a2f3 100644 --- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h +++ b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h @@ -27,6 +27,7 @@ #include "clangrefactoringbackend_global.h" +#include <filepathcachingfwd.h> #include <sourcelocationscontainer.h> #include <clang/Tooling/Refactoring.h> @@ -40,27 +41,31 @@ namespace ClangBackEnd { class SymbolLocationFinderAction { public: + SymbolLocationFinderAction(FilePathCachingInterface &filePathCache) + : m_filePathCache(filePathCache) + {} - std::unique_ptr<clang::ASTConsumer> newASTConsumer(); + std::unique_ptr<clang::ASTConsumer> newASTConsumer(); - SourceLocationsContainer takeSourceLocations() - { - return std::move(m_sourceLocations); - } + SourceLocationsContainer takeSourceLocations() + { + return std::move(m_sourceLocations); + } - void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions) - { - m_unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions); - } + void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions) + { + m_unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions); + } - const std::vector<USRName> &unifiedSymbolResolutions() const - { - return m_unifiedSymbolResolutions_; - } + const std::vector<USRName> &unifiedSymbolResolutions() const + { + return m_unifiedSymbolResolutions_; + } private: - ClangBackEnd::SourceLocationsContainer m_sourceLocations; - std::vector<USRName> m_unifiedSymbolResolutions_; + ClangBackEnd::SourceLocationsContainer m_sourceLocations; + std::vector<USRName> m_unifiedSymbolResolutions_; + FilePathCachingInterface &m_filePathCache; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp index c759232a04..a6e8b21727 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp @@ -27,7 +27,7 @@ namespace ClangBackEnd { -SymbolsCollector::SymbolsCollector(FilePathCache<std::mutex> &filePathCache) +SymbolsCollector::SymbolsCollector(FilePathCachingInterface &filePathCache) : m_collectSymbolsAction(filePathCache) { } diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h index 6bbdfbcf9e..279de0dadb 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.h +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h @@ -30,14 +30,15 @@ #include "collectsymbolsaction.h" #include "symbolscollectorinterface.h" #include "symbolentry.h" -#include "stringcache.h" + +#include <filepathcachingfwd.h> namespace ClangBackEnd { class SymbolsCollector : public ClangTool, public SymbolsCollectorInterface { public: - SymbolsCollector(FilePathCache<std::mutex> &filePathCache); + SymbolsCollector(FilePathCachingInterface &filePathCache); void addFiles(const Utils::PathStringVector &filePaths, const Utils::SmallStringVector &arguments) override; diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h index 835f7dec92..b1fdb75d11 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorage.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h @@ -29,9 +29,7 @@ #include <sqliteexception.h> #include <sqlitetransaction.h> -#include <stringcache.h> - -#include <mutex> +#include <filepathcachingfwd.h> namespace ClangBackEnd { @@ -45,7 +43,7 @@ class SymbolStorage : public SymbolStorageInterface public: SymbolStorage(StatementFactory &statementFactory, - FilePathCache<std::mutex> &filePathCache) + FilePathCachingInterface &filePathCache) : m_statementFactory(statementFactory), m_filePathCache(filePathCache) { @@ -61,7 +59,6 @@ public: addNewSymbolsToSymbols(); syncNewSymbolsFromSymbols(); syncSymbolsIntoNewLocations(); - insertNewSources(); deleteAllLocationsFromUpdatedFiles(); insertNewLocationsInLocations(); deleteNewSymbolsTable(); @@ -89,7 +86,7 @@ public: statement.write(locationsEntry.symbolId, locationsEntry.line, locationsEntry.column, - locationsEntry.fileId); + locationsEntry.filePathId.fileNameId); } } @@ -118,23 +115,6 @@ public: m_statementFactory.insertNewLocationsInLocationsStatement.execute(); } - FilePathIndices selectNewSourceIds() const - { - ReadStatement &statement = m_statementFactory.selectNewSourceIdsStatement; - - return statement.template values<FilePathIndex>(16); - } - - void insertNewSources() - { - WriteStatement &statement = m_statementFactory.insertSourcesStatement; - - FilePathIndices newSourceIds = selectNewSourceIds(); - - for (FilePathIndex sourceId : newSourceIds) - statement.write(sourceId, m_filePathCache.string(sourceId)); - } - void deleteNewSymbolsTable() { m_statementFactory.deleteNewSymbolsTableStatement.execute(); @@ -152,7 +132,7 @@ public: private: StatementFactory &m_statementFactory; - FilePathCache<std::mutex> &m_filePathCache; + FilePathCachingInterface &m_filePathCache; }; } // namespace ClangBackEnd |