ClangRefactoring: Add project part queue

Change-Id: Id137233a042181553ff7bb766c9dafa6eb9cf046
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-08-06 17:31:12 +02:00
parent 06a78b6264
commit 613db15cea
5 changed files with 303 additions and 3 deletions

View File

@@ -21,7 +21,8 @@ HEADERS += \
$$PWD/projectpartartefactexception.h \
$$PWD/projectpartartefact.h \
$$PWD/filestatuscache.h \
$$PWD/indexdataconsumer.h
$$PWD/indexdataconsumer.h \
$$PWD/projectpartqueue.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
@@ -66,4 +67,5 @@ SOURCES += \
$$PWD/sourcerangefilter.cpp \
$$PWD/symbolindexer.cpp \
$$PWD/projectpartartefact.cpp \
$$PWD/filestatuscache.cpp
$$PWD/filestatuscache.cpp \
$$PWD/projectpartqueue.cpp

View File

@@ -0,0 +1,147 @@
/****************************************************************************
**
** 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"
namespace ClangBackEnd {
ProjectPartQueue::ProjectPartQueue()
{
}
namespace {
template<class InputIt1,
class InputIt2,
class OutputIt,
class Compare,
class Merge>
OutputIt set_union_merge(InputIt1 first1,
InputIt1 last1,
InputIt2 first2,
InputIt2 last2,
OutputIt d_first,
Compare comp,
Merge merge)
{
for (; first1 != last1; ++d_first) {
if (first2 == last2)
return std::copy(first1, last1, d_first);
if (comp(*first2, *first1)) {
*d_first = *first2++;
} else {
if (comp(*first1, *first2)) {
*d_first = *first1;
} else {
*d_first = merge(*first1, *first2);
++first2;
}
++first1;
}
}
return std::copy(first2, last2, d_first);
}
}
void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
{
auto compare = [](const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
return first.projectPartId < second.projectPartId;
};
auto merge = [](V2::ProjectPartContainer &&first,
V2::ProjectPartContainer &&second) {
first.arguments = std::move(second.arguments);
first.compilerMacros = std::move(second.compilerMacros);
first.includeSearchPaths = std::move(second.includeSearchPaths);
FilePathIds headerPathIds;
headerPathIds.reserve(first.headerPathIds.size() + second.headerPathIds.size());
std::set_union(first.headerPathIds.begin(),
first.headerPathIds.end(),
second.headerPathIds.begin(),
second.headerPathIds.end(),
std::back_inserter(headerPathIds));
first.headerPathIds = std::move(headerPathIds);
FilePathIds sourcePathIds;
headerPathIds.reserve(first.sourcePathIds.size() + second.sourcePathIds.size());
std::set_union(first.sourcePathIds.begin(),
first.sourcePathIds.end(),
second.sourcePathIds.begin(),
second.sourcePathIds.end(),
std::back_inserter(sourcePathIds));
first.sourcePathIds = std::move(sourcePathIds);
return first;
};
V2::ProjectPartContainers mergedProjectParts;
mergedProjectParts.reserve(m_projectParts.size() + projectParts.size());
set_union_merge(std::make_move_iterator(m_projectParts.begin()),
std::make_move_iterator(m_projectParts.end()),
std::make_move_iterator(projectParts.begin()),
std::make_move_iterator(projectParts.end()),
std::back_inserter(mergedProjectParts),
compare,
merge);
m_projectParts = std::move(mergedProjectParts);
}
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)
{
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);
}
const V2::ProjectPartContainers &ProjectPartQueue::projectParts() const
{
return m_projectParts;
}
} // namespace ClangBackEnd

View 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 <projectpartcontainerv2.h>
namespace ClangBackEnd {
class ProjectPartQueue
{
public:
ProjectPartQueue();
void addProjectParts(V2::ProjectPartContainers &&projectParts);
void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
const V2::ProjectPartContainers &projectParts() const;
private:
V2::ProjectPartContainers m_projectParts;
};
} // namespace ClangBackEnd

View File

@@ -0,0 +1,104 @@
/****************************************************************************
**
** 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 <projectpartqueue.h>
namespace {
class ProjectPartQueue : public testing::Test
{
protected:
ClangBackEnd::ProjectPartQueue queue;
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
{"--yi"},
{{"YI","1"}},
{"/yi"},
{{1, 1}},
{{1, 2}}};
ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
{"--er"},
{{"ER","2"}},
{"/bar"},
{{2, 1}},
{{2, 2}}};
ClangBackEnd::V2::ProjectPartContainer projectPart2b{"ProjectPart2",
{"--liang"},
{{"LIANG","3"}},
{"/liang"},
{{2, 3}},
{{2, 2}, {2, 4}}};
ClangBackEnd::V2::ProjectPartContainer projectPart3{"ProjectPart3",
{"--san"},
{{"SAN","2"}},
{"/SAN"},
{{3, 1}},
{{3, 2}}};
ClangBackEnd::V2::ProjectPartContainer projectPartMerged{"ProjectPart2",
{"--liang"},
{{"LIANG","3"}},
{"/liang"},
{{2, 1}, {2, 3}},
{{2, 2}, {2, 4}}};
};
TEST_F(ProjectPartQueue, AddProjectPart)
{
queue.addProjectParts({projectPart1});
queue.addProjectParts({projectPart2});
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
}
TEST_F(ProjectPartQueue, IgnoreIdenticalProjectPart)
{
queue.addProjectParts({projectPart1, projectPart2});
queue.addProjectParts({projectPart1, projectPart2});
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
}
TEST_F(ProjectPartQueue, MergeSameProjectPartWithSameId)
{
queue.addProjectParts({projectPart1, projectPart2});
queue.addProjectParts({projectPart1, projectPart2b, projectPart3});
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPartMerged, projectPart3));
}
TEST_F(ProjectPartQueue, RemoveProjectPart)
{
queue.addProjectParts({projectPart1, projectPart2, projectPart3});
queue.removeProjectParts({projectPart2.projectPartId});
ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart3));
}
}

View File

@@ -92,7 +92,8 @@ SOURCES += \
projectpartartefact-test.cpp \
filestatuscache-test.cpp \
highlightingresultreporter-test.cpp \
precompiledheaderstorage-test.cpp
precompiledheaderstorage-test.cpp \
projectpartqueue-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \