forked from qt-creator/qt-creator
PchManager: Split pch tasks in project and system pch tasks
Like you can see in the task numbers this patch is touching many different areas. So I will only touch the main parts. It is using a clang action instead of an extra process which will be enabling the handling of generated files in PCHs. The flags from the project part are now not anymore transformed in a command line but they are saved in the container semantically aware so that they can later be merged. Most of this patch is simply polishing of other patches. Task-number: QTCREATORBUG-21346 Task-number: QTCREATORBUG-21380 Task-number: QTCREATORBUG-21382 Task-number: QTCREATORBUG-21383 Task-number: QTCREATORBUG-21693 Task-number: QTCREATORBUG-21778 Change-Id: I9b0c02d8149b554254e819448fbc61eeaa5b7494 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -44,7 +44,6 @@ SOURCES += \
|
||||
$$PWD/pchmanagerserverinterface.cpp \
|
||||
$$PWD/pchmanagerserverproxy.cpp \
|
||||
$$PWD/precompiledheadersupdatedmessage.cpp \
|
||||
$$PWD/projectpartcontainerv2.cpp \
|
||||
$$PWD/projectpartpch.cpp \
|
||||
$$PWD/readmessageblock.cpp \
|
||||
$$PWD/refactoringclientinterface.cpp \
|
||||
@@ -87,7 +86,8 @@ SOURCES += \
|
||||
$$PWD/baseserverproxy.cpp \
|
||||
$$PWD/updategeneratedfilesmessage.cpp \
|
||||
$$PWD/removegeneratedfilesmessage.cpp \
|
||||
$$PWD/generatedfiles.cpp
|
||||
$$PWD/generatedfiles.cpp \
|
||||
$$PWD/projectpartcontainer.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/cancelmessage.h \
|
||||
@@ -138,7 +138,6 @@ HEADERS += \
|
||||
$$PWD/pchmanagerserverinterface.h \
|
||||
$$PWD/pchmanagerserverproxy.h \
|
||||
$$PWD/precompiledheadersupdatedmessage.h \
|
||||
$$PWD/projectpartcontainerv2.h \
|
||||
$$PWD/projectpartpch.h \
|
||||
$$PWD/readmessageblock.h \
|
||||
$$PWD/refactoringclientinterface.h \
|
||||
@@ -205,6 +204,9 @@ HEADERS += \
|
||||
$$PWD/generatedfiles.h \
|
||||
$$PWD/generatedfilesinterface.h \
|
||||
$$PWD/progressmessage.h \
|
||||
$$PWD/progresscounter.h
|
||||
$$PWD/progresscounter.h \
|
||||
$$PWD/includesearchpath.h \
|
||||
$$PWD/commandlinebuilder.h \
|
||||
$$PWD/projectpartcontainer.h
|
||||
|
||||
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
||||
|
258
src/libs/clangsupport/commandlinebuilder.h
Normal file
258
src/libs/clangsupport/commandlinebuilder.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "filepathview.h"
|
||||
|
||||
#include <compilermacro.h>
|
||||
#include <includesearchpath.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
#include <utils/cpplanguage_details.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
template<typename ProjectInfo, typename OutputContainer = std::vector<std::string>>
|
||||
class CommandLineBuilder
|
||||
{
|
||||
public:
|
||||
CommandLineBuilder(const ProjectInfo &projectInfo,
|
||||
const Utils::SmallStringVector &toolChainArguments = {},
|
||||
FilePathView sourcePath = {},
|
||||
FilePathView outputPath = {},
|
||||
FilePathView includePchPath = {})
|
||||
{
|
||||
commandLine.reserve(128);
|
||||
|
||||
addCompiler(projectInfo.language);
|
||||
addToolChainArguments(toolChainArguments);
|
||||
addLanguage(projectInfo);
|
||||
addLanguageVersion(projectInfo);
|
||||
addNoStdIncAndNoStdLibInc();
|
||||
addProjectIncludeSearchPaths(
|
||||
sortedIncludeSearchPaths(projectInfo.projectIncludeSearchPaths));
|
||||
addSystemAndBuiltInIncludeSearchPaths(
|
||||
sortedIncludeSearchPaths(projectInfo.systemIncludeSearchPaths));
|
||||
addIncludePchPath(includePchPath);
|
||||
addOutputPath(outputPath);
|
||||
addSourcePath(sourcePath);
|
||||
}
|
||||
|
||||
void addCompiler(Utils::Language language)
|
||||
{
|
||||
if (language == Utils::Language::Cxx)
|
||||
commandLine.emplace_back("clang++");
|
||||
else
|
||||
commandLine.emplace_back("clang");
|
||||
}
|
||||
|
||||
void addToolChainArguments(const Utils::SmallStringVector &toolChainArguments)
|
||||
{
|
||||
for (Utils::SmallStringView argument : toolChainArguments)
|
||||
commandLine.emplace_back(argument);
|
||||
}
|
||||
|
||||
static const char *language(const ProjectInfo &projectInfo)
|
||||
{
|
||||
switch (projectInfo.language) {
|
||||
case Utils::Language::C:
|
||||
if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
|
||||
return "objective-c-header";
|
||||
|
||||
return "c-header";
|
||||
case Utils::Language::Cxx:
|
||||
if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
|
||||
return "objective-c++-header";
|
||||
}
|
||||
|
||||
return "c++-header";
|
||||
}
|
||||
|
||||
void addLanguage(const ProjectInfo &projectInfo)
|
||||
{
|
||||
commandLine.emplace_back("-x");
|
||||
commandLine.emplace_back(language(projectInfo));
|
||||
}
|
||||
|
||||
const char *standardLanguageVersion(Utils::LanguageVersion languageVersion)
|
||||
{
|
||||
switch (languageVersion) {
|
||||
case Utils::LanguageVersion::C89:
|
||||
return "-std=c89";
|
||||
case Utils::LanguageVersion::C99:
|
||||
return "-std=c99";
|
||||
case Utils::LanguageVersion::C11:
|
||||
return "-std=c11";
|
||||
case Utils::LanguageVersion::C18:
|
||||
return "-std=c18";
|
||||
case Utils::LanguageVersion::CXX98:
|
||||
return "-std=c++98";
|
||||
case Utils::LanguageVersion::CXX03:
|
||||
return "-std=c++03";
|
||||
case Utils::LanguageVersion::CXX11:
|
||||
return "-std=c++11";
|
||||
case Utils::LanguageVersion::CXX14:
|
||||
return "-std=c++14";
|
||||
case Utils::LanguageVersion::CXX17:
|
||||
return "-std=c++17";
|
||||
case Utils::LanguageVersion::CXX2a:
|
||||
return "-std=c++2a";
|
||||
}
|
||||
|
||||
return "-std=c++2a";
|
||||
}
|
||||
|
||||
const char *gnuLanguageVersion(Utils::LanguageVersion languageVersion)
|
||||
{
|
||||
switch (languageVersion) {
|
||||
case Utils::LanguageVersion::C89:
|
||||
return "-std=gnu89";
|
||||
case Utils::LanguageVersion::C99:
|
||||
return "-std=gnu99";
|
||||
case Utils::LanguageVersion::C11:
|
||||
return "-std=gnu11";
|
||||
case Utils::LanguageVersion::C18:
|
||||
return "-std=gnu18";
|
||||
case Utils::LanguageVersion::CXX98:
|
||||
return "-std=gnu++98";
|
||||
case Utils::LanguageVersion::CXX03:
|
||||
return "-std=gnu++03";
|
||||
case Utils::LanguageVersion::CXX11:
|
||||
return "-std=gnu++11";
|
||||
case Utils::LanguageVersion::CXX14:
|
||||
return "-std=gnu++14";
|
||||
case Utils::LanguageVersion::CXX17:
|
||||
return "-std=gnu++17";
|
||||
case Utils::LanguageVersion::CXX2a:
|
||||
return "-std=gnu++2a";
|
||||
}
|
||||
|
||||
return "-std=gnu++2a";
|
||||
}
|
||||
|
||||
const char *includeOption(IncludeSearchPathType type)
|
||||
{
|
||||
switch (type) {
|
||||
case IncludeSearchPathType::User:
|
||||
case IncludeSearchPathType::System:
|
||||
case IncludeSearchPathType::BuiltIn:
|
||||
return "-isystem";
|
||||
case IncludeSearchPathType::Framework:
|
||||
return "-F";
|
||||
case IncludeSearchPathType::Invalid:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "-I";
|
||||
}
|
||||
|
||||
void addLanguageVersion(const ProjectInfo &projectInfo)
|
||||
{
|
||||
if (projectInfo.languageExtension && Utils::LanguageExtension::Gnu)
|
||||
commandLine.emplace_back(gnuLanguageVersion(projectInfo.languageVersion));
|
||||
else
|
||||
commandLine.emplace_back(standardLanguageVersion(projectInfo.languageVersion));
|
||||
}
|
||||
|
||||
IncludeSearchPaths sortedIncludeSearchPaths(const IncludeSearchPaths &unsortedPaths)
|
||||
{
|
||||
IncludeSearchPaths paths = unsortedPaths;
|
||||
std::sort(paths.begin(), paths.end(), [](const auto &first, const auto &second) {
|
||||
return first.index < second.index;
|
||||
});
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
void addProjectIncludeSearchPaths(const IncludeSearchPaths &projectIncludeSearchPaths)
|
||||
{
|
||||
for (const IncludeSearchPath &path : projectIncludeSearchPaths) {
|
||||
commandLine.emplace_back("-I");
|
||||
commandLine.emplace_back(path.path);
|
||||
}
|
||||
}
|
||||
|
||||
void addSystemAndBuiltInIncludeSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
|
||||
{
|
||||
addSystemIncludeSearchPaths(systemIncludeSearchPaths);
|
||||
addBuiltInSystemSearchPaths(systemIncludeSearchPaths);
|
||||
}
|
||||
|
||||
void addSystemIncludeSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
|
||||
{
|
||||
for (const IncludeSearchPath &path : systemIncludeSearchPaths) {
|
||||
if (path.type != IncludeSearchPathType::BuiltIn) {
|
||||
commandLine.emplace_back(includeOption(path.type));
|
||||
commandLine.emplace_back(path.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addBuiltInSystemSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
|
||||
{
|
||||
for (const IncludeSearchPath &path : systemIncludeSearchPaths) {
|
||||
if (path.type == IncludeSearchPathType::BuiltIn) {
|
||||
commandLine.emplace_back(includeOption(path.type));
|
||||
commandLine.emplace_back(path.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addOutputPath(FilePathView outputPath)
|
||||
{
|
||||
if (!outputPath.isEmpty()) {
|
||||
commandLine.emplace_back("-o");
|
||||
commandLine.emplace_back(outputPath);
|
||||
}
|
||||
}
|
||||
|
||||
void addSourcePath(FilePathView sourcePath)
|
||||
{
|
||||
if (!sourcePath.isEmpty())
|
||||
commandLine.emplace_back(sourcePath);
|
||||
}
|
||||
|
||||
void addIncludePchPath(FilePathView includePchPath)
|
||||
{
|
||||
if (!includePchPath.isEmpty()) {
|
||||
commandLine.emplace_back("-Xclang");
|
||||
commandLine.emplace_back("-include-pch");
|
||||
commandLine.emplace_back("-Xclang");
|
||||
commandLine.emplace_back(includePchPath);
|
||||
}
|
||||
}
|
||||
|
||||
void addNoStdIncAndNoStdLibInc()
|
||||
{
|
||||
commandLine.emplace_back("-nostdinc");
|
||||
commandLine.emplace_back("-nostdlibinc");
|
||||
}
|
||||
|
||||
public:
|
||||
OutputContainer commandLine;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -51,6 +51,14 @@ public:
|
||||
m_slashIndex = view.slashIndex();
|
||||
}
|
||||
|
||||
explicit FilePath(Utils::SmallStringView &&filePath)
|
||||
: Utils::PathString(filePath)
|
||||
{
|
||||
FilePathView view{*this};
|
||||
|
||||
m_slashIndex = view.slashIndex();
|
||||
}
|
||||
|
||||
FilePath(FilePathView filePathView)
|
||||
: Utils::PathString(filePathView.toStringView()),
|
||||
m_slashIndex(filePathView.slashIndex())
|
||||
|
@@ -37,6 +37,7 @@ template <char WindowsSlash>
|
||||
class AbstractFilePathView : public Utils::SmallStringView
|
||||
{
|
||||
public:
|
||||
constexpr AbstractFilePathView() = default;
|
||||
explicit AbstractFilePathView(const char *const string, const size_type size) noexcept
|
||||
: Utils::SmallStringView(string, size),
|
||||
m_slashIndex(lastSlashIndex(*this))
|
||||
|
102
src/libs/clangsupport/includesearchpath.h
Normal file
102
src/libs/clangsupport/includesearchpath.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <utils/smallstringio.h>
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
enum class IncludeSearchPathType : unsigned char {
|
||||
Invalid,
|
||||
User,
|
||||
BuiltIn,
|
||||
System,
|
||||
Framework,
|
||||
};
|
||||
|
||||
class IncludeSearchPath
|
||||
{
|
||||
public:
|
||||
IncludeSearchPath() = default;
|
||||
IncludeSearchPath(Utils::PathString &&path, int index, IncludeSearchPathType type)
|
||||
: path(std::move(path))
|
||||
, index(index)
|
||||
, type(type)
|
||||
{}
|
||||
|
||||
IncludeSearchPath(Utils::PathString &&path, int index, int type)
|
||||
: path(std::move(path))
|
||||
, index(index)
|
||||
, type(static_cast<IncludeSearchPathType>(type))
|
||||
{}
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const IncludeSearchPath &includeSearchPath)
|
||||
{
|
||||
out << includeSearchPath.path;
|
||||
out << includeSearchPath.index;
|
||||
out << static_cast<unsigned char>(includeSearchPath.type);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
friend QDataStream &operator>>(QDataStream &in, IncludeSearchPath &includeSearchPath)
|
||||
{
|
||||
unsigned char type;
|
||||
|
||||
in >> includeSearchPath.path;
|
||||
in >> includeSearchPath.index;
|
||||
in >> type;
|
||||
|
||||
includeSearchPath.type = static_cast<IncludeSearchPathType>(type);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
friend bool operator==(const IncludeSearchPath &first, const IncludeSearchPath &second)
|
||||
{
|
||||
return std::tie(first.type, first.index, first.path)
|
||||
== std::tie(second.type, second.index, second.path);
|
||||
}
|
||||
|
||||
friend bool operator<(const IncludeSearchPath &first, const IncludeSearchPath &second)
|
||||
{
|
||||
return std::tie(first.path, first.index, first.type)
|
||||
< std::tie(second.path, second.index, second.type);
|
||||
}
|
||||
|
||||
public:
|
||||
Utils::PathString path;
|
||||
int index = -1;
|
||||
IncludeSearchPathType type = IncludeSearchPathType::Invalid;
|
||||
};
|
||||
|
||||
using IncludeSearchPaths = std::vector<IncludeSearchPath>;
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -40,23 +40,29 @@ public:
|
||||
|
||||
void addTotal(int total)
|
||||
{
|
||||
m_total += total;
|
||||
if (total) {
|
||||
m_total += total;
|
||||
|
||||
m_progressCallback(m_progress, m_total);
|
||||
m_progressCallback(m_progress, m_total);
|
||||
}
|
||||
}
|
||||
|
||||
void removeTotal(int total)
|
||||
{
|
||||
m_total -= total;
|
||||
if (total) {
|
||||
m_total -= total;
|
||||
|
||||
sendProgress();
|
||||
sendProgress();
|
||||
}
|
||||
}
|
||||
|
||||
void addProgress(int progress)
|
||||
{
|
||||
m_progress += progress;
|
||||
if (progress) {
|
||||
m_progress += progress;
|
||||
|
||||
sendProgress();
|
||||
sendProgress();
|
||||
}
|
||||
}
|
||||
|
||||
void sendProgress()
|
||||
|
@@ -23,22 +23,19 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "projectpartcontainerv2.h"
|
||||
#include "projectpartcontainer.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
namespace V2 {
|
||||
|
||||
QDebug operator<<(QDebug debug, const ProjectPartContainer &container)
|
||||
{
|
||||
debug.nospace() << "ProjectPartContainer("
|
||||
<< container.projectPartId << ","
|
||||
<< container.arguments << ", "
|
||||
<< container.toolChainArguments << ", "
|
||||
<< container.headerPathIds << ", "
|
||||
<< container.sourcePathIds
|
||||
<< ")";
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
} // namespace V2
|
||||
} // namespace ClangBackEnd
|
164
src/libs/clangsupport/projectpartcontainer.h
Normal file
164
src/libs/clangsupport/projectpartcontainer.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangsupport_global.h"
|
||||
|
||||
#include "compilermacro.h"
|
||||
#include "filepathid.h"
|
||||
#include "includesearchpath.h"
|
||||
|
||||
#include <utils/cpplanguage_details.h>
|
||||
#include <utils/smallstringio.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ProjectPartContainer
|
||||
{
|
||||
using uchar = unsigned char;
|
||||
public:
|
||||
ProjectPartContainer() = default;
|
||||
ProjectPartContainer(Utils::SmallString &&projectPartId,
|
||||
Utils::SmallStringVector &&arguments,
|
||||
CompilerMacros &&compilerMacros,
|
||||
IncludeSearchPaths &&systemIncludeSearchPaths,
|
||||
IncludeSearchPaths &&projectIncludeSearchPaths,
|
||||
FilePathIds &&headerPathIds,
|
||||
FilePathIds &&sourcePathIds,
|
||||
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))
|
||||
, headerPathIds(std::move(headerPathIds))
|
||||
, sourcePathIds(std::move(sourcePathIds))
|
||||
, language(language)
|
||||
, languageVersion(languageVersion)
|
||||
, languageExtension(languageExtension)
|
||||
{
|
||||
}
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
|
||||
{
|
||||
out << container.projectPartId;
|
||||
out << container.toolChainArguments;
|
||||
out << container.compilerMacros;
|
||||
out << container.systemIncludeSearchPaths;
|
||||
out << container.projectIncludeSearchPaths;
|
||||
out << container.headerPathIds;
|
||||
out << container.sourcePathIds;
|
||||
out << uchar(container.language);
|
||||
out << uchar(container.languageVersion);
|
||||
out << uchar(container.languageExtension);
|
||||
return out;
|
||||
}
|
||||
|
||||
friend QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
|
||||
{
|
||||
uchar language;
|
||||
uchar languageVersion;
|
||||
uchar languageExtension;
|
||||
|
||||
in >> container.projectPartId;
|
||||
in >> container.toolChainArguments;
|
||||
in >> container.compilerMacros;
|
||||
in >> container.systemIncludeSearchPaths;
|
||||
in >> container.projectIncludeSearchPaths;
|
||||
in >> container.headerPathIds;
|
||||
in >> container.sourcePathIds;
|
||||
in >> language;
|
||||
in >> languageVersion;
|
||||
in >> languageExtension;
|
||||
|
||||
container.language = static_cast<Utils::Language>(language);
|
||||
container.languageVersion = static_cast<Utils::LanguageVersion>(languageVersion);
|
||||
container.languageExtension = static_cast<Utils::LanguageExtension>(languageExtension);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
|
||||
{
|
||||
return first.projectPartId == second.projectPartId
|
||||
&& first.toolChainArguments == second.toolChainArguments
|
||||
&& first.compilerMacros == second.compilerMacros
|
||||
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
||||
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
|
||||
&& first.headerPathIds == second.headerPathIds
|
||||
&& first.sourcePathIds == second.sourcePathIds&& first.language == second.language
|
||||
&& first.languageVersion == second.languageVersion
|
||||
&& first.languageExtension == second.languageExtension;
|
||||
}
|
||||
|
||||
friend bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &second)
|
||||
{
|
||||
return std::tie(first.projectPartId,
|
||||
first.toolChainArguments,
|
||||
first.compilerMacros,
|
||||
first.systemIncludeSearchPaths,
|
||||
first.projectIncludeSearchPaths,
|
||||
first.headerPathIds,
|
||||
first.sourcePathIds,
|
||||
first.language,
|
||||
first.languageVersion,
|
||||
first.languageExtension)
|
||||
< std::tie(second.projectPartId,
|
||||
second.toolChainArguments,
|
||||
second.compilerMacros,
|
||||
second.systemIncludeSearchPaths,
|
||||
second.projectIncludeSearchPaths,
|
||||
second.headerPathIds,
|
||||
second.sourcePathIds,
|
||||
second.language,
|
||||
second.languageVersion,
|
||||
second.languageExtension);
|
||||
}
|
||||
|
||||
ProjectPartContainer clone() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
using ProjectPartContainers = std::vector<ProjectPartContainer>;
|
||||
|
||||
QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
|
||||
} // namespace ClangBackEnd
|
@@ -1,125 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangsupport_global.h"
|
||||
|
||||
#include "compilermacro.h"
|
||||
#include "filepathid.h"
|
||||
|
||||
#include <utils/smallstringio.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
namespace V2 {
|
||||
|
||||
class ProjectPartContainer
|
||||
{
|
||||
public:
|
||||
ProjectPartContainer() = default;
|
||||
ProjectPartContainer(Utils::SmallString &&projectPartId,
|
||||
Utils::SmallStringVector &&arguments,
|
||||
CompilerMacros &&compilerMacros,
|
||||
Utils::SmallStringVector &&includeSearchPaths,
|
||||
FilePathIds &&headerPathIds,
|
||||
FilePathIds &&sourcePathIds)
|
||||
: projectPartId(std::move(projectPartId)),
|
||||
arguments(std::move(arguments)),
|
||||
compilerMacros(std::move(compilerMacros)),
|
||||
includeSearchPaths(std::move(includeSearchPaths)),
|
||||
headerPathIds(std::move(headerPathIds)),
|
||||
sourcePathIds(std::move(sourcePathIds))
|
||||
{
|
||||
}
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
|
||||
{
|
||||
out << container.projectPartId;
|
||||
out << container.arguments;
|
||||
out << container.compilerMacros;
|
||||
out << container.includeSearchPaths;
|
||||
out << container.headerPathIds;
|
||||
out << container.sourcePathIds;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
friend QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
|
||||
{
|
||||
in >> container.projectPartId;
|
||||
in >> container.arguments;
|
||||
in >> container.compilerMacros;
|
||||
in >> container.includeSearchPaths;
|
||||
in >> container.headerPathIds;
|
||||
in >> container.sourcePathIds;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
|
||||
{
|
||||
return first.projectPartId == second.projectPartId
|
||||
&& first.arguments == second.arguments
|
||||
&& first.compilerMacros == second.compilerMacros
|
||||
&& first.includeSearchPaths == second.includeSearchPaths
|
||||
&& first.headerPathIds == second.headerPathIds
|
||||
&& first.sourcePathIds == second.sourcePathIds;
|
||||
}
|
||||
|
||||
friend bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &second)
|
||||
{
|
||||
return std::tie(first.projectPartId,
|
||||
first.arguments,
|
||||
first.compilerMacros,
|
||||
first.includeSearchPaths,
|
||||
first.headerPathIds,
|
||||
first.sourcePathIds)
|
||||
< std::tie(second.projectPartId,
|
||||
second.arguments,
|
||||
second.compilerMacros,
|
||||
first.includeSearchPaths,
|
||||
second.headerPathIds,
|
||||
second.sourcePathIds);
|
||||
}
|
||||
|
||||
ProjectPartContainer clone() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
Utils::SmallString projectPartId;
|
||||
Utils::SmallStringVector arguments;
|
||||
CompilerMacros compilerMacros;
|
||||
Utils::SmallStringVector includeSearchPaths;
|
||||
FilePathIds headerPathIds;
|
||||
FilePathIds sourcePathIds;
|
||||
};
|
||||
|
||||
using ProjectPartContainers = std::vector<ProjectPartContainer>;
|
||||
|
||||
QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
|
||||
} // namespace V2
|
||||
} // namespace ClangBackEnd
|
@@ -28,6 +28,7 @@
|
||||
#include "clangsupport_global.h"
|
||||
|
||||
#include <utils/smallstringio.h>
|
||||
#include <filepath.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -36,15 +37,16 @@ class ProjectPartPch
|
||||
public:
|
||||
ProjectPartPch() = default;
|
||||
ProjectPartPch(Utils::SmallString &&projectPartId,
|
||||
Utils::SmallString &&pchPath,
|
||||
FilePath &&pchPath,
|
||||
long long lastModified)
|
||||
: projectPartId(std::move(projectPartId)),
|
||||
pchPath(std::move(pchPath)),
|
||||
lastModified(lastModified)
|
||||
{}
|
||||
|
||||
ProjectPartPch(Utils::SmallStringView pchPath,
|
||||
long long lastModified)
|
||||
: pchPath(pchPath),
|
||||
: pchPath(FilePathView(pchPath)),
|
||||
lastModified(lastModified)
|
||||
{}
|
||||
|
||||
@@ -78,7 +80,7 @@ public:
|
||||
|
||||
public:
|
||||
Utils::SmallString projectPartId;
|
||||
Utils::SmallString pchPath;
|
||||
FilePath pchPath;
|
||||
long long lastModified = -1;
|
||||
};
|
||||
|
||||
|
@@ -125,7 +125,8 @@ public:
|
||||
const Sqlite::Column &projectPartNameColumn = table.addColumn("projectPartName", Sqlite::ColumnType::Text);
|
||||
table.addColumn("compilerArguments", Sqlite::ColumnType::Text);
|
||||
table.addColumn("compilerMacros", Sqlite::ColumnType::Text);
|
||||
table.addColumn("includeSearchPaths", Sqlite::ColumnType::Text);
|
||||
table.addColumn("systemIncludeSearchPaths", Sqlite::ColumnType::Text);
|
||||
table.addColumn("projectIncludeSearchPaths", Sqlite::ColumnType::Text);
|
||||
table.addUniqueIndex({projectPartNameColumn});
|
||||
|
||||
table.initialize(database);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "projectpartcontainerv2.h"
|
||||
#include "projectpartcontainer.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "filecontainerv2.h"
|
||||
#include "projectpartcontainerv2.h"
|
||||
#include "projectpartcontainer.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -34,11 +34,13 @@ class UpdateProjectPartsMessage
|
||||
{
|
||||
public:
|
||||
UpdateProjectPartsMessage() = default;
|
||||
UpdateProjectPartsMessage(V2::ProjectPartContainers &&projectsParts)
|
||||
UpdateProjectPartsMessage(ProjectPartContainers &&projectsParts,
|
||||
Utils::SmallStringVector &&toolChainArguments)
|
||||
: projectsParts(std::move(projectsParts))
|
||||
, toolChainArguments(toolChainArguments)
|
||||
{}
|
||||
|
||||
V2::ProjectPartContainers takeProjectsParts()
|
||||
ProjectPartContainers takeProjectsParts()
|
||||
{
|
||||
return std::move(projectsParts);
|
||||
}
|
||||
@@ -46,6 +48,7 @@ public:
|
||||
friend QDataStream &operator<<(QDataStream &out, const UpdateProjectPartsMessage &message)
|
||||
{
|
||||
out << message.projectsParts;
|
||||
out << message.toolChainArguments;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -53,6 +56,7 @@ public:
|
||||
friend QDataStream &operator>>(QDataStream &in, UpdateProjectPartsMessage &message)
|
||||
{
|
||||
in >> message.projectsParts;
|
||||
in >> message.toolChainArguments;
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -60,7 +64,8 @@ public:
|
||||
friend bool operator==(const UpdateProjectPartsMessage &first,
|
||||
const UpdateProjectPartsMessage &second)
|
||||
{
|
||||
return first.projectsParts == second.projectsParts;
|
||||
return first.projectsParts == second.projectsParts
|
||||
&& first.toolChainArguments == second.toolChainArguments;
|
||||
}
|
||||
|
||||
UpdateProjectPartsMessage clone() const
|
||||
@@ -69,7 +74,8 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
V2::ProjectPartContainers projectsParts;
|
||||
ProjectPartContainers projectsParts;
|
||||
Utils::SmallStringVector toolChainArguments;
|
||||
};
|
||||
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const UpdateProjectPartsMessage &message);
|
||||
|
@@ -60,4 +60,16 @@ enum class LanguageExtension : unsigned char {
|
||||
|
||||
Q_DECLARE_FLAGS(LanguageExtensions, LanguageExtension)
|
||||
|
||||
constexpr enum LanguageExtension operator|(const LanguageExtension first,
|
||||
const LanguageExtension second)
|
||||
{
|
||||
return static_cast<LanguageExtension>(
|
||||
(static_cast<unsigned char>(first) | static_cast<unsigned char>(second)));
|
||||
}
|
||||
|
||||
constexpr bool operator&&(const LanguageExtension first, const LanguageExtension second)
|
||||
{
|
||||
return static_cast<unsigned char>(first) & static_cast<unsigned char>(second);
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <cpptools/compileroptionsbuilder.h>
|
||||
#include <cpptools/projectpart.h>
|
||||
#include <cpptools/headerpathfilter.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
@@ -64,10 +65,11 @@ ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &s
|
||||
{
|
||||
}
|
||||
|
||||
void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts)
|
||||
void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments)
|
||||
{
|
||||
m_server.updateProjectParts(
|
||||
ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts)});
|
||||
m_server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{
|
||||
toProjectPartContainers(projectParts), std::move(toolChainArguments)});
|
||||
}
|
||||
|
||||
void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
|
||||
@@ -147,11 +149,21 @@ HeaderAndSources ProjectUpdater::headerAndSourcesFromProjectPart(
|
||||
return headerAndSources;
|
||||
}
|
||||
|
||||
QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart)
|
||||
QStringList ProjectUpdater::toolChainArguments(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
using CppTools::CompilerOptionsBuilder;
|
||||
CompilerOptionsBuilder builder(*projectPart, CppTools::UseSystemHeader::Yes);
|
||||
return builder.build(CppTools::ProjectFile::CXXHeader, CppTools::UsePrecompiledHeaders::No);
|
||||
|
||||
builder.addWordWidth();
|
||||
builder.addPicIfCompilerFlagsContainsIt();
|
||||
builder.addTargetTriple();
|
||||
builder.addExtraCodeModelFlags();
|
||||
builder.undefineClangVersionMacrosForMsvc();
|
||||
builder.undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
builder.addProjectConfigFileInclude();
|
||||
builder.addMsvcCompatibilityVersion();
|
||||
|
||||
return builder.options();
|
||||
}
|
||||
|
||||
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectExplorer::Macros &projectMacros)
|
||||
@@ -167,43 +179,102 @@ ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectE
|
||||
return macros;
|
||||
}
|
||||
|
||||
Utils::SmallStringVector ProjectUpdater::createIncludeSearchPaths(
|
||||
const ProjectExplorer::HeaderPaths &projectPartHeaderPaths)
|
||||
namespace {
|
||||
ClangBackEnd::IncludeSearchPathType convertType(ProjectExplorer::HeaderPathType sourceType)
|
||||
{
|
||||
Utils::SmallStringVector includePaths;
|
||||
using ProjectExplorer::HeaderPathType;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
|
||||
for (const ProjectExplorer::HeaderPath &projectPartHeaderPath : projectPartHeaderPaths) {
|
||||
if (!projectPartHeaderPath.path.isEmpty())
|
||||
includePaths.emplace_back(projectPartHeaderPath.path);
|
||||
switch (sourceType) {
|
||||
case HeaderPathType::User:
|
||||
return IncludeSearchPathType::User;
|
||||
case HeaderPathType::System:
|
||||
return IncludeSearchPathType::System;
|
||||
case HeaderPathType::BuiltIn:
|
||||
return IncludeSearchPathType::BuiltIn;
|
||||
case HeaderPathType::Framework:
|
||||
return IncludeSearchPathType::Framework;
|
||||
}
|
||||
|
||||
std::sort(includePaths.begin(), includePaths.end());
|
||||
|
||||
return includePaths;
|
||||
return IncludeSearchPathType::Invalid;
|
||||
}
|
||||
|
||||
ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
|
||||
ClangBackEnd::IncludeSearchPaths convertToIncludeSearchPaths(ProjectExplorer::HeaderPaths headerPaths)
|
||||
{
|
||||
ClangBackEnd::IncludeSearchPaths paths;
|
||||
paths.reserve(Utils::usize(headerPaths));
|
||||
|
||||
int index = 0;
|
||||
for (const ProjectExplorer::HeaderPath &headerPath : headerPaths)
|
||||
paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
|
||||
|
||||
std::sort(paths.begin(), paths.end());
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
ClangBackEnd::IncludeSearchPaths convertToIncludeSearchPaths(
|
||||
ProjectExplorer::HeaderPaths headerPaths, ProjectExplorer::HeaderPaths headerPaths2)
|
||||
{
|
||||
ClangBackEnd::IncludeSearchPaths paths;
|
||||
paths.reserve(Utils::usize(headerPaths) + Utils::usize(headerPaths2));
|
||||
|
||||
int index = 0;
|
||||
for (const ProjectExplorer::HeaderPath &headerPath : headerPaths)
|
||||
paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
|
||||
|
||||
for (const ProjectExplorer::HeaderPath &headerPath : headerPaths2)
|
||||
paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
|
||||
|
||||
std::sort(paths.begin(), paths.end());
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ProjectUpdater::SystemAndProjectIncludeSearchPaths ProjectUpdater::createIncludeSearchPaths(
|
||||
const CppTools::ProjectPart &projectPart)
|
||||
{
|
||||
CppTools::HeaderPathFilter filter(projectPart,
|
||||
CppTools::UseTweakedHeaderPaths::Yes,
|
||||
CLANG_VERSION,
|
||||
CLANG_RESOURCE_DIR);
|
||||
filter.process();
|
||||
|
||||
return {convertToIncludeSearchPaths(filter.systemHeaderPaths, filter.builtInHeaderPaths),
|
||||
convertToIncludeSearchPaths(filter.userHeaderPaths)};
|
||||
}
|
||||
|
||||
ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
|
||||
CppTools::ProjectPart *projectPart) const
|
||||
{
|
||||
|
||||
QStringList arguments = compilerArguments(projectPart);
|
||||
QStringList arguments = toolChainArguments(projectPart);
|
||||
|
||||
HeaderAndSources headerAndSources = headerAndSourcesFromProjectPart(projectPart);
|
||||
|
||||
return ClangBackEnd::V2::ProjectPartContainer(projectPart->id(),
|
||||
Utils::SmallStringVector(arguments),
|
||||
createCompilerMacros(projectPart->projectMacros),
|
||||
createIncludeSearchPaths(projectPart->headerPaths),
|
||||
std::move(headerAndSources.headers),
|
||||
std::move(headerAndSources.sources));
|
||||
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
|
||||
|
||||
return ClangBackEnd::ProjectPartContainer(projectPart->id(),
|
||||
Utils::SmallStringVector(arguments),
|
||||
createCompilerMacros(projectPart->projectMacros),
|
||||
std::move(includeSearchPaths.system),
|
||||
std::move(includeSearchPaths.project),
|
||||
std::move(headerAndSources.headers),
|
||||
std::move(headerAndSources.sources),
|
||||
projectPart->language,
|
||||
projectPart->languageVersion,
|
||||
static_cast<Utils::LanguageExtension>(
|
||||
int(projectPart->languageExtensions)));
|
||||
}
|
||||
|
||||
std::vector<ClangBackEnd::V2::ProjectPartContainer> ProjectUpdater::toProjectPartContainers(
|
||||
ClangBackEnd::ProjectPartContainers ProjectUpdater::toProjectPartContainers(
|
||||
std::vector<CppTools::ProjectPart *> projectParts) const
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
|
||||
std::vector<ClangBackEnd::V2::ProjectPartContainer> projectPartContainers;
|
||||
std::vector<ClangBackEnd::ProjectPartContainer> projectPartContainers;
|
||||
projectPartContainers.reserve(projectParts.size());
|
||||
|
||||
std::transform(projectParts.begin(),
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include <filecontainerv2.h>
|
||||
#include <filepathcachinginterface.h>
|
||||
#include <generatedfiles.h>
|
||||
#include <includesearchpath.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
#include <projectexplorer/headerpath.h>
|
||||
|
||||
@@ -46,10 +48,6 @@ class ProjectFile;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
class ProjectManagementServerInterface;
|
||||
|
||||
namespace V2 {
|
||||
class ProjectPartContainer;
|
||||
}
|
||||
}
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QStringList)
|
||||
@@ -64,33 +62,39 @@ class PchManagerClient;
|
||||
class CLANGPCHMANAGER_EXPORT ProjectUpdater
|
||||
{
|
||||
public:
|
||||
struct SystemAndProjectIncludeSearchPaths
|
||||
{
|
||||
ClangBackEnd::IncludeSearchPaths system;
|
||||
ClangBackEnd::IncludeSearchPaths project;
|
||||
};
|
||||
|
||||
ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
ClangBackEnd::FilePathCachingInterface &filePathCache);
|
||||
|
||||
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts);
|
||||
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments);
|
||||
void removeProjectParts(const QStringList &projectPartIds);
|
||||
|
||||
void updateGeneratedFiles(ClangBackEnd::V2::FileContainers &&generatedFiles);
|
||||
void removeGeneratedFiles(ClangBackEnd::FilePaths &&filePaths);
|
||||
|
||||
unittest_public:
|
||||
void setExcludedPaths(ClangBackEnd::FilePaths &&excludedPaths);
|
||||
const ClangBackEnd::FilePaths &excludedPaths() const;
|
||||
|
||||
const ClangBackEnd::GeneratedFiles &generatedFiles() const;
|
||||
|
||||
HeaderAndSources headerAndSourcesFromProjectPart(CppTools::ProjectPart *projectPart) const;
|
||||
ClangBackEnd::V2::ProjectPartContainer toProjectPartContainer(
|
||||
ClangBackEnd::ProjectPartContainer toProjectPartContainer(
|
||||
CppTools::ProjectPart *projectPart) const;
|
||||
std::vector<ClangBackEnd::V2::ProjectPartContainer> toProjectPartContainers(
|
||||
ClangBackEnd::ProjectPartContainers toProjectPartContainers(
|
||||
std::vector<CppTools::ProjectPart *> projectParts) const;
|
||||
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
|
||||
const CppTools::ProjectFile &projectFile) const;
|
||||
static QStringList compilerArguments(CppTools::ProjectPart *projectPart);
|
||||
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
|
||||
static ClangBackEnd::CompilerMacros createCompilerMacros(
|
||||
const ProjectExplorer::Macros &projectMacros);
|
||||
static Utils::SmallStringVector createIncludeSearchPaths(
|
||||
const ProjectExplorer::HeaderPaths &projectPartHeaderPaths);
|
||||
static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
|
||||
const CppTools::ProjectPart &projectPart);
|
||||
static ClangBackEnd::FilePaths createExcludedPaths(
|
||||
const ClangBackEnd::V2::FileContainers &generatedFiles);
|
||||
|
||||
|
@@ -71,7 +71,8 @@ public:
|
||||
|
||||
void projectPartsUpdated(ProjectExplorer::Project *project)
|
||||
{
|
||||
ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project));
|
||||
|
||||
ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project), {}); // TODO add support for toolchainarguments
|
||||
}
|
||||
|
||||
void projectPartsRemoved(const QStringList &projectPartIds)
|
||||
|
@@ -35,7 +35,7 @@ void RefactoringProjectUpdater::precompiledHeaderUpdated(const QString &projectP
|
||||
{
|
||||
auto projectPart = m_cppModelManager.projectPartForId(projectPartId);
|
||||
if (projectPart)
|
||||
updateProjectParts({projectPart.data()});
|
||||
updateProjectParts({projectPart.data()}, {});
|
||||
}
|
||||
|
||||
void RefactoringProjectUpdater::precompiledHeaderRemoved(const QString &projectPartId)
|
||||
|
@@ -249,6 +249,12 @@ void CompilerOptionsBuilder::addExtraCodeModelFlags()
|
||||
add(m_projectPart.extraCodeModelFlags);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addPicIfCompilerFlagsContainsIt()
|
||||
{
|
||||
if (m_projectPart.compilerFlags.contains("-fPIC"))
|
||||
add("-fPIC");
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addCompilerFlags()
|
||||
{
|
||||
add(m_compilerFlags.flags);
|
||||
|
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
void addTargetTriple();
|
||||
void addExtraCodeModelFlags();
|
||||
void addPicIfCompilerFlagsContainsIt();
|
||||
void addCompilerFlags();
|
||||
void insertWrappedQtHeaders();
|
||||
void addLanguageVersionAndExtensions();
|
||||
|
@@ -164,6 +164,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
|
||||
part->extraCodeModelFlags = tcInfo.extraCodeModelFlags;
|
||||
part->compilerFlags = flags.commandLineFlags;
|
||||
part->warningFlags = flags.warningFlags;
|
||||
part->language = language;
|
||||
part->languageExtensions = flags.languageExtensions;
|
||||
|
||||
// Toolchain macros and language version
|
||||
|
@@ -39,6 +39,8 @@
|
||||
|
||||
#include <cplusplus/Token.h>
|
||||
|
||||
#include <utils/cpplanguage_details.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QSharedPointer>
|
||||
|
||||
@@ -91,6 +93,7 @@ public:
|
||||
QString callGroupId;
|
||||
|
||||
// Versions, features and extensions
|
||||
::Utils::Language language = Utils::Language::Cxx;
|
||||
::Utils::LanguageVersion languageVersion = ::Utils::LanguageVersion::LatestCxx;
|
||||
::Utils::LanguageExtensions languageExtensions = ::Utils::LanguageExtension::None;
|
||||
CPlusPlus::LanguageFeatures languageFeatures;
|
||||
|
@@ -23,18 +23,24 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <builddependenciesprovider.h>
|
||||
#include <builddependenciesstorage.h>
|
||||
#include <builddependencycollector.h>
|
||||
#include <clangpathwatcher.h>
|
||||
#include <connectionserver.h>
|
||||
#include <environment.h>
|
||||
#include <generatedfiles.h>
|
||||
#include <modifiedtimechecker.h>
|
||||
#include <pchcreator.h>
|
||||
#include <pchmanagerserver.h>
|
||||
#include <pchmanagerclientproxy.h>
|
||||
#include <pchtaskgenerator.h>
|
||||
#include <pchtaskqueue.h>
|
||||
#include <pchtasksmerger.h>
|
||||
#include <precompiledheaderstorage.h>
|
||||
#include <processormanager.h>
|
||||
#include <progresscounter.h>
|
||||
#include <projectparts.h>
|
||||
#include <projectpartqueue.h>
|
||||
#include <filepathcaching.h>
|
||||
#include <refactoringdatabaseinitializer.h>
|
||||
#include <sqlitedatabase.h>
|
||||
@@ -42,12 +48,12 @@
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QLoggingCategory>
|
||||
#include <QProcess>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTimer>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
@@ -62,6 +68,8 @@ using ClangBackEnd::PchManagerServer;
|
||||
using ClangBackEnd::PrecompiledHeaderStorage;
|
||||
using ClangBackEnd::ProjectParts;
|
||||
using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::FilePathView;
|
||||
using ClangBackEnd::TimeStamp;
|
||||
|
||||
class PchManagerApplication final : public QCoreApplication
|
||||
{
|
||||
@@ -93,11 +101,6 @@ public:
|
||||
return m_pchBuildDirectoryPath;
|
||||
}
|
||||
|
||||
QString clangCompilerPath() const override
|
||||
{
|
||||
return QString(CLANG_COMPILER_PATH);
|
||||
}
|
||||
|
||||
uint hardwareConcurrency() const override
|
||||
{
|
||||
return std::thread::hardware_concurrency();
|
||||
@@ -132,13 +135,11 @@ public:
|
||||
PchCreatorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
|
||||
ClangBackEnd::Environment &environment,
|
||||
Sqlite::Database &database,
|
||||
PchManagerServer &pchManagerServer,
|
||||
ClangBackEnd::ClangPathWatcherInterface &fileSystemWatcher)
|
||||
PchManagerServer &pchManagerServer)
|
||||
: ProcessorManager(generatedFiles),
|
||||
m_environment(environment),
|
||||
m_database(database),
|
||||
m_pchManagerServer(pchManagerServer),
|
||||
m_fileSystemWatcher(fileSystemWatcher)
|
||||
m_pchManagerServer(pchManagerServer)
|
||||
{}
|
||||
|
||||
protected:
|
||||
@@ -146,25 +147,22 @@ protected:
|
||||
{
|
||||
return std::make_unique<PchCreator>(m_environment,
|
||||
m_database,
|
||||
*m_pchManagerServer.client(),
|
||||
m_fileSystemWatcher);
|
||||
*m_pchManagerServer.client());
|
||||
}
|
||||
|
||||
private:
|
||||
ClangBackEnd::Environment &m_environment;
|
||||
Sqlite::Database &m_database;
|
||||
ClangBackEnd::PchManagerServer &m_pchManagerServer;
|
||||
ClangBackEnd::ClangPathWatcherInterface &m_fileSystemWatcher;
|
||||
};
|
||||
|
||||
struct Data // because we have a cycle dependency
|
||||
{
|
||||
using TaskScheduler = ClangBackEnd::TaskScheduler<PchCreatorManager, ClangBackEnd::ProjectPartQueue::Task>;
|
||||
using TaskScheduler = ClangBackEnd::TaskScheduler<PchCreatorManager, ClangBackEnd::PchTaskQueue::Task>;
|
||||
|
||||
Data(const QString &databasePath,
|
||||
const QString &pchsPath)
|
||||
: database{Utils::PathString{databasePath}, 100000ms},
|
||||
environment{pchsPath}
|
||||
Data(const QString &databasePath, const QString &pchsPath)
|
||||
: database{Utils::PathString{databasePath}, 100000ms}
|
||||
, environment{pchsPath}
|
||||
{}
|
||||
Sqlite::Database database;
|
||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
||||
@@ -173,12 +171,39 @@ struct Data // because we have a cycle dependency
|
||||
ApplicationEnvironment environment;
|
||||
ProjectParts projectParts;
|
||||
GeneratedFiles generatedFiles;
|
||||
PchCreatorManager pchCreatorManager{generatedFiles, environment, database, clangPchManagerServer, includeWatcher};
|
||||
PchCreatorManager pchCreatorManager{generatedFiles, environment, database, clangPchManagerServer};
|
||||
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
|
||||
ClangBackEnd::ProgressCounter progressCounter{[&] (int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
|
||||
TaskScheduler taskScheduler{pchCreatorManager, projectPartQueue, progressCounter, std::thread::hardware_concurrency()};
|
||||
ClangBackEnd::ProjectPartQueue projectPartQueue{taskScheduler, preCompiledHeaderStorage, database, progressCounter};
|
||||
PchManagerServer clangPchManagerServer{includeWatcher, projectPartQueue, projectParts, generatedFiles};
|
||||
ClangBackEnd::ProgressCounter progressCounter{
|
||||
[&](int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
|
||||
TaskScheduler systemTaskScheduler{pchCreatorManager,
|
||||
pchTaskQueue,
|
||||
progressCounter,
|
||||
std::thread::hardware_concurrency(),
|
||||
ClangBackEnd::CallDoInMainThreadAfterFinished::No};
|
||||
TaskScheduler projectTaskScheduler{pchCreatorManager,
|
||||
pchTaskQueue,
|
||||
progressCounter,
|
||||
std::thread::hardware_concurrency(),
|
||||
ClangBackEnd::CallDoInMainThreadAfterFinished::Yes};
|
||||
ClangBackEnd::PchTaskQueue pchTaskQueue{systemTaskScheduler,
|
||||
projectTaskScheduler,
|
||||
progressCounter,
|
||||
preCompiledHeaderStorage,
|
||||
database};
|
||||
ClangBackEnd::PchTasksMerger pchTaskMerger{pchTaskQueue};
|
||||
ClangBackEnd::BuildDependenciesStorage<> buildDependencyStorage{database};
|
||||
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache};
|
||||
std::function<TimeStamp(FilePathView filePath)> getModifiedTime{
|
||||
[&](ClangBackEnd::FilePathView path) -> TimeStamp {
|
||||
return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch();
|
||||
}};
|
||||
ClangBackEnd::ModifiedTimeChecker modifiedTimeChecker{getModifiedTime, filePathCache};
|
||||
ClangBackEnd::BuildDependenciesProvider buildDependencyProvider{buildDependencyStorage,
|
||||
modifiedTimeChecker,
|
||||
buildDependencyCollector,
|
||||
database};
|
||||
ClangBackEnd::PchTaskGenerator pchTaskGenerator{buildDependencyProvider, pchTaskMerger};
|
||||
PchManagerServer clangPchManagerServer{includeWatcher, pchTaskGenerator, projectParts, generatedFiles};
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@@ -53,7 +53,7 @@ OutputContainer setUnion(InputContainer1 &&input1,
|
||||
return results;
|
||||
}
|
||||
|
||||
BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart)
|
||||
BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart)
|
||||
{
|
||||
SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds,
|
||||
projectPart.projectPartId);
|
||||
|
@@ -50,7 +50,7 @@ public:
|
||||
, m_transactionBackend(transactionBackend)
|
||||
{}
|
||||
|
||||
BuildDependency create(const V2::ProjectPartContainer &projectPart) override;
|
||||
BuildDependency create(const ProjectPartContainer &projectPart) override;
|
||||
|
||||
private:
|
||||
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
|
||||
|
@@ -27,14 +27,14 @@
|
||||
|
||||
#include "builddependency.h"
|
||||
|
||||
#include "projectpartcontainerv2.h"
|
||||
#include "projectpartcontainer.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class BuildDependenciesProviderInterface
|
||||
{
|
||||
public:
|
||||
virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0;
|
||||
virtual BuildDependency create(const ProjectPartContainer &projectPart) = 0;
|
||||
|
||||
protected:
|
||||
~BuildDependenciesProviderInterface() = default;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "builddependencycollector.h"
|
||||
|
||||
#include "collectbuilddependencytoolaction.h"
|
||||
#include "commandlinebuilder.h"
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
@@ -44,9 +45,12 @@ FilePathIds operator+(const FilePathIds &first, const FilePathIds &second)
|
||||
}
|
||||
}
|
||||
|
||||
BuildDependency BuildDependencyCollector::create(const V2::ProjectPartContainer &projectPart)
|
||||
BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &projectPart)
|
||||
{
|
||||
addFiles(projectPart.sourcePathIds, projectPart.arguments);
|
||||
CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector> builder{
|
||||
projectPart, projectPart.toolChainArguments};
|
||||
|
||||
addFiles(projectPart.sourcePathIds, builder.commandLine);
|
||||
|
||||
setExcludedFilePaths(
|
||||
m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds));
|
||||
|
@@ -42,7 +42,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
BuildDependency create(const V2::ProjectPartContainer &projectPart) override;
|
||||
BuildDependency create(const ProjectPartContainer &projectPart) override;
|
||||
|
||||
void collect();
|
||||
|
||||
|
@@ -27,14 +27,14 @@
|
||||
|
||||
#include "builddependency.h"
|
||||
|
||||
#include "projectpartcontainerv2.h"
|
||||
#include "projectpartcontainer.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class BuildDependencyGeneratorInterface
|
||||
{
|
||||
public:
|
||||
virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0;
|
||||
virtual BuildDependency create(const ProjectPartContainer &projectPart) = 0;
|
||||
|
||||
protected:
|
||||
~BuildDependencyGeneratorInterface() = default;
|
||||
|
@@ -4,7 +4,6 @@ SOURCES += \
|
||||
$$PWD/builddependenciesprovider.cpp \
|
||||
$$PWD/pchmanagerserver.cpp \
|
||||
$$PWD/projectparts.cpp \
|
||||
$$PWD/projectpartqueue.cpp \
|
||||
$$PWD/pchtaskgenerator.cpp \
|
||||
$$PWD/pchtasksmerger.cpp \
|
||||
$$PWD/pchtaskqueue.cpp
|
||||
@@ -17,9 +16,7 @@ HEADERS += \
|
||||
$$PWD/projectparts.h \
|
||||
$$PWD/pchcreatorinterface.h \
|
||||
$$PWD/projectpartsinterface.h \
|
||||
$$PWD/projectpartqueue.h \
|
||||
$$PWD/queueinterface.h \
|
||||
$$PWD/projectpartqueueinterface.h \
|
||||
$$PWD/processormanagerinterface.h \
|
||||
$$PWD/processorinterface.h \
|
||||
$$PWD/taskscheduler.h \
|
||||
@@ -40,7 +37,11 @@ HEADERS += \
|
||||
$$PWD/pchtasksmergerinterface.h \
|
||||
$$PWD/pchtasksmerger.h \
|
||||
$$PWD/pchtaskqueueinterface.h \
|
||||
$$PWD/pchtaskqueue.h
|
||||
$$PWD/pchtaskqueue.h \
|
||||
$$PWD/generatepchactionfactory.h \
|
||||
$$PWD/pchtaskgeneratorinterface.h \
|
||||
$$PWD/toolchainargumentscache.h \
|
||||
$$PWD/modifiedtimechecker.h
|
||||
|
||||
!isEmpty(LIBTOOLING_LIBS) {
|
||||
SOURCES += \
|
||||
|
@@ -37,7 +37,6 @@ public:
|
||||
Environment &operator=(const Environment &) = delete;
|
||||
|
||||
virtual QString pchBuildDirectory() const = 0;
|
||||
virtual QString clangCompilerPath() const = 0;
|
||||
virtual uint hardwareConcurrency() const = 0;
|
||||
|
||||
protected:
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <clang/Tooling/Tooling.h>
|
||||
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
class GeneratePCHActionFactory final : public clang::tooling::FrontendActionFactory
|
||||
{
|
||||
public:
|
||||
clang::FrontendAction *create() override
|
||||
{
|
||||
return new clang::GeneratePCHAction;
|
||||
}
|
||||
};
|
||||
} // namespace ClangBackEnd
|
149
src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
Normal file
149
src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "modifiedtimecheckerinterface.h"
|
||||
|
||||
#include <filepathcachinginterface.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface
|
||||
{
|
||||
public:
|
||||
using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>;
|
||||
ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache)
|
||||
: m_getModifiedTime(getModifiedTime)
|
||||
, m_filePathCache(filePathCache)
|
||||
{}
|
||||
|
||||
bool isUpToDate(const SourceEntries &sourceEntries) const
|
||||
{
|
||||
if (sourceEntries.empty())
|
||||
return false;
|
||||
|
||||
updateCurrentSourceTimeStamps(sourceEntries);
|
||||
|
||||
return compareEntries(sourceEntries);
|
||||
}
|
||||
|
||||
void pathsChanged(const FilePathIds &filePathIds)
|
||||
{
|
||||
using SourceTimeStampPointers = std::vector<SourceTimeStamp*>;
|
||||
|
||||
class BackInserterIterator : public std::back_insert_iterator<SourceTimeStampPointers>
|
||||
{
|
||||
public:
|
||||
BackInserterIterator(SourceTimeStampPointers &container)
|
||||
: std::back_insert_iterator<SourceTimeStampPointers>(container)
|
||||
{}
|
||||
|
||||
BackInserterIterator &operator=(SourceTimeStamp &timeStamp)
|
||||
{
|
||||
container->push_back(&timeStamp);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BackInserterIterator &operator*() { return *this; }
|
||||
};
|
||||
|
||||
SourceTimeStampPointers timeStampsToUpdate;
|
||||
timeStampsToUpdate.reserve(filePathIds.size());
|
||||
|
||||
std::set_intersection(m_currentSourceTimeStamps.begin(),
|
||||
m_currentSourceTimeStamps.end(),
|
||||
filePathIds.begin(),
|
||||
filePathIds.end(),
|
||||
BackInserterIterator(timeStampsToUpdate));
|
||||
|
||||
for (SourceTimeStamp *sourceTimeStamp : timeStampsToUpdate) {
|
||||
sourceTimeStamp->lastModified = m_getModifiedTime(
|
||||
m_filePathCache.filePath(sourceTimeStamp->sourceId));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool compareEntries(const SourceEntries &sourceEntries) const
|
||||
{
|
||||
SourceTimeStamps currentSourceTimeStamp;
|
||||
currentSourceTimeStamp.reserve(sourceEntries.size());
|
||||
std::set_intersection(m_currentSourceTimeStamps.begin(),
|
||||
m_currentSourceTimeStamps.end(),
|
||||
sourceEntries.begin(),
|
||||
sourceEntries.end(),
|
||||
std::back_inserter(currentSourceTimeStamp));
|
||||
|
||||
return std::equal(currentSourceTimeStamp.begin(),
|
||||
currentSourceTimeStamp.end(),
|
||||
sourceEntries.begin(),
|
||||
sourceEntries.end(),
|
||||
[](SourceTimeStamp first, SourceTimeStamp second) {
|
||||
return first.lastModified <= second.lastModified;
|
||||
});
|
||||
}
|
||||
|
||||
void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
|
||||
{
|
||||
SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries);
|
||||
|
||||
for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) {
|
||||
newSourceTimeStamp.lastModified = m_getModifiedTime(
|
||||
m_filePathCache.filePath(newSourceTimeStamp.sourceId));
|
||||
}
|
||||
|
||||
auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
|
||||
m_currentSourceTimeStamps.begin(),
|
||||
m_currentSourceTimeStamps.end());
|
||||
std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
|
||||
|
||||
m_currentSourceTimeStamps = sourceTimeStamps;
|
||||
}
|
||||
|
||||
SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
|
||||
{
|
||||
SourceTimeStamps newTimeStamps;
|
||||
newTimeStamps.reserve(sourceEntries.size() + m_currentSourceTimeStamps.size());
|
||||
|
||||
std::set_difference(sourceEntries.begin(),
|
||||
sourceEntries.end(),
|
||||
m_currentSourceTimeStamps.begin(),
|
||||
m_currentSourceTimeStamps.end(),
|
||||
std::back_inserter(newTimeStamps));
|
||||
|
||||
return newTimeStamps;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable SourceTimeStamps m_currentSourceTimeStamps;
|
||||
GetModifiedTime &m_getModifiedTime;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -25,8 +25,10 @@
|
||||
|
||||
#include "pchcreator.h"
|
||||
|
||||
#include "environment.h"
|
||||
#include "builddependencycollector.h"
|
||||
#include "commandlinebuilder.h"
|
||||
#include "environment.h"
|
||||
#include "generatepchactionfactory.h"
|
||||
#include "pchnotcreatederror.h"
|
||||
|
||||
#include <clangpathwatcherinterface.h>
|
||||
@@ -44,41 +46,6 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
namespace {
|
||||
template <typename Source,
|
||||
typename Target>
|
||||
void append(Target &target, const Source &source)
|
||||
{
|
||||
using ValueType = typename Target::value_type;
|
||||
Source clonedSource = source.clone();
|
||||
|
||||
target.reserve(target.size() + source.size());
|
||||
|
||||
for (auto &&entry : clonedSource)
|
||||
target.push_back(ValueType(std::move(entry)));
|
||||
}
|
||||
|
||||
void appendFilePathId(ClangBackEnd::FilePaths &target,
|
||||
const ClangBackEnd::FilePathIds &source,
|
||||
const ClangBackEnd::FilePathCachingInterface &filePathCache)
|
||||
{
|
||||
for (FilePathId id : source)
|
||||
target.emplace_back(filePathCache.filePath(id));
|
||||
}
|
||||
|
||||
Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFiles)
|
||||
{
|
||||
Utils::PathStringVector generaredFilePaths;
|
||||
generaredFilePaths.reserve(generaredFiles.size());
|
||||
|
||||
for (const V2::FileContainer &generatedFile : generaredFiles)
|
||||
generaredFilePaths.push_back(generatedFile.filePath.path());
|
||||
|
||||
return generaredFilePaths;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::size_t contentSize(const FilePaths &includes)
|
||||
@@ -106,239 +73,72 @@ Utils::SmallString PchCreator::generatePchIncludeFileContent(const FilePathIds &
|
||||
}
|
||||
|
||||
|
||||
bool PchCreator::generatePch(Utils::SmallStringVector &&compilerArguments)
|
||||
bool PchCreator::generatePch()
|
||||
{
|
||||
QProcess process;
|
||||
clang::tooling::ClangTool tool = m_clangTool.createOutputTool();
|
||||
|
||||
process.setProcessChannelMode(QProcess::ForwardedChannels);
|
||||
process.setArguments(QStringList(compilerArguments));
|
||||
process.setProgram(QString(m_environment.clangCompilerPath()));
|
||||
auto action = std::make_unique<GeneratePCHActionFactory>();
|
||||
|
||||
process.start();
|
||||
process.waitForFinished(300000);
|
||||
|
||||
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
|
||||
return tool.run(action.get()) != 1;
|
||||
}
|
||||
|
||||
QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
|
||||
FilePath PchCreator::generatePchHeaderFilePath() const
|
||||
{
|
||||
QStringList qStringList;
|
||||
std::uniform_int_distribution<std::mt19937_64::result_type> distribution;
|
||||
|
||||
append(qStringList, compilerArguments);
|
||||
|
||||
return qStringList;
|
||||
return FilePathView{Utils::PathString{Utils::SmallString(m_environment.pchBuildDirectory()),
|
||||
"/",
|
||||
std::to_string(distribution(randomNumberGenator)),
|
||||
".h"}};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void hashProjectPart(QCryptographicHash &hash, const V2::ProjectPartContainer &projectPart)
|
||||
FilePath PchCreator::generatePchFilePath() const
|
||||
{
|
||||
const auto &projectPartId = projectPart.projectPartId;
|
||||
hash.addData(projectPartId.data(), int(projectPartId.size()));
|
||||
std::uniform_int_distribution<std::uint_fast64_t> distribution(
|
||||
1, std::numeric_limits<std::uint_fast64_t>::max());
|
||||
|
||||
for (const auto &argument : projectPart.arguments)
|
||||
hash.addData(argument.data(), int(argument.size()));
|
||||
}
|
||||
return FilePathView{Utils::PathString{Utils::SmallString(m_environment.pchBuildDirectory()),
|
||||
"/",
|
||||
std::to_string(distribution(randomNumberGenator)),
|
||||
".pch"}};
|
||||
}
|
||||
|
||||
Utils::SmallStringVector PchCreator::generateProjectPartCommandLine(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
std::vector<std::string> PchCreator::generateClangCompilerArguments(
|
||||
PchTask &&pchTask,
|
||||
FilePathView sourceFilePath,
|
||||
FilePathView pchOutputPath)
|
||||
{
|
||||
const Utils::SmallStringVector &arguments = projectPart.arguments;
|
||||
CommandLineBuilder<PchTask> builder{pchTask,
|
||||
pchTask.toolChainArguments,
|
||||
sourceFilePath,
|
||||
pchOutputPath,
|
||||
pchTask.systemPchPath};
|
||||
|
||||
Utils::SmallStringVector commandLine;
|
||||
commandLine.reserve(arguments.size() + 1);
|
||||
|
||||
commandLine.emplace_back(m_environment.clangCompilerPath());
|
||||
|
||||
append(commandLine , arguments);
|
||||
|
||||
return commandLine;
|
||||
return builder.commandLine;
|
||||
}
|
||||
|
||||
Utils::SmallString PchCreator::generateProjectPartPchFilePathWithoutExtension(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
|
||||
fileName += '/';
|
||||
fileName += projectPartHash(projectPart);
|
||||
|
||||
return Utils::SmallString::fromQByteArray(fileName);
|
||||
}
|
||||
|
||||
Utils::PathStringVector PchCreator::generateProjectPartHeaders(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
Utils::PathStringVector headerPaths;
|
||||
headerPaths.reserve(projectPart.headerPathIds.size() + m_unsavedFiles.size());
|
||||
|
||||
std::transform(projectPart.headerPathIds.begin(),
|
||||
projectPart.headerPathIds.end(),
|
||||
std::back_inserter(headerPaths),
|
||||
[&] (FilePathId filePathId) {
|
||||
return m_filePathCache.filePath(filePathId);
|
||||
});
|
||||
|
||||
Utils::PathStringVector generatedPath = generatedFilePaths(m_unsavedFiles);
|
||||
|
||||
std::copy(std::make_move_iterator(generatedPath.begin()),
|
||||
std::make_move_iterator(generatedPath.end()),
|
||||
std::back_inserter(headerPaths));
|
||||
|
||||
return headerPaths;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::size_t sizeOfContent(const ClangBackEnd::FilePaths &paths)
|
||||
{
|
||||
return std::accumulate(paths.begin(),
|
||||
paths.end(),
|
||||
std::size_t(0),
|
||||
[] (std::size_t size, const auto &path) {
|
||||
const char includeTemplate[] = "#include \"\"\n";
|
||||
return size + path.size() + sizeof(includeTemplate);
|
||||
});
|
||||
}
|
||||
|
||||
Utils::SmallString concatContent(const ClangBackEnd::FilePaths &paths, std::size_t size)
|
||||
{
|
||||
Utils::SmallString content;
|
||||
content.reserve(size);
|
||||
|
||||
for (const ClangBackEnd::FilePath &path : paths) {
|
||||
content += "#include \"";
|
||||
content += path;
|
||||
content += "\"\n";
|
||||
};
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Utils::SmallString PchCreator::generateProjectPartSourcesContent(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
ClangBackEnd::FilePaths paths = generateProjectPartSourcePaths(projectPart);
|
||||
|
||||
return concatContent(paths, sizeOfContent(paths));
|
||||
}
|
||||
|
||||
ClangBackEnd::FilePaths PchCreator::generateProjectPartSourcePaths(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
ClangBackEnd::FilePaths includeAndSources;
|
||||
includeAndSources.reserve(projectPart.sourcePathIds.size());
|
||||
|
||||
appendFilePathId(includeAndSources, projectPart.sourcePathIds, m_filePathCache);
|
||||
|
||||
return includeAndSources;
|
||||
}
|
||||
|
||||
SourceEntries PchCreator::generateProjectPartPchIncludes(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
Utils::SmallString jointedFileContent = generateProjectPartSourcesContent(projectPart);
|
||||
Utils::SmallString jointedFilePath = generateProjectPartSourceFilePath(projectPart);
|
||||
auto jointFile = generateFileWithContent(jointedFilePath, jointedFileContent);
|
||||
Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart);
|
||||
FilePath filePath{Utils::PathString(jointedFilePath)};
|
||||
|
||||
BuildDependencyCollector collector(m_filePathCache);
|
||||
|
||||
collector.setExcludedFilePaths(generateProjectPartSourcePaths(projectPart));
|
||||
|
||||
collector.addFile(filePath, projectPart.sourcePathIds, arguments);
|
||||
|
||||
collector.addUnsavedFiles(m_unsavedFiles);
|
||||
|
||||
collector.collect();
|
||||
|
||||
jointFile->remove();
|
||||
|
||||
return collector.includeIds();
|
||||
}
|
||||
|
||||
Utils::SmallString PchCreator::generateProjectPathPchHeaderFilePath(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".h"};
|
||||
}
|
||||
|
||||
Utils::SmallString PchCreator::generateProjectPartPchFilePath(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".pch"};
|
||||
}
|
||||
|
||||
Utils::SmallString PchCreator::generateProjectPartSourceFilePath(const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".cpp"};
|
||||
}
|
||||
|
||||
Utils::SmallStringVector PchCreator::generateProjectPartPchCompilerArguments(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
Utils::SmallStringVector arguments;
|
||||
arguments.reserve(5);
|
||||
|
||||
arguments.emplace_back("-x");
|
||||
arguments.emplace_back("c++-header");
|
||||
arguments.emplace_back("-Xclang");
|
||||
arguments.emplace_back("-emit-pch");
|
||||
arguments.emplace_back("-o");
|
||||
arguments.emplace_back(generateProjectPartPchFilePath(projectPart));
|
||||
arguments.emplace_back(generateProjectPathPchHeaderFilePath(projectPart));
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
Utils::SmallStringVector PchCreator::generateProjectPartClangCompilerArguments(
|
||||
const V2::ProjectPartContainer &projectPart) const
|
||||
{
|
||||
Utils::SmallStringVector compilerArguments = projectPart.arguments.clone();
|
||||
const auto pchArguments = generateProjectPartPchCompilerArguments(projectPart);
|
||||
|
||||
append(compilerArguments, pchArguments);
|
||||
|
||||
return compilerArguments;
|
||||
}
|
||||
|
||||
IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &projectPart)
|
||||
void PchCreator::generatePch(PchTask &&pchTask)
|
||||
{
|
||||
long long lastModified = QDateTime::currentSecsSinceEpoch();
|
||||
auto includes = generateProjectPartPchIncludes(projectPart);
|
||||
auto content = generatePchIncludeFileContent(topIncludeIds(includes));
|
||||
auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart);
|
||||
auto pchFilePath = generateProjectPartPchFilePath(projectPart);
|
||||
generateFileWithContent(pchIncludeFilePath, content);
|
||||
auto content = generatePchIncludeFileContent(pchTask.includes);
|
||||
auto pchSourceFilePath = generatePchHeaderFilePath();
|
||||
auto pchOutputPath = generatePchFilePath();
|
||||
generateFileWithContent(pchSourceFilePath, content);
|
||||
|
||||
bool success = generatePch(generateProjectPartClangCompilerArguments(projectPart));
|
||||
m_clangTool.addFile(
|
||||
pchSourceFilePath.directory(),
|
||||
pchSourceFilePath.name(),
|
||||
"",
|
||||
generateClangCompilerArguments(std::move(pchTask), pchSourceFilePath, pchOutputPath));
|
||||
|
||||
m_projectPartPch.projectPartId = projectPart.projectPartId;
|
||||
bool success = generatePch();
|
||||
|
||||
m_projectPartPch.projectPartId = pchTask.projectPartId();
|
||||
|
||||
if (success) {
|
||||
m_projectPartPch.pchPath = std::move(pchFilePath);
|
||||
m_projectPartPch.pchPath = std::move(pchOutputPath);
|
||||
m_projectPartPch.lastModified = lastModified;
|
||||
}
|
||||
|
||||
return {projectPart.projectPartId.clone(), allIncludeIds(includes)};
|
||||
}
|
||||
|
||||
void PchCreator::generatePchDeprecated(const V2::ProjectPartContainer &projectPart)
|
||||
{
|
||||
m_projectIncludeIds = generateProjectPartPch(projectPart);
|
||||
}
|
||||
|
||||
void PchCreator::generatePch(const PchTask &pchTask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IdPaths PchCreator::takeProjectIncludes()
|
||||
{
|
||||
return std::move(m_projectIncludeIds);
|
||||
}
|
||||
|
||||
const ProjectPartPch &PchCreator::projectPartPch()
|
||||
@@ -363,19 +163,12 @@ bool PchCreator::isUsed() const
|
||||
|
||||
void PchCreator::clear()
|
||||
{
|
||||
m_projectPartPch = ProjectPartPch{};
|
||||
m_projectIncludeIds = IdPaths{};
|
||||
m_projectPartPch = {};
|
||||
}
|
||||
|
||||
void PchCreator::doInMainThreadAfterFinished()
|
||||
{
|
||||
m_pchManagerClient.precompiledHeadersUpdated(ProjectPartPchs{m_projectPartPch});
|
||||
m_fileSystemWatcher.updateIdPaths({takeProjectIncludes()});
|
||||
}
|
||||
|
||||
const IdPaths &PchCreator::projectIncludes() const
|
||||
{
|
||||
return m_projectIncludeIds;
|
||||
}
|
||||
|
||||
const FilePathCaching &PchCreator::filePathCache()
|
||||
@@ -383,9 +176,8 @@ const FilePathCaching &PchCreator::filePathCache()
|
||||
return m_filePathCache;
|
||||
}
|
||||
|
||||
std::unique_ptr<QFile> PchCreator::generateFileWithContent(
|
||||
const Utils::SmallString &filePath,
|
||||
const Utils::SmallString &content)
|
||||
std::unique_ptr<QFile> PchCreator::generateFileWithContent(const Utils::SmallString &filePath,
|
||||
const Utils::SmallString &content)
|
||||
{
|
||||
std::unique_ptr<QFile> precompiledIncludeFile(new QFile(QString(filePath)));
|
||||
|
||||
@@ -397,41 +189,4 @@ std::unique_ptr<QFile> PchCreator::generateFileWithContent(
|
||||
return precompiledIncludeFile;
|
||||
}
|
||||
|
||||
FilePathIds PchCreator::topIncludeIds(const SourceEntries &includes)
|
||||
{
|
||||
FilePathIds topIncludes;
|
||||
topIncludes.reserve(includes.size());
|
||||
|
||||
for (SourceEntry include : includes) {
|
||||
if (include.sourceType == SourceType::TopProjectInclude)
|
||||
topIncludes.push_back(include.sourceId);
|
||||
}
|
||||
|
||||
return topIncludes;
|
||||
}
|
||||
|
||||
FilePathIds PchCreator::allIncludeIds(const SourceEntries &includes)
|
||||
{
|
||||
FilePathIds allIncludes;
|
||||
allIncludes.reserve(includes.size());
|
||||
|
||||
std::transform(includes.begin(),
|
||||
includes.end(),
|
||||
std::back_inserter(allIncludes),
|
||||
[](auto &&entry) { return entry.sourceId; });
|
||||
|
||||
return allIncludes;
|
||||
}
|
||||
|
||||
QByteArray PchCreator::projectPartHash(const V2::ProjectPartContainer &projectPart)
|
||||
{
|
||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||
|
||||
hashProjectPart(hash, projectPart);
|
||||
|
||||
auto result = hash.result();
|
||||
|
||||
return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -29,12 +29,14 @@
|
||||
|
||||
#include "idpaths.h"
|
||||
#include "sourceentry.h"
|
||||
#include "clangtool.h"
|
||||
|
||||
#include <filepathcaching.h>
|
||||
#include <projectpartpch.h>
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
#include <vector>
|
||||
#include <random>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QFile)
|
||||
QT_FORWARD_DECLARE_CLASS(QCryptographicHash)
|
||||
@@ -60,18 +62,13 @@ class PchCreator final : public PchCreatorInterface
|
||||
public:
|
||||
PchCreator(Environment &environment,
|
||||
Sqlite::Database &database,
|
||||
PchManagerClientInterface &pchManagerClient,
|
||||
ClangPathWatcherInterface &fileSystemWatcher)
|
||||
: m_filePathCache(database),
|
||||
m_environment(environment),
|
||||
m_pchManagerClient(pchManagerClient),
|
||||
m_fileSystemWatcher(fileSystemWatcher)
|
||||
{
|
||||
}
|
||||
PchManagerClientInterface &pchManagerClient)
|
||||
: m_filePathCache(database)
|
||||
, m_environment(environment)
|
||||
, m_pchManagerClient(pchManagerClient)
|
||||
{}
|
||||
|
||||
void generatePchDeprecated(const V2::ProjectPartContainer &projectsPart) override;
|
||||
void generatePch(const PchTask &pchTask) override;
|
||||
IdPaths takeProjectIncludes() override;
|
||||
void generatePch(PchTask &&pchTask) override;
|
||||
const ProjectPartPch &projectPartPch() override;
|
||||
void setUnsavedFiles(const V2::FileContainers &fileContainers) override;
|
||||
void setIsUsed(bool isUsed) override;
|
||||
@@ -79,56 +76,27 @@ public:
|
||||
void clear() override;
|
||||
void doInMainThreadAfterFinished() override;
|
||||
|
||||
const IdPaths &projectIncludes() const;
|
||||
const FilePathCaching &filePathCache();
|
||||
|
||||
Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const;
|
||||
bool generatePch(Utils::SmallStringVector &&commandLineArguments);
|
||||
bool generatePch();
|
||||
|
||||
static QStringList convertToQStringList(const Utils::SmallStringVector &convertToQStringList);
|
||||
|
||||
Utils::SmallStringVector generateProjectPartCommandLine(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallString generateProjectPartPchFilePathWithoutExtension(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::PathStringVector generateProjectPartHeaders(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallString generateProjectPartSourcesContent(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
ClangBackEnd::FilePaths generateProjectPartSourcePaths(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
SourceEntries generateProjectPartPchIncludes(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallString generateProjectPathPchHeaderFilePath(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallString generateProjectPartPchFilePath(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallString generateProjectPartSourceFilePath(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallStringVector generateProjectPartPchCompilerArguments(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
Utils::SmallStringVector generateProjectPartClangCompilerArguments(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
IdPaths generateProjectPartPch(
|
||||
const V2::ProjectPartContainer &projectPart);
|
||||
static std::unique_ptr<QFile> generateFileWithContent(
|
||||
const Utils::SmallString &filePath,
|
||||
const Utils::SmallString &content);
|
||||
|
||||
static FilePathIds topIncludeIds(const SourceEntries &includes);
|
||||
static FilePathIds allIncludeIds(const SourceEntries &includes);
|
||||
|
||||
private:
|
||||
static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
|
||||
FilePath generatePchHeaderFilePath() const;
|
||||
FilePath generatePchFilePath() const;
|
||||
static std::vector<std::string> generateClangCompilerArguments(PchTask &&pchTask,
|
||||
FilePathView includePchHeaderPath,
|
||||
FilePathView pchPath);
|
||||
static std::unique_ptr<QFile> generateFileWithContent(const Utils::SmallString &filePath,
|
||||
const Utils::SmallString &content);
|
||||
|
||||
private:
|
||||
mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
|
||||
ClangTool m_clangTool;
|
||||
ProjectPartPch m_projectPartPch;
|
||||
IdPaths m_projectIncludeIds;
|
||||
FilePathCaching m_filePathCache;
|
||||
V2::FileContainers m_unsavedFiles;
|
||||
Environment &m_environment;
|
||||
PchManagerClientInterface &m_pchManagerClient;
|
||||
ClangPathWatcherInterface &m_fileSystemWatcher;
|
||||
bool m_isUsed = false;
|
||||
};
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#include "processorinterface.h"
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -42,9 +42,7 @@ public:
|
||||
PchCreatorInterface(const PchCreatorInterface &) = delete;
|
||||
PchCreatorInterface &operator=(const PchCreatorInterface &) = delete;
|
||||
|
||||
virtual void generatePchDeprecated(const V2::ProjectPartContainer &projectsPart) = 0;
|
||||
virtual void generatePch(const PchTask &pchTask) = 0;
|
||||
virtual IdPaths takeProjectIncludes() = 0;
|
||||
virtual void generatePch(PchTask &&pchTask) = 0;
|
||||
virtual const ProjectPartPch &projectPartPch() = 0;
|
||||
|
||||
protected:
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <pchmanagerclientinterface.h>
|
||||
#include <precompiledheadersupdatedmessage.h>
|
||||
#include <progressmessage.h>
|
||||
#include <projectpartqueue.h>
|
||||
#include <pchtaskgeneratorinterface.h>
|
||||
#include <removegeneratedfilesmessage.h>
|
||||
#include <removeprojectpartsmessage.h>
|
||||
#include <updategeneratedfilesmessage.h>
|
||||
@@ -41,11 +41,11 @@
|
||||
namespace ClangBackEnd {
|
||||
|
||||
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
||||
ProjectPartQueueInterface &projectPartQueue,
|
||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||
ProjectPartsInterface &projectParts,
|
||||
GeneratedFilesInterface &generatedFiles)
|
||||
: m_fileSystemWatcher(fileSystemWatcher),
|
||||
m_projectPartQueue(projectPartQueue),
|
||||
m_pchTaskGenerator(pchTaskGenerator),
|
||||
m_projectParts(projectParts),
|
||||
m_generatedFiles(generatedFiles)
|
||||
{
|
||||
@@ -55,12 +55,14 @@ PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
||||
void PchManagerServer::end()
|
||||
{
|
||||
QCoreApplication::exit();
|
||||
|
||||
}
|
||||
|
||||
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
|
||||
{
|
||||
m_projectPartQueue.addProjectParts(m_projectParts.update(message.takeProjectsParts()));
|
||||
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
|
||||
|
||||
m_pchTaskGenerator.addProjectParts(
|
||||
m_projectParts.update(message.takeProjectsParts()), std::move(message.toolChainArguments));
|
||||
}
|
||||
|
||||
void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
|
||||
@@ -69,7 +71,9 @@ void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
|
||||
|
||||
m_projectParts.remove(message.projectsPartIds);
|
||||
|
||||
m_projectPartQueue.removeProjectParts(message.projectsPartIds);
|
||||
m_pchTaskGenerator.removeProjectParts(message.projectsPartIds);
|
||||
|
||||
m_toolChainsArgumentsCache.remove(message.projectsPartIds);
|
||||
}
|
||||
|
||||
void PchManagerServer::updateGeneratedFiles(UpdateGeneratedFilesMessage &&message)
|
||||
@@ -84,7 +88,12 @@ void PchManagerServer::removeGeneratedFiles(RemoveGeneratedFilesMessage &&messag
|
||||
|
||||
void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
|
||||
{
|
||||
m_projectPartQueue.addProjectParts(m_projectParts.projects(ids));
|
||||
ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(ids);
|
||||
|
||||
for (ArgumentsEntry &entry : entries) {
|
||||
m_pchTaskGenerator.addProjectParts(
|
||||
m_projectParts.projects(entry.ids), std::move(entry.arguments));
|
||||
}
|
||||
}
|
||||
|
||||
void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/)
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "pchcreatorinterface.h"
|
||||
#include "pchmanagerserverinterface.h"
|
||||
#include "projectpartsinterface.h"
|
||||
#include "toolchainargumentscache.h"
|
||||
|
||||
#include <generatedfilesinterface.h>
|
||||
#include <ipcclientprovider.h>
|
||||
@@ -37,7 +38,7 @@
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SourceRangesAndDiagnosticsForQueryMessage;
|
||||
class ProjectPartQueueInterface;
|
||||
class PchTaskGeneratorInterface;
|
||||
|
||||
class PchManagerServer : public PchManagerServerInterface,
|
||||
public ClangPathWatcherNotifier,
|
||||
@@ -46,7 +47,7 @@ class PchManagerServer : public PchManagerServerInterface,
|
||||
{
|
||||
public:
|
||||
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
|
||||
ProjectPartQueueInterface &projectPartQueue,
|
||||
PchTaskGeneratorInterface &pchTaskGenerator,
|
||||
ProjectPartsInterface &projectParts,
|
||||
GeneratedFilesInterface &generatedFiles);
|
||||
|
||||
@@ -63,9 +64,10 @@ public:
|
||||
|
||||
private:
|
||||
ClangPathWatcherInterface &m_fileSystemWatcher;
|
||||
ProjectPartQueueInterface &m_projectPartQueue;
|
||||
PchTaskGeneratorInterface &m_pchTaskGenerator;
|
||||
ProjectPartsInterface &m_projectParts;
|
||||
GeneratedFilesInterface &m_generatedFiles;
|
||||
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -28,8 +28,11 @@
|
||||
#include "builddependency.h"
|
||||
|
||||
#include <compilermacro.h>
|
||||
#include <filepath.h>
|
||||
#include <includesearchpath.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
#include <utils/cpplanguage_details.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -39,21 +42,45 @@ public:
|
||||
PchTask(Utils::SmallString &&projectPartId,
|
||||
FilePathIds &&includes,
|
||||
CompilerMacros &&compilerMacros,
|
||||
UsedMacros &&usedMacros)
|
||||
UsedMacros &&usedMacros,
|
||||
Utils::SmallStringVector toolChainArguments,
|
||||
IncludeSearchPaths systemIncludeSearchPaths,
|
||||
IncludeSearchPaths projectIncludeSearchPaths,
|
||||
Utils::Language language = Utils::Language::Cxx,
|
||||
Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98,
|
||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
||||
: projectPartIds({projectPartId})
|
||||
, includes(includes)
|
||||
, compilerMacros(compilerMacros)
|
||||
, usedMacros(usedMacros)
|
||||
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
||||
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
||||
, toolChainArguments(std::move(toolChainArguments))
|
||||
, language(language)
|
||||
, languageVersion(languageVersion)
|
||||
, languageExtension(languageExtension)
|
||||
{}
|
||||
|
||||
PchTask(Utils::SmallStringVector &&projectPartIds,
|
||||
FilePathIds &&includes,
|
||||
CompilerMacros &&compilerMacros,
|
||||
UsedMacros &&usedMacros)
|
||||
UsedMacros &&usedMacros,
|
||||
Utils::SmallStringVector toolChainArguments,
|
||||
IncludeSearchPaths systemIncludeSearchPaths,
|
||||
IncludeSearchPaths projectIncludeSearchPaths,
|
||||
Utils::Language language = Utils::Language::Cxx,
|
||||
Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98,
|
||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
|
||||
: projectPartIds(std::move(projectPartIds))
|
||||
, includes(includes)
|
||||
, compilerMacros(compilerMacros)
|
||||
, usedMacros(usedMacros)
|
||||
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
|
||||
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
|
||||
, toolChainArguments(std::move(toolChainArguments))
|
||||
, language(language)
|
||||
, languageVersion(languageVersion)
|
||||
, languageExtension(languageExtension)
|
||||
{}
|
||||
|
||||
friend bool operator==(const PchTask &first, const PchTask &second)
|
||||
@@ -61,17 +88,29 @@ public:
|
||||
return first.systemPchPath == second.systemPchPath
|
||||
&& first.projectPartIds == second.projectPartIds && first.includes == second.includes
|
||||
&& first.compilerMacros == second.compilerMacros
|
||||
&& first.usedMacros == second.usedMacros;
|
||||
&& first.usedMacros == second.usedMacros
|
||||
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
||||
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
|
||||
&& first.toolChainArguments == second.toolChainArguments
|
||||
&& first.language == second.language
|
||||
&& first.languageVersion == second.languageVersion
|
||||
&& first.languageExtension == second.languageExtension;
|
||||
}
|
||||
|
||||
Utils::SmallStringView projectPartId() const { return projectPartIds.front(); }
|
||||
|
||||
public:
|
||||
Utils::PathString systemPchPath;
|
||||
FilePath systemPchPath;
|
||||
Utils::SmallStringVector projectPartIds;
|
||||
FilePathIds includes;
|
||||
CompilerMacros compilerMacros;
|
||||
UsedMacros usedMacros;
|
||||
IncludeSearchPaths systemIncludeSearchPaths;
|
||||
IncludeSearchPaths projectIncludeSearchPaths;
|
||||
Utils::SmallStringVector toolChainArguments;
|
||||
Utils::Language language = Utils::Language::Cxx;
|
||||
Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
|
||||
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
|
||||
};
|
||||
|
||||
class PchTaskSet
|
||||
|
@@ -34,7 +34,8 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
|
||||
void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments)
|
||||
{
|
||||
PchTaskSets pchTaskSets;
|
||||
pchTaskSets.reserve(projectParts.size());
|
||||
@@ -46,18 +47,33 @@ void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
|
||||
filter.filter(projectPart.compilerMacros);
|
||||
|
||||
pchTaskSets.emplace_back(PchTask{projectPart.projectPartId.clone(),
|
||||
std::move(filter.systemIncludes),
|
||||
std::move(filter.topSystemIncludes),
|
||||
std::move(filter.systemCompilerMacros),
|
||||
std::move(filter.systemUsedMacros)
|
||||
|
||||
},
|
||||
std::move(filter.systemUsedMacros),
|
||||
projectPart.toolChainArguments,
|
||||
projectPart.systemIncludeSearchPaths,
|
||||
projectPart.projectIncludeSearchPaths,
|
||||
projectPart.language,
|
||||
projectPart.languageVersion,
|
||||
projectPart.languageExtension},
|
||||
PchTask{std::move(projectPart.projectPartId),
|
||||
std::move(filter.projectIncludes),
|
||||
std::move(filter.topProjectIncludes),
|
||||
std::move(filter.projectCompilerMacros),
|
||||
std::move(filter.projectUsedMacros)});
|
||||
std::move(filter.projectUsedMacros),
|
||||
projectPart.toolChainArguments,
|
||||
projectPart.systemIncludeSearchPaths,
|
||||
projectPart.projectIncludeSearchPaths,
|
||||
projectPart.language,
|
||||
projectPart.languageVersion,
|
||||
projectPart.languageExtension});
|
||||
}
|
||||
|
||||
m_pchTasksMergerInterface.mergeTasks(std::move(pchTaskSets));
|
||||
m_pchTasksMergerInterface.mergeTasks(std::move(pchTaskSets), std::move(toolChainArguments));
|
||||
}
|
||||
|
||||
void PchTaskGenerator::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
|
||||
{
|
||||
m_pchTasksMergerInterface.removePchTasks(projectsPartIds);
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -26,8 +26,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pchtask.h"
|
||||
#include "pchtaskgeneratorinterface.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -35,7 +36,7 @@ class PchTasksMergerInterface;
|
||||
|
||||
class BuildDependenciesProviderInterface;
|
||||
|
||||
class PchTaskGenerator
|
||||
class PchTaskGenerator : public PchTaskGeneratorInterface
|
||||
{
|
||||
public:
|
||||
PchTaskGenerator(BuildDependenciesProviderInterface &buildDependenciesProvider,
|
||||
@@ -44,7 +45,9 @@ public:
|
||||
, m_pchTasksMergerInterface(pchTasksMergerInterface)
|
||||
{}
|
||||
|
||||
void create(V2::ProjectPartContainers &&projectParts);
|
||||
void addProjectParts(ProjectPartContainers &&projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments);
|
||||
void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
|
||||
|
||||
private:
|
||||
BuildDependenciesProviderInterface &m_buildDependenciesProvider;
|
||||
|
@@ -25,19 +25,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "queueinterface.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class ProjectPartQueueInterface : public QueueInterface
|
||||
class PchTaskGeneratorInterface
|
||||
{
|
||||
public:
|
||||
virtual void addProjectParts(V2::ProjectPartContainers &&projectParts) = 0;
|
||||
virtual void addProjectParts(ProjectPartContainers &&projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments)
|
||||
= 0;
|
||||
virtual void removeProjectParts(const Utils::SmallStringVector &projectsPartIds) = 0;
|
||||
|
||||
protected:
|
||||
~ProjectPartQueueInterface() = default;
|
||||
~PchTaskGeneratorInterface() = default;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -52,8 +52,6 @@ void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination)
|
||||
destination = std::move(mergedPchTasks);
|
||||
|
||||
m_progressCounter.addTotal(int(destination.size() - oldSize));
|
||||
|
||||
processEntries();
|
||||
}
|
||||
|
||||
void PchTaskQueue::removePchTasksByProjectPartId(const Utils::SmallStringVector &projectsPartIds,
|
||||
@@ -143,22 +141,17 @@ std::vector<PchTaskQueue::Task> PchTaskQueue::createProjectTasks(PchTasks &&pchT
|
||||
|
||||
auto convert = [this](auto &&pchTask) {
|
||||
return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable {
|
||||
Sqlite::DeferredTransaction readTransaction(m_transactionsInterface);
|
||||
const auto projectPartId = pchTask.projectPartId();
|
||||
pchTask.systemPchPath = m_precompiledHeaderStorage.fetchSystemPrecompiledHeaderPath(
|
||||
pchTask.projectPartId());
|
||||
readTransaction.commit();
|
||||
pchCreator.generatePch(pchTask);
|
||||
projectPartId);
|
||||
pchCreator.generatePch(std::move(pchTask));
|
||||
const auto &projectPartPch = pchCreator.projectPartPch();
|
||||
Sqlite::ImmediateTransaction writeTransaction(m_transactionsInterface);
|
||||
if (projectPartPch.pchPath.empty()) {
|
||||
m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(pchTask.projectPartId());
|
||||
m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId);
|
||||
} else {
|
||||
m_precompiledHeaderStorage
|
||||
.insertProjectPrecompiledHeader(pchTask.projectPartId(),
|
||||
projectPartPch.pchPath,
|
||||
projectPartPch.lastModified);
|
||||
m_precompiledHeaderStorage.insertProjectPrecompiledHeader(
|
||||
projectPartId, projectPartPch.pchPath, projectPartPch.lastModified);
|
||||
}
|
||||
writeTransaction.commit();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -176,21 +169,17 @@ std::vector<PchTaskQueue::Task> PchTaskQueue::createSystemTasks(PchTasks &&pchTa
|
||||
tasks.reserve(pchTasks.size());
|
||||
|
||||
auto convert = [this](auto &&pchTask) {
|
||||
return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) {
|
||||
pchCreator.generatePch(pchTask);
|
||||
return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable {
|
||||
const auto projectPartIds = pchTask.projectPartIds;
|
||||
pchCreator.generatePch(std::move(pchTask));
|
||||
const auto &projectPartPch = pchCreator.projectPartPch();
|
||||
Sqlite::ImmediateTransaction transaction(m_transactionsInterface);
|
||||
for (Utils::SmallStringView projectPartId : pchTask.projectPartIds) {
|
||||
if (projectPartPch.pchPath.empty()) {
|
||||
m_precompiledHeaderStorage.deleteSystemPrecompiledHeader(projectPartId);
|
||||
} else {
|
||||
m_precompiledHeaderStorage
|
||||
.insertSystemPrecompiledHeader(projectPartId,
|
||||
projectPartPch.pchPath,
|
||||
projectPartPch.lastModified);
|
||||
}
|
||||
if (projectPartPch.pchPath.empty()) {
|
||||
m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds);
|
||||
} else {
|
||||
m_precompiledHeaderStorage.insertSystemPrecompiledHeaders(projectPartIds,
|
||||
projectPartPch.pchPath,
|
||||
projectPartPch.lastModified);
|
||||
}
|
||||
transaction.commit();
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -29,7 +29,8 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets)
|
||||
void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets,
|
||||
Utils::SmallStringVector &&/*toolChainArguments*/)
|
||||
{
|
||||
PchTasks systemTasks;
|
||||
systemTasks.reserve(taskSets.size());
|
||||
@@ -46,4 +47,9 @@ void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets)
|
||||
m_pchTaskQueue.processEntries();
|
||||
}
|
||||
|
||||
void PchTasksMerger::removePchTasks(const Utils::SmallStringVector &projectPartIds)
|
||||
{
|
||||
m_pchTaskQueue.removePchTasks(projectPartIds);
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -39,7 +39,8 @@ public:
|
||||
: m_pchTaskQueue(pchTaskQueue)
|
||||
{}
|
||||
|
||||
void mergeTasks(PchTaskSets &&taskSets) override;
|
||||
void mergeTasks(PchTaskSets &&taskSets, Utils::SmallStringVector &&toolChainArguments) override;
|
||||
void removePchTasks(const Utils::SmallStringVector &projectPartIds) override;
|
||||
|
||||
private:
|
||||
PchTaskQueueInterface &m_pchTaskQueue;
|
||||
|
@@ -31,7 +31,8 @@ namespace ClangBackEnd {
|
||||
class PchTasksMergerInterface
|
||||
{
|
||||
public:
|
||||
virtual void mergeTasks(PchTaskSets &&taskSets) = 0;
|
||||
virtual void mergeTasks(PchTaskSets &&taskSets, Utils::SmallStringVector &&toolChainArguments) = 0;
|
||||
virtual void removePchTasks(const Utils::SmallStringVector &projectPartIds) = 0;
|
||||
|
||||
protected:
|
||||
~PchTasksMergerInterface() = default;
|
||||
|
@@ -48,8 +48,8 @@ public:
|
||||
}
|
||||
|
||||
void insertProjectPrecompiledHeader(Utils::SmallStringView projectPartName,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime) override
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime) override
|
||||
{
|
||||
try {
|
||||
Sqlite::ImmediateTransaction transaction{m_database};
|
||||
@@ -76,42 +76,44 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void insertSystemPrecompiledHeader(Utils::SmallStringView projectPartName,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime) override
|
||||
void insertSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime) override
|
||||
{
|
||||
try {
|
||||
Sqlite::ImmediateTransaction transaction{m_database};
|
||||
|
||||
m_insertProjectPartStatement.write(projectPartName);
|
||||
m_insertSystemPrecompiledHeaderStatement.write(projectPartName, pchPath, pchBuildTime);
|
||||
|
||||
for (Utils::SmallStringView projectPartName : projectPartNames) {
|
||||
m_insertProjectPartStatement.write(projectPartName);
|
||||
m_insertSystemPrecompiledHeaderStatement.write(projectPartName, pchPath, pchBuildTime);
|
||||
}
|
||||
transaction.commit();
|
||||
} catch (const Sqlite::StatementIsBusy) {
|
||||
insertSystemPrecompiledHeader(projectPartName, pchPath, pchBuildTime);
|
||||
insertSystemPrecompiledHeaders(projectPartNames, pchPath, pchBuildTime);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteSystemPrecompiledHeader(Utils::SmallStringView projectPartName) override
|
||||
void deleteSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames) override
|
||||
{
|
||||
try {
|
||||
Sqlite::ImmediateTransaction transaction{m_database};
|
||||
|
||||
m_deleteSystemPrecompiledHeaderStatement.write(projectPartName);
|
||||
for (Utils::SmallStringView projectPartName : projectPartNames)
|
||||
m_deleteSystemPrecompiledHeaderStatement.write(projectPartName);
|
||||
|
||||
transaction.commit();
|
||||
} catch (const Sqlite::StatementIsBusy) {
|
||||
deleteSystemPrecompiledHeader(projectPartName);
|
||||
deleteSystemPrecompiledHeaders(projectPartNames);
|
||||
}
|
||||
}
|
||||
|
||||
Utils::PathString fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) override
|
||||
FilePath fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) override
|
||||
{
|
||||
try {
|
||||
Sqlite::DeferredTransaction transaction{m_database};
|
||||
|
||||
auto value = m_fetchSystemPrecompiledHeaderPathStatement
|
||||
.template value<Utils::PathString>(projectPartName);
|
||||
auto value = m_fetchSystemPrecompiledHeaderPathStatement.template value<FilePath>(
|
||||
projectPartName);
|
||||
|
||||
if (value)
|
||||
return value.value();
|
||||
@@ -121,7 +123,7 @@ public:
|
||||
return fetchSystemPrecompiledHeaderPath(projectPartName);
|
||||
}
|
||||
|
||||
return Utils::SmallStringView("");
|
||||
return FilePath("");
|
||||
}
|
||||
|
||||
public:
|
||||
|
@@ -25,7 +25,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
#include <filepath.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -42,13 +44,12 @@ public:
|
||||
long long pchBuildTime)
|
||||
= 0;
|
||||
virtual void deleteProjectPrecompiledHeader(Utils::SmallStringView projectPartName) = 0;
|
||||
virtual void insertSystemPrecompiledHeader(Utils::SmallStringView projectPartName,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime)
|
||||
virtual void insertSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime)
|
||||
= 0;
|
||||
virtual void deleteSystemPrecompiledHeader(Utils::SmallStringView projectPartName) = 0;
|
||||
virtual Utils::PathString fetchSystemPrecompiledHeaderPath(
|
||||
Utils::SmallStringView projectPartName) = 0;
|
||||
virtual void deleteSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames) = 0;
|
||||
virtual FilePath fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) = 0;
|
||||
|
||||
protected:
|
||||
~PrecompiledHeaderStorageInterface() = default;
|
||||
|
@@ -1,137 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "projectpartqueue.h"
|
||||
|
||||
#include <pchcreatorinterface.h>
|
||||
#include <precompiledheaderstorageinterface.h>
|
||||
#include <progresscounter.h>
|
||||
#include <sqlitetransaction.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
|
||||
{
|
||||
auto compare = [](const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
|
||||
return first.projectPartId < second.projectPartId;
|
||||
};
|
||||
|
||||
const std::size_t oldSize = m_projectParts.size();
|
||||
|
||||
V2::ProjectPartContainers mergedProjectParts;
|
||||
mergedProjectParts.reserve(m_projectParts.size() + projectParts.size());
|
||||
std::set_union(std::make_move_iterator(projectParts.begin()),
|
||||
std::make_move_iterator(projectParts.end()),
|
||||
std::make_move_iterator(m_projectParts.begin()),
|
||||
std::make_move_iterator(m_projectParts.end()),
|
||||
std::back_inserter(mergedProjectParts),
|
||||
compare);
|
||||
|
||||
m_projectParts = std::move(mergedProjectParts);
|
||||
|
||||
m_progressCounter.addTotal(int(m_projectParts.size() - oldSize));
|
||||
|
||||
processEntries();
|
||||
}
|
||||
|
||||
class CompareDifference
|
||||
{
|
||||
public:
|
||||
bool operator()(const V2::ProjectPartContainer &first, const Utils::SmallString &second)
|
||||
{
|
||||
return first.projectPartId < second;
|
||||
}
|
||||
|
||||
bool operator()(const Utils::SmallString &first, const V2::ProjectPartContainer &second)
|
||||
{
|
||||
return first < second.projectPartId;
|
||||
}
|
||||
};
|
||||
|
||||
void ProjectPartQueue::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
|
||||
{
|
||||
const std::size_t oldSize = m_projectParts.size();
|
||||
|
||||
V2::ProjectPartContainers notToBeRemovedProjectParts;
|
||||
notToBeRemovedProjectParts.reserve(m_projectParts.size());
|
||||
std::set_difference(std::make_move_iterator(m_projectParts.begin()),
|
||||
std::make_move_iterator(m_projectParts.end()),
|
||||
projectsPartIds.begin(),
|
||||
projectsPartIds.end(),
|
||||
std::back_inserter(notToBeRemovedProjectParts),
|
||||
CompareDifference{});
|
||||
|
||||
m_projectParts = std::move(notToBeRemovedProjectParts);
|
||||
|
||||
m_progressCounter.removeTotal(int(oldSize - m_projectParts.size()));
|
||||
}
|
||||
|
||||
void ProjectPartQueue::processEntries()
|
||||
{
|
||||
uint taskCount = m_taskScheduler.slotUsage().free;
|
||||
|
||||
auto newEnd = std::prev(m_projectParts.end(), std::min<int>(int(taskCount), int(m_projectParts.size())));
|
||||
m_taskScheduler.addTasks(
|
||||
createPchTasks({std::make_move_iterator(newEnd),
|
||||
std::make_move_iterator(m_projectParts.end())}));
|
||||
m_projectParts.erase(newEnd, m_projectParts.end());
|
||||
}
|
||||
|
||||
const V2::ProjectPartContainers &ProjectPartQueue::projectParts() const
|
||||
{
|
||||
return m_projectParts;
|
||||
}
|
||||
|
||||
std::vector<ProjectPartQueue::Task> ProjectPartQueue::createPchTasks(
|
||||
V2::ProjectPartContainers &&projectParts) const
|
||||
{
|
||||
std::vector<Task> tasks;
|
||||
tasks.reserve(projectParts.size());
|
||||
|
||||
auto convert = [this] (auto &&projectPart) {
|
||||
return [projectPart=std::move(projectPart), this] (PchCreatorInterface &pchCreator) {
|
||||
pchCreator.generatePchDeprecated(projectPart);
|
||||
const auto &projectPartPch = pchCreator.projectPartPch();
|
||||
Sqlite::ImmediateTransaction transaction(m_transactionsInterface);
|
||||
if (projectPartPch.pchPath.empty()) {
|
||||
m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartPch.projectPartId);
|
||||
} else {
|
||||
m_precompiledHeaderStorage.insertProjectPrecompiledHeader(projectPartPch.projectPartId,
|
||||
projectPartPch.pchPath,
|
||||
projectPartPch.lastModified);
|
||||
}
|
||||
transaction.commit();
|
||||
};
|
||||
};
|
||||
|
||||
std::transform(std::make_move_iterator(projectParts.begin()),
|
||||
std::make_move_iterator(projectParts.end()),
|
||||
std::back_inserter(tasks),
|
||||
convert);
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -1,74 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "projectpartqueueinterface.h"
|
||||
#include "taskschedulerinterface.h"
|
||||
|
||||
namespace Sqlite {
|
||||
class TransactionInterface;
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class PrecompiledHeaderStorageInterface;
|
||||
class ProgressCounter;
|
||||
class PchTaskSchedulerInterface;
|
||||
class PchCreatorInterface;
|
||||
|
||||
class ProjectPartQueue final : public ProjectPartQueueInterface
|
||||
{
|
||||
public:
|
||||
using Task = std::function<void (PchCreatorInterface&)>;
|
||||
|
||||
ProjectPartQueue(TaskSchedulerInterface<Task> &taskScheduler,
|
||||
PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
|
||||
Sqlite::TransactionInterface &transactionsInterface,
|
||||
ProgressCounter &progressCounter)
|
||||
: m_taskScheduler(taskScheduler),
|
||||
m_precompiledHeaderStorage(precompiledHeaderStorage),
|
||||
m_transactionsInterface(transactionsInterface),
|
||||
m_progressCounter(progressCounter)
|
||||
{}
|
||||
|
||||
void addProjectParts(V2::ProjectPartContainers &&projectParts);
|
||||
void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
|
||||
|
||||
void processEntries();
|
||||
|
||||
const V2::ProjectPartContainers &projectParts() const;
|
||||
|
||||
std::vector<Task> createPchTasks(V2::ProjectPartContainers &&projectParts) const;
|
||||
|
||||
private:
|
||||
V2::ProjectPartContainers m_projectParts;
|
||||
TaskSchedulerInterface<Task> &m_taskScheduler;
|
||||
PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
|
||||
Sqlite::TransactionInterface &m_transactionsInterface;
|
||||
ProgressCounter &m_progressCounter;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "projectparts.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ClangBackEnd {
|
||||
|
||||
inline namespace Pch {
|
||||
|
||||
V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&projectsParts)
|
||||
ProjectPartContainers ProjectParts::update(ProjectPartContainers &&projectsParts)
|
||||
{
|
||||
auto updatedProjectPartContainers = newProjectParts(std::move(projectsParts));
|
||||
|
||||
@@ -44,7 +44,7 @@ V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&proje
|
||||
|
||||
void ProjectParts::remove(const Utils::SmallStringVector &ids)
|
||||
{
|
||||
auto shouldRemove = [&] (const V2::ProjectPartContainer &projectPart) {
|
||||
auto shouldRemove = [&] (const ProjectPartContainer &projectPart) {
|
||||
return std::find(ids.begin(), ids.end(), projectPart.projectPartId) != ids.end();
|
||||
};
|
||||
|
||||
@@ -52,23 +52,23 @@ void ProjectParts::remove(const Utils::SmallStringVector &ids)
|
||||
m_projectParts.erase(newEnd, m_projectParts.end());
|
||||
}
|
||||
|
||||
V2::ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
|
||||
ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
|
||||
{
|
||||
V2::ProjectPartContainers projectPartsWithIds;
|
||||
ProjectPartContainers projectPartsWithIds;
|
||||
|
||||
std::copy_if(m_projectParts.begin(),
|
||||
m_projectParts.end(),
|
||||
std::back_inserter(projectPartsWithIds),
|
||||
[&] (const V2::ProjectPartContainer &projectPart) {
|
||||
[&] (const ProjectPartContainer &projectPart) {
|
||||
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), projectPart.projectPartId);
|
||||
});
|
||||
|
||||
return projectPartsWithIds;
|
||||
}
|
||||
|
||||
V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainers &&projectsParts) const
|
||||
ProjectPartContainers ProjectParts::newProjectParts(ProjectPartContainers &&projectsParts) const
|
||||
{
|
||||
V2::ProjectPartContainers updatedProjectPartContainers;
|
||||
ProjectPartContainers updatedProjectPartContainers;
|
||||
updatedProjectPartContainers.reserve(projectsParts.size());
|
||||
|
||||
std::set_difference(std::make_move_iterator(projectsParts.begin()),
|
||||
@@ -80,12 +80,12 @@ V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainer
|
||||
return updatedProjectPartContainers;
|
||||
}
|
||||
|
||||
void ProjectParts::mergeProjectParts(const V2::ProjectPartContainers &projectsParts)
|
||||
void ProjectParts::mergeProjectParts(const ProjectPartContainers &projectsParts)
|
||||
{
|
||||
V2::ProjectPartContainers newProjectParts;
|
||||
ProjectPartContainers newProjectParts;
|
||||
newProjectParts.reserve(m_projectParts.size() + projectsParts.size());
|
||||
|
||||
auto compare = [] (const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
|
||||
auto compare = [] (const ProjectPartContainer &first, const ProjectPartContainer &second) {
|
||||
return first.projectPartId < second.projectPartId;
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ void ProjectParts::mergeProjectParts(const V2::ProjectPartContainers &projectsPa
|
||||
m_projectParts = newProjectParts;
|
||||
}
|
||||
|
||||
const V2::ProjectPartContainers &ProjectParts::projectParts() const
|
||||
const ProjectPartContainers &ProjectParts::projectParts() const
|
||||
{
|
||||
return m_projectParts;
|
||||
}
|
||||
|
@@ -38,17 +38,17 @@ inline namespace Pch {
|
||||
class ProjectParts final : public ProjectPartsInterface
|
||||
{
|
||||
public:
|
||||
V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) override;
|
||||
ProjectPartContainers update(ProjectPartContainers &&projectsParts) override;
|
||||
void remove(const Utils::SmallStringVector &projectPartIds) override;
|
||||
V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
|
||||
ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
|
||||
|
||||
unittest_public:
|
||||
V2::ProjectPartContainers newProjectParts(V2::ProjectPartContainers &&projectsParts) const;
|
||||
void mergeProjectParts(const V2::ProjectPartContainers &projectsParts);
|
||||
const V2::ProjectPartContainers &projectParts() const;
|
||||
ProjectPartContainers newProjectParts(ProjectPartContainers &&projectsParts) const;
|
||||
void mergeProjectParts(const ProjectPartContainers &projectsParts);
|
||||
const ProjectPartContainers &projectParts() const;
|
||||
|
||||
private:
|
||||
V2::ProjectPartContainers m_projectParts;
|
||||
ProjectPartContainers m_projectParts;
|
||||
};
|
||||
|
||||
} // namespace Pch
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -36,9 +36,9 @@ public:
|
||||
ProjectPartsInterface(const ProjectPartsInterface &) = delete;
|
||||
ProjectPartsInterface &operator=(const ProjectPartsInterface &) = delete;
|
||||
|
||||
virtual V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) = 0;
|
||||
virtual ProjectPartContainers update(ProjectPartContainers &&projectsParts) = 0;
|
||||
virtual void remove(const Utils::SmallStringVector &projectPartIds) = 0;
|
||||
virtual V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const = 0;
|
||||
virtual ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const = 0;
|
||||
|
||||
protected:
|
||||
~ProjectPartsInterface() = default;
|
||||
|
@@ -56,41 +56,81 @@ public:
|
||||
int64 value = -1;
|
||||
};
|
||||
|
||||
class SourceEntry
|
||||
class SourceTimeStamp
|
||||
{
|
||||
protected:
|
||||
using int64 = long long;
|
||||
public:
|
||||
SourceEntry(int sourceId, int64 lastModified, int sourceType)
|
||||
: lastModified(lastModified),
|
||||
sourceId(sourceId),
|
||||
sourceType(static_cast<SourceType>(sourceType))
|
||||
SourceTimeStamp(int sourceId, int64 lastModified)
|
||||
: lastModified(lastModified)
|
||||
, sourceId(sourceId)
|
||||
{}
|
||||
|
||||
SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified)
|
||||
: lastModified(lastModified),
|
||||
sourceId(sourceId),
|
||||
sourceType(sourceType)
|
||||
SourceTimeStamp(FilePathId sourceId, TimeStamp lastModified)
|
||||
: lastModified(lastModified)
|
||||
, sourceId(sourceId)
|
||||
{}
|
||||
|
||||
friend
|
||||
bool operator<(SourceEntry first, SourceEntry second)
|
||||
friend bool operator<(SourceTimeStamp first, SourceTimeStamp second)
|
||||
{
|
||||
return first.sourceId < second.sourceId;
|
||||
}
|
||||
|
||||
friend
|
||||
bool operator==(SourceEntry first, SourceEntry second)
|
||||
friend bool operator<(SourceTimeStamp first, FilePathId second)
|
||||
{
|
||||
return first.sourceId == second.sourceId
|
||||
&& first.sourceType == second.sourceType
|
||||
&& first.lastModified == second.lastModified ;
|
||||
return first.sourceId < second;
|
||||
}
|
||||
|
||||
friend bool operator<(FilePathId first, SourceTimeStamp second)
|
||||
{
|
||||
return first < second.sourceId;
|
||||
}
|
||||
|
||||
friend bool operator==(SourceTimeStamp first, SourceTimeStamp second)
|
||||
{
|
||||
return first.sourceId == second.sourceId && first.lastModified == second.lastModified;
|
||||
}
|
||||
|
||||
friend bool operator!=(SourceTimeStamp first, SourceTimeStamp second)
|
||||
{
|
||||
return !(first == second);
|
||||
}
|
||||
|
||||
public:
|
||||
TimeStamp lastModified;
|
||||
FilePathId sourceId;
|
||||
};
|
||||
|
||||
using SourceTimeStamps = std::vector<SourceTimeStamp>;
|
||||
|
||||
class SourceEntry : public SourceTimeStamp
|
||||
{
|
||||
|
||||
public:
|
||||
SourceEntry(int sourceId, int64 lastModified, int sourceType)
|
||||
: SourceTimeStamp(sourceId, lastModified)
|
||||
, sourceType(static_cast<SourceType>(sourceType))
|
||||
{}
|
||||
|
||||
SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified)
|
||||
: SourceTimeStamp(sourceId, lastModified)
|
||||
, sourceType(sourceType)
|
||||
{}
|
||||
|
||||
friend bool operator<(SourceEntry first, SourceEntry second)
|
||||
{
|
||||
return first.sourceId < second.sourceId;
|
||||
}
|
||||
|
||||
friend bool operator==(SourceEntry first, SourceEntry second)
|
||||
{
|
||||
return first.sourceId == second.sourceId && first.sourceType == second.sourceType
|
||||
&& first.lastModified == second.lastModified;
|
||||
}
|
||||
|
||||
friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); }
|
||||
|
||||
public:
|
||||
TimeStamp lastModified;
|
||||
FilePathId sourceId;
|
||||
SourceType sourceType = SourceType::UserInclude;
|
||||
};
|
||||
|
||||
|
@@ -56,6 +56,8 @@ class ProcessorManagerInterface;
|
||||
class QueueInterface;
|
||||
class SymbolStorageInterface;
|
||||
|
||||
enum class CallDoInMainThreadAfterFinished : char { Yes, No };
|
||||
|
||||
template <typename ProcessorManager,
|
||||
typename Task>
|
||||
class TaskScheduler : public TaskSchedulerInterface<Task>
|
||||
@@ -68,23 +70,22 @@ public:
|
||||
QueueInterface &queue,
|
||||
ProgressCounter &progressCounter,
|
||||
uint hardwareConcurrency,
|
||||
CallDoInMainThreadAfterFinished callDoInMainThreadAfterFinished,
|
||||
std::launch launchPolicy = std::launch::async)
|
||||
: m_processorManager(processorManager),
|
||||
m_queue(queue),
|
||||
m_progressCounter(progressCounter),
|
||||
m_hardwareConcurrency(hardwareConcurrency),
|
||||
m_launchPolicy(launchPolicy)
|
||||
: m_processorManager(processorManager)
|
||||
, m_queue(queue)
|
||||
, m_progressCounter(progressCounter)
|
||||
, m_hardwareConcurrency(hardwareConcurrency)
|
||||
, m_launchPolicy(launchPolicy)
|
||||
, m_callDoInMainThreadAfterFinished(callDoInMainThreadAfterFinished)
|
||||
{}
|
||||
|
||||
void addTasks(std::vector<Task> &&tasks)
|
||||
{
|
||||
for (auto &task : tasks) {
|
||||
auto callWrapper = [&, task=std::move(task)] (auto processor)
|
||||
-> ProcessorInterface& {
|
||||
auto callWrapper = [&, task = std::move(task)](auto processor) -> ProcessorInterface & {
|
||||
task(processor.get());
|
||||
executeInLoop([&] {
|
||||
m_queue.processEntries();
|
||||
});
|
||||
executeInLoop([&] { m_queue.processEntries(); });
|
||||
|
||||
return processor;
|
||||
};
|
||||
@@ -130,9 +131,10 @@ private:
|
||||
|
||||
auto split = std::partition(m_futures.begin(), m_futures.end(), notReady);
|
||||
|
||||
std::for_each(split, m_futures.end(), [] (Future &future) {
|
||||
std::for_each(split, m_futures.end(), [&] (Future &future) {
|
||||
ProcessorInterface &processor = future.get();
|
||||
processor.doInMainThreadAfterFinished();
|
||||
if (m_callDoInMainThreadAfterFinished == CallDoInMainThreadAfterFinished::Yes)
|
||||
processor.doInMainThreadAfterFinished();
|
||||
processor.setIsUsed(false);
|
||||
processor.clear();
|
||||
});
|
||||
@@ -191,6 +193,7 @@ private:
|
||||
uint m_hardwareConcurrency;
|
||||
std::launch m_launchPolicy;
|
||||
bool m_isDisabled = false;
|
||||
CallDoInMainThreadAfterFinished m_callDoInMainThreadAfterFinished;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <functional>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
struct ArgumentsEntry
|
||||
{
|
||||
ArgumentsEntry(Utils::SmallStringVector &&ids, const Utils::SmallStringVector &arguments)
|
||||
: ids(std::move(ids))
|
||||
, arguments(arguments)
|
||||
{}
|
||||
|
||||
ArgumentsEntry(const Utils::SmallStringVector &ids, const Utils::SmallStringVector &arguments)
|
||||
: ids(ids)
|
||||
, arguments(arguments)
|
||||
{}
|
||||
|
||||
void mergeIds(Utils::SmallStringVector &&newIds)
|
||||
{
|
||||
Utils::SmallStringVector mergedIds;
|
||||
mergedIds.reserve(ids.size() + newIds.size());
|
||||
|
||||
std::set_union(std::make_move_iterator(ids.begin()),
|
||||
std::make_move_iterator(ids.end()),
|
||||
std::make_move_iterator(newIds.begin()),
|
||||
std::make_move_iterator(newIds.end()),
|
||||
std::back_inserter(mergedIds));
|
||||
|
||||
ids = mergedIds;
|
||||
}
|
||||
|
||||
void removeIds(const Utils::SmallStringVector &idsToBeRemoved)
|
||||
{
|
||||
Utils::SmallStringVector idsWithout;
|
||||
idsWithout.reserve(ids.size());
|
||||
std::set_difference(std::make_move_iterator(ids.begin()),
|
||||
std::make_move_iterator(ids.end()),
|
||||
idsToBeRemoved.begin(),
|
||||
idsToBeRemoved.end(),
|
||||
std::back_inserter(idsWithout));
|
||||
|
||||
ids = idsWithout;
|
||||
}
|
||||
|
||||
Utils::SmallStringVector ids;
|
||||
Utils::SmallStringVector arguments;
|
||||
};
|
||||
|
||||
using ArgumentsEntries = std::vector<ArgumentsEntry>;
|
||||
|
||||
class ToolChainsArgumentsCache
|
||||
{
|
||||
public:
|
||||
void update(const ProjectPartContainers &projectParts,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
{
|
||||
struct Compare
|
||||
{
|
||||
bool operator()(const ArgumentsEntry &entry, const Utils::SmallStringVector &arguments)
|
||||
{
|
||||
return entry.arguments < arguments;
|
||||
}
|
||||
|
||||
bool operator()(const Utils::SmallStringVector &arguments, const ArgumentsEntry &entry)
|
||||
{
|
||||
return arguments < entry.arguments;
|
||||
}
|
||||
};
|
||||
|
||||
auto found = std::lower_bound(m_argumentEntries.begin(),
|
||||
m_argumentEntries.end(),
|
||||
arguments,
|
||||
Compare{});
|
||||
|
||||
if (found != m_argumentEntries.end() && found->arguments == arguments) {
|
||||
auto ids = createIds(projectParts);
|
||||
auto removeIds = [&] (ArgumentsEntry &entry) {
|
||||
entry.removeIds(ids);
|
||||
};
|
||||
std::for_each(m_argumentEntries.begin(), found, removeIds);
|
||||
std::for_each(std::next(found), m_argumentEntries.end(), removeIds);
|
||||
found->mergeIds(std::move(ids));
|
||||
} else {
|
||||
auto ids = createIds(projectParts);
|
||||
for (ArgumentsEntry &entry : m_argumentEntries)
|
||||
entry.removeIds(ids);
|
||||
found = m_argumentEntries.emplace(found, std::move(ids), arguments);
|
||||
}
|
||||
|
||||
removeEmptyEntries();
|
||||
}
|
||||
|
||||
void remove(const Utils::SmallStringVector &idsToBeRemoved)
|
||||
{
|
||||
ArgumentsEntries entries;
|
||||
for (ArgumentsEntry &entry : m_argumentEntries) {
|
||||
Utils::SmallStringVector usedIds;
|
||||
std::set_difference(entry.ids.begin(),
|
||||
entry.ids.end(),
|
||||
idsToBeRemoved.begin(),
|
||||
idsToBeRemoved.end(),
|
||||
std::back_inserter(usedIds));
|
||||
|
||||
entry.ids = std::move(usedIds);
|
||||
}
|
||||
|
||||
removeEmptyEntries();
|
||||
}
|
||||
|
||||
ArgumentsEntries arguments(const Utils::SmallStringVector &ids) const
|
||||
{
|
||||
ArgumentsEntries entries;
|
||||
for (const ArgumentsEntry &entry : m_argumentEntries) {
|
||||
Utils::SmallStringVector usedIds;
|
||||
std::set_intersection(entry.ids.begin(),
|
||||
entry.ids.end(),
|
||||
ids.begin(),
|
||||
ids.end(),
|
||||
std::back_inserter(usedIds));
|
||||
|
||||
if (!usedIds.empty())
|
||||
entries.emplace_back(usedIds, entry.arguments);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_argumentEntries.size();
|
||||
}
|
||||
|
||||
private:
|
||||
static Utils::SmallStringVector createIds(const ProjectPartContainers &projectParts)
|
||||
{
|
||||
Utils::SmallStringVector ids;
|
||||
ids.reserve(projectParts.size());
|
||||
for (const auto &projectPart : projectParts)
|
||||
ids.emplace_back(projectPart.projectPartId);
|
||||
|
||||
std::sort(ids.begin(), ids.end());
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
void removeEmptyEntries()
|
||||
{
|
||||
auto newEnd = std::remove_if(m_argumentEntries.begin(),
|
||||
m_argumentEntries.end(),
|
||||
[](const auto &entry) { return entry.ids.empty(); });
|
||||
|
||||
m_argumentEntries.erase(newEnd, m_argumentEntries.end());
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ArgumentsEntry> m_argumentEntries;
|
||||
};
|
||||
|
||||
}
|
@@ -52,6 +52,8 @@ public:
|
||||
{
|
||||
systemIncludes.reserve(includes.size());
|
||||
projectIncludes.reserve(includes.size());
|
||||
topSystemIncludes.reserve(includes.size() / 10);
|
||||
topProjectIncludes.reserve(includes.size() / 10);
|
||||
|
||||
for (SourceEntry include : includes)
|
||||
filterInclude(include);
|
||||
@@ -76,10 +78,16 @@ private:
|
||||
{
|
||||
switch (include.sourceType) {
|
||||
case SourceType::TopSystemInclude:
|
||||
topSystemIncludes.emplace_back(include.sourceId);
|
||||
systemIncludes.emplace_back(include.sourceId);
|
||||
break;
|
||||
case SourceType::SystemInclude:
|
||||
systemIncludes.emplace_back(include.sourceId);
|
||||
break;
|
||||
case SourceType::TopProjectInclude:
|
||||
topProjectIncludes.emplace_back(include.sourceId);
|
||||
projectIncludes.emplace_back(include.sourceId);
|
||||
break;
|
||||
case SourceType::ProjectInclude:
|
||||
projectIncludes.emplace_back(include.sourceId);
|
||||
break;
|
||||
@@ -173,6 +181,8 @@ private:
|
||||
public:
|
||||
FilePathIds projectIncludes;
|
||||
FilePathIds systemIncludes;
|
||||
FilePathIds topProjectIncludes;
|
||||
FilePathIds topSystemIncludes;
|
||||
UsedMacros projectUsedMacros;
|
||||
UsedMacros systemUsedMacros;
|
||||
CompilerMacros projectCompilerMacros;
|
||||
|
@@ -50,9 +50,9 @@ void ClangTool::addFile(std::string &&directory,
|
||||
std::vector<std::string> &&commandLine)
|
||||
{
|
||||
m_fileContents.emplace_back(toNativePath(std::move(directory)),
|
||||
std::move(fileName),
|
||||
std::move(content),
|
||||
std::move(commandLine));
|
||||
std::move(fileName),
|
||||
std::move(content),
|
||||
std::move(commandLine));
|
||||
|
||||
const auto &fileContent = m_fileContents.back();
|
||||
|
||||
@@ -140,4 +140,13 @@ clang::tooling::ClangTool ClangTool::createTool() const
|
||||
return tool;
|
||||
}
|
||||
|
||||
clang::tooling::ClangTool ClangTool::createOutputTool() const
|
||||
{
|
||||
clang::tooling::ClangTool tool = createTool();
|
||||
|
||||
tool.clearArgumentsAdjusters();
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -91,6 +91,7 @@ public:
|
||||
void addUnsavedFiles(const V2::FileContainers &unsavedFiles);
|
||||
|
||||
clang::tooling::ClangTool createTool() const;
|
||||
clang::tooling::ClangTool createOutputTool() const;
|
||||
|
||||
private:
|
||||
RefactoringCompilationDatabase m_compilationDatabase;
|
||||
|
@@ -33,16 +33,7 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
ProjectPartArtefact::ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
|
||||
Utils::SmallStringView compilerMacrosText,
|
||||
Utils::SmallStringView includeSearchPaths,
|
||||
int projectPartId)
|
||||
: compilerArguments(toStringVector(compilerArgumentsText)),
|
||||
compilerMacros(toCompilerMacros(compilerMacrosText)),
|
||||
includeSearchPaths(toStringVector(includeSearchPaths)),
|
||||
projectPartId(projectPartId)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringView jsonText)
|
||||
{
|
||||
@@ -58,19 +49,35 @@ Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringV
|
||||
|
||||
CompilerMacros ProjectPartArtefact::createCompilerMacrosFromDocument(const QJsonDocument &document)
|
||||
{
|
||||
QJsonObject object = document.object();
|
||||
QJsonArray array = document.array();
|
||||
CompilerMacros macros;
|
||||
macros.reserve(object.size());
|
||||
macros.reserve(array.size());
|
||||
|
||||
int index = 0;
|
||||
for (auto current = object.constBegin(); current != object.constEnd(); ++current)
|
||||
macros.emplace_back(current.key(), current.value().toString(), ++index);
|
||||
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())
|
||||
@@ -93,6 +100,17 @@ QJsonDocument ProjectPartArtefact::createJsonDocument(Utils::SmallStringView jso
|
||||
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) {
|
||||
@@ -104,7 +122,9 @@ void ProjectPartArtefact::checkError(const char *whatError, const QJsonParseErro
|
||||
bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second)
|
||||
{
|
||||
return first.compilerArguments == second.compilerArguments
|
||||
&& first.compilerMacros == second.compilerMacros;
|
||||
&& first.compilerMacros == second.compilerMacros
|
||||
&& first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
|
||||
&& first.projectIncludeSearchPaths == second.projectIncludeSearchPaths;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <compilermacro.h>
|
||||
#include <includesearchpath.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QJsonDocument)
|
||||
QT_FORWARD_DECLARE_STRUCT(QJsonParseError)
|
||||
@@ -41,27 +42,30 @@ class ProjectPartArtefact
|
||||
public:
|
||||
ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
|
||||
Utils::SmallStringView compilerMacrosText,
|
||||
Utils::SmallStringView includeSearchPaths,
|
||||
int projectPartId);
|
||||
Utils::SmallStringView systemIncludeSearchPathsText,
|
||||
Utils::SmallStringView projectIncludeSearchPathsText,
|
||||
int projectPartId)
|
||||
: compilerArguments(toStringVector(compilerArgumentsText))
|
||||
, compilerMacros(toCompilerMacros(compilerMacrosText))
|
||||
, systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
|
||||
, projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
|
||||
, projectPartId(projectPartId)
|
||||
{}
|
||||
|
||||
static
|
||||
Utils::SmallStringVector toStringVector(Utils::SmallStringView jsonText);
|
||||
static
|
||||
CompilerMacros createCompilerMacrosFromDocument(const QJsonDocument &document);
|
||||
static
|
||||
CompilerMacros toCompilerMacros(Utils::SmallStringView jsonText);
|
||||
static
|
||||
QJsonDocument createJsonDocument(Utils::SmallStringView jsonText,
|
||||
const char *whatError);
|
||||
static
|
||||
void checkError(const char *whatError, const QJsonParseError &error);
|
||||
friend
|
||||
bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second);
|
||||
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:
|
||||
Utils::SmallStringVector compilerArguments;
|
||||
CompilerMacros compilerMacros;
|
||||
Utils::SmallStringVector includeSearchPaths;
|
||||
IncludeSearchPaths systemIncludeSearchPaths;
|
||||
IncludeSearchPaths projectIncludeSearchPaths;
|
||||
int projectPartId = -1;
|
||||
};
|
||||
|
||||
|
@@ -25,8 +25,10 @@
|
||||
|
||||
#include "symbolindexer.h"
|
||||
|
||||
#include <symbolscollectorinterface.h>
|
||||
#include <symbolindexertaskqueue.h>
|
||||
#include "symbolscollectorinterface.h"
|
||||
#include "symbolindexertaskqueue.h"
|
||||
|
||||
#include <commandlinebuilder.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
@@ -65,7 +67,7 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
|
||||
Sqlite::TransactionInterface &transactionInterface)
|
||||
: m_symbolIndexerTaskQueue(symbolIndexerTaskQueue),
|
||||
m_symbolStorage(symbolStorage),
|
||||
m_usedMacroAndSourceStorage(usedMacroAndSourceStorage),
|
||||
m_buildDependencyStorage(usedMacroAndSourceStorage),
|
||||
m_pathWatcher(pathWatcher),
|
||||
m_filePathCache(filePathCache),
|
||||
m_fileStatusCache(fileStatusCache),
|
||||
@@ -74,20 +76,22 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
|
||||
pathWatcher.setNotifier(this);
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts)
|
||||
void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
|
||||
{
|
||||
for (V2::ProjectPartContainer &projectPart : projectParts)
|
||||
for (ProjectPartContainer &projectPart : projectParts)
|
||||
updateProjectPart(std::move(projectPart));
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
|
||||
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||
{
|
||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||
const auto optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(projectPart.projectPartId);
|
||||
int projectPartId = m_symbolStorage.insertOrUpdateProjectPart(projectPart.projectPartId,
|
||||
projectPart.arguments,
|
||||
projectPart.compilerMacros,
|
||||
projectPart.includeSearchPaths);
|
||||
int projectPartId = m_symbolStorage.insertOrUpdateProjectPart(
|
||||
projectPart.projectPartId,
|
||||
projectPart.toolChainArguments,
|
||||
projectPart.compilerMacros,
|
||||
projectPart.systemIncludeSearchPaths,
|
||||
projectPart.projectIncludeSearchPaths);
|
||||
if (optionalArtefact)
|
||||
projectPartId = optionalArtefact->projectPartId;
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(projectPartId);
|
||||
@@ -97,14 +101,20 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
|
||||
if (sourcePathIds.empty())
|
||||
return;
|
||||
|
||||
const Utils::SmallStringVector arguments = compilerArguments(projectPart.arguments,
|
||||
optionalProjectPartPch);
|
||||
using Builder = CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>;
|
||||
Builder commandLineBuilder{projectPart,
|
||||
projectPart.toolChainArguments,
|
||||
{},
|
||||
{},
|
||||
optionalProjectPartPch
|
||||
? FilePathView{optionalProjectPartPch.value().pchPath}
|
||||
: FilePathView{}};
|
||||
|
||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
||||
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
||||
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
||||
auto indexing = [projectPartId, arguments, sourcePathId, this]
|
||||
(SymbolsCollectorInterface &symbolsCollector) {
|
||||
auto indexing = [projectPartId, arguments = commandLineBuilder.commandLine, sourcePathId, this](
|
||||
SymbolsCollectorInterface &symbolsCollector) {
|
||||
symbolsCollector.setFile(sourcePathId, arguments);
|
||||
|
||||
symbolsCollector.collectSymbols();
|
||||
@@ -114,14 +124,14 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
|
||||
m_symbolStorage.updateProjectPartSources(projectPartId,
|
||||
symbolsCollector.sourceFiles());
|
||||
m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
|
||||
symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
};
|
||||
@@ -155,22 +165,23 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
m_fileStatusCache.update(filePathId);
|
||||
|
||||
Sqlite::DeferredTransaction transaction{m_transactionInterface};
|
||||
const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(filePathId);
|
||||
const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(
|
||||
filePathId);
|
||||
if (!optionalArtefact)
|
||||
return;
|
||||
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(optionalArtefact->projectPartId);
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(
|
||||
optionalArtefact->projectPartId);
|
||||
transaction.commit();
|
||||
|
||||
if (!optionalArtefact.value().compilerArguments.empty()) {
|
||||
|
||||
const ProjectPartArtefact &artefact = optionalArtefact.value();
|
||||
|
||||
const Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments,
|
||||
optionalProjectPartPch);
|
||||
|
||||
auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId, this]
|
||||
(SymbolsCollectorInterface &symbolsCollector) {
|
||||
auto indexing = [projectPartId = artefact.projectPartId, arguments, filePathId, this](
|
||||
SymbolsCollectorInterface &symbolsCollector) {
|
||||
symbolsCollector.setFile(filePathId, arguments);
|
||||
|
||||
symbolsCollector.collectSymbols();
|
||||
@@ -182,39 +193,43 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
|
||||
m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
m_usedMacroAndSourceStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
|
||||
symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
};
|
||||
|
||||
symbolIndexerTask.emplace_back(filePathId, optionalArtefact->projectPartId, std::move(indexing));
|
||||
symbolIndexerTask.emplace_back(filePathId,
|
||||
optionalArtefact->projectPartId,
|
||||
std::move(indexing));
|
||||
}
|
||||
}
|
||||
|
||||
bool SymbolIndexer::compilerMacrosOrIncludeSearchPathsAreDifferent(
|
||||
const V2::ProjectPartContainer &projectPart,
|
||||
const ProjectPartContainer &projectPart,
|
||||
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const
|
||||
{
|
||||
if (optionalArtefact) {
|
||||
const ProjectPartArtefact &artefact = optionalArtefact.value();
|
||||
return projectPart.compilerMacros != artefact.compilerMacros
|
||||
|| projectPart.includeSearchPaths != artefact.includeSearchPaths;
|
||||
|| projectPart.systemIncludeSearchPaths != artefact.systemIncludeSearchPaths
|
||||
|| projectPart.projectIncludeSearchPaths != artefact.projectIncludeSearchPaths;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FilePathIds SymbolIndexer::filterChangedFiles(const V2::ProjectPartContainer &projectPart) const
|
||||
FilePathIds SymbolIndexer::filterChangedFiles(const ProjectPartContainer &projectPart) const
|
||||
{
|
||||
FilePathIds ids;
|
||||
ids.reserve(projectPart.sourcePathIds.size());
|
||||
|
||||
for (const FilePathId &sourceId : projectPart.sourcePathIds) {
|
||||
long long oldLastModified = m_usedMacroAndSourceStorage.fetchLowestLastModifiedTime(sourceId);
|
||||
long long oldLastModified = m_buildDependencyStorage.fetchLowestLastModifiedTime(sourceId);
|
||||
long long currentLastModified = m_fileStatusCache.lastModifiedTime(sourceId);
|
||||
if (oldLastModified < currentLastModified)
|
||||
ids.push_back(sourceId);
|
||||
@@ -223,7 +238,7 @@ FilePathIds SymbolIndexer::filterChangedFiles(const V2::ProjectPartContainer &pr
|
||||
return ids;
|
||||
}
|
||||
|
||||
FilePathIds SymbolIndexer::updatableFilePathIds(const V2::ProjectPartContainer &projectPart,
|
||||
FilePathIds SymbolIndexer::updatableFilePathIds(const ProjectPartContainer &projectPart,
|
||||
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const
|
||||
{
|
||||
if (compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart, optionalArtefact))
|
||||
@@ -233,8 +248,8 @@ FilePathIds SymbolIndexer::updatableFilePathIds(const V2::ProjectPartContainer &
|
||||
}
|
||||
|
||||
Utils::SmallStringVector SymbolIndexer::compilerArguments(
|
||||
Utils::SmallStringVector arguments,
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch) const
|
||||
Utils::SmallStringVector arguments,
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch) const
|
||||
{
|
||||
if (optionalProjectPartPch) {
|
||||
arguments.emplace_back("-Xclang");
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#include "builddependenciesstorageinterface.h"
|
||||
#include "clangpathwatcher.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
@@ -49,8 +49,8 @@ public:
|
||||
FileStatusCache &fileStatusCache,
|
||||
Sqlite::TransactionInterface &transactionInterface);
|
||||
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts);
|
||||
void updateProjectPart(V2::ProjectPartContainer &&projectPart);
|
||||
void updateProjectParts(ProjectPartContainers &&projectParts);
|
||||
void updateProjectPart(ProjectPartContainer &&projectPart);
|
||||
|
||||
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
|
||||
void pathsChanged(const FilePathIds &filePathIds) override;
|
||||
@@ -58,22 +58,23 @@ public:
|
||||
std::vector<SymbolIndexerTask> &symbolIndexerTask);
|
||||
|
||||
bool compilerMacrosOrIncludeSearchPathsAreDifferent(
|
||||
const V2::ProjectPartContainer &projectPart,
|
||||
const ProjectPartContainer &projectPart,
|
||||
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
|
||||
|
||||
FilePathIds filterChangedFiles(
|
||||
const V2::ProjectPartContainer &projectPart) const;
|
||||
const ProjectPartContainer &projectPart) const;
|
||||
|
||||
FilePathIds updatableFilePathIds(const V2::ProjectPartContainer &projectPart,
|
||||
FilePathIds updatableFilePathIds(const ProjectPartContainer &projectPart,
|
||||
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
|
||||
|
||||
Utils::SmallStringVector compilerArguments(Utils::SmallStringVector arguments,
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch) const;
|
||||
Utils::SmallStringVector compilerArguments(
|
||||
Utils::SmallStringVector arguments,
|
||||
const Utils::optional<ProjectPartPch> optionalProjectPartPch) const;
|
||||
|
||||
private:
|
||||
SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
|
||||
SymbolStorageInterface &m_symbolStorage;
|
||||
BuildDependenciesStorageInterface &m_usedMacroAndSourceStorage;
|
||||
BuildDependenciesStorageInterface &m_buildDependencyStorage;
|
||||
ClangPathWatcherInterface &m_pathWatcher;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
FileStatusCache &m_fileStatusCache;
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void SymbolIndexing::updateProjectParts(V2::ProjectPartContainers &&projectParts)
|
||||
void SymbolIndexing::updateProjectParts(ProjectPartContainers &&projectParts)
|
||||
{
|
||||
m_indexer.updateProjectParts(std::move(projectParts));
|
||||
}
|
||||
|
@@ -81,12 +81,16 @@ public:
|
||||
FilePathCachingInterface &filePathCache,
|
||||
const GeneratedFiles &generatedFiles,
|
||||
ProgressCounter::SetProgressCallback &&setProgressCallback)
|
||||
: m_filePathCache(filePathCache),
|
||||
m_usedMacroAndSourceStorage(database),
|
||||
m_symbolStorage(database),
|
||||
m_collectorManger(generatedFiles, database),
|
||||
m_progressCounter(std::move(setProgressCallback)),
|
||||
m_indexerScheduler(m_collectorManger, m_indexerQueue, m_progressCounter, std::thread::hardware_concurrency())
|
||||
: m_filePathCache(filePathCache)
|
||||
, m_buildDependencyStorage(database)
|
||||
, m_symbolStorage(database)
|
||||
, m_collectorManger(generatedFiles, database)
|
||||
, m_progressCounter(std::move(setProgressCallback))
|
||||
, m_indexerScheduler(m_collectorManger,
|
||||
m_indexerQueue,
|
||||
m_progressCounter,
|
||||
std::thread::hardware_concurrency(),
|
||||
CallDoInMainThreadAfterFinished::Yes)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -109,12 +113,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts) override;
|
||||
void updateProjectParts(ProjectPartContainers &&projectParts) override;
|
||||
|
||||
private:
|
||||
using SymbolIndexerTaskScheduler = TaskScheduler<SymbolsCollectorManager, SymbolIndexerTask::Callable>;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
BuildDependenciesStorage m_usedMacroAndSourceStorage;
|
||||
BuildDependenciesStorage m_buildDependencyStorage;
|
||||
SymbolStorage m_symbolStorage;
|
||||
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
|
||||
FileStatusCache m_fileStatusCache{m_filePathCache};
|
||||
@@ -124,7 +128,7 @@ private:
|
||||
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter};
|
||||
SymbolIndexer m_indexer{m_indexerQueue,
|
||||
m_symbolStorage,
|
||||
m_usedMacroAndSourceStorage,
|
||||
m_buildDependencyStorage,
|
||||
m_sourceWatcher,
|
||||
m_filePathCache,
|
||||
m_fileStatusCache,
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
SymbolIndexingInterface(const SymbolIndexingInterface&) = delete;
|
||||
SymbolIndexingInterface &operator=(const SymbolIndexingInterface&) = delete;
|
||||
|
||||
virtual void updateProjectParts(V2::ProjectPartContainers &&projectParts) = 0;
|
||||
virtual void updateProjectParts(ProjectPartContainers &&projectParts) = 0;
|
||||
|
||||
protected:
|
||||
~SymbolIndexingInterface() = default;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <sqliteexception.h>
|
||||
#include <sqlitetransaction.h>
|
||||
#include <sqlitetable.h>
|
||||
#include <includesearchpath.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@@ -68,45 +69,39 @@ public:
|
||||
}
|
||||
|
||||
int insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const Utils::SmallStringVector &includeSearchPaths) override
|
||||
const Utils::SmallStringVector &commandLineArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const IncludeSearchPaths &systemIncludeSearchPaths,
|
||||
const IncludeSearchPaths &projectIncludeSearchPaths) override
|
||||
{
|
||||
m_database.setLastInsertedRowId(-1);
|
||||
|
||||
Utils::SmallString compilerArguementsAsJson = toJson(commandLineArguments);
|
||||
Utils::SmallString compilerMacrosAsJson = toJson(compilerMacros);
|
||||
Utils::SmallString includeSearchPathsAsJason = toJson(includeSearchPaths);
|
||||
Utils::SmallString systemIncludeSearchPathsAsJason = toJson(systemIncludeSearchPaths);
|
||||
Utils::SmallString projectIncludeSearchPathsAsJason = toJson(projectIncludeSearchPaths);
|
||||
|
||||
WriteStatement &insertStatement = m_insertProjectPartStatement;
|
||||
insertStatement.write(projectPartName,
|
||||
compilerArguementsAsJson,
|
||||
compilerMacrosAsJson,
|
||||
includeSearchPathsAsJason);
|
||||
m_insertOrUpdateProjectPartStatement.write(projectPartName,
|
||||
compilerArguementsAsJson,
|
||||
compilerMacrosAsJson,
|
||||
systemIncludeSearchPathsAsJason,
|
||||
projectIncludeSearchPathsAsJason);
|
||||
|
||||
if (m_database.lastInsertedRowId() == -1) {
|
||||
WriteStatement &updateStatement = m_updateProjectPartStatement;
|
||||
updateStatement.write(compilerArguementsAsJson,
|
||||
compilerMacrosAsJson,
|
||||
includeSearchPathsAsJason,
|
||||
projectPartName);
|
||||
}
|
||||
auto projectPartId = m_getProjectPartIdStatement.template value<int>(projectPartName);
|
||||
|
||||
return int(m_database.lastInsertedRowId());
|
||||
return projectPartId.value();
|
||||
}
|
||||
|
||||
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const override
|
||||
{
|
||||
ReadStatement &statement = m_getProjectPartArtefactsBySourceId;
|
||||
|
||||
return statement.template value<ProjectPartArtefact, 4>(sourceId.filePathId);
|
||||
return statement.template value<ProjectPartArtefact, 5>(sourceId.filePathId);
|
||||
}
|
||||
|
||||
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const override
|
||||
{
|
||||
ReadStatement &statement = m_getProjectPartArtefactsByProjectPartName;
|
||||
|
||||
return statement.template value<ProjectPartArtefact, 4>(projectPartName);
|
||||
return statement.template value<ProjectPartArtefact, 5>(projectPartName);
|
||||
}
|
||||
|
||||
void updateProjectPartSources(int projectPartId,
|
||||
@@ -137,12 +132,25 @@ public:
|
||||
static Utils::SmallString toJson(const CompilerMacros &compilerMacros)
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonObject object;
|
||||
QJsonArray array;
|
||||
|
||||
for (const CompilerMacro ¯o : compilerMacros)
|
||||
object.insert(QString(macro.key), QString(macro.value));
|
||||
array.push_back(QJsonArray{{QString(macro.key), QString(macro.value), macro.index}});
|
||||
|
||||
document.setObject(object);
|
||||
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);
|
||||
}
|
||||
@@ -299,14 +307,12 @@ public:
|
||||
"DELETE FROM newLocations",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_insertProjectPartStatement{
|
||||
"INSERT OR IGNORE INTO projectParts(projectPartName, compilerArguments, compilerMacros, includeSearchPaths) VALUES (?,?,?,?)",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_updateProjectPartStatement{
|
||||
"UPDATE projectParts SET compilerArguments = ?, compilerMacros = ?, includeSearchPaths = ? WHERE projectPartName = ?",
|
||||
m_database
|
||||
};
|
||||
WriteStatement m_insertOrUpdateProjectPartStatement{
|
||||
"INSERT INTO projectParts(projectPartName, compilerArguments, compilerMacros, "
|
||||
"systemIncludeSearchPaths, projectIncludeSearchPaths) VALUES (?001,?002,?003,?004,?005) ON "
|
||||
"CONFLICT(projectPartName) DO UPDATE SET compilerArguments=?002, compilerMacros=?003, "
|
||||
"systemIncludeSearchPaths=?004, projectIncludeSearchPaths=?005",
|
||||
m_database};
|
||||
mutable ReadStatement m_getProjectPartIdStatement{
|
||||
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
|
||||
m_database
|
||||
@@ -324,13 +330,14 @@ public:
|
||||
m_database
|
||||
};
|
||||
mutable ReadStatement m_getProjectPartArtefactsBySourceId{
|
||||
"SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)",
|
||||
m_database
|
||||
};
|
||||
"SELECT compilerArguments, compilerMacros, systemIncludeSearchPaths, projectIncludeSearchPaths, "
|
||||
"projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM "
|
||||
"projectPartsSources WHERE sourceId = ?)",
|
||||
m_database};
|
||||
mutable ReadStatement m_getProjectPartArtefactsByProjectPartName{
|
||||
"SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartName = ?",
|
||||
m_database
|
||||
};
|
||||
"SELECT compilerArguments, compilerMacros, systemIncludeSearchPaths, "
|
||||
"projectIncludeSearchPaths, projectPartId FROM projectParts WHERE projectPartName = ?",
|
||||
m_database};
|
||||
mutable ReadStatement m_getPrecompiledHeader{
|
||||
"SELECT projectPchPath, projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?",
|
||||
m_database
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#include "symbolentry.h"
|
||||
#include "usedmacro.h"
|
||||
|
||||
#include <includesearchpath.h>
|
||||
|
||||
#include <sqlitetransaction.h>
|
||||
|
||||
#include <compilermacro.h>
|
||||
@@ -48,15 +50,20 @@ public:
|
||||
SymbolStorageInterface &operator=(const SymbolStorageInterface &) = delete;
|
||||
|
||||
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
|
||||
const SourceLocationEntries &sourceLocations) = 0;
|
||||
virtual int insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const Utils::SmallStringVector &includeSearchPaths) = 0;
|
||||
virtual void updateProjectPartSources(int projectPartId,
|
||||
const FilePathIds &sourceFilePathIds) = 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const = 0;
|
||||
const SourceLocationEntries &sourceLocations)
|
||||
= 0;
|
||||
virtual int insertOrUpdateProjectPart(
|
||||
Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArguments,
|
||||
const CompilerMacros &compilerMacros,
|
||||
const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
|
||||
const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths)
|
||||
= 0;
|
||||
virtual void updateProjectPartSources(int projectPartId, const FilePathIds &sourceFilePathIds) = 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
|
||||
FilePathId sourceId) const = 0;
|
||||
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
|
||||
Utils::SmallStringView projectPartName) const = 0;
|
||||
virtual Utils::optional<ProjectPartPch> fetchPrecompiledHeader(int projectPartId) const = 0;
|
||||
|
||||
protected:
|
||||
|
@@ -63,18 +63,28 @@ protected:
|
||||
mockModifiedTimeChecker,
|
||||
mockBuildDependenciesGenerator,
|
||||
mockSqliteTransactionBackend};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
|
||||
{"--yi"},
|
||||
{{"YI", "1", 1}},
|
||||
{"/yi"},
|
||||
{1},
|
||||
{2}};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
|
||||
{"--er"},
|
||||
{{"ER", "2", 1}},
|
||||
{"/er"},
|
||||
{1},
|
||||
{2, 3, 4}};
|
||||
ClangBackEnd::ProjectPartContainer projectPart1{
|
||||
"ProjectPart1",
|
||||
{"--yi"},
|
||||
{{"YI", "1", 1}},
|
||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||
{{"/project/yi", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||
{1},
|
||||
{2},
|
||||
Utils::Language::C,
|
||||
Utils::LanguageVersion::C11,
|
||||
Utils::LanguageExtension::All};
|
||||
ClangBackEnd::ProjectPartContainer projectPart2{
|
||||
"ProjectPart2",
|
||||
{"--er"},
|
||||
{{"ER", "2", 1}},
|
||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||
{{"/project/er", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||
{1},
|
||||
{2, 3, 4},
|
||||
Utils::Language::C,
|
||||
Utils::LanguageVersion::C11,
|
||||
Utils::LanguageExtension::All};
|
||||
SourceEntries firstSources{{1, SourceType::UserInclude, 1},
|
||||
{2, SourceType::UserInclude, 1},
|
||||
{10, SourceType::UserInclude, 1}};
|
||||
|
@@ -529,25 +529,27 @@ TEST_F(BuildDependencyCollector, MissingInclude)
|
||||
|
||||
TEST_F(BuildDependencyCollector, Create)
|
||||
{
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
ClangBackEnd::BuildDependencyCollector collector{filePathCache};
|
||||
ClangBackEnd::V2::ProjectPartContainer
|
||||
projectPart{"project1",
|
||||
{"cc",
|
||||
"-I",
|
||||
TESTDATA_DIR "/builddependencycollector/external",
|
||||
"-I",
|
||||
TESTDATA_DIR "/builddependencycollector/project",
|
||||
"-isystem",
|
||||
TESTDATA_DIR "/builddependencycollector/system"},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
|
||||
},
|
||||
{id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")}};
|
||||
ClangBackEnd::ProjectPartContainer projectPart{
|
||||
"project1",
|
||||
{},
|
||||
{},
|
||||
{{TESTDATA_DIR "/builddependencycollector/system", 1, IncludeSearchPathType::System}},
|
||||
{
|
||||
{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User},
|
||||
{TESTDATA_DIR "/builddependencycollector/external", 2, IncludeSearchPathType::User},
|
||||
},
|
||||
{
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
|
||||
},
|
||||
{id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")},
|
||||
Utils::Language::Cxx,
|
||||
Utils::LanguageVersion::CXX11,
|
||||
Utils::LanguageExtension::None};
|
||||
|
||||
auto buildDependency = collector.create(projectPart);
|
||||
|
||||
|
481
tests/unit/unittest/commandlinebuilder-test.cpp
Normal file
481
tests/unit/unittest/commandlinebuilder-test.cpp
Normal file
@@ -0,0 +1,481 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <commandlinebuilder.h>
|
||||
#include <pchtask.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
namespace {
|
||||
template<typename ProjectInfo>
|
||||
using Builder = ClangBackEnd::CommandLineBuilder<ProjectInfo>;
|
||||
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
|
||||
template <typename ProjectInfo>
|
||||
class CommandLineBuilder : public testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
class CommandLineBuilder<ClangBackEnd::PchTask> : public testing::Test
|
||||
{
|
||||
public:
|
||||
CommandLineBuilder()
|
||||
{
|
||||
cppProjectInfo.language = Utils::Language::Cxx;
|
||||
}
|
||||
|
||||
public:
|
||||
ClangBackEnd::PchTask emptyProjectInfo{"empty", {}, {}, {}, {}, {}, {}};
|
||||
ClangBackEnd::PchTask cppProjectInfo{"project1", {}, {}, {}, {}, {}, {}};
|
||||
};
|
||||
|
||||
template <>
|
||||
class CommandLineBuilder<ClangBackEnd::ProjectPartContainer> : public testing::Test
|
||||
{
|
||||
public:
|
||||
CommandLineBuilder()
|
||||
{
|
||||
cppProjectInfo.language = Utils::Language::Cxx;
|
||||
}
|
||||
|
||||
public:
|
||||
ClangBackEnd::ProjectPartContainer emptyProjectInfo{"empty",
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
Utils::Language::Cxx,
|
||||
Utils::LanguageVersion::CXX98,
|
||||
Utils::LanguageExtension::None};
|
||||
ClangBackEnd::ProjectPartContainer cppProjectInfo{"project1",
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
Utils::Language::Cxx,
|
||||
Utils::LanguageVersion::CXX98,
|
||||
Utils::LanguageExtension::None};
|
||||
};
|
||||
|
||||
using ProjectInfos = testing::Types<ClangBackEnd::PchTask, ClangBackEnd::ProjectPartContainer>;
|
||||
TYPED_TEST_SUITE(CommandLineBuilder, ProjectInfos);
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, AddToolChainArguments)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {"-m64", "-PIC"}, {}};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, AllOf(Contains("-m64"), Contains("-PIC")));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, CTask)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(
|
||||
builder.commandLine,
|
||||
ElementsAre("clang", "-x", "c-header", "-std=c11", "-nostdinc", "-nostdlibinc", "/source/file.c"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, ObjectiveCTask)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::ObjectiveC;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang",
|
||||
"-x",
|
||||
"objective-c-header",
|
||||
"-std=c11",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"/source/file.c"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, CppTask)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, ObjectiveCppTask)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::ObjectiveC;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"objective-c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp98)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++98"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp03)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX03;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++03"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp11)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++11"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp14)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX14;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++14"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp17)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX17;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++17"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, Cpp20)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX2a;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c++2a"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp98)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++98"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp03)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX03;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++03"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp11)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++11"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp14)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX14;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++14"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp17)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX17;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++17"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuCpp20)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX2a;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu++2a"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, C89)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C89;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c89"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, C99)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C99;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c99"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, C11)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c11"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, C18)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C18;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=c18"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuC89)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C89;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu89"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuC99)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C99;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu99"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuC11)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu11"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, GnuC18)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::C;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C18;
|
||||
this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
|
||||
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine, Contains("-std=gnu18"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, IncludesOrder)
|
||||
{
|
||||
this->emptyProjectInfo.language = Utils::Language::Cxx;
|
||||
this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
|
||||
this->emptyProjectInfo.projectIncludeSearchPaths = {{"/include/bar", 2, IncludeSearchPathType::User},
|
||||
{"/include/foo", 1, IncludeSearchPathType::User}};
|
||||
this->emptyProjectInfo.systemIncludeSearchPaths = {{"/system/bar", 4, IncludeSearchPathType::System},
|
||||
{"/system/foo", 3, IncludeSearchPathType::Framework},
|
||||
{"/builtin/bar", 2, IncludeSearchPathType::BuiltIn},
|
||||
{"/builtin/foo", 1, IncludeSearchPathType::BuiltIn}};
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++11",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"-I",
|
||||
"/include/foo",
|
||||
"-I",
|
||||
"/include/bar",
|
||||
"-F",
|
||||
"/system/foo",
|
||||
"-isystem",
|
||||
"/system/bar",
|
||||
"-isystem",
|
||||
"/builtin/foo",
|
||||
"-isystem",
|
||||
"/builtin/bar",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, EmptySourceFile)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, {}};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++", "-x", "c++-header", "-std=c++98", "-nostdinc", "-nostdlibinc"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, SourceFile)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, EmptyOutputFile)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", ""};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, OutputFile)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", "/output/file.o"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"-o",
|
||||
"/output/file.o",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
TYPED_TEST(CommandLineBuilder, IncludePchPath)
|
||||
{
|
||||
Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", "/output/file.o", "/pch/file.pch"};
|
||||
|
||||
ASSERT_THAT(builder.commandLine,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"-Xclang",
|
||||
"-include-pch",
|
||||
"-Xclang",
|
||||
"/pch/file.pch",
|
||||
"-o",
|
||||
"/output/file.o",
|
||||
"/source/file.cpp"));
|
||||
}
|
||||
|
||||
} // namespace
|
@@ -38,6 +38,7 @@ using testing::Assign;
|
||||
using testing::ByMove;
|
||||
using testing::ByRef;
|
||||
using testing::Contains;
|
||||
using testing::ContainerEq;
|
||||
using testing::ElementsAre;
|
||||
using testing::Field;
|
||||
using testing::HasSubstr;
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-printers.h>
|
||||
#include <gtest/gtest-typed-test.h>
|
||||
|
||||
#include "compare-operators.h"
|
||||
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include <filestatus.h>
|
||||
#include <filepath.h>
|
||||
#include <fulltokeninfo.h>
|
||||
#include <includesearchpath.h>
|
||||
#include <nativefilepath.h>
|
||||
#include <pchcreator.h>
|
||||
#include <pchtask.h>
|
||||
@@ -56,6 +57,7 @@
|
||||
#include <symbolindexertaskqueue.h>
|
||||
#include <symbol.h>
|
||||
#include <tooltipinfo.h>
|
||||
#include <toolchainargumentscache.h>
|
||||
#include <projectpartentry.h>
|
||||
#include <usedmacro.h>
|
||||
|
||||
@@ -181,6 +183,100 @@ std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn)
|
||||
return out << "(" << lineColumn.line << ", " << lineColumn.column << ")";
|
||||
}
|
||||
|
||||
const char * toText(Utils::Language language)
|
||||
{
|
||||
using Utils::Language;
|
||||
|
||||
switch (language) {
|
||||
case Language::C:
|
||||
return "C";
|
||||
case Language::Cxx:
|
||||
return "Cxx";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::Language &language)
|
||||
{
|
||||
return out << "Utils::" << toText(language);
|
||||
}
|
||||
|
||||
const char * toText(Utils::LanguageVersion languageVersion)
|
||||
{
|
||||
using Utils::LanguageVersion;
|
||||
|
||||
switch (languageVersion) {
|
||||
case LanguageVersion::C11:
|
||||
return "C11";
|
||||
case LanguageVersion::C18:
|
||||
return "C18";
|
||||
case LanguageVersion::C89:
|
||||
return "C89";
|
||||
case LanguageVersion::C99:
|
||||
return "C99";
|
||||
case LanguageVersion::CXX03:
|
||||
return "CXX03";
|
||||
case LanguageVersion::CXX11:
|
||||
return "CXX11";
|
||||
case LanguageVersion::CXX14:
|
||||
return "CXX14";
|
||||
case LanguageVersion::CXX17:
|
||||
return "CXX17";
|
||||
case LanguageVersion::CXX2a:
|
||||
return "CXX2a";
|
||||
case LanguageVersion::CXX98:
|
||||
return "CXX98";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion)
|
||||
{
|
||||
return out << "Utils::" << toText(languageVersion);
|
||||
}
|
||||
|
||||
const std::string toText(Utils::LanguageExtension extension, std::string prefix = {})
|
||||
{
|
||||
std::stringstream out;
|
||||
using Utils::LanguageExtension;
|
||||
|
||||
if (extension == LanguageExtension::None) {
|
||||
out << prefix << "None";
|
||||
} else if (extension == LanguageExtension::All) {
|
||||
out << prefix << "All";
|
||||
} else {
|
||||
std::string split = "";
|
||||
if (extension == LanguageExtension::Gnu) {
|
||||
out << prefix << "Gnu";
|
||||
split = " | ";
|
||||
}
|
||||
if (extension == LanguageExtension::Microsoft) {
|
||||
out << split << prefix << "Microsoft";
|
||||
split = " | ";
|
||||
}
|
||||
if (extension == LanguageExtension::Borland) {
|
||||
out << split << prefix << "Borland";
|
||||
split = " | ";
|
||||
}
|
||||
if (extension == LanguageExtension::OpenMP) {
|
||||
out << split << prefix << "OpenMP";
|
||||
split = " | ";
|
||||
}
|
||||
if (extension == LanguageExtension::ObjectiveC) {
|
||||
out << split << prefix << "ObjectiveC";
|
||||
}
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension)
|
||||
{
|
||||
return out << toText(languageExtension, "Utils::");
|
||||
}
|
||||
|
||||
void PrintTo(Utils::SmallStringView text, ::std::ostream *os)
|
||||
{
|
||||
*os << "\"" << text << "\"";
|
||||
@@ -1061,7 +1157,15 @@ std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes)
|
||||
std::ostream &operator<<(std::ostream &out, const PchTask &task)
|
||||
{
|
||||
return out << "(" << task.projectPartIds << ", " << task.includes << ", " << task.compilerMacros
|
||||
<< ", " << task.usedMacros << ")";
|
||||
<< ", " << task.usedMacros << ", " << toText(task.language) << ", "
|
||||
<< task.systemIncludeSearchPaths << ", " << task.projectIncludeSearchPaths << ", "
|
||||
<< task.toolChainArguments << ", " << toText(task.languageVersion) << ", "
|
||||
<< toText(task.languageExtension) << ")";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet)
|
||||
{
|
||||
return out << "(" << taskSet.system << ", " << taskSet.project << ")";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency)
|
||||
@@ -1105,6 +1209,50 @@ std::ostream &operator<<(std::ostream &out, const SourceEntry &entry)
|
||||
return out << "(" << entry.sourceId << ", " << sourceTypeString(entry.sourceType) << ")";
|
||||
}
|
||||
|
||||
const char *typeToString(IncludeSearchPathType type)
|
||||
{
|
||||
switch (type) {
|
||||
case IncludeSearchPathType::Invalid:
|
||||
return "Invalid";
|
||||
case IncludeSearchPathType::User:
|
||||
return "User";
|
||||
case IncludeSearchPathType::System:
|
||||
return "System";
|
||||
case IncludeSearchPathType::BuiltIn:
|
||||
return "BuiltIn";
|
||||
case IncludeSearchPathType::Framework:
|
||||
return "Framework";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const IncludeSearchPathType &pathType)
|
||||
{
|
||||
return out << "IncludeSearchPathType::" << typeToString(pathType);
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const IncludeSearchPath &path)
|
||||
{
|
||||
return out << "(" << path.path << ", " << path.index << ", " << typeToString(path.type) << ")";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry)
|
||||
{
|
||||
return out << "(" << entry.ids << ", " << entry.arguments << ")";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container)
|
||||
{
|
||||
out << "(" << container.projectPartId << ", " << container.toolChainArguments << ", "
|
||||
<< container.headerPathIds << ", " << container.sourcePathIds << ", "
|
||||
<< container.compilerMacros << ", " << container.systemIncludeSearchPaths << ", "
|
||||
<< container.projectIncludeSearchPaths << ", " << toText(container.language) << ", "
|
||||
<< toText(container.languageVersion) << ", " << toText(container.languageExtension) << ")";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void PrintTo(const FilePath &filePath, ::std::ostream *os)
|
||||
{
|
||||
*os << filePath;
|
||||
@@ -1138,19 +1286,6 @@ std::ostream &operator<<(std::ostream &os, const FileContainer &container)
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container)
|
||||
{
|
||||
out << "("
|
||||
<< container.projectPartId << ", "
|
||||
<< container.arguments << ", "
|
||||
<< container.headerPathIds << ", "
|
||||
<< container.sourcePathIds << ", "
|
||||
<< container.compilerMacros << ", "
|
||||
<< container.includeSearchPaths << ")";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container)
|
||||
{
|
||||
os << "("
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/cpplanguage_details.h>
|
||||
#include <utils/smallstringio.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
@@ -74,6 +75,9 @@ class LineColumn;
|
||||
class SmallStringView;
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn);
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::Language &language);
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion);
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension);
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &out, const Utils::optional<Type> &optional)
|
||||
@@ -176,10 +180,15 @@ class SymbolIndexerTask;
|
||||
class ProgressMessage;
|
||||
class PchCreatorIncludes;
|
||||
class PchTask;
|
||||
class PchTaskSet;
|
||||
class BuildDependency;
|
||||
class SourceEntry;
|
||||
class FilePathCaching;
|
||||
class SlotUsage;
|
||||
class IncludeSearchPath;
|
||||
enum class IncludeSearchPathType : unsigned char;
|
||||
class ArgumentsEntry;
|
||||
class ProjectPartContainer;
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
|
||||
std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
|
||||
@@ -262,9 +271,14 @@ std::ostream &operator<<(std::ostream &out, const SymbolIndexerTask &task);
|
||||
std::ostream &operator<<(std::ostream &out, const ProgressMessage &message);
|
||||
std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes);
|
||||
std::ostream &operator<<(std::ostream &out, const PchTask &task);
|
||||
std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet);
|
||||
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency);
|
||||
std::ostream &operator<<(std::ostream &out, const SourceEntry &entry);
|
||||
std::ostream &operator<<(std::ostream &out, const SlotUsage &slotUsage);
|
||||
std::ostream &operator<<(std::ostream &out, const IncludeSearchPathType &pathType);
|
||||
std::ostream &operator<<(std::ostream &out, const IncludeSearchPath &path);
|
||||
std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry);
|
||||
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
|
||||
|
||||
void PrintTo(const FilePath &filePath, ::std::ostream *os);
|
||||
void PrintTo(const FilePathView &filePathView, ::std::ostream *os);
|
||||
@@ -272,12 +286,10 @@ void PrintTo(const FilePathId &filePathId, ::std::ostream *os);
|
||||
|
||||
namespace V2 {
|
||||
class FileContainer;
|
||||
class ProjectPartContainer;
|
||||
class SourceRangeContainer;
|
||||
class SourceLocationContainer;
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const FileContainer &container);
|
||||
std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
|
||||
std::ostream &operator<<(std::ostream &out, const SourceLocationContainer &container);
|
||||
std::ostream &operator<<(std::ostream &out, const SourceRangeContainer &container);
|
||||
} // namespace V2
|
||||
|
@@ -34,5 +34,5 @@ class MockBuildDependenciesProvider : public ClangBackEnd::BuildDependenciesProv
|
||||
public:
|
||||
MOCK_METHOD1(
|
||||
create,
|
||||
ClangBackEnd::BuildDependency(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
|
||||
ClangBackEnd::BuildDependency(const ClangBackEnd::ProjectPartContainer &projectPart));
|
||||
};
|
||||
|
@@ -33,6 +33,6 @@ class MockBuildDependencyGenerator : public ClangBackEnd::BuildDependencyGenerat
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(create,
|
||||
ClangBackEnd::BuildDependency (const ClangBackEnd::V2::ProjectPartContainer &projectPart));
|
||||
ClangBackEnd::BuildDependency (const ClangBackEnd::ProjectPartContainer &projectPart));
|
||||
};
|
||||
|
||||
|
@@ -30,18 +30,21 @@
|
||||
#include <filecontainerv2.h>
|
||||
#include <pchcreatorinterface.h>
|
||||
#include <projectpartpch.h>
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <projectpartcontainer.h>
|
||||
|
||||
class MockPchCreator : public ClangBackEnd::PchCreatorInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(generatePchDeprecated, void(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
|
||||
MOCK_METHOD1(generatePch, void(const ClangBackEnd::PchTask &pchTask));
|
||||
MOCK_METHOD0(takeProjectIncludes, ClangBackEnd::IdPaths());
|
||||
MOCK_METHOD0(projectPartPch, const ClangBackEnd::ProjectPartPch &());
|
||||
MOCK_METHOD1(setUnsavedFiles, void(const ClangBackEnd::V2::FileContainers &fileContainers));
|
||||
MOCK_METHOD0(clear, void());
|
||||
MOCK_METHOD0(doInMainThreadAfterFinished, void());
|
||||
MOCK_CONST_METHOD0(isUsed, bool());
|
||||
MOCK_METHOD1(setIsUsed, void(bool));
|
||||
|
||||
void generatePch(ClangBackEnd::PchTask &&pchTask) override
|
||||
{
|
||||
generatePch(pchTask);
|
||||
}
|
||||
};
|
||||
|
46
tests/unit/unittest/mockpchtaskgenerator.h
Normal file
46
tests/unit/unittest/mockpchtaskgenerator.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "googletest.h"
|
||||
|
||||
#include <pchtaskgeneratorinterface.h>
|
||||
|
||||
class MockPchTaskGenerator : public ClangBackEnd::PchTaskGeneratorInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2(addProjectParts,
|
||||
void(const ClangBackEnd::ProjectPartContainers &projectParts,
|
||||
const Utils::SmallStringVector &toolChainArguments));
|
||||
MOCK_METHOD1(removeProjectParts,
|
||||
void (const Utils::SmallStringVector &projectsPartIds));
|
||||
|
||||
void addProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments) override
|
||||
{
|
||||
addProjectParts(projectParts, toolChainArguments);
|
||||
}
|
||||
};
|
@@ -32,7 +32,15 @@
|
||||
class MockPchTasksMerger : public ClangBackEnd::PchTasksMergerInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(mergeTasks, void(const ClangBackEnd::PchTaskSets &pchTaskSets));
|
||||
MOCK_METHOD2(mergeTasks,
|
||||
void(const ClangBackEnd::PchTaskSets &pchTaskSets,
|
||||
const Utils::SmallStringVector &toolChainArguments));
|
||||
|
||||
void mergeTasks(ClangBackEnd::PchTaskSets &&pchTaskSets) override { mergeTasks(pchTaskSets); }
|
||||
MOCK_METHOD1(removePchTasks, void(const Utils::SmallStringVector &projectPartIds));
|
||||
|
||||
void mergeTasks(ClangBackEnd::PchTaskSets &&pchTaskSets,
|
||||
Utils::SmallStringVector &&toolChainArguments) override
|
||||
{
|
||||
mergeTasks(pchTaskSets, toolChainArguments);
|
||||
}
|
||||
};
|
||||
|
@@ -37,11 +37,12 @@ public:
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime));
|
||||
MOCK_METHOD1(deleteProjectPrecompiledHeader, void(Utils::SmallStringView projectPartName));
|
||||
MOCK_METHOD3(insertSystemPrecompiledHeader,
|
||||
void(Utils::SmallStringView projectPartName,
|
||||
MOCK_METHOD3(insertSystemPrecompiledHeaders,
|
||||
void(const Utils::SmallStringVector &projectPartNames,
|
||||
Utils::SmallStringView pchPath,
|
||||
long long pchBuildTime));
|
||||
MOCK_METHOD1(deleteSystemPrecompiledHeader, void(Utils::SmallStringView projectPartName));
|
||||
MOCK_METHOD1(deleteSystemPrecompiledHeaders,
|
||||
void(const Utils::SmallStringVector &projectPartNames));
|
||||
MOCK_METHOD1(fetchSystemPrecompiledHeaderPath,
|
||||
Utils::PathString(Utils::SmallStringView projectPartName));
|
||||
ClangBackEnd::FilePath(Utils::SmallStringView projectPartName));
|
||||
};
|
||||
|
@@ -33,13 +33,13 @@ class MockProjectPartQueue : public ClangBackEnd::ProjectPartQueueInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(addProjectParts,
|
||||
void (const ClangBackEnd::V2::ProjectPartContainers &projectParts));
|
||||
void (const ClangBackEnd::ProjectPartContainers &projectParts));
|
||||
MOCK_METHOD1(removeProjectParts,
|
||||
void (const Utils::SmallStringVector &projectsPartIds));
|
||||
|
||||
MOCK_METHOD0(processEntries, void ());
|
||||
|
||||
void addProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts) override
|
||||
void addProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts) override
|
||||
{
|
||||
addProjectParts(projectParts);
|
||||
}
|
||||
|
@@ -33,13 +33,13 @@ class MockProjectParts : public ClangBackEnd::ProjectPartsInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(update,
|
||||
ClangBackEnd::V2::ProjectPartContainers(const ClangBackEnd::V2::ProjectPartContainers &projectsParts));
|
||||
ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartContainers &projectsParts));
|
||||
MOCK_METHOD1(remove,
|
||||
void(const Utils::SmallStringVector &projectPartIds));
|
||||
MOCK_CONST_METHOD1(projects,
|
||||
ClangBackEnd::V2::ProjectPartContainers(const Utils::SmallStringVector &projectPartIds));
|
||||
ClangBackEnd::ProjectPartContainers(const Utils::SmallStringVector &projectPartIds));
|
||||
|
||||
ClangBackEnd::V2::ProjectPartContainers update(ClangBackEnd::V2::ProjectPartContainers &&projectsParts) override
|
||||
ClangBackEnd::ProjectPartContainers update(ClangBackEnd::ProjectPartContainers &&projectsParts) override
|
||||
{
|
||||
return update(projectsParts);
|
||||
}
|
||||
|
@@ -144,16 +144,23 @@ MockSqliteReadStatement::value<Utils::PathString>(const Utils::SmallStringView &
|
||||
return valueReturnPathString(path);
|
||||
}
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::FilePath>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::FilePath>(const Utils::SmallStringView &path)
|
||||
{
|
||||
return valueReturnFilePath(path);
|
||||
}
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::ProjectPartArtefact>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int& sourceId)
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int& sourceId)
|
||||
{
|
||||
return valueReturnProjectPartArtefact(sourceId);
|
||||
}
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::ProjectPartArtefact>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const Utils::SmallStringView &projectPartName)
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const Utils::SmallStringView &projectPartName)
|
||||
{
|
||||
return valueReturnProjectPartArtefact(projectPartName);
|
||||
}
|
||||
|
@@ -99,6 +99,9 @@ public:
|
||||
MOCK_METHOD1(valueReturnPathString,
|
||||
Utils::optional<Utils::PathString>(Utils::SmallStringView));
|
||||
|
||||
MOCK_METHOD1(valueReturnFilePath,
|
||||
Utils::optional<ClangBackEnd::FilePath>(Utils::SmallStringView));
|
||||
|
||||
MOCK_METHOD1(valueReturnSmallString,
|
||||
Utils::optional<Utils::SmallString>(int));
|
||||
|
||||
@@ -212,6 +215,10 @@ template <>
|
||||
Utils::optional<int>
|
||||
MockSqliteReadStatement::value<int>(const Utils::PathString&);
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::FilePath>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::FilePath>(const Utils::SmallStringView&);
|
||||
|
||||
template <>
|
||||
Utils::optional<int>
|
||||
MockSqliteReadStatement::value<int>(const int&, const Utils::SmallStringView&);
|
||||
@@ -230,11 +237,11 @@ MockSqliteReadStatement::value<Utils::PathString>(const Utils::SmallStringView&)
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::ProjectPartArtefact>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&);
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int&);
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::ProjectPartArtefact>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&);
|
||||
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int&);
|
||||
|
||||
template <>
|
||||
Utils::optional<ClangBackEnd::ProjectPartPch>
|
||||
|
@@ -78,6 +78,12 @@ public:
|
||||
Utils::SmallStringView,
|
||||
Utils::SmallStringView));
|
||||
|
||||
MOCK_METHOD5(write,
|
||||
void (Utils::SmallStringView,
|
||||
Utils::SmallStringView,
|
||||
Utils::SmallStringView,
|
||||
Utils::SmallStringView,
|
||||
Utils::SmallStringView));
|
||||
MOCK_METHOD1(write,
|
||||
void (Utils::SmallStringView));
|
||||
|
||||
|
@@ -33,9 +33,9 @@ class MockSymbolIndexing : public ClangBackEnd::SymbolIndexingInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(updateProjectParts,
|
||||
void(const ClangBackEnd::V2::ProjectPartContainers &projectParts));
|
||||
void(const ClangBackEnd::ProjectPartContainers &projectParts));
|
||||
|
||||
void updateProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts) override
|
||||
void updateProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts) override
|
||||
{
|
||||
updateProjectParts(projectParts);
|
||||
}
|
||||
|
@@ -37,11 +37,12 @@ public:
|
||||
MOCK_METHOD2(addSymbolsAndSourceLocations,
|
||||
void(const ClangBackEnd::SymbolEntries &symbolEentries,
|
||||
const ClangBackEnd::SourceLocationEntries &sourceLocations));
|
||||
MOCK_METHOD4(insertOrUpdateProjectPart,
|
||||
MOCK_METHOD5(insertOrUpdateProjectPart,
|
||||
int(Utils::SmallStringView projectPartName,
|
||||
const Utils::SmallStringVector &commandLineArgument,
|
||||
const ClangBackEnd::CompilerMacros &compilerMacros,
|
||||
const Utils::SmallStringVector &includeSearchPaths));
|
||||
const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
|
||||
const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths));
|
||||
MOCK_METHOD2(updateProjectPartSources,
|
||||
void(int projectPartId,
|
||||
const ClangBackEnd::FilePathIds &sourceFilePathIds));
|
||||
|
109
tests/unit/unittest/modifiedtimechecker-test.cpp
Normal file
109
tests/unit/unittest/modifiedtimechecker-test.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <filepathcaching.h>
|
||||
#include <modifiedtimechecker.h>
|
||||
#include <refactoringdatabaseinitializer.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::SourceEntries;
|
||||
using ClangBackEnd::SourceType;
|
||||
using ClangBackEnd::FilePathView;
|
||||
|
||||
|
||||
class ModifiedTimeChecker : public testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
ClangBackEnd::FilePathId id(const Utils::SmallStringView &path) const
|
||||
{
|
||||
return filePathCache.filePathId(ClangBackEnd::FilePathView{path});
|
||||
}
|
||||
|
||||
|
||||
ModifiedTimeChecker()
|
||||
{
|
||||
ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(50));
|
||||
ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
|
||||
}
|
||||
NiceMock<MockFunction<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>> getModifiedTimeCallback;
|
||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||
decltype(getModifiedTimeCallback.AsStdFunction()) callback = getModifiedTimeCallback
|
||||
.AsStdFunction();
|
||||
ClangBackEnd::ModifiedTimeChecker checker{callback, filePathCache};
|
||||
SourceEntries upToDateEntries = {{id("/path1"), SourceType::UserInclude, 100},
|
||||
{id("/path2"), SourceType::SystemInclude, 30}};
|
||||
SourceEntries notUpToDateEntries = {{id("/path1"), SourceType::UserInclude, 50},
|
||||
{id("/path2"), SourceType::SystemInclude, 20}};
|
||||
};
|
||||
|
||||
TEST_F(ModifiedTimeChecker, IsUpToDate)
|
||||
{
|
||||
auto isUpToDate = checker.isUpToDate(upToDateEntries);
|
||||
|
||||
ASSERT_TRUE(isUpToDate);
|
||||
}
|
||||
|
||||
TEST_F(ModifiedTimeChecker, IsNotUpToDateIfSourceEntriesAreEmpty)
|
||||
{
|
||||
auto isUpToDate = checker.isUpToDate({});
|
||||
|
||||
ASSERT_FALSE(isUpToDate);
|
||||
}
|
||||
|
||||
TEST_F(ModifiedTimeChecker, IsNotUpToDate)
|
||||
{
|
||||
auto isUpToDate = checker.isUpToDate({});
|
||||
|
||||
ASSERT_FALSE(isUpToDate);
|
||||
}
|
||||
|
||||
TEST_F(ModifiedTimeChecker, PathChangesUpdatesTimeStamps)
|
||||
{
|
||||
checker.isUpToDate(upToDateEntries);
|
||||
|
||||
EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1"))));
|
||||
EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2"))));
|
||||
|
||||
checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
|
||||
}
|
||||
|
||||
TEST_F(ModifiedTimeChecker, IsNotUpToDateAnyMoreAfterUpdating)
|
||||
{
|
||||
checker.isUpToDate(upToDateEntries);
|
||||
ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(120));
|
||||
ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
|
||||
|
||||
checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
|
||||
|
||||
ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
|
||||
}
|
||||
|
||||
} // namespace
|
@@ -50,22 +50,25 @@ using ClangBackEnd::FilePathIds;
|
||||
using ClangBackEnd::FilePathView;
|
||||
using ClangBackEnd::GeneratedFiles;
|
||||
using ClangBackEnd::IdPaths;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
using ClangBackEnd::PchTask;
|
||||
using ClangBackEnd::ProjectPartPch;
|
||||
using ClangBackEnd::SourceEntries;
|
||||
using ClangBackEnd::SourceEntry;
|
||||
using ClangBackEnd::SourceType;
|
||||
using ClangBackEnd::V2::FileContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::ProjectPartContainer;
|
||||
|
||||
using Utils::PathString;
|
||||
using Utils::SmallString;
|
||||
|
||||
using UnitTests::EndsWith;
|
||||
|
||||
MATCHER_P2(HasIdAndType, sourceId, sourceType,
|
||||
std::string(negation ? "hasn't" : "has") +
|
||||
PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType,
|
||||
-1)))
|
||||
MATCHER_P2(HasIdAndType,
|
||||
sourceId,
|
||||
sourceType,
|
||||
std::string(negation ? "hasn't" : "has")
|
||||
+ PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType, -1)))
|
||||
{
|
||||
const ClangBackEnd::SourceEntry &entry = arg;
|
||||
return entry.sourceId == sourceId && entry.sourceType == sourceType;
|
||||
@@ -74,7 +77,7 @@ MATCHER_P2(HasIdAndType, sourceId, sourceType,
|
||||
class PchCreator: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp()
|
||||
PchCreator()
|
||||
{
|
||||
creator.setUnsavedFiles({generatedFile});
|
||||
}
|
||||
@@ -96,86 +99,26 @@ protected:
|
||||
TestEnvironment environment;
|
||||
FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}};
|
||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
||||
ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient, mockClangPathWatcher};
|
||||
ProjectPartContainer projectPart1{"project1",
|
||||
{"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"},
|
||||
{id(header1Path)},
|
||||
{id(main1Path)}};
|
||||
ProjectPartContainer projectPart2{"project2",
|
||||
{"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"},
|
||||
{id(header2Path)},
|
||||
{id(main2Path)}};
|
||||
ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient};
|
||||
PchTask pchTask1{
|
||||
"project1",
|
||||
{id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
|
||||
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{{TESTDATA_DIR "/builddependencycollector/system", 2, IncludeSearchPathType::BuiltIn},
|
||||
{TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
|
||||
{{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}},
|
||||
};
|
||||
};
|
||||
using PchCreatorSlowTest = PchCreator;
|
||||
using PchCreatorVerySlowTest = PchCreator;
|
||||
|
||||
TEST_F(PchCreator, ConvertToQStringList)
|
||||
TEST_F(PchCreator, CreateProjectPartPchFileContent)
|
||||
{
|
||||
auto arguments = creator.convertToQStringList({"-I", TESTDATA_DIR});
|
||||
|
||||
ASSERT_THAT(arguments, ElementsAre(QString("-I"), QString(TESTDATA_DIR)));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartCommandLine)
|
||||
{
|
||||
auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
|
||||
|
||||
ASSERT_THAT(commandLine, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system", "-Wno-pragma-once-outside-header"));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartHeaders)
|
||||
{
|
||||
auto includeIds = creator.generateProjectPartHeaders(projectPart1);
|
||||
|
||||
ASSERT_THAT(includeIds, UnorderedElementsAre(header1Path, generatedFilePath));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartSources)
|
||||
{
|
||||
auto includeIds = creator.generateProjectPartSourcePaths(projectPart1);
|
||||
|
||||
ASSERT_THAT(includeIds, UnorderedElementsAre(main1Path));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludes)
|
||||
{
|
||||
using ClangBackEnd::PchCreatorIncludes;
|
||||
|
||||
auto includeIds = creator.generateProjectPartPchIncludes(projectPart1);
|
||||
|
||||
ASSERT_THAT(
|
||||
includeIds,
|
||||
AllOf(
|
||||
Contains(HasIdAndType(
|
||||
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
|
||||
SourceType::TopProjectInclude)),
|
||||
Contains(HasIdAndType(
|
||||
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
|
||||
SourceType::TopSystemInclude)),
|
||||
Contains(HasIdAndType(
|
||||
id(TESTDATA_DIR
|
||||
"/builddependencycollector/system/indirect_system.h"),
|
||||
SourceType::SystemInclude)),
|
||||
Contains(HasIdAndType(
|
||||
id(TESTDATA_DIR
|
||||
"/builddependencycollector/external/external1.h"),
|
||||
SourceType::TopProjectInclude)),
|
||||
Contains(HasIdAndType(
|
||||
id(TESTDATA_DIR
|
||||
"/builddependencycollector/external/external2.h"),
|
||||
SourceType::TopProjectInclude))));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent)
|
||||
{
|
||||
auto includes = creator.generateProjectPartPchIncludes(projectPart1);
|
||||
|
||||
auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes));
|
||||
auto content = creator.generatePchIncludeFileContent(pchTask1.includes);
|
||||
|
||||
ASSERT_THAT(std::string(content),
|
||||
AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"),
|
||||
@@ -183,11 +126,10 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent)
|
||||
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n")));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile)
|
||||
TEST_F(PchCreator, CreatePchIncludeFile)
|
||||
{
|
||||
auto includes = creator.generateProjectPartPchIncludes(projectPart1);
|
||||
auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes));
|
||||
auto pchIncludeFilePath = creator.generateProjectPathPchHeaderFilePath(projectPart1);
|
||||
auto content = creator.generatePchIncludeFileContent(pchTask1.includes);
|
||||
auto pchIncludeFilePath = creator.generatePchHeaderFilePath();
|
||||
auto file = creator.generateFileWithContent(pchIncludeFilePath, content);
|
||||
file->open(QIODevice::ReadOnly);
|
||||
|
||||
@@ -199,38 +141,63 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile)
|
||||
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n")));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartPchCompilerArguments)
|
||||
{
|
||||
auto arguments = creator.generateProjectPartPchCompilerArguments(projectPart1);
|
||||
|
||||
ASSERT_THAT(arguments, AllOf(Contains("-x"),
|
||||
Contains("c++-header"),
|
||||
Contains("-Xclang"),
|
||||
Contains("-emit-pch"),
|
||||
Contains("-o"),
|
||||
Contains(EndsWith(".pch"))));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
|
||||
{
|
||||
auto arguments = creator.generateProjectPartClangCompilerArguments(projectPart1);
|
||||
auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1),
|
||||
"project.h",
|
||||
"project.pch");
|
||||
|
||||
ASSERT_THAT(arguments, AllOf(Contains(TESTDATA_DIR),
|
||||
Contains("-emit-pch"),
|
||||
Contains("-o"),
|
||||
Not(Contains(environment.clangCompilerPath()))));
|
||||
ASSERT_THAT(arguments,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"-I",
|
||||
TESTDATA_DIR "/builddependencycollector/project",
|
||||
"-isystem",
|
||||
TESTDATA_DIR "/builddependencycollector/external",
|
||||
"-isystem",
|
||||
TESTDATA_DIR "/builddependencycollector/system",
|
||||
"-o",
|
||||
"project.pch",
|
||||
"project.h"));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, IncludesForCreatePchsForProjectParts)
|
||||
TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
pchTask1.systemPchPath = "system.pch";
|
||||
|
||||
ASSERT_THAT(creator.takeProjectIncludes().id, "project1");
|
||||
auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1),
|
||||
"project.h",
|
||||
"project.pch");
|
||||
|
||||
ASSERT_THAT(arguments,
|
||||
ElementsAre("clang++",
|
||||
"-x",
|
||||
"c++-header",
|
||||
"-std=c++98",
|
||||
"-nostdinc",
|
||||
"-nostdlibinc",
|
||||
"-I",
|
||||
TESTDATA_DIR "/builddependencycollector/project",
|
||||
"-isystem",
|
||||
TESTDATA_DIR "/builddependencycollector/external",
|
||||
"-isystem",
|
||||
TESTDATA_DIR "/builddependencycollector/system",
|
||||
"-Xclang",
|
||||
"-include-pch",
|
||||
"-Xclang",
|
||||
"system.pch",
|
||||
"-o",
|
||||
"project.pch",
|
||||
"project.h"));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
creator.generatePch(std::move(pchTask1));
|
||||
|
||||
EXPECT_CALL(mockPchManagerClient,
|
||||
precompiledHeadersUpdated(
|
||||
@@ -240,30 +207,10 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
|
||||
creator.doInMainThreadAfterFinished();
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, UpdateFileWatcherIncludes)
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
|
||||
EXPECT_CALL(mockClangPathWatcher,
|
||||
updateIdPaths(ElementsAre(creator.projectIncludes())));
|
||||
|
||||
creator.doInMainThreadAfterFinished();
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
|
||||
ASSERT_THAT(creator.takeProjectIncludes(),
|
||||
AllOf(Field(&IdPaths::id, "project1"),
|
||||
Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/builddependencycollector/project/header2.h")),
|
||||
Contains(id(TESTDATA_DIR "/builddependencycollector/external/external1.h")),
|
||||
Contains(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))))));
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForProjectPart)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
creator.generatePch(std::move(pchTask1));
|
||||
|
||||
ASSERT_THAT(creator.projectPartPch(),
|
||||
AllOf(Field(&ProjectPartPch::projectPartId, Eq("project1")),
|
||||
@@ -273,52 +220,29 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForProjectPart)
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
creator.generatePch(std::move(pchTask1));
|
||||
|
||||
creator.clear();
|
||||
|
||||
ASSERT_THAT(creator.projectPartPch(), ClangBackEnd::ProjectPartPch{});
|
||||
}
|
||||
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, ProjectIncludesCleared)
|
||||
TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask)
|
||||
{
|
||||
creator.generatePchDeprecated(projectPart1);
|
||||
PchTask faultyPchTask{"faultyProjectPart",
|
||||
{id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{},
|
||||
{},
|
||||
{{TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
|
||||
{{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}}};
|
||||
|
||||
creator.clear();
|
||||
|
||||
ASSERT_THAT(creator.projectIncludes(), ClangBackEnd::IdPaths{});
|
||||
}
|
||||
|
||||
TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesNoPchForProjectPart)
|
||||
{
|
||||
ProjectPartContainer faultyProjectPart{"faultyProject",
|
||||
{"-I", TESTDATA_DIR},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{"/includes"},
|
||||
{},
|
||||
{id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")}};
|
||||
|
||||
creator.generatePchDeprecated(faultyProjectPart);
|
||||
creator.generatePch(std::move(faultyPchTask));
|
||||
|
||||
ASSERT_THAT(creator.projectPartPch(),
|
||||
AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProject")),
|
||||
AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProjectPart")),
|
||||
Field(&ProjectPartPch::pchPath, IsEmpty()),
|
||||
Field(&ProjectPartPch::lastModified, Eq(-1))));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, CreateProjectPartSourcesContent)
|
||||
{
|
||||
auto content = creator.generateProjectPartSourcesContent(projectPart1);
|
||||
|
||||
ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/builddependencycollector/project/main3.cpp\"\n"));
|
||||
}
|
||||
|
||||
TEST_F(PchCreator, Call)
|
||||
{
|
||||
auto content = creator.generateProjectPartSourcesContent(projectPart1);
|
||||
|
||||
ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/builddependencycollector/project/main3.cpp\"\n"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -62,10 +62,10 @@ protected:
|
||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||
ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client, filePathCache};
|
||||
Utils::SmallString projectPartId{"projectPartId"};
|
||||
Utils::SmallString pchFilePath{"/path/to/pch"};
|
||||
ClangBackEnd::FilePath pchFilePath{"/path/to/pch"};
|
||||
PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone(), 1}}};
|
||||
Utils::SmallString projectPartId2{"projectPartId2"};
|
||||
Utils::SmallString pchFilePath2{"/path/to/pch2"};
|
||||
ClangBackEnd::FilePath pchFilePath2{"/path/to/pch2"};
|
||||
PrecompiledHeadersUpdatedMessage message2{{{projectPartId2.clone(), pchFilePath2.clone(), 1}}};
|
||||
};
|
||||
|
||||
|
@@ -49,7 +49,7 @@ using ClangBackEnd::UpdateProjectPartsMessage;
|
||||
using ClangBackEnd::RemoveGeneratedFilesMessage;
|
||||
using ClangBackEnd::RemoveProjectPartsMessage;
|
||||
using ClangBackEnd::V2::FileContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::ProjectPartContainer;
|
||||
using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
|
||||
|
||||
using ::testing::Args;
|
||||
@@ -97,13 +97,18 @@ TEST_F(PchManagerClientServerInProcess, SendAliveMessage)
|
||||
|
||||
TEST_F(PchManagerClientServerInProcess, SendUpdateProjectPartsMessage)
|
||||
{
|
||||
ProjectPartContainer projectPart2{"projectPartId",
|
||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{"/includes"},
|
||||
{{1, 1}},
|
||||
{{1, 2}}};
|
||||
UpdateProjectPartsMessage message{{projectPart2}};
|
||||
ProjectPartContainer projectPart2{
|
||||
"projectPartId",
|
||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||
{{1, 1}},
|
||||
{{1, 2}},
|
||||
Utils::Language::C,
|
||||
Utils::LanguageVersion::C11,
|
||||
Utils::LanguageExtension::All};
|
||||
UpdateProjectPartsMessage message{{projectPart2}, {"-m32"}};
|
||||
|
||||
EXPECT_CALL(mockPchManagerServer, updateProjectParts(message));
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "mockclangpathwatcher.h"
|
||||
#include "mockpchmanagerclient.h"
|
||||
#include "mockprojectpartqueue.h"
|
||||
#include "mockpchtaskgenerator.h"
|
||||
#include "mockprojectparts.h"
|
||||
#include "mockgeneratedfiles.h"
|
||||
|
||||
@@ -46,7 +46,7 @@ using Utils::PathString;
|
||||
using Utils::SmallString;
|
||||
using ClangBackEnd::V2::FileContainer;
|
||||
using ClangBackEnd::V2::FileContainers;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::ProjectPartContainer;
|
||||
|
||||
class PchManagerServer : public ::testing::Test
|
||||
{
|
||||
@@ -64,14 +64,15 @@ class PchManagerServer : public ::testing::Test
|
||||
}
|
||||
|
||||
protected:
|
||||
NiceMock<MockProjectPartQueue> mockProjectPartQueue;
|
||||
NiceMock<MockPchTaskGenerator> mockPchTaskGenerator;
|
||||
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
|
||||
NiceMock<MockProjectParts> mockProjectParts;
|
||||
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
|
||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
||||
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
|
||||
ClangBackEnd::PchManagerServer server{
|
||||
mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
|
||||
NiceMock<MockPchManagerClient> mockPchManagerClient;
|
||||
SmallString projectPartId1 = "project1";
|
||||
SmallString projectPartId2 = "project2";
|
||||
@@ -80,22 +81,33 @@ protected:
|
||||
PathString header1Path = TESTDATA_DIR "/BuildDependencyCollector_header1.h";
|
||||
PathString header2Path = TESTDATA_DIR "/BuildDependencyCollector_header2.h";
|
||||
ClangBackEnd::IdPaths idPath{projectPartId1, {1, 2}};
|
||||
ProjectPartContainer projectPart1{projectPartId1.clone(),
|
||||
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{"/includes"},
|
||||
{id(header1Path)},
|
||||
{id(main1Path)}};
|
||||
ProjectPartContainer projectPart2{projectPartId2.clone(),
|
||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{"/includes"},
|
||||
{id(header2Path)},
|
||||
{id(main2Path)}};
|
||||
ProjectPartContainer projectPart1{
|
||||
projectPartId1.clone(),
|
||||
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||
{id(header1Path)},
|
||||
{id(main1Path)},
|
||||
Utils::Language::C,
|
||||
Utils::LanguageVersion::C11,
|
||||
Utils::LanguageExtension::All};
|
||||
ProjectPartContainer projectPart2{
|
||||
projectPartId2.clone(),
|
||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{{"DEFINE", "1", 1}},
|
||||
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
|
||||
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
|
||||
{id(header2Path)},
|
||||
{id(main2Path)},
|
||||
Utils::Language::C,
|
||||
Utils::LanguageVersion::C11,
|
||||
Utils::LanguageExtension::All};
|
||||
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
|
||||
std::vector<ProjectPartContainer> projectParts2{projectPart2};
|
||||
FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
|
||||
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{Utils::clone(projectParts)};
|
||||
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
|
||||
Utils::clone(projectParts), {"toolChainArgument"}};
|
||||
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{{projectPart1.projectPartId.clone(),
|
||||
projectPart2.projectPartId.clone()}};
|
||||
};
|
||||
@@ -104,8 +116,10 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts)).WillOnce(Return(projectParts2));
|
||||
EXPECT_CALL(mockProjectPartQueue, addProjectParts(Eq(projectParts2)));
|
||||
EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts))
|
||||
.WillOnce(Return(projectParts2));
|
||||
EXPECT_CALL(
|
||||
mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
|
||||
|
||||
server.updateProjectParts(updateProjectPartsMessage.clone());
|
||||
}
|
||||
@@ -146,14 +160,17 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
|
||||
{
|
||||
EXPECT_CALL(mockClangPathWatcher, setNotifier(_));
|
||||
|
||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
|
||||
ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
|
||||
}
|
||||
|
||||
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
|
||||
{
|
||||
server.updateProjectParts(
|
||||
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
|
||||
|
||||
EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId)))
|
||||
.WillOnce(Return(std::vector<ClangBackEnd::V2::ProjectPartContainer>{{projectPart1}}));
|
||||
EXPECT_CALL(mockProjectPartQueue, addProjectParts(ElementsAre(projectPart1)));
|
||||
.WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}}));
|
||||
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
|
||||
|
||||
server.pathsWithIdsChanged({projectPartId1});
|
||||
}
|
||||
@@ -166,4 +183,17 @@ TEST_F(PchManagerServer, SetProgress)
|
||||
server.setProgress(20, 30);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(PchManagerServer, RemoveToolChainsArguments)
|
||||
{
|
||||
server.updateProjectParts(
|
||||
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
|
||||
|
||||
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
|
||||
server.removeProjectParts(removeProjectPartsMessage.clone());
|
||||
|
||||
server.pathsWithIdsChanged({projectPart1.projectPartId});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -32,10 +32,12 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::BuildDependency;
|
||||
using ClangBackEnd::BuildDependencies;
|
||||
using ClangBackEnd::BuildDependency;
|
||||
using ClangBackEnd::CompilerMacro;
|
||||
using ClangBackEnd::FilePathId;
|
||||
using ClangBackEnd::IncludeSearchPath;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
using ClangBackEnd::PchTask;
|
||||
using ClangBackEnd::PchTaskSet;
|
||||
using ClangBackEnd::SourceEntries;
|
||||
@@ -49,21 +51,29 @@ protected:
|
||||
NiceMock<MockBuildDependenciesProvider> mockBuildDependenciesProvider;
|
||||
NiceMock<MockPchTasksMerger> mockPchTaskMerger;
|
||||
ClangBackEnd::PchTaskGenerator generator{mockBuildDependenciesProvider, mockPchTaskMerger};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
|
||||
{"--yi"},
|
||||
{{"YI", "1", 1},
|
||||
{"QI", "7", 1},
|
||||
{"ER", "2", 2},
|
||||
{"SAN", "3", 3},
|
||||
{"SE", "4", 4},
|
||||
{"BA", "8", 4},
|
||||
{"WU", "5", 5},
|
||||
{"LUI", "6", 6},
|
||||
{"JIU", "9", 9},
|
||||
{"SHI", "10", 10}},
|
||||
{"/yi"},
|
||||
{{1, 1}},
|
||||
{{1, 2}}};
|
||||
ClangBackEnd::ProjectPartContainer projectPart1{
|
||||
"ProjectPart1",
|
||||
{"--yi"},
|
||||
{{"YI", "1", 1},
|
||||
{"QI", "7", 1},
|
||||
{"ER", "2", 2},
|
||||
{"SAN", "3", 3},
|
||||
{"SE", "4", 4},
|
||||
{"BA", "8", 4},
|
||||
{"WU", "5", 5},
|
||||
{"LUI", "6", 6},
|
||||
{"JIU", "9", 9},
|
||||
{"SHI", "10", 10}},
|
||||
{IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
|
||||
{IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}},
|
||||
{{1, 1}},
|
||||
{{1, 2}},
|
||||
Utils::Language::Cxx,
|
||||
Utils::LanguageVersion::CXX11,
|
||||
Utils::LanguageExtension::All};
|
||||
SourceEntries firstSources{{1, SourceType::ProjectInclude, 1},
|
||||
{2, SourceType::UserInclude, 1},
|
||||
{3, SourceType::TopProjectInclude, 1},
|
||||
@@ -73,32 +83,68 @@ protected:
|
||||
BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}};
|
||||
};
|
||||
|
||||
TEST_F(PchTaskGenerator, Create)
|
||||
TEST_F(PchTaskGenerator, AddProjectParts)
|
||||
{
|
||||
ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
|
||||
|
||||
EXPECT_CALL(mockPchTaskMerger,
|
||||
mergeTasks(ElementsAre(
|
||||
AllOf(Field(&PchTaskSet::system,
|
||||
AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
|
||||
Field(&PchTask::includes, ElementsAre(4, 5)),
|
||||
Field(&PchTask::compilerMacros,
|
||||
ElementsAre(CompilerMacro{"SE", "4", 4},
|
||||
CompilerMacro{"WU", "5", 5})),
|
||||
Field(&PchTask::usedMacros,
|
||||
ElementsAre(UsedMacro{"SE", 4}, UsedMacro{"WU", 5})))),
|
||||
AllOf(Field(&PchTaskSet::project,
|
||||
AllOf(Field(&PchTask::projectPartIds,
|
||||
ElementsAre("ProjectPart1")),
|
||||
Field(&PchTask::includes, ElementsAre(1, 3)),
|
||||
Field(&PchTask::compilerMacros,
|
||||
ElementsAre(CompilerMacro{"YI", "1", 1},
|
||||
CompilerMacro{"SAN", "3", 3})),
|
||||
Field(&PchTask::usedMacros,
|
||||
ElementsAre(UsedMacro{"YI", 1},
|
||||
UsedMacro{"SAN", 3})))))))));
|
||||
EXPECT_CALL(
|
||||
mockPchTaskMerger,
|
||||
mergeTasks(
|
||||
ElementsAre(AllOf(
|
||||
Field(
|
||||
&PchTaskSet::system,
|
||||
AllOf(
|
||||
Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
|
||||
Field(&PchTask::includes, ElementsAre(5)),
|
||||
Field(&PchTask::compilerMacros,
|
||||
ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})),
|
||||
Field(&PchTask::usedMacros, ElementsAre(UsedMacro{"SE", 4}, UsedMacro{"WU", 5})),
|
||||
Field(&PchTask::systemIncludeSearchPaths,
|
||||
ElementsAre(
|
||||
IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})),
|
||||
Field(&PchTask::projectIncludeSearchPaths,
|
||||
ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})),
|
||||
Field(&PchTask::toolChainArguments, ElementsAre("--yi")),
|
||||
Field(&PchTask::language, Eq(Utils::Language::Cxx)),
|
||||
Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)),
|
||||
Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All)))),
|
||||
AllOf(Field(
|
||||
&PchTaskSet::project,
|
||||
AllOf(
|
||||
Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
|
||||
Field(&PchTask::includes, ElementsAre(3)),
|
||||
Field(&PchTask::compilerMacros,
|
||||
ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
|
||||
Field(&PchTask::usedMacros, ElementsAre(UsedMacro{"YI", 1}, UsedMacro{"SAN", 3})),
|
||||
Field(&PchTask::systemIncludeSearchPaths,
|
||||
ElementsAre(
|
||||
IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})),
|
||||
Field(&PchTask::projectIncludeSearchPaths,
|
||||
ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})),
|
||||
Field(&PchTask::toolChainArguments, ElementsAre("--yi")),
|
||||
Field(&PchTask::language, Eq(Utils::Language::Cxx)),
|
||||
Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)),
|
||||
Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All))))))),
|
||||
ElementsAre(Eq("ToolChainArgument"))));
|
||||
|
||||
generator.create({projectPart1});
|
||||
generator.addProjectParts({projectPart1}, {"ToolChainArgument"});
|
||||
}
|
||||
|
||||
TEST_F(PchTaskGenerator, RemoveProjectParts)
|
||||
{
|
||||
ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
|
||||
|
||||
EXPECT_CALL(
|
||||
mockPchTaskMerger,
|
||||
removePchTasks(ElementsAre("project1", "project2")));
|
||||
|
||||
generator.removeProjectParts({"project1", "project2"});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -35,6 +35,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::IncludeSearchPath;
|
||||
using ClangBackEnd::IncludeSearchPaths;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
using ClangBackEnd::PchTask;
|
||||
using ClangBackEnd::SlotUsage;
|
||||
|
||||
@@ -52,42 +55,75 @@ protected:
|
||||
progressCounter,
|
||||
mockPrecompiledHeaderStorage,
|
||||
mockSqliteTransactionBackend};
|
||||
IncludeSearchPaths systemIncludeSearchPaths{
|
||||
{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
||||
{"/other/includes", 2, IncludeSearchPathType::System}};
|
||||
IncludeSearchPaths projectIncludeSearchPaths{
|
||||
{"/project/includes", 1, IncludeSearchPathType::User},
|
||||
{"/other/project/includes", 2, IncludeSearchPathType::User}};
|
||||
PchTask systemTask1{"ProjectPart1",
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask systemTask2{"ProjectPart2",
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask systemTask2b{"ProjectPart2",
|
||||
{3, 4},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask systemTask3{"ProjectPart3",
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask projectTask1{"ProjectPart1",
|
||||
{11, 12},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask projectTask2{"ProjectPart2",
|
||||
{11, 12},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask projectTask2b{"ProjectPart2",
|
||||
{21, 22},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask projectTask3{"ProjectPart3",
|
||||
{21, 22},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
PchTask systemTask4{Utils::SmallStringVector{"ProjectPart1", "ProjectPart3"},
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
systemIncludeSearchPaths,
|
||||
projectIncludeSearchPaths};
|
||||
};
|
||||
|
||||
TEST_F(PchTaskQueue, AddProjectPchTask)
|
||||
@@ -111,28 +147,31 @@ TEST_F(PchTaskQueue, AddSystemPchTask)
|
||||
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProcessEntriesForSystemTaskSchedulerIsNotBusy)
|
||||
{
|
||||
InSequence s;
|
||||
queue.addProjectPchTasks({projectTask1, projectTask2});
|
||||
|
||||
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(SizeIs(2)));
|
||||
|
||||
queue.addProjectPchTasks({projectTask1, projectTask2});
|
||||
queue.processEntries();
|
||||
}
|
||||
|
||||
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProcessEntriesForSystemTaskSchedulerIsBusy)
|
||||
{
|
||||
InSequence s;
|
||||
queue.addProjectPchTasks({projectTask1, projectTask2});
|
||||
|
||||
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 1}));
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).Times(0);
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(_)).Times(0);
|
||||
|
||||
queue.addProjectPchTasks({projectTask1, projectTask2});
|
||||
queue.processEntries();
|
||||
}
|
||||
|
||||
TEST_F(PchTaskQueue, AddSystemPchTasksCallsProcessEntries)
|
||||
{
|
||||
InSequence s;
|
||||
queue.addSystemPchTasks({projectTask1, projectTask2});
|
||||
|
||||
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
|
||||
EXPECT_CALL(mockSytemPchTaskScheduler, addTasks(SizeIs(2)));
|
||||
@@ -140,7 +179,7 @@ TEST_F(PchTaskQueue, AddSystemPchTasksCallsProcessEntries)
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).Times(0);
|
||||
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(_)).Times(0);
|
||||
|
||||
queue.addSystemPchTasks({projectTask1, projectTask2});
|
||||
queue.processEntries();
|
||||
}
|
||||
|
||||
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProgressCounter)
|
||||
@@ -250,20 +289,13 @@ TEST_F(PchTaskQueue, CreateProjectTaskFromPchTask)
|
||||
auto projectTask = projectTask1;
|
||||
projectTask.systemPchPath = "/path/to/pch";
|
||||
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
|
||||
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq("ProjectPart1")))
|
||||
.WillOnce(Return(Utils::PathString{"/path/to/pch"}));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
.WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
|
||||
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage,
|
||||
insertProjectPrecompiledHeader(Eq("ProjectPart1"), Eq("/path/to/pch"), 99));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
@@ -277,19 +309,11 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated)
|
||||
auto projectTask = projectTask1;
|
||||
projectTask.systemPchPath = "/path/to/pch";
|
||||
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq("ProjectPart1")))
|
||||
.WillOnce(Return(Utils::PathString{"/path/to/pch"}));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
.WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
|
||||
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq("ProjectPart1")));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
@@ -310,14 +334,10 @@ TEST_F(PchTaskQueue, CreateSystemTaskFromPchTask)
|
||||
|
||||
EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage,
|
||||
insertSystemPrecompiledHeader(Eq("ProjectPart1"), Eq("/path/to/pch"), 99));
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage,
|
||||
insertSystemPrecompiledHeader(Eq("ProjectPart3"), Eq("/path/to/pch"), 99));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
insertSystemPrecompiledHeaders(UnorderedElementsAre("ProjectPart1", "ProjectPart3"),
|
||||
Eq("/path/to/pch"),
|
||||
99));
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
@@ -331,12 +351,8 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated)
|
||||
|
||||
EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, deleteSystemPrecompiledHeader(Eq("ProjectPart1")));
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, deleteSystemPrecompiledHeader(Eq("ProjectPart3")));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage,
|
||||
deleteSystemPrecompiledHeaders(UnorderedElementsAre("ProjectPart1", "ProjectPart3")));
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
|
@@ -29,16 +29,21 @@
|
||||
|
||||
#include <pchtasksmerger.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::IncludeSearchPath;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
using ClangBackEnd::PchTask;
|
||||
using ClangBackEnd::PchTaskSet;
|
||||
|
||||
class PchTasksMerger : public testing::Test
|
||||
{
|
||||
protected:
|
||||
template<class T>
|
||||
T clone(T entry)
|
||||
PchTask clone(PchTask entry) const
|
||||
{
|
||||
return *&entry;
|
||||
// entry.toolChainArguments = toolChainArguments;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -47,19 +52,44 @@ protected:
|
||||
PchTask systemTask1{"ProjectPart1",
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
{IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
|
||||
{IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||
PchTask projectTask1{"ProjectPart1",
|
||||
{11, 12},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
{IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
|
||||
{IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||
PchTask systemTask2{"ProjectPart2",
|
||||
{1, 2},
|
||||
{{"YI", "1", 1}, {"SAN", "3", 3}},
|
||||
{{"LIANG", 0}, {"YI", 1}}};
|
||||
{{"LIANG", 0}, {"YI", 1}},
|
||||
{"--yi"},
|
||||
{IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
|
||||
{IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||
PchTask projectTask2{"ProjectPart2",
|
||||
{11, 12},
|
||||
{{"SE", "4", 4}, {"WU", "5", 5}},
|
||||
{{"ER", 2}, {"SAN", 3}}};
|
||||
{{"ER", 2}, {"SAN", 3}},
|
||||
{"--yi"},
|
||||
{IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
|
||||
IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
|
||||
IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
|
||||
{IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
|
||||
IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
|
||||
Utils::SmallStringVector toolChainArguments = {"toolChainArguments"};
|
||||
};
|
||||
|
||||
TEST_F(PchTasksMerger, AddProjectTasks)
|
||||
@@ -70,8 +100,8 @@ TEST_F(PchTasksMerger, AddProjectTasks)
|
||||
EXPECT_CALL(mockPchTaskQueue, processEntries());
|
||||
|
||||
merger.mergeTasks(
|
||||
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask1), clone(projectTask2)}});
|
||||
|
||||
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask1), clone(projectTask2)}},
|
||||
std::move(toolChainArguments));
|
||||
}
|
||||
|
||||
TEST_F(PchTasksMerger, AddSystemTasks)
|
||||
@@ -82,5 +112,14 @@ TEST_F(PchTasksMerger, AddSystemTasks)
|
||||
EXPECT_CALL(mockPchTaskQueue, processEntries());
|
||||
|
||||
merger.mergeTasks(
|
||||
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask2), clone(projectTask2)}});
|
||||
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask2), clone(projectTask2)}},
|
||||
std::move(toolChainArguments));
|
||||
}
|
||||
|
||||
TEST_F(PchTasksMerger, RemoveTasks)
|
||||
{
|
||||
EXPECT_CALL(mockPchTaskQueue, removePchTasks(ElementsAre("project1", "project2")));
|
||||
|
||||
merger.removePchTasks({"project1", "project2"});
|
||||
}
|
||||
}
|
||||
|
@@ -119,7 +119,7 @@ TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaderStatementIsBusy)
|
||||
storage.deleteProjectPrecompiledHeader("project1");
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeader)
|
||||
TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaders)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
@@ -129,12 +129,17 @@ TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeader)
|
||||
write(TypedEq<Utils::SmallStringView>("project1"),
|
||||
TypedEq<Utils::SmallStringView>("/path/to/pch"),
|
||||
TypedEq<long long>(22)));
|
||||
EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project2")));
|
||||
EXPECT_CALL(insertSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project2"),
|
||||
TypedEq<Utils::SmallStringView>("/path/to/pch"),
|
||||
TypedEq<long long>(22)));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.insertSystemPrecompiledHeader("project1", "/path/to/pch", 22);
|
||||
storage.insertSystemPrecompiledHeaders({"project1", "project2"}, "/path/to/pch", 22);
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaderStatementIsBusy)
|
||||
TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeadersStatementIsBusy)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
@@ -145,32 +150,43 @@ TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaderStatementIsBusy)
|
||||
write(TypedEq<Utils::SmallStringView>("project1"),
|
||||
TypedEq<Utils::SmallStringView>("/path/to/pch"),
|
||||
TypedEq<long long>(22)));
|
||||
EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project2")));
|
||||
EXPECT_CALL(insertSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project2"),
|
||||
TypedEq<Utils::SmallStringView>("/path/to/pch"),
|
||||
TypedEq<long long>(22)));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.insertSystemPrecompiledHeader("project1", "/path/to/pch", 22);
|
||||
storage.insertSystemPrecompiledHeaders({"project1", "project2"}, "/path/to/pch", 22);
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeader)
|
||||
TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeaders)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(database, immediateBegin());
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1")));
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project1")));
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project2")));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.deleteSystemPrecompiledHeader("project1");
|
||||
storage.deleteSystemPrecompiledHeaders({"project1", "project2"});
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeaderStatementIsBusy)
|
||||
TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeadersStatementIsBusy)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
|
||||
EXPECT_CALL(database, immediateBegin());
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1")));
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project1")));
|
||||
EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
|
||||
write(TypedEq<Utils::SmallStringView>("project2")));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.deleteSystemPrecompiledHeader("project1");
|
||||
storage.deleteSystemPrecompiledHeaders({"project1", "project2"});
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, CompilePrecompiledHeaderStatements)
|
||||
@@ -187,7 +203,7 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCalls)
|
||||
|
||||
EXPECT_CALL(database, deferredBegin());
|
||||
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
|
||||
valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")));
|
||||
valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.fetchSystemPrecompiledHeaderPath("project1");
|
||||
@@ -196,8 +212,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCalls)
|
||||
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeader)
|
||||
{
|
||||
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
|
||||
valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(Utils::PathString{"/path/to/pch"}));
|
||||
valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
|
||||
|
||||
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
|
||||
|
||||
@@ -207,8 +223,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeader)
|
||||
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsEmptyPath)
|
||||
{
|
||||
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
|
||||
valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(Utils::PathString{}));
|
||||
valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(ClangBackEnd::FilePath{}));
|
||||
|
||||
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
|
||||
|
||||
@@ -218,8 +234,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsEmptyPath)
|
||||
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsNullOptional)
|
||||
{
|
||||
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
|
||||
valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(Utils::optional<Utils::PathString>{}));
|
||||
valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
|
||||
.WillOnce(Return(Utils::optional<ClangBackEnd::FilePath>{}));
|
||||
|
||||
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
|
||||
|
||||
|
@@ -56,6 +56,15 @@ TEST_F(ProgressCounter, AddTotal)
|
||||
counter.addTotal(7);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, AddTotalZero)
|
||||
{
|
||||
counter.addTotal(5);
|
||||
|
||||
EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
|
||||
|
||||
counter.addTotal(0);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, RemoveTotal)
|
||||
{
|
||||
counter.addTotal(11);
|
||||
@@ -66,6 +75,15 @@ TEST_F(ProgressCounter, RemoveTotal)
|
||||
counter.removeTotal(7);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, RemoveTotalZero)
|
||||
{
|
||||
counter.addTotal(11);
|
||||
|
||||
EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
|
||||
|
||||
counter.removeTotal(0);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, AddProgress)
|
||||
{
|
||||
counter.addTotal(11);
|
||||
@@ -76,6 +94,16 @@ TEST_F(ProgressCounter, AddProgress)
|
||||
counter.addProgress(4);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, AddProgressZero)
|
||||
{
|
||||
counter.addTotal(11);
|
||||
counter.addProgress(3);
|
||||
|
||||
EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
|
||||
|
||||
counter.addProgress(0);
|
||||
}
|
||||
|
||||
TEST_F(ProgressCounter, AddTotalAfterFinishingProgress)
|
||||
{
|
||||
counter.addTotal(11);
|
||||
|
@@ -30,30 +30,32 @@
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::CompilerMacro;
|
||||
using ClangBackEnd::IncludeSearchPath;
|
||||
using ClangBackEnd::IncludeSearchPathType;
|
||||
|
||||
TEST(ProjectPartArtefact, CompilerArguments)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFoo\",\"-DBar\"]", "", "", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFoo\",\"-DBar\"]", "", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.compilerArguments, ElementsAre(Eq("-DFoo"), Eq("-DBar")));
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, EmptyCompilerArguments)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.compilerArguments, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, CompilerArgumentsParseError)
|
||||
{
|
||||
ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("\"-DFoo\",\"-DBar\"]", "", "", 1),
|
||||
ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("\"-DFoo\",\"-DBar\"]", "", "", "", 1),
|
||||
ClangBackEnd::ProjectPartArtefactParseError);
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, CompilerMacros)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "{\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", R"([["Foo","1",1], ["Bar","42",2]])", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.compilerMacros,
|
||||
UnorderedElementsAre(Eq(CompilerMacro{"Foo", "1", 1}), Eq(CompilerMacro{"Bar", "42", 2})));
|
||||
@@ -61,35 +63,65 @@ TEST(ProjectPartArtefact, CompilerMacros)
|
||||
|
||||
TEST(ProjectPartArtefact, EmptyCompilerMacros)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.compilerMacros, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, CompilerMacrosParseError)
|
||||
{
|
||||
ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1),
|
||||
ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", R"([["Foo":"1", 1], ["Bar", "42", 2]])", "", "", 1),
|
||||
ClangBackEnd::ProjectPartArtefactParseError);
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, IncludeSearchPaths)
|
||||
TEST(ProjectPartArtefact, SystemIncludeSearchPaths)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "[\"/includes\",\"/other/includes\"]", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{
|
||||
"", "", R"([["/includes", 1, 2], ["/other/includes", 2, 3]])", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.includeSearchPaths, ElementsAre(Eq("/includes"), Eq("/other/includes")));
|
||||
ASSERT_THAT(
|
||||
artefact.systemIncludeSearchPaths,
|
||||
ElementsAre(Eq(IncludeSearchPath("/includes", 1, IncludeSearchPathType::BuiltIn)),
|
||||
Eq(IncludeSearchPath("/other/includes", 2, IncludeSearchPathType::System))));
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, EmptyIncludeSearchPaths)
|
||||
TEST(ProjectPartArtefact, EmptySystemIncludeSearchPaths)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.includeSearchPaths, IsEmpty());
|
||||
ASSERT_THAT(artefact.systemIncludeSearchPaths, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, IncludeSearchPathsParseError)
|
||||
TEST(ProjectPartArtefact, ProjectIncludeSearchPaths)
|
||||
{
|
||||
ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "", "\"/includes\",\"/other/includes\"]", 1),
|
||||
ClangBackEnd::ProjectPartArtefactParseError);
|
||||
ClangBackEnd::ProjectPartArtefact artefact{
|
||||
"", "", R"([["/project/includes", 1, 1], ["/other/project/includes", 2, 1]])", "", 1};
|
||||
|
||||
ASSERT_THAT(
|
||||
artefact.systemIncludeSearchPaths,
|
||||
ElementsAre(
|
||||
Eq(IncludeSearchPath("/project/includes", 1, IncludeSearchPathType::User)),
|
||||
Eq(IncludeSearchPath("/other/project/includes", 2, IncludeSearchPathType::User))));
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, EmptyProjectIncludeSearchPaths)
|
||||
{
|
||||
ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
|
||||
|
||||
ASSERT_THAT(artefact.projectIncludeSearchPaths, IsEmpty());
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, IncludeSystemSearchPathsParseError)
|
||||
{
|
||||
ASSERT_THROW(
|
||||
ClangBackEnd::ProjectPartArtefact("", "", R"(["/includes", 1, 3], ["/other/includes", 2, 2]])", "", 1),
|
||||
ClangBackEnd::ProjectPartArtefactParseError);
|
||||
}
|
||||
|
||||
TEST(ProjectPartArtefact, IncludeProjectSearchPathsParseError)
|
||||
{
|
||||
ASSERT_THROW(
|
||||
ClangBackEnd::ProjectPartArtefact("", "", R"(["/project/includes", 1, 1], ["/other/project/includes", 2, 1]])", "", 1),
|
||||
ClangBackEnd::ProjectPartArtefactParseError);
|
||||
}
|
||||
}
|
||||
|
@@ -1,183 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include "mocktaskscheduler.h"
|
||||
#include "mockpchcreator.h"
|
||||
#include "mockprecompiledheaderstorage.h"
|
||||
#include "mocksqlitetransactionbackend.h"
|
||||
|
||||
#include <projectpartqueue.h>
|
||||
#include <progresscounter.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::SlotUsage;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
|
||||
class ProjectPartQueue : public testing::Test
|
||||
{
|
||||
protected:
|
||||
NiceMock<MockTaskScheduler<ClangBackEnd::ProjectPartQueue::Task>> mockTaskScheduler;
|
||||
MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
|
||||
MockSqliteTransactionBackend mockSqliteTransactionBackend;
|
||||
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
|
||||
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
|
||||
ClangBackEnd::ProjectPartQueue queue{mockTaskScheduler, mockPrecompiledHeaderStorage, mockSqliteTransactionBackend, progressCounter};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
|
||||
{"--yi"},
|
||||
{{"YI","1", 1}},
|
||||
{"/yi"},
|
||||
{1},
|
||||
{2}};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
|
||||
{"--er"},
|
||||
{{"ER","2", 1}},
|
||||
{"/bar"},
|
||||
{1},
|
||||
{2}};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart2b{"ProjectPart2",
|
||||
{"--liang"},
|
||||
{{"LIANG","3", 1}},
|
||||
{"/liang"},
|
||||
{3},
|
||||
{2, 4}};
|
||||
ClangBackEnd::V2::ProjectPartContainer projectPart3{"ProjectPart3",
|
||||
{"--san"},
|
||||
{{"SAN","2", 1}},
|
||||
{"/SAN"},
|
||||
{1},
|
||||
{2}};
|
||||
};
|
||||
|
||||
TEST_F(ProjectPartQueue, AddProjectPart)
|
||||
{
|
||||
queue.addProjectParts({projectPart1});
|
||||
|
||||
queue.addProjectParts({projectPart2});
|
||||
|
||||
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, AddProjectPartCallsProcessEntries)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
|
||||
EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
|
||||
|
||||
queue.addProjectParts({projectPart1, projectPart2});
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, AddProjectPartCallsProgressCounter)
|
||||
{
|
||||
queue.addProjectParts({projectPart1, projectPart2});
|
||||
|
||||
EXPECT_CALL(mockSetProgressCallback, Call(0, 3));
|
||||
|
||||
queue.addProjectParts({projectPart2b, projectPart3});
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, IgnoreIdenticalProjectPart)
|
||||
{
|
||||
queue.addProjectParts({projectPart1, projectPart2});
|
||||
|
||||
queue.addProjectParts({projectPart1, projectPart2});
|
||||
|
||||
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, ReplaceProjectPartWithSameId)
|
||||
{
|
||||
queue.addProjectParts({projectPart1, projectPart2});
|
||||
|
||||
queue.addProjectParts({projectPart1, projectPart2b, projectPart3});
|
||||
|
||||
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2b, projectPart3));
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, RemoveProjectPart)
|
||||
{
|
||||
queue.addProjectParts({projectPart1, projectPart2, projectPart3});
|
||||
|
||||
queue.removeProjectParts({projectPart2.projectPartId});
|
||||
|
||||
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart3));
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, RemoveProjectPartCallsProgressCounter)
|
||||
{
|
||||
queue.addProjectParts({projectPart1, projectPart2, projectPart3});
|
||||
|
||||
EXPECT_CALL(mockSetProgressCallback, Call(0, 2));
|
||||
|
||||
queue.removeProjectParts({projectPart2.projectPartId});
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, CreateTasksSizeEqualsInputSize)
|
||||
{
|
||||
auto tasks = queue.createPchTasks({projectPart1, projectPart2});
|
||||
|
||||
ASSERT_THAT(tasks, SizeIs(2));
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, CreateTaskFromProjectPart)
|
||||
{
|
||||
InSequence s;
|
||||
MockPchCreator mockPchCreator;
|
||||
ClangBackEnd::ProjectPartPch projectPartPch{"project1", "/path/to/pch", 99};
|
||||
auto tasks = queue.createPchTasks({projectPart1});
|
||||
|
||||
EXPECT_CALL(mockPchCreator, generatePchDeprecated(Eq(projectPart1)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, insertProjectPrecompiledHeader(Eq("project1"), Eq("/path/to/pch"), 99));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
|
||||
TEST_F(ProjectPartQueue, DeletePchEntryInDatabaseIfNoPchIsGenerated)
|
||||
{
|
||||
InSequence s;
|
||||
MockPchCreator mockPchCreator;
|
||||
ClangBackEnd::ProjectPartPch projectPartPch{"project1", "", 0};
|
||||
auto tasks = queue.createPchTasks({projectPart1});
|
||||
|
||||
EXPECT_CALL(mockPchCreator, generatePchDeprecated(Eq(projectPart1)));
|
||||
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, lock());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||
EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq("project1")));
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||
EXPECT_CALL(mockSqliteTransactionBackend, unlock());
|
||||
|
||||
tasks.front()(mockPchCreator);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user