ClangPchManager: Introduce PchTasksMerger

So far no merging is happening but we will add it after the rest of the
pipeline is in shape.

Task-number: QTCREATORBUG-21381
Change-Id: I610c243eabcb305843ad6339fdc636b0c3966fc1
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-12-03 17:44:38 +01:00
parent 24ecd7fe6a
commit 96eb407266
16 changed files with 355 additions and 43 deletions

View File

@@ -5,7 +5,8 @@ SOURCES += \
$$PWD/pchmanagerserver.cpp \
$$PWD/projectparts.cpp \
$$PWD/projectpartqueue.cpp \
$$PWD/pchtaskgenerator.cpp
$$PWD/pchtaskgenerator.cpp \
$$PWD/pchtasksmerger.cpp
HEADERS += \
$$PWD/pchmanagerserver.h \
@@ -35,7 +36,9 @@ HEADERS += \
$$PWD/builddependenciesstorage.h \
$$PWD/builddependencygeneratorinterface.h \
$$PWD/usedmacrofilter.h \
$$PWD/pchtasksmergerinterface.h
$$PWD/pchtasksmergerinterface.h \
$$PWD/pchtasksmerger.h \
$$PWD/pchtaskqueueinterface.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \

View File

@@ -46,6 +46,15 @@ public:
, usedMacros(usedMacros)
{}
friend bool operator==(const PchTask &first, const PchTask &second)
{
return first.projectPartId == second.projectPartId
&& first.dependentIds == second.dependentIds && first.includes == second.includes
&& first.compilerMacros == second.compilerMacros
&& first.usedMacros == second.usedMacros;
}
public:
Utils::SmallString projectPartId;
Utils::SmallStringVector dependentIds;
FilePathIds includes;
@@ -53,5 +62,19 @@ public:
UsedMacros usedMacros;
};
class PchTaskSet
{
public:
PchTaskSet(PchTask &&system, PchTask &&project)
: system(std::move(system))
, project(std::move(project))
{}
public:
PchTask system;
PchTask project;
};
using PchTasks = std::vector<PchTask>;
using PchTaskSets = std::vector<PchTaskSet>;
} // namespace ClangBackEnd

View File

