projectupdater.cpp 5.71 KB
Newer Older
Marco Bubke's avatar
Marco Bubke committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/****************************************************************************
**
** 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.
**
****************************************************************************/

#include "projectupdater.h"

#include "pchmanagerclient.h"

#include <pchmanagerserverinterface.h>
#include <removepchprojectpartsmessage.h>
#include <updatepchprojectpartsmessage.h>

#include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/projectpart.h>

Marco Bubke's avatar
Marco Bubke committed
37 38 39
#include <algorithm>
#include <functional>

Marco Bubke's avatar
Marco Bubke committed
40 41
namespace ClangPchManager {

Marco Bubke's avatar
Marco Bubke committed
42 43 44 45 46 47 48 49 50 51 52 53 54
class HeaderAndSources
{
public:
    void reserve(std::size_t size)
    {
        headers.reserve(size);
        sources.reserve(size);
    }

    Utils::PathStringVector headers;
    Utils::PathStringVector sources;
};

Marco Bubke's avatar
Marco Bubke committed
55 56
ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
    : m_server(server)
Marco Bubke's avatar
Marco Bubke committed
57 58 59
{
}

Marco Bubke's avatar
Marco Bubke committed
60 61
void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
                                        ClangBackEnd::V2::FileContainers &&generatedFiles)
Marco Bubke's avatar
Marco Bubke committed
62
{
Marco Bubke's avatar
Marco Bubke committed
63 64 65 66
    m_excludedPaths = createExcludedPaths(generatedFiles);

    ClangBackEnd::UpdatePchProjectPartsMessage message{toProjectPartContainers(projectParts),
                                                       std::move(generatedFiles)};
Marco Bubke's avatar
Marco Bubke committed
67 68 69 70 71 72 73 74 75 76 77

    m_server.updatePchProjectParts(std::move(message));
}

void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
{
    ClangBackEnd::RemovePchProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};

    m_server.removePchProjectParts(std::move(message));
}

Marco Bubke's avatar
Marco Bubke committed
78
void ProjectUpdater::setExcludedPaths(Utils::PathStringVector &&excludedPaths)
Marco Bubke's avatar
Marco Bubke committed
79
{
Marco Bubke's avatar
Marco Bubke committed
80 81
    m_excludedPaths = excludedPaths;
}
Marco Bubke's avatar
Marco Bubke committed
82

Marco Bubke's avatar
Marco Bubke committed
83 84
void ProjectUpdater::addToHeaderAndSources(HeaderAndSources &headerAndSources,
                                           const CppTools::ProjectFile &projectFile) const
Marco Bubke's avatar
Marco Bubke committed
85
{
Marco Bubke's avatar
Marco Bubke committed
86 87
    Utils::PathString path = projectFile.path;
    bool exclude = std::binary_search(m_excludedPaths.begin(), m_excludedPaths.end(), path);
Marco Bubke's avatar
Marco Bubke committed
88

Marco Bubke's avatar
Marco Bubke committed
89
    if (!exclude) {
Marco Bubke's avatar
Marco Bubke committed
90
        if (projectFile.isSource())
Marco Bubke's avatar
Marco Bubke committed
91
            headerAndSources.sources.push_back(path);
Marco Bubke's avatar
Marco Bubke committed
92
        else if (projectFile.isHeader())
Marco Bubke's avatar
Marco Bubke committed
93
            headerAndSources.headers.push_back(path);
Marco Bubke's avatar
Marco Bubke committed
94
    }
Marco Bubke's avatar
Marco Bubke committed
95 96 97 98 99 100 101 102 103 104
}

HeaderAndSources ProjectUpdater::headerAndSourcesFromProjectPart(
        CppTools::ProjectPart *projectPart) const
{
    HeaderAndSources headerAndSources;
    headerAndSources.reserve(std::size_t(projectPart->files.size()) * 3 / 2);

    for (const CppTools::ProjectFile &projectFile : projectPart->files)
        addToHeaderAndSources(headerAndSources, projectFile);
Marco Bubke's avatar
Marco Bubke committed
105 106 107 108

    return headerAndSources;
}

109 110
QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart)
{
111 112 113
    using ClangCOBuilder = CppTools::ClangCompilerOptionsBuilder;
    ClangCOBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
    return builder.build(CppTools::ProjectFile::CXXHeader, ClangCOBuilder::PchUsage::None);
114 115
}

Marco Bubke's avatar
Marco Bubke committed
116 117
ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
        CppTools::ProjectPart *projectPart) const
Marco Bubke's avatar
Marco Bubke committed
118 119
{

120
    QStringList arguments = compilerArguments(projectPart);
Marco Bubke's avatar
Marco Bubke committed
121 122 123 124 125 126 127 128 129 130

    HeaderAndSources headerAndSources = headerAndSourcesFromProjectPart(projectPart);

    return ClangBackEnd::V2::ProjectPartContainer(projectPart->displayName,
                                                  Utils::SmallStringVector(arguments),
                                                  std::move(headerAndSources.headers),
                                                  std::move(headerAndSources.sources));
}

std::vector<ClangBackEnd::V2::ProjectPartContainer> ProjectUpdater::toProjectPartContainers(
Marco Bubke's avatar
Marco Bubke committed
131
        std::vector<CppTools::ProjectPart *> projectParts) const
Marco Bubke's avatar
Marco Bubke committed
132
{
Marco Bubke's avatar
Marco Bubke committed
133 134
    using namespace std::placeholders;

Marco Bubke's avatar
Marco Bubke committed
135 136 137 138 139 140
    std::vector<ClangBackEnd::V2::ProjectPartContainer> projectPartContainers;
    projectPartContainers.reserve(projectParts.size());

    std::transform(projectParts.begin(),
                   projectParts.end(),
                   std::back_inserter(projectPartContainers),
Marco Bubke's avatar
Marco Bubke committed
141
                   std::bind(&ProjectUpdater::toProjectPartContainer, this, _1));
Marco Bubke's avatar
Marco Bubke committed
142 143 144 145

    return projectPartContainers;
}

Marco Bubke's avatar
Marco Bubke committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
Utils::PathStringVector ProjectUpdater::createExcludedPaths(
        const ClangBackEnd::V2::FileContainers &generatedFiles)
{
    Utils::PathStringVector excludedPaths;
    excludedPaths.reserve(generatedFiles.size());

    auto convertToPath = [] (const ClangBackEnd::V2::FileContainer &fileContainer) {
        return fileContainer.filePath().path();
    };

    std::transform(generatedFiles.begin(),
                   generatedFiles.end(),
                   std::back_inserter(excludedPaths),
                   convertToPath);

    std::sort(excludedPaths.begin(), excludedPaths.end());

    return excludedPaths;
}

Marco Bubke's avatar
Marco Bubke committed
166
} // namespace ClangPchManager