aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/clangsupport
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2019-03-13 15:09:30 +0100
committerMarco Bubke <marco.bubke@qt.io>2019-04-01 10:31:38 +0000
commit6effa1822bd9bd265504c5ac3fed3fa5281e169f (patch)
tree794897a4f1f31c6040b64910ad807a865b0af451 /src/libs/clangsupport
parent72494277490566a04cb03bfbc25936eaa996c3b1 (diff)
Clang: Improve project part updating
The project part ids are now already created very early in the database. This removes some checks because we can assume that an id already exists. The project part are now completely persistent, so we can read them from the database and compare them with new generated from a new creator session. This should help to not recreate the same PCH again and again. Task-number: QTCREATORBUG-21151 Change-Id: Iced818ff9f7431eaed3e37978087cc0a43b9afda Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'src/libs/clangsupport')
-rw-r--r--src/libs/clangsupport/clangpathwatcher.h67
-rw-r--r--src/libs/clangsupport/clangpathwatcherinterface.h2
-rw-r--r--src/libs/clangsupport/clangpathwatchernotifier.h3
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri7
-rw-r--r--src/libs/clangsupport/clangsupportexceptions.h (renamed from src/libs/clangsupport/removeprojectpartsmessage.cpp)25
-rw-r--r--src/libs/clangsupport/filepath.h2
-rw-r--r--src/libs/clangsupport/filepathid.h2
-rw-r--r--src/libs/clangsupport/idpaths.h5
-rw-r--r--src/libs/clangsupport/projectpartartefact.cpp130
-rw-r--r--src/libs/clangsupport/projectpartartefact.h122
-rw-r--r--src/libs/clangsupport/projectpartcontainer.cpp9
-rw-r--r--src/libs/clangsupport/projectpartcontainer.h56
-rw-r--r--src/libs/clangsupport/projectpartid.h77
-rw-r--r--src/libs/clangsupport/projectpartpch.cpp3
-rw-r--r--src/libs/clangsupport/projectpartpch.h29
-rw-r--r--src/libs/clangsupport/projectpartpchproviderinterface.h2
-rw-r--r--src/libs/clangsupport/projectpartsstorage.h336
-rw-r--r--src/libs/clangsupport/projectpartsstorageinterface.h73
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h34
-rw-r--r--src/libs/clangsupport/removeprojectpartsmessage.h11
20 files changed, 879 insertions, 116 deletions
diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h
index 258c63e9383..dab52996c28 100644
--- a/src/libs/clangsupport/clangpathwatcher.h
+++ b/src/libs/clangsupport/clangpathwatcher.h
@@ -38,7 +38,7 @@ namespace ClangBackEnd {
class WatcherEntry
{
public:
- int id;
+ ProjectPartId id;
FilePathId pathId;
friend bool operator==(WatcherEntry first, WatcherEntry second)
@@ -69,13 +69,6 @@ public:
using WatcherEntries = std::vector<WatcherEntry>;
-using IdCache = StringCache<Utils::SmallString,
- Utils::SmallStringView,
- int,
- NonLockingMutex,
- decltype(&Utils::compare),
- Utils::compare>;
-
template <typename FileSystemWatcher,
typename Timer>
class CLANGSUPPORT_GCCEXPORT ClangPathWatcher : public ClangPathWatcherInterface
@@ -109,9 +102,9 @@ public:
removeUnusedEntries(entriesAndIds.first, entriesAndIds.second);
}
- void removeIds(const Utils::SmallStringVector &ids) override
+ void removeIds(const ProjectPartIds &ids) override
{
- auto removedEntries = removeIdsFromWatchedEntries(convertToIdNumbers(ids));
+ auto removedEntries = removeIdsFromWatchedEntries(ids);
auto filteredPaths = filterNotWatchedPaths(removedEntries);
@@ -124,7 +117,6 @@ public:
m_notifier = notifier;
}
-unittest_public:
static std::vector<uint> idsFromIdPaths(const std::vector<IdPaths> &idPaths)
{
std::vector<uint> ids;
@@ -144,15 +136,6 @@ unittest_public:
return ids;
}
- std::vector<int> convertToIdNumbers(const Utils::SmallStringVector &ids)
- {
- std::vector<int> idNumbers = m_idCache.stringIds(ids);
-
- std::sort(idNumbers.begin(), idNumbers.end());
-
- return idNumbers;
- }
-
std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths)
{
auto sumSize = [] (std::size_t size, const IdPaths &idPath) {
@@ -162,20 +145,19 @@ unittest_public:
return std::accumulate(idPaths.begin(), idPaths.end(), std::size_t(0), sumSize);
}
-
- std::pair<WatcherEntries, std::vector<int>>
- convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths)
+ std::pair<WatcherEntries, ProjectPartIds> convertIdPathsToWatcherEntriesAndIds(
+ const std::vector<IdPaths> &idPaths)
{
WatcherEntries entries;
entries.reserve(sizeOfIdPaths(idPaths));
- std::vector<int> ids;
+ ProjectPartIds ids;
ids.reserve(ids.size());
auto outputIterator = std::back_inserter(entries);
for (const IdPaths &idPath : idPaths)
{
- int id = m_idCache.stringId(idPath.id);
+ ProjectPartId id = idPath.id;
ids.push_back(id);
@@ -203,8 +185,7 @@ unittest_public:
m_fileSystemWatcher.addPaths(convertWatcherEntriesToQStringList(filteredPaths));
}
- void removeUnusedEntries(const WatcherEntries &entries,
- const std::vector<int> &ids)
+ void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids)
{
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
@@ -286,9 +267,8 @@ unittest_public:
return notAnymoreWatchedEntries;
}
- WatcherEntries notAnymoreWatchedEntriesWithIds(
- const WatcherEntries &newEntries,
- const std::vector<int> &ids) const
+ WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries,
+ const ProjectPartIds &ids) const
{
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
@@ -345,16 +325,13 @@ unittest_public:
return m_watchedEntries;
}
- WatcherEntries removeIdsFromWatchedEntries(const std::vector<int> &ids)
+ WatcherEntries removeIdsFromWatchedEntries(const ProjectPartIds &ids)
{
-
- auto keep = [&] (WatcherEntry entry) {
+ auto keep = [&](WatcherEntry entry) {
return !std::binary_search(ids.begin(), ids.end(), entry.id);
};
- auto found = std::stable_partition(m_watchedEntries.begin(),
- m_watchedEntries.end(),
- keep);
+ auto found = std::stable_partition(m_watchedEntries.begin(), m_watchedEntries.end(), keep);
WatcherEntries removedEntries(found, m_watchedEntries.end());
@@ -410,22 +387,20 @@ unittest_public:
return watchedFilePathIds;
}
- Utils::SmallStringVector idsForWatcherEntries(const WatcherEntries &foundEntries)
+ ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries)
{
- Utils::SmallStringVector ids;
+ ProjectPartIds ids;
ids.reserve(foundEntries.size());
std::transform(foundEntries.begin(),
foundEntries.end(),
std::back_inserter(ids),
- [&] (WatcherEntry entry) {
- return Utils::SmallString(m_idCache.string(entry.id));
- });
+ [&](WatcherEntry entry) { return entry.id; });
return ids;
}
- Utils::SmallStringVector uniqueIds(Utils::SmallStringVector &&ids)
+ ProjectPartIds uniqueIds(ProjectPartIds &&ids)
{
std::sort(ids.begin(), ids.end());
auto newEnd = std::unique(ids.begin(), ids.end());
@@ -439,7 +414,7 @@ unittest_public:
if (m_notifier) {
WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePathIds));
- Utils::SmallStringVector changedIds = idsForWatcherEntries(foundEntries);
+ ProjectPartIds changedIds = idsForWatcherEntries(foundEntries);
m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds)));
m_notifier->pathsChanged(watchedPaths(filePathIds));
@@ -451,13 +426,7 @@ unittest_public:
return m_pathCache;
}
- IdCache &idCache()
- {
- return m_idCache;
- }
-
private:
- IdCache m_idCache;
WatcherEntries m_watchedEntries;
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
FileSystemWatcher m_fileSystemWatcher;
diff --git a/src/libs/clangsupport/clangpathwatcherinterface.h b/src/libs/clangsupport/clangpathwatcherinterface.h
index 2a290561cd9..1b478fd19a4 100644
--- a/src/libs/clangsupport/clangpathwatcherinterface.h
+++ b/src/libs/clangsupport/clangpathwatcherinterface.h
@@ -41,7 +41,7 @@ public:
ClangPathWatcherInterface &operator=(const ClangPathWatcherInterface &) = delete;
virtual void updateIdPaths(const std::vector<IdPaths> &idPaths) = 0;
- virtual void removeIds(const Utils::SmallStringVector &ids) = 0;
+ virtual void removeIds(const ProjectPartIds &ids) = 0;
virtual void setNotifier(ClangPathWatcherNotifier *notifier) = 0;
diff --git a/src/libs/clangsupport/clangpathwatchernotifier.h b/src/libs/clangsupport/clangpathwatchernotifier.h
index 188f11a8c22..393525dbf23 100644
--- a/src/libs/clangsupport/clangpathwatchernotifier.h
+++ b/src/libs/clangsupport/clangpathwatchernotifier.h
@@ -28,6 +28,7 @@
#include "clangsupport_global.h"
#include <filepathid.h>
+#include <projectpartid.h>
#include <utils/smallstringvector.h>
@@ -40,7 +41,7 @@ public:
ClangPathWatcherNotifier(const ClangPathWatcherNotifier &) = delete;
ClangPathWatcherNotifier &operator=(const ClangPathWatcherNotifier &) = delete;
- virtual void pathsWithIdsChanged(const Utils::SmallStringVector &ids) = 0;
+ virtual void pathsWithIdsChanged(const ProjectPartIds &ids) = 0;
virtual void pathsChanged(const FilePathIds &filePathIds) = 0;
protected:
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index 7ab8e47ac78..0668382803e 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -52,7 +52,6 @@ SOURCES += \
$$PWD/refactoringserverproxy.cpp \
$$PWD/referencesmessage.cpp \
$$PWD/unsavedfilesupdatedmessage.cpp \
- $$PWD/removeprojectpartsmessage.cpp \
$$PWD/requestannotationsmessage.cpp \
$$PWD/requestfollowsymbolmessage.cpp \
$$PWD/requestreferencesmessage.cpp \
@@ -87,6 +86,7 @@ SOURCES += \
$$PWD/updategeneratedfilesmessage.cpp \
$$PWD/removegeneratedfilesmessage.cpp \
$$PWD/generatedfiles.cpp \
+ $$PWD/projectpartartefact.cpp \
$$PWD/projectpartcontainer.cpp
HEADERS += \
@@ -107,8 +107,12 @@ HEADERS += \
$$PWD/clangrefactoringmessages.h \
$$PWD/clangrefactoringservermessages.h \
$$PWD/alivemessage.h \
+ $$PWD/clangsupportexceptions.h \
$$PWD/completionsmessage.h \
$$PWD/executeinloop.h \
+ $$PWD/projectpartid.h \
+ $$PWD/projectpartsstorage.h \
+ $$PWD/projectpartsstorageinterface.h \
$$PWD/requestcompletionsmessage.h \
$$PWD/echomessage.h \
$$PWD/endmessage.h \
@@ -208,6 +212,7 @@ HEADERS += \
$$PWD/progresscounter.h \
$$PWD/includesearchpath.h \
$$PWD/commandlinebuilder.h \
+ $$PWD/projectpartartefact.h \
$$PWD/projectpartcontainer.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangsupport/removeprojectpartsmessage.cpp b/src/libs/clangsupport/clangsupportexceptions.h
index d76d67cc40f..05e48bea508 100644
--- a/src/libs/clangsupport/removeprojectpartsmessage.cpp
+++ b/src/libs/clangsupport/clangsupportexceptions.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,16 +23,25 @@
**
****************************************************************************/
-#include "removeprojectpartsmessage.h"
+#pragma once
+
+#include <sqliteexception.h>
namespace ClangBackEnd {
-CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const RemoveProjectPartsMessage &message)
+class ProjectPartArtefactParseError : public Sqlite::Exception
{
- debug.nospace() << "RemoveProjectPartsMessage("
- << message.projectsPartIds << ")";
-
- return debug;
-}
+public:
+ ProjectPartArtefactParseError(const char *whatErrorHasHappen, Utils::SmallString &&errorMessage)
+ : Exception(whatErrorHasHappen, std::move(errorMessage))
+ {}
+};
+class ProjectPartDoesNotExists : public Sqlite::Exception
+{
+public:
+ ProjectPartDoesNotExists(const char *whatErrorHasHappen, Utils::SmallString &&errorMessage)
+ : Exception(whatErrorHasHappen, std::move(errorMessage))
+ {}
+};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepath.h b/src/libs/clangsupport/filepath.h
index 72076841945..b016b7de4fa 100644
--- a/src/libs/clangsupport/filepath.h
+++ b/src/libs/clangsupport/filepath.h
@@ -95,6 +95,8 @@ public:
m_slashIndex(std::ptrdiff_t(directory.size()))
{}
+ bool isValid() const { return size() > 0 && m_slashIndex >= 0; }
+
Utils::SmallStringView directory() const noexcept
{
return mid(0, std::size_t(std::max(std::ptrdiff_t(0), m_slashIndex)));
diff --git a/src/libs/clangsupport/filepathid.h b/src/libs/clangsupport/filepathid.h
index 88426d93fcb..4feb06a5311 100644
--- a/src/libs/clangsupport/filepathid.h
+++ b/src/libs/clangsupport/filepathid.h
@@ -40,6 +40,8 @@ class FilePathId
public:
constexpr FilePathId() = default;
+ FilePathId(const char *) = delete;
+
FilePathId(int filePathId)
: filePathId(filePathId)
{}
diff --git a/src/libs/clangsupport/idpaths.h b/src/libs/clangsupport/idpaths.h
index 9fa06bdd4d2..d67a73e83e9 100644
--- a/src/libs/clangsupport/idpaths.h
+++ b/src/libs/clangsupport/idpaths.h
@@ -25,8 +25,7 @@
#pragma once
-#include <utils/smallstring.h>
-
+#include "projectpartid.h"
#include "filepathid.h"
namespace ClangBackEnd {
@@ -34,7 +33,7 @@ namespace ClangBackEnd {
class IdPaths
{
public:
- Utils::SmallString id;
+ ProjectPartId id;
FilePathIds filePathIds;
friend bool operator==(const IdPaths &first, const IdPaths &second)
diff --git a/src/libs/clangsupport/projectpartartefact.cpp b/src/libs/clangsupport/projectpartartefact.cpp
new file mode 100644
index 00000000000..7623f38796b
--- /dev/null
+++ b/src/libs/clangsupport/projectpartartefact.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "projectpartartefact.h"
+
+#include <utils/algorithm.h>
+
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace ClangBackEnd {
+
+
+
+Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringView jsonText)
+{
+ if (jsonText.isEmpty())
+ return {};
+
+ QJsonDocument document = createJsonDocument(jsonText, "Compiler arguments parsing error");
+
+ return Utils::transform<Utils::SmallStringVector>(document.array(), [] (const QJsonValue &value) {
+ return Utils::SmallString{value.toString()};
+ });
+}
+
+CompilerMacros ProjectPartArtefact::createCompilerMacrosFromDocument(const QJsonDocument &document)
+{
+ QJsonArray array = document.array();
+ CompilerMacros macros;
+ macros.reserve(array.size());
+
+ for (const QJsonValueRef entry : array) {
+ const QJsonArray entryArray = entry.toArray();
+ macros.emplace_back(
+ entryArray[0].toString(), entryArray[1].toString(), entryArray[2].toInt());
+ }
+
+ std::sort(macros.begin(), macros.end());
+
+ return macros;
+}
+
+IncludeSearchPaths ProjectPartArtefact::createIncludeSearchPathsFromDocument(const QJsonDocument &document)
+{
+ QJsonArray array = document.array();
+ IncludeSearchPaths paths;
+ paths.reserve(array.size());
+
+ for (const QJsonValueRef entry : array) {
+ const QJsonArray entryArray = entry.toArray();
+ paths.emplace_back(entryArray[0].toString(), entryArray[1].toInt(), entryArray[2].toInt());
+ }
+
+ return paths;
+}
+
+CompilerMacros ProjectPartArtefact::toCompilerMacros(Utils::SmallStringView jsonText)
+{
+ if (jsonText.isEmpty())
+ return {};
+
+ QJsonDocument document = createJsonDocument(jsonText, "Compiler macros parsing error");
+
+ return createCompilerMacrosFromDocument(document);
+}
+
+QJsonDocument ProjectPartArtefact::createJsonDocument(Utils::SmallStringView jsonText,
+ const char *whatError)
+{
+ QJsonParseError error;
+ QJsonDocument document = QJsonDocument::fromJson(QByteArray::fromRawData(jsonText.data(),
+ jsonText.size()),
+ &error);
+ checkError(whatError, error);
+
+ return document;
+}
+
+IncludeSearchPaths ProjectPartArtefact::toIncludeSearchPaths(Utils::SmallStringView jsonText)
+{
+
+ if (jsonText.isEmpty())
+ return {};
+
+ QJsonDocument document = createJsonDocument(jsonText, "Include search paths parsing error");
+
+ return createIncludeSearchPathsFromDocument(document);
+}
+
+void ProjectPartArtefact::checkError(const char *whatError, const QJsonParseError &error)
+{
+ if (error.error != QJsonParseError::NoError) {
+ throw ProjectPartArtefactParseError(whatError,
+ error.errorString());
+ }
+}
+
+bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second)
+{
+ return first.toolChainArguments == second.toolChainArguments
+ && first.compilerMacros == second.compilerMacros
+ && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
+ && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartartefact.h b/src/libs/clangsupport/projectpartartefact.h
new file mode 100644
index 00000000000..ac8c44a8910
--- /dev/null
+++ b/src/libs/clangsupport/projectpartartefact.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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 "clangsupportexceptions.h"
+#include "projectpartid.h"
+
+#include <utils/cpplanguage_details.h>
+#include <utils/smallstringvector.h>
+
+#include <compilermacro.h>
+#include <includesearchpath.h>
+
+QT_FORWARD_DECLARE_CLASS(QJsonDocument)
+QT_FORWARD_DECLARE_STRUCT(QJsonParseError)
+
+namespace ClangBackEnd {
+
+class CLANGSUPPORT_EXPORT ProjectPartArtefact
+{
+public:
+ ProjectPartArtefact() = default;
+ ProjectPartArtefact(ProjectPartId projectPartId,
+ Utils::SmallStringVector &&toolChainArguments,
+ CompilerMacros &&compilerMacros,
+ IncludeSearchPaths &&systemIncludeSearchPaths,
+ IncludeSearchPaths &&projectIncludeSearchPaths,
+ Utils::Language language,
+ Utils::LanguageVersion languageVersion,
+ Utils::LanguageExtension languageExtension)
+ : projectPartId(projectPartId)
+ , toolChainArguments(std::move(toolChainArguments))
+ , compilerMacros(std::move(compilerMacros))
+ , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
+ , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
+ , language(language)
+ , languageVersion(languageVersion)
+ , languageExtension(languageExtension)
+ {}
+
+ ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
+ Utils::SmallStringView compilerMacrosText,
+ Utils::SmallStringView systemIncludeSearchPathsText,
+ Utils::SmallStringView projectIncludeSearchPathsText,
+ int projectPartId,
+ int language,
+ int languageVersion,
+ int languageExtension)
+ : projectPartId(projectPartId)
+ , toolChainArguments(toStringVector(compilerArgumentsText))
+ , compilerMacros(toCompilerMacros(compilerMacrosText))
+ , systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
+ , projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
+ , language(static_cast<Utils::Language>(language))
+ , languageVersion(static_cast<Utils::LanguageVersion>(languageVersion))
+ , languageExtension(static_cast<Utils::LanguageExtension>(languageExtension))
+ {}
+
+ ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
+ Utils::SmallStringView compilerMacrosText,
+ Utils::SmallStringView systemIncludeSearchPathsText,
+ Utils::SmallStringView projectIncludeSearchPathsText,
+ int projectPartId,
+ Utils::Language language,
+ Utils::LanguageVersion languageVersion,
+ Utils::LanguageExtension languageExtension)
+ : projectPartId(projectPartId)
+ , toolChainArguments(toStringVector(compilerArgumentsText))
+ , compilerMacros(toCompilerMacros(compilerMacrosText))
+ , systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
+ , projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
+ , language(language)
+ , languageVersion(languageVersion)
+ , languageExtension(languageExtension)
+ {}
+
+ static Utils::SmallStringVector toStringVector(Utils::SmallStringView jsonText);
+ static CompilerMacros createCompilerMacrosFromDocument(const QJsonDocument &document);
+ static IncludeSearchPaths createIncludeSearchPathsFromDocument(const QJsonDocument &document);
+ static CompilerMacros toCompilerMacros(Utils::SmallStringView jsonText);
+ static QJsonDocument createJsonDocument(Utils::SmallStringView jsonText, const char *whatError);
+ static IncludeSearchPaths toIncludeSearchPaths(Utils::SmallStringView jsonText);
+ static void checkError(const char *whatError, const QJsonParseError &error);
+ friend bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second);
+
+public:
+ ProjectPartId projectPartId;
+ Utils::SmallStringVector toolChainArguments;
+ CompilerMacros compilerMacros;
+ IncludeSearchPaths systemIncludeSearchPaths;
+ IncludeSearchPaths projectIncludeSearchPaths;
+ Utils::Language language = Utils::Language::Cxx;
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
+ Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
+};
+
+using ProjectPartArtefacts = std::vector<ProjectPartArtefact>;
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartcontainer.cpp b/src/libs/clangsupport/projectpartcontainer.cpp
index a51e927db59..680b414dc7d 100644
--- a/src/libs/clangsupport/projectpartcontainer.cpp
+++ b/src/libs/clangsupport/projectpartcontainer.cpp
@@ -29,12 +29,9 @@ namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const ProjectPartContainer &container)
{
- debug.nospace() << "ProjectPartContainer("
- << container.projectPartId << ","
- << container.toolChainArguments << ", "
- << container.headerPathIds << ", "
- << container.sourcePathIds
- << ")";
+ debug.nospace() << "ProjectPartContainer(" << container.projectPartId.projectPathId << ","
+ << container.toolChainArguments << ", " << container.headerPathIds << ", "
+ << container.sourcePathIds << ")";
return debug;
}
diff --git a/src/libs/clangsupport/projectpartcontainer.h b/src/libs/clangsupport/projectpartcontainer.h
index 06065911372..f1c64bd2375 100644
--- a/src/libs/clangsupport/projectpartcontainer.h
+++ b/src/libs/clangsupport/projectpartcontainer.h
@@ -30,19 +30,21 @@
#include "compilermacro.h"
#include "filepathid.h"
#include "includesearchpath.h"
+#include "projectpartartefact.h"
+#include "projectpartid.h"
#include <utils/cpplanguage_details.h>
#include <utils/smallstringio.h>
namespace ClangBackEnd {
-class ProjectPartContainer
+class ProjectPartContainer : public ProjectPartArtefact
{
using uchar = unsigned char;
public:
ProjectPartContainer() = default;
- ProjectPartContainer(Utils::SmallString &&projectPartId,
- Utils::SmallStringVector &&arguments,
+ ProjectPartContainer(ProjectPartId projectPartId,
+ Utils::SmallStringVector &&toolChainArguments,
CompilerMacros &&compilerMacros,
IncludeSearchPaths &&systemIncludeSearchPaths,
IncludeSearchPaths &&projectIncludeSearchPaths,
@@ -51,18 +53,36 @@ public:
Utils::Language language,
Utils::LanguageVersion languageVersion,
Utils::LanguageExtension languageExtension)
- : projectPartId(std::move(projectPartId))
- , toolChainArguments(std::move(arguments))
- , compilerMacros(std::move(compilerMacros))
- , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
- , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
+ : ProjectPartArtefact(projectPartId,
+ std::move(toolChainArguments),
+ std::move(compilerMacros),
+ std::move(systemIncludeSearchPaths),
+ std::move(projectIncludeSearchPaths),
+ language,
+ languageVersion,
+ languageExtension)
, headerPathIds(std::move(headerPathIds))
, sourcePathIds(std::move(sourcePathIds))
- , language(language)
- , languageVersion(languageVersion)
- , languageExtension(languageExtension)
- {
- }
+
+ {}
+
+ ProjectPartContainer(Utils::SmallStringView compilerArgumentsText,
+ Utils::SmallStringView compilerMacrosText,
+ Utils::SmallStringView systemIncludeSearchPathsText,
+ Utils::SmallStringView projectIncludeSearchPathsText,
+ int projectPartId,
+ int language,
+ int languageVersion,
+ int languageExtension)
+ : ProjectPartArtefact(compilerArgumentsText,
+ compilerMacrosText,
+ systemIncludeSearchPathsText,
+ projectIncludeSearchPathsText,
+ projectPartId,
+ language,
+ languageVersion,
+ languageExtension)
+ {}
friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
{
@@ -146,20 +166,14 @@ public:
}
public:
- Utils::SmallString projectPartId;
- Utils::SmallStringVector toolChainArguments;
- CompilerMacros compilerMacros;
- IncludeSearchPaths systemIncludeSearchPaths;
- IncludeSearchPaths projectIncludeSearchPaths;
FilePathIds headerPathIds;
FilePathIds sourcePathIds;
- Utils::Language language = Utils::Language::Cxx;
- Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
- Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
bool updateIsDeferred = false;
};
+using ProjectPartContainerReference = std::reference_wrapper<ProjectPartContainer>;
using ProjectPartContainers = std::vector<ProjectPartContainer>;
+using ProjectPartContainerReferences = std::vector<ProjectPartContainerReference>;
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
diff --git a/src/libs/clangsupport/projectpartid.h b/src/libs/clangsupport/projectpartid.h
new file mode 100644
index 00000000000..c372682bafc
--- /dev/null
+++ b/src/libs/clangsupport/projectpartid.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <QDataStream>
+
+namespace ClangBackEnd {
+
+class ProjectPartId
+{
+public:
+ constexpr ProjectPartId() = default;
+
+ ProjectPartId(const char *) = delete;
+
+ ProjectPartId(int projectPathId)
+ : projectPathId(projectPathId)
+ {}
+
+ bool isValid() const { return projectPathId >= 0; }
+
+ friend bool operator==(ProjectPartId first, ProjectPartId second)
+ {
+ return first.isValid() && first.projectPathId == second.projectPathId;
+ }
+
+ friend bool operator!=(ProjectPartId first, ProjectPartId second) { return !(first == second); }
+
+ friend bool operator<(ProjectPartId first, ProjectPartId second)
+ {
+ return first.projectPathId < second.projectPathId;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const ProjectPartId &projectPathId)
+ {
+ out << projectPathId.projectPathId;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, ProjectPartId &projectPathId)
+ {
+ in >> projectPathId.projectPathId;
+
+ return in;
+ }
+
+public:
+ int projectPathId = -1;
+};
+
+using ProjectPartIds = std::vector<ProjectPartId>;
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartpch.cpp b/src/libs/clangsupport/projectpartpch.cpp
index 35ab29c799b..aac672441c7 100644
--- a/src/libs/clangsupport/projectpartpch.cpp
+++ b/src/libs/clangsupport/projectpartpch.cpp
@@ -29,8 +29,7 @@ namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch)
{
- debug.nospace() << "FileContainer("
- << projectPartPch.projectPartId << ", "
+ debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ", "
<< projectPartPch.pchPath << ")";
return debug;
diff --git a/src/libs/clangsupport/projectpartpch.h b/src/libs/clangsupport/projectpartpch.h
index a413915b767..c471b46b166 100644
--- a/src/libs/clangsupport/projectpartpch.h
+++ b/src/libs/clangsupport/projectpartpch.h
@@ -27,8 +27,8 @@
#include "clangsupport_global.h"
-#include <utils/smallstringio.h>
#include <filepath.h>
+#include <projectpartid.h>
namespace ClangBackEnd {
@@ -36,24 +36,28 @@ class ProjectPartPch
{
public:
ProjectPartPch() = default;
- ProjectPartPch(Utils::SmallString &&projectPartId,
- FilePath &&pchPath,
- long long lastModified)
- : projectPartId(std::move(projectPartId)),
- pchPath(std::move(pchPath)),
- lastModified(lastModified)
+ ProjectPartPch(ProjectPartId projectPartId, FilePath &&pchPath, long long lastModified)
+ : projectPartId(projectPartId)
+ , pchPath(std::move(pchPath))
+ , lastModified(lastModified)
{}
- ProjectPartPch(Utils::SmallStringView pchPath,
- long long lastModified)
- : pchPath(FilePathView(pchPath)),
- lastModified(lastModified)
+ ProjectPartPch(int projectPartId, Utils::SmallStringView pchPath, long long lastModified)
+ : projectPartId(projectPartId)
+ , pchPath(FilePathView(pchPath))
+ , lastModified(lastModified)
{}
+ bool isValid() const
+ {
+ return projectPartId.isValid() && pchPath.isValid() && lastModified >= 0;
+ }
+
friend QDataStream &operator<<(QDataStream &out, const ProjectPartPch &container)
{
out << container.projectPartId;
out << container.pchPath;
+ out << container.lastModified;
return out;
}
@@ -62,6 +66,7 @@ public:
{
in >> container.projectPartId;
in >> container.pchPath;
+ in >> container.lastModified;
return in;
}
@@ -79,7 +84,7 @@ public:
}
public:
- Utils::SmallString projectPartId;
+ ProjectPartId projectPartId;
FilePath pchPath;
long long lastModified = -1;
};
diff --git a/src/libs/clangsupport/projectpartpchproviderinterface.h b/src/libs/clangsupport/projectpartpchproviderinterface.h
index 0b74bd6083c..282e541cfd8 100644
--- a/src/libs/clangsupport/projectpartpchproviderinterface.h
+++ b/src/libs/clangsupport/projectpartpchproviderinterface.h
@@ -39,7 +39,7 @@ public:
ProjectPartPchProviderInterface &operator=(const ProjectPartPchProviderInterface &) = delete;
virtual Utils::optional<ClangBackEnd::ProjectPartPch> projectPartPch(
- Utils::SmallStringView projectPartId) const = 0;
+ ClangBackEnd::ProjectPartId projectPartId) const = 0;
virtual const ClangBackEnd::ProjectPartPchs &projectPartPchs() const = 0;
diff --git a/src/libs/clangsupport/projectpartsstorage.h b/src/libs/clangsupport/projectpartsstorage.h
new file mode 100644
index 00000000000..c91291bca20
--- /dev/null
+++ b/src/libs/clangsupport/projectpartsstorage.h
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "clangsupportexceptions.h"
+#include "projectpartsstorageinterface.h"
+
+#include <sqliteexception.h>
+#include <sqlitetransaction.h>
+
+namespace ClangBackEnd {
+
+template<typename Database = Sqlite::Database>
+class ProjectPartsStorage final : public ProjectPartsStorageInterface
+{
+ using ReadStatement = typename Database::ReadStatement;
+ using WriteStatement = typename Database::WriteStatement;
+
+public:
+ ProjectPartsStorage(Database &database)
+ : transaction(database)
+ , database(database)
+ {
+ transaction.commit();
+ }
+
+ ProjectPartContainers fetchProjectParts() const override
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ auto values = fetchProjectPartsStatement.template values<ProjectPartContainer, 8>(4096);
+
+ transaction.commit();
+
+ return values;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectParts();
+ }
+ }
+
+ FilePathIds fetchHeaders(ProjectPartId projectPartId) const
+ {
+ return fetchProjectPartsHeadersByIdStatement
+ .template values<FilePathId>(1024, projectPartId.projectPathId);
+ }
+
+ FilePathIds fetchSources(ProjectPartId projectPartId) const
+ {
+ return fetchProjectPartsSourcesByIdStatement
+ .template values<FilePathId>(1024, projectPartId.projectPathId);
+ }
+
+ ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const override
+ {
+ try {
+ ProjectPartContainers projectParts;
+ projectParts.reserve(projectPartIds.size());
+
+ Sqlite::DeferredTransaction transaction{database};
+
+ for (ProjectPartId projectPartId : projectPartIds) {
+ auto value = fetchProjectPartByIdStatement.template value<ProjectPartContainer, 8>(
+ projectPartId.projectPathId);
+ if (value) {
+ value->headerPathIds = fetchHeaders(projectPartId);
+ value->sourcePathIds = fetchSources(projectPartId);
+ projectParts.push_back(*std::move(value));
+ }
+ }
+
+ transaction.commit();
+
+ return projectParts;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectParts(projectPartIds);
+ }
+ }
+
+ ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const override
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ ProjectPartId projectPartId;
+ auto optionalProjectPartId = fetchProjectPartIdStatement.template value<ProjectPartId>(
+ projectPartName);
+
+ if (optionalProjectPartId) {
+ projectPartId = *optionalProjectPartId;
+ } else {
+ insertProjectPartNameStatement.write(projectPartName);
+
+ projectPartId = static_cast<int>(database.lastInsertedRowId());
+ }
+
+ transaction.commit();
+
+ return projectPartId;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectPartId(projectPartName);
+ }
+ }
+
+ Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ auto optionalProjectPartName = fetchProjectPartNameStatement.template value<Utils::PathString>(
+ projectPartId.projectPathId);
+
+ transaction.commit();
+
+ if (optionalProjectPartName)
+ return *std::move(optionalProjectPartName);
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectPartName(projectPartId);
+ }
+
+ throwProjectPartDoesNotExists(projectPartId);
+ }
+
+ void insertHeaders(ProjectPartId projectPartId, const FilePathIds &headerPathIds)
+ {
+ deleteProjectPartsHeadersByIdStatement.write(projectPartId.projectPathId);
+ for (FilePathId headerPathId : headerPathIds) {
+ insertProjectPartsHeadersStatement.write(projectPartId.projectPathId,
+ headerPathId.filePathId);
+ }
+ }
+
+ void insertSources(ProjectPartId projectPartId, const FilePathIds &sourcePathIds)
+ {
+ deleteProjectPartsSourcesByIdStatement.write(projectPartId.projectPathId);
+ for (FilePathId sourcePathId : sourcePathIds) {
+ insertProjectPartsSourcesStatement.write(projectPartId.projectPathId,
+ sourcePathId.filePathId);
+ }
+ }
+
+ void updateProjectPart(ProjectPartId projectPartId,
+ const Utils::SmallStringVector &toolChainArguments,
+ const CompilerMacros &compilerMacros,
+ const IncludeSearchPaths &systemIncludeSearchPaths,
+ const IncludeSearchPaths &projectIncludeSearchPaths,
+ Utils::Language language,
+ Utils::LanguageVersion languageVersion,
+ Utils::LanguageExtension languageExtension) override
+ {
+ Utils::SmallString toolChainArgumentsAsJson = toJson(toolChainArguments);
+ Utils::SmallString compilerMacrosAsJson = toJson(compilerMacros);
+ Utils::SmallString systemIncludeSearchPathsAsJason = toJson(systemIncludeSearchPaths);
+ Utils::SmallString projectIncludeSearchPathsAsJason = toJson(projectIncludeSearchPaths);
+
+ updateProjectPartStatement.write(projectPartId.projectPathId,
+ toolChainArgumentsAsJson,
+ compilerMacrosAsJson,
+ systemIncludeSearchPathsAsJason,
+ projectIncludeSearchPathsAsJason,
+ static_cast<int>(language),
+ static_cast<int>(languageVersion),
+ static_cast<int>(languageExtension));
+ }
+
+ void updateProjectPart(const ProjectPartContainer &projectPart)
+ {
+ Utils::SmallString toolChainArgumentsAsJson = toJson(projectPart.toolChainArguments);
+ Utils::SmallString compilerMacrosAsJson = toJson(projectPart.compilerMacros);
+ Utils::SmallString systemIncludeSearchPathsAsJason = toJson(
+ projectPart.systemIncludeSearchPaths);
+ Utils::SmallString projectIncludeSearchPathsAsJason = toJson(
+ projectPart.projectIncludeSearchPaths);
+
+ updateProjectPartStatement.write(projectPart.projectPartId.projectPathId,
+ toolChainArgumentsAsJson,
+ compilerMacrosAsJson,
+ systemIncludeSearchPathsAsJason,
+ projectIncludeSearchPathsAsJason,
+ static_cast<int>(projectPart.language),
+ static_cast<int>(projectPart.languageVersion),
+ static_cast<int>(projectPart.languageExtension));
+
+ insertHeaders(projectPart.projectPartId, projectPart.headerPathIds);
+ insertSources(projectPart.projectPartId, projectPart.sourcePathIds);
+ }
+
+ void updateProjectParts(const ProjectPartContainers &projectParts) override
+ {
+ try {
+ Sqlite::ImmediateTransaction transaction{database};
+
+ for (const ProjectPartContainer &projectPart : projectParts)
+ updateProjectPart(projectPart);
+
+ transaction.commit();
+ } catch (const Sqlite::StatementIsBusy &) {
+ updateProjectParts(projectParts);
+ }
+ }
+
+ Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const override
+ {
+ ReadStatement &statement = getProjectPartArtefactsBySourceId;
+
+ return statement.template value<ProjectPartArtefact, 8>(sourceId.filePathId);
+ }
+
+ Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(ProjectPartId projectPartId) const override
+ {
+ ReadStatement &statement = getProjectPartArtefactsByProjectPartId;
+
+ return statement.template value<ProjectPartArtefact, 8>(projectPartId.projectPathId);
+ }
+
+ Sqlite::TransactionInterface &transactionBackend() override { return database; }
+
+ static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
+ {
+ QJsonDocument document;
+ QJsonArray array;
+
+ std::transform(strings.begin(),
+ strings.end(),
+ std::back_inserter(array),
+ [](const auto &string) { return QJsonValue(string.data()); });
+
+ document.setArray(array);
+
+ return document.toJson(QJsonDocument::Compact);
+ }
+
+ static Utils::SmallString toJson(const CompilerMacros &compilerMacros)
+ {
+ QJsonDocument document;
+ QJsonArray array;
+
+ for (const CompilerMacro &macro : compilerMacros)
+ array.push_back(QJsonArray{{QString(macro.key), QString(macro.value), macro.index}});
+
+ document.setArray(array);
+
+ return document.toJson(QJsonDocument::Compact);
+ }
+
+ static Utils::SmallString toJson(const IncludeSearchPaths &includeSearchPaths)
+ {
+ QJsonDocument document;
+ QJsonArray array;
+
+ for (const IncludeSearchPath &path : includeSearchPaths)
+ array.push_back(QJsonArray{{path.path.data(), path.index, int(path.type)}});
+
+ document.setArray(array);
+
+ return document.toJson(QJsonDocument::Compact);
+ }
+
+ [[noreturn]] void throwProjectPartDoesNotExists(ProjectPartId projectPartId) const
+ {
+ throw ProjectPartDoesNotExists("Try to fetch non existing project part id: ",
+ Utils::SmallString::number(projectPartId.projectPathId));
+ }
+
+public:
+ Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
+ Database &database;
+ mutable ReadStatement fetchProjectPartIdStatement{
+ "SELECT projectPartId FROM projectParts WHERE projectPartName = ?", database};
+ mutable WriteStatement insertProjectPartNameStatement{
+ "INSERT INTO projectParts(projectPartName) VALUES (?)", database};
+ mutable ReadStatement fetchProjectPartNameStatement{
+ "SELECT projectPartName FROM projectParts WHERE projectPartId = ?", database};
+ mutable ReadStatement fetchProjectPartsStatement{
+ "SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
+ "projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
+ "FROM projectParts",
+ database};
+ mutable ReadStatement fetchProjectPartByIdStatement{
+ "SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
+ "projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
+ "FROM projectParts WHERE projectPartId = ?",
+ database};
+ WriteStatement updateProjectPartStatement{
+ "UPDATE projectParts SET toolChainArguments=?002, compilerMacros=?003, "
+ "systemIncludeSearchPaths=?004, projectIncludeSearchPaths=?005, language=?006, "
+ "languageVersion=?007, languageExtension=?008 WHERE projectPartId = ?001",
+ database};
+ mutable ReadStatement getProjectPartArtefactsBySourceId{
+ "SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
+ "projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
+ "FROM projectParts WHERE projectPartId = (SELECT "
+ "projectPartId FROM projectPartsFiles WHERE sourceId = ?)",
+ database};
+ mutable ReadStatement getProjectPartArtefactsByProjectPartId{
+ "SELECT toolChainArguments, compilerMacros, systemIncludeSearchPaths, "
+ "projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension "
+ "FROM projectParts WHERE projectPartId = ?",
+ database};
+ WriteStatement deleteProjectPartsHeadersByIdStatement{
+ "DELETE FROM projectPartsHeaders WHERE projectPartId = ?", database};
+ WriteStatement deleteProjectPartsSourcesByIdStatement{
+ "DELETE FROM projectPartsSources WHERE projectPartId = ?", database};
+ WriteStatement insertProjectPartsHeadersStatement{
+ "INSERT INTO projectPartsHeaders(projectPartId, sourceId) VALUES (?,?)", database};
+ WriteStatement insertProjectPartsSourcesStatement{
+ "INSERT INTO projectPartsSources(projectPartId, sourceId) VALUES (?,?)", database};
+ mutable ReadStatement fetchProjectPartsHeadersByIdStatement{
+ "SELECT sourceId FROM projectPartsHeaders WHERE projectPartId = ?", database};
+ mutable ReadStatement fetchProjectPartsSourcesByIdStatement{
+ "SELECT sourceId FROM projectPartsSources WHERE projectPartId = ?", database};
+};
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartsstorageinterface.h b/src/libs/clangsupport/projectpartsstorageinterface.h
new file mode 100644
index 00000000000..1127f70b1fc
--- /dev/null
+++ b/src/libs/clangsupport/projectpartsstorageinterface.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <projectpartcontainer.h>
+
+#include <sqlitetransaction.h>
+#include <utils/optional.h>
+#include <utils/smallstringview.h>
+
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace ClangBackEnd {
+
+class ProjectPartsStorageInterface
+{
+public:
+ ProjectPartsStorageInterface() = default;
+ ProjectPartsStorageInterface(const ProjectPartsStorageInterface &) = delete;
+ ProjectPartsStorageInterface &operator=(const ProjectPartsStorageInterface &) = delete;
+
+ virtual ProjectPartContainers fetchProjectParts() const = 0;
+ virtual ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const = 0;
+ virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const = 0;
+ virtual Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const = 0;
+ virtual void updateProjectPart(ProjectPartId projectPartId,
+ const Utils::SmallStringVector &commandLineArguments,
+ const CompilerMacros &compilerMacros,
+ const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
+ const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths,
+ Utils::Language language,
+ Utils::LanguageVersion languageVersion,
+ Utils::LanguageExtension languageExtension)
+ = 0;
+
+ virtual void updateProjectParts(const ProjectPartContainers &projectParts) = 0;
+
+ virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0;
+ virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
+ ProjectPartId projectPartId) const = 0;
+
+ virtual Sqlite::TransactionInterface &transactionBackend() = 0;
+
+protected:
+ ~ProjectPartsStorageInterface() = default;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index f6d64a81d31..efca9254132 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -47,11 +47,13 @@ public:
createSourcesTable();
createDirectoriesTable();
createProjectPartsTable();
- createProjectPartsSourcesTable();
+ createProjectPartsFilesTable();
createUsedMacrosTable();
createFileStatusesTable();
createSourceDependenciesTable();
createPrecompiledHeadersTable();
+ createProjectPartsHeadersTable();
+ createProjectPartsSourcesTable();
transaction.commit();
@@ -135,11 +137,11 @@ public:
table.initialize(database);
}
- void createProjectPartsSourcesTable()
+ void createProjectPartsFilesTable()
{
Sqlite::Table table;
table.setUseIfNotExists(true);
- table.setName("projectPartsSources");
+ table.setName("projectPartsFiles");
const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", Sqlite::ColumnType::Integer);
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
table.addColumn("sourceType", Sqlite::ColumnType::Integer);
@@ -203,6 +205,32 @@ public:
table.initialize(database);
}
+ void createProjectPartsHeadersTable()
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("projectPartsHeaders");
+ const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId",
+ Sqlite::ColumnType::Integer);
+ table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+ table.addIndex({projectPartIdColumn});
+
+ table.initialize(database);
+ }
+
+ void createProjectPartsSourcesTable()
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("projectPartsSources");
+ const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId",
+ Sqlite::ColumnType::Integer);
+ table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+ table.addIndex({projectPartIdColumn});
+
+ table.initialize(database);
+ }
+
public:
DatabaseType &database;
};
diff --git a/src/libs/clangsupport/removeprojectpartsmessage.h b/src/libs/clangsupport/removeprojectpartsmessage.h
index 0aea092fead..ef80b521785 100644
--- a/src/libs/clangsupport/removeprojectpartsmessage.h
+++ b/src/libs/clangsupport/removeprojectpartsmessage.h
@@ -33,14 +33,11 @@ class RemoveProjectPartsMessage
{
public:
RemoveProjectPartsMessage() = default;
- RemoveProjectPartsMessage(Utils::SmallStringVector &&projectsPartIds)
+ RemoveProjectPartsMessage(ProjectPartIds &&projectsPartIds)
: projectsPartIds(std::move(projectsPartIds))
{}
- Utils::SmallStringVector takeProjectsPartIds()
- {
- return std::move(projectsPartIds);
- }
+ ProjectPartIds takeProjectsPartIds() { return std::move(projectsPartIds); }
friend QDataStream &operator<<(QDataStream &out, const RemoveProjectPartsMessage &message)
{
@@ -68,11 +65,9 @@ public:
}
public:
- Utils::SmallStringVector projectsPartIds;
+ ProjectPartIds projectsPartIds;
};
-CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const RemoveProjectPartsMessage &message);
-
DECLARE_MESSAGE(RemoveProjectPartsMessage)
} // namespace ClangBackEnd