@@ -36,23 +36,28 @@ namespace ClangBackEnd {
void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
{
PchTaskSets pchTaskSets;
pchTaskSets.reserve(projectParts.size());
for (auto &projectPart : projectParts) {
BuildDependency buildDependency = m_buildDependenciesProvider.create(projectPart);
UsedMacroFilter filter{buildDependency.includes, buildDependency.usedMacros};
filter.filter(projectPart.compilerMacros);
m_pchTasksMergerInterface.addTask({projectPart.projectPartId.clone(),
std::move(filter.systemIncludes),
std::move(filter.systemCompilerMacros),
std::move(filter.systemUsedMacros)
pchTaskSets.emplace_back(PchTask{projectPart.projectPartId.clone(),
std::move(filter.systemIncludes),
std::move(filter.systemCompilerMacros),
std::move(filter.systemUsedMacros)
},
{std::move(projectPart.projectPartId),
std::move(filter.projectIncludes),
std::move(filter.projectCompilerMacros),
std::move(filter.projectUsedMacros)});
},
PchTask{std::move(projectPart.projectPartId),
std::move(filter.projectIncludes),
std::move(filter.projectCompilerMacros),
std::move(filter.projectUsedMacros)});
}
m_pchTasksMergerInterface.mergeTasks(std::move(pchTaskSets));
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,43 @@
/****************************************************************************
**
** 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 "queueinterface.h"
#include "pchtask.h"
namespace ClangBackEnd {
class PchTaskQueueInterface : public QueueInterface
{
public:
virtual void addSystemPchTasks(PchTasks &&pchTasks) = 0;
virtual void addProjectPchTasks(PchTasks &&pchTasks) = 0;
virtual void removePchTasks(const Utils::SmallStringVector &projectsPartIds) = 0;
protected:
~PchTaskQueueInterface() = default;
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,49 @@
/****************************************************************************
**
** 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 "pchtasksmerger.h"
#include "pchtaskqueueinterface.h"
namespace ClangBackEnd {
void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets)
{
PchTasks systemTasks;
systemTasks.reserve(taskSets.size());
PchTasks projectTasks;
projectTasks.reserve(taskSets.size());
for (PchTaskSet &taskSet : taskSets) {
projectTasks.push_back(std::move(taskSet.project));
systemTasks.push_back(std::move(taskSet.system));
}
m_pchTaskQueue.addSystemPchTasks(std::move(systemTasks));
m_pchTaskQueue.addProjectPchTasks(std::move(projectTasks));
m_pchTaskQueue.processEntries();
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,48 @@
/****************************************************************************
**
** 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 "pchtasksmergerinterface.h"
#include "pchtask.h"
namespace ClangBackEnd {
class PchTaskQueueInterface;
class PchTasksMerger : public PchTasksMergerInterface
{
public:
PchTasksMerger(PchTaskQueueInterface &pchTaskQueue)
: m_pchTaskQueue(pchTaskQueue)
{}
void mergeTasks(PchTaskSets &&taskSets) override;
private:
PchTaskQueueInterface &m_pchTaskQueue;
};
} // namespace ClangBackEnd

View File

@@ -31,7 +31,7 @@ namespace ClangBackEnd {
class PchTasksMergerInterface
{
public:
virtual void addTask(PchTask &&systemTask, PchTask &&projectTask) = 0;
virtual void mergeTasks(PchTaskSets &&taskSets) = 0;
protected:
~PchTasksMergerInterface() = default;

View File

@@ -0,0 +1,49 @@
/****************************************************************************
**
** 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 <pchtaskqueueinterface.h>
class MockPchTaskQueue : public ClangBackEnd::PchTaskQueueInterface
{
public:
MOCK_METHOD1(addSystemPchTasks, void(const ClangBackEnd::PchTasks &pchTasks));
MOCK_METHOD1(addProjectPchTasks, void(const ClangBackEnd::PchTasks &pchTasks));
MOCK_METHOD1(removePchTasks, void(const Utils::SmallStringVector &projectsPartIds));
MOCK_METHOD0(processEntries, void ());
void addSystemPchTasks(ClangBackEnd::PchTasks &&pchTasks) override
{
addSystemPchTasks(pchTasks);
}
void addProjectPchTasks(ClangBackEnd::PchTasks &&pchTasks) override
{
addProjectPchTasks(pchTasks);
}
};

View File

@@ -32,12 +32,7 @@
class MockPchTasksMerger : public ClangBackEnd::PchTasksMergerInterface
{
public:
MOCK_METHOD2(addTask,
void(const ClangBackEnd::PchTask &systemPchTask,
const ClangBackEnd::PchTask &projectPchTask));
MOCK_METHOD1(mergeTasks, void(const ClangBackEnd::PchTaskSets &pchTaskSets));
void addTask(ClangBackEnd::PchTask &&systemPchTask, ClangBackEnd::PchTask &&projectPchTask)
{
addTask(systemPchTask, projectPchTask);
}
void mergeTasks(ClangBackEnd::PchTaskSets &&pchTaskSets) override { mergeTasks(pchTaskSets); }
};

View File

@@ -37,6 +37,7 @@ using ClangBackEnd::BuildDependencies;
using ClangBackEnd::CompilerMacro;
using ClangBackEnd::FilePathId;
using ClangBackEnd::PchTask;
using ClangBackEnd::PchTaskSet;
using ClangBackEnd::SourceEntries;
using ClangBackEnd::SourceType;
using ClangBackEnd::UsedMacro;
@@ -77,20 +78,24 @@ TEST_F(PchTaskGenerator, Create)
ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
EXPECT_CALL(mockPchTaskMerger,
addTask(AllOf(Field(&PchTask::projectPartId, Eq("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(&PchTask::projectPartId, Eq("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})))));
mergeTasks(ElementsAre(
AllOf(Field(&PchTaskSet::system,
AllOf(Field(&PchTask::projectPartId, Eq("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::projectPartId, Eq("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})))))))));
generator.create({projectPart1});
}

View File

@@ -0,0 +1,86 @@
/****************************************************************************
**
** 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 "mockpchtaskqueue.h"
#include <pchtasksmerger.h>
using ClangBackEnd::PchTask;
using ClangBackEnd::PchTaskSet;
class PchTasksMerger : public testing::Test
{
protected:
template<class T>
T clone(T entry)
{
return *&entry;
}
protected:
NiceMock<MockPchTaskQueue> mockPchTaskQueue;
ClangBackEnd::PchTasksMerger merger{mockPchTaskQueue};
PchTask systemTask1{"ProjectPart1",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
{{"LIANG", 0}, {"YI", 1}}};
PchTask projectTask1{"ProjectPart1",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
{{"ER", 2}, {"SAN", 3}}};
PchTask systemTask2{"ProjectPart2",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
{{"LIANG", 0}, {"YI", 1}}};
PchTask projectTask2{"ProjectPart2",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
{{"ER", 2}, {"SAN", 3}}};
};
TEST_F(PchTasksMerger, AddProjectTasks)
{
InSequence s;
EXPECT_CALL(mockPchTaskQueue, addProjectPchTasks(ElementsAre(projectTask1, projectTask2)));
EXPECT_CALL(mockPchTaskQueue, processEntries());
merger.mergeTasks(
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask1), clone(projectTask2)}});
}
TEST_F(PchTasksMerger, AddSystemTasks)
{
InSequence s;
EXPECT_CALL(mockPchTaskQueue, addSystemPchTasks(ElementsAre(systemTask1, systemTask2)));
EXPECT_CALL(mockPchTaskQueue, processEntries());
merger.mergeTasks(
{{clone(systemTask1), clone(projectTask1)}, {clone(systemTask2), clone(projectTask2)}});
}

View File

@@ -29,7 +29,7 @@
#include <utils/smallstring.h>
#include <QDir>
#include <utils/temporarydirectory.h>
using testing::Contains;
using testing::IsEmpty;
@@ -60,8 +60,8 @@ protected:
protected:
ClangBackEnd::RefactoringCompilationDatabase database;
Utils::SmallString temporaryDirectoryPath = QDir::toNativeSeparators(QDir::tempPath());
Utils::SmallString temporarySourceFilePath = QDir::toNativeSeparators(QDir::tempPath() + "/data.cpp");
Utils::SmallString temporaryDirectoryPath = QDir::toNativeSeparators(Utils::TemporaryDirectory::masterDirectoryPath());
Utils::SmallString temporarySourceFilePath = QDir::toNativeSeparators(Utils::TemporaryDirectory::masterDirectoryPath() + "/data.cpp");
};

View File

@@ -36,7 +36,8 @@
#include <refactoringserver.h>
#include <sqlitedatabase.h>
#include <QDir>
#include <utils/temporarydirectory.h>
#include <QTemporaryFile>
namespace {
@@ -100,7 +101,7 @@ protected:
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
sourceContent.clone(),
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}};
QTemporaryFile temporaryFile{QDir::tempPath() + "/clangQuery-XXXXXX.cpp"};
QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath() + "/clangQuery-XXXXXX.cpp"};
int processingSlotCount = 2;
};

View File

@@ -32,6 +32,8 @@
#include <sqlitewritestatement.h>
#include <utf8string.h>
#include <utils/temporarydirectory.h>
#include <QSignalSpy>
#include <QTemporaryFile>
#include <QVariant>
@@ -127,7 +129,8 @@ TEST_F(SqliteDatabase, DatabaseIsInitializedIfDatabasePathExistsAtOpening)
TEST_F(SqliteDatabase, DatabaseIsNotInitializedIfDatabasePathDoesNotExistAtOpening)
{
Sqlite::Database database{Utils::PathString{QDir::tempPath() + "/database_does_not_exist.db"}};
Sqlite::Database database{Utils::PathString{Utils::TemporaryDirectory::masterDirectoryPath()
+ "/database_does_not_exist.db"}};
ASSERT_FALSE(database.isInitialized());
}

View File

@@ -27,7 +27,7 @@
#include <utils/smallstring.h>
#include <QDir>
#include <utils/temporarydirectory.h>
inline
bool operator==(const QString &first, const char *second)
@@ -40,6 +40,6 @@ namespace UnitTest {
inline
Utils::PathString temporaryDirPath()
{
return Utils::PathString::fromQString(QDir::tempPath());
return Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath());
}
} // namespace UnitTest

View File

@@ -108,7 +108,8 @@ SOURCES += \
compilationdatabaseutils-test.cpp \
builddependenciesprovider-test.cpp \
builddependenciesstorage-test.cpp \
usedmacrofilter-test.cpp
usedmacrofilter-test.cpp \
pchtasksmerger-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -258,7 +259,8 @@ HEADERS += \
mockmodifiedtimechecker.h \
mockbuilddependenciesstorage.h \
mockbuilddependencygenerator.h \
mockpchtasksmerger.h
mockpchtasksmerger.h \
mockpchtaskqueue.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \