From 64a3a130acc0dc7610168396422f6b8c735f45c8 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 12 Nov 2018 19:27:51 +0100 Subject: [PATCH] Clang: Add BuildDependencyCollector IncludeCollector is renamed to BuildDependencyCollector. It is now returning a BuildDependency instead of individual getter. The test coverage is improved too. Task-number: QTCREATORBUG-21379 Change-Id: Ifc2d1c40c85772cf498c21968de526f4408b6023 Reviewed-by: Ivan Donchevskii --- src/libs/utils/smallstringio.h | 15 +- .../source/builddependenciesprovider.cpp | 2 +- .../source/builddependenciesprovider.h | 6 +- .../source/builddependency.h | 19 +- .../source/builddependencycollector.cpp | 124 ++++ ...collector.h => builddependencycollector.h} | 52 +- ....h => builddependencygeneratorinterface.h} | 4 +- .../source/clangpchmanagerbackend-source.pri | 16 +- ...ction.h => collectbuilddependencyaction.h} | 44 +- ...ectbuilddependencypreprocessorcallbacks.h} | 108 +-- ...n.h => collectbuilddependencytoolaction.h} | 61 +- ...sedmacrosandsourcespreprocessorcallbacks.h | 10 +- .../source/includecollector.cpp | 103 --- .../source/pchcreator.cpp | 60 +- .../source/pchcreator.h | 8 +- .../source/sourceentry.h | 10 +- .../source/clangtool.cpp | 2 + .../source/filestatus.h | 6 + .../source/sourcedependency.h | 25 +- .../source/symbolsvisitorbase.h | 2 +- .../builddependenciesprovider-test.cpp | 12 +- .../builddependenciesstorage-test.cpp | 4 +- .../builddependencycollector-test.cpp | 635 ++++++++++++++++++ .../external/external1.h | 0 .../external/external2.h | 0 .../external/external3.h | 0 .../external/indirect_external.h | 0 .../external/indirect_external2.h | 0 .../project/false.h | 0 .../project/faulty.cpp | 0 .../project/faulty.h | 0 .../project/header1.h | 0 .../project/header2.h | 0 .../project/if.cpp | 0 .../builddependencycollector/project/macros.h | 11 + .../project/main.cpp | 0 .../project/main2.cpp | 0 .../project/main3.cpp | 0 .../project/main4.cpp | 9 + .../project/missingfile.cpp | 0 .../project/missingfile.h | 8 + .../project/true.h | 0 .../system/indirect_system.h | 0 .../system/indirect_system2.h | 0 .../system/system1.h | 0 .../system/system2.h | 0 .../system/system3.h | 0 .../unit/unittest/gtest-creator-printing.cpp | 36 +- tests/unit/unittest/gtest-creator-printing.h | 3 + tests/unit/unittest/includecollector-test.cpp | 422 ------------ ...rator.h => mockbuilddependencygenerator.h} | 4 +- tests/unit/unittest/pchcreator-test.cpp | 105 +-- tests/unit/unittest/pchmanagerserver-test.cpp | 8 +- tests/unit/unittest/pchtaskgenerator-test.cpp | 4 +- tests/unit/unittest/symbolindexer-test.cpp | 2 +- tests/unit/unittest/unittest.pro | 8 +- 56 files changed, 1135 insertions(+), 813 deletions(-) create mode 100644 src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp rename src/tools/clangpchmanagerbackend/source/{includecollector.h => builddependencycollector.h} (65%) rename src/tools/clangpchmanagerbackend/source/{builddependenciesgeneratorinterface.h => builddependencygeneratorinterface.h} (93%) rename src/tools/clangpchmanagerbackend/source/{collectincludesaction.h => collectbuilddependencyaction.h} (64%) rename src/tools/clangpchmanagerbackend/source/{collectincludespreprocessorcallbacks.h => collectbuilddependencypreprocessorcallbacks.h} (67%) rename src/tools/clangpchmanagerbackend/source/{collectincludestoolaction.h => collectbuilddependencytoolaction.h} (57%) delete mode 100644 src/tools/clangpchmanagerbackend/source/includecollector.cpp create mode 100644 tests/unit/unittest/builddependencycollector-test.cpp rename tests/unit/unittest/data/{includecollector => builddependencycollector}/external/external1.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/external/external2.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/external/external3.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/external/indirect_external.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/external/indirect_external2.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/false.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/faulty.cpp (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/faulty.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/header1.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/header2.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/if.cpp (100%) create mode 100644 tests/unit/unittest/data/builddependencycollector/project/macros.h rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/main.cpp (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/main2.cpp (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/main3.cpp (100%) create mode 100644 tests/unit/unittest/data/builddependencycollector/project/main4.cpp rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/missingfile.cpp (100%) create mode 100644 tests/unit/unittest/data/builddependencycollector/project/missingfile.h rename tests/unit/unittest/data/{includecollector => builddependencycollector}/project/true.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/system/indirect_system.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/system/indirect_system2.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/system/system1.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/system/system2.h (100%) rename tests/unit/unittest/data/{includecollector => builddependencycollector}/system/system3.h (100%) delete mode 100644 tests/unit/unittest/includecollector-test.cpp rename tests/unit/unittest/{mockbuilddependenciesgenerator.h => mockbuilddependencygenerator.h} (90%) diff --git a/src/libs/utils/smallstringio.h b/src/libs/utils/smallstringio.h index 10efd066278..6e9e2a7bc22 100644 --- a/src/libs/utils/smallstringio.h +++ b/src/libs/utils/smallstringio.h @@ -32,6 +32,7 @@ #include #include +#include namespace Utils { @@ -232,7 +233,19 @@ ostream &operator<<(ostream &out, const vector &vector) { out << "["; - copy(vector.cbegin(), vector.cend(), ostream_iterator(out, ", ")); + for (auto current = vector.begin(); current != vector.end(); ++current) { + std::ostringstream entryStream; + entryStream << *current; + std::string entryString = entryStream.str(); + + if (entryString.size() > 4) + out << "\n\t"; + + out << entryString; + + if (std::next(current) != vector.end()) + out << ", "; + } out << "]"; diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp index f10b6494d8c..c3146408f85 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp @@ -27,7 +27,7 @@ #include "builddependenciesstorageinterface.h" #include "modifiedtimecheckerinterface.h" -#include "builddependenciesgeneratorinterface.h" +#include "builddependencygeneratorinterface.h" #include diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h index 00d4101b166..8c22077e816 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h @@ -31,14 +31,14 @@ namespace ClangBackEnd { class BuildDependenciesStorageInterface; class ModifiedTimeCheckerInterface; -class BuildDependenciesGeneratorInterface; +class BuildDependencyGeneratorInterface; class BuildDependenciesProvider : public BuildDependenciesProviderInterface { public: BuildDependenciesProvider(BuildDependenciesStorageInterface &buildDependenciesStorage, ModifiedTimeCheckerInterface &modifiedTimeChecker, - BuildDependenciesGeneratorInterface &buildDependenciesGenerator) + BuildDependencyGeneratorInterface &buildDependenciesGenerator) : m_buildDependenciesStorage(buildDependenciesStorage), m_modifiedTimeChecker(modifiedTimeChecker), m_buildDependenciesGenerator(buildDependenciesGenerator) @@ -56,7 +56,7 @@ private: private: BuildDependenciesStorageInterface &m_buildDependenciesStorage; ModifiedTimeCheckerInterface &m_modifiedTimeChecker; - BuildDependenciesGeneratorInterface &m_buildDependenciesGenerator; + BuildDependencyGeneratorInterface &m_buildDependenciesGenerator; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependency.h b/src/tools/clangpchmanagerbackend/source/builddependency.h index 8821b0162c0..3faa16c0e33 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependency.h +++ b/src/tools/clangpchmanagerbackend/source/builddependency.h @@ -25,6 +25,8 @@ #pragma once +#include "filestatus.h" +#include "sourcedependency.h" #include "sourceentry.h" #include "usedmacro.h" @@ -32,13 +34,24 @@ namespace ClangBackEnd { class BuildDependency { +public: + void clear() + { + includes.clear(); + usedMacros.clear(); + sourceFiles.clear(); + fileStatuses.clear(); + sourceDependencies.clear(); + } + public: SourceEntries includes; - FilePathIds topIncludeIds; - FilePathIds topsSystemIncludeIds; UsedMacros usedMacros; + FilePathIds sourceFiles; + SourceDependencies sourceDependencies; + FileStatuses fileStatuses; }; using BuildDependencies = std::vector; -} +} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp new file mode 100644 index 00000000000..4ba3e8c0e66 --- /dev/null +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** 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 "builddependencycollector.h" + +#include "collectbuilddependencytoolaction.h" + +#include + +#include + +namespace ClangBackEnd { + +namespace { +FilePathIds operator+(const FilePathIds &first, const FilePathIds &second) +{ + FilePathIds result = first; + + std::copy(second.begin(), second.end(), std::back_inserter(result)); + + return result; +} +} + +BuildDependency BuildDependencyCollector::create(const V2::ProjectPartContainer &projectPart) +{ + addFiles(projectPart.sourcePathIds, projectPart.arguments); + + setExcludedFilePaths( + m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds)); + + collect(); + + return std::move(m_buildDependency); +} + +void BuildDependencyCollector::collect() +{ + clang::tooling::ClangTool tool = m_clangTool.createTool(); + + auto action = std::make_unique(m_buildDependency, + m_filePathCache, + m_excludedFilePaths, + m_sourcesManager); + + tool.run(action.get()); +} + +void BuildDependencyCollector::setExcludedFilePaths(ClangBackEnd::FilePaths &&excludedFilePaths) +{ + if (Utils::HostOsInfo::isWindowsHost()) { + m_excludedFilePaths.clear(); + m_excludedFilePaths.reserve(excludedFilePaths.size()); + std::transform(std::make_move_iterator(excludedFilePaths.begin()), + std::make_move_iterator(excludedFilePaths.end()), + std::back_inserter(m_excludedFilePaths), + [](auto &&path) { + path.replace("/", "\\"); + return std::move(path); + }); + } else { + m_excludedFilePaths = std::move(excludedFilePaths); + } +} + +void BuildDependencyCollector::addFiles(const FilePathIds &filePathIds, + const Utils::SmallStringVector &arguments) +{ + m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); + m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(), + filePathIds.begin(), + filePathIds.end()); +} + +void BuildDependencyCollector::addFile(FilePathId filePathId, + const Utils::SmallStringVector &arguments) +{ + addFiles({filePathId}, arguments); +} + +void BuildDependencyCollector::addFile(FilePath filePath, + const FilePathIds &sourceFileIds, + const Utils::SmallStringVector &arguments) +{ + m_clangTool.addFiles({filePath}, arguments); + m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(), + sourceFileIds.begin(), + sourceFileIds.end()); +} + +void BuildDependencyCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles) +{ + m_clangTool.addUnsavedFiles(unsavedFiles); +} + +void BuildDependencyCollector::clear() +{ + m_clangTool = ClangTool(); + m_buildDependency.clear(); +} + +} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h similarity index 65% rename from src/tools/clangpchmanagerbackend/source/includecollector.h rename to src/tools/clangpchmanagerbackend/source/builddependencycollector.h index f97a4901e7c..cab749c3166 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.h +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h @@ -25,27 +25,28 @@ #pragma once +#include "builddependencygeneratorinterface.h" + #include -#include -#include #include -#include #include namespace ClangBackEnd { -class IncludeCollector : public ClangTool +class BuildDependencyCollector : public BuildDependencyGeneratorInterface { public: - IncludeCollector(const FilePathCachingInterface &filePathCache) + BuildDependencyCollector(const FilePathCachingInterface &filePathCache) : m_filePathCache(filePathCache) { } + BuildDependency create(const V2::ProjectPartContainer &projectPart) override; + void collect(); - void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes); + void setExcludedFilePaths(ClangBackEnd::FilePaths &&excludedIncludes); void addFiles(const FilePathIds &filePathIds, const Utils::SmallStringVector &arguments); void addFile(FilePathId filePathId, @@ -53,62 +54,43 @@ public: void addFile(FilePath filePath, const FilePathIds &sourceFileIds, const Utils::SmallStringVector &arguments); + void addUnsavedFiles(const V2::FileContainers &unsavedFiles); void clear(); const FileStatuses &fileStatuses() const { - return m_fileStatuses; + return m_buildDependency.fileStatuses; } const FilePathIds &sourceFiles() const { - return m_sourceFiles; + return m_buildDependency.sourceFiles; } const UsedMacros &usedMacros() const { - return m_usedMacros; + return m_buildDependency.usedMacros; } const SourceDependencies &sourceDependencies() const { - return m_sourceDependencies; + return m_buildDependency.sourceDependencies; } - FilePathIds takeIncludeIds() + const SourceEntries &includeIds() { - std::sort(m_includeIds.begin(), m_includeIds.end()); + std::sort(m_buildDependency.includes.begin(), m_buildDependency.includes.end()); - return std::move(m_includeIds); - } - - FilePathIds takeTopIncludeIds() - { - std::sort(m_topIncludeIds.begin(), m_topIncludeIds.end()); - - return std::move(m_topIncludeIds); - } - - FilePathIds takeTopsSystemIncludeIds() - { - std::sort(m_topsSystemIncludeIds.begin(), m_topsSystemIncludeIds.end()); - - return std::move(m_topsSystemIncludeIds); + return std::move(m_buildDependency.includes); } private: ClangTool m_clangTool; - Utils::PathStringVector m_excludedIncludes; - FilePathIds m_includeIds; - FilePathIds m_topIncludeIds; - FilePathIds m_topsSystemIncludeIds; + BuildDependency m_buildDependency; + ClangBackEnd::FilePaths m_excludedFilePaths; Utils::SmallStringVector m_directories; SourcesManager m_sourcesManager; - UsedMacros m_usedMacros; - FilePathIds m_sourceFiles; - SourceDependencies m_sourceDependencies; - FileStatuses m_fileStatuses; const FilePathCachingInterface &m_filePathCache; }; diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesgeneratorinterface.h b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h similarity index 93% rename from src/tools/clangpchmanagerbackend/source/builddependenciesgeneratorinterface.h rename to src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h index f3863d8027b..f6e13f3a1af 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesgeneratorinterface.h +++ b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h @@ -31,13 +31,13 @@ namespace ClangBackEnd { -class BuildDependenciesGeneratorInterface +class BuildDependencyGeneratorInterface { public: virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0; protected: - ~BuildDependenciesGeneratorInterface() = default; + ~BuildDependencyGeneratorInterface() = default; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri index abdebd22f08..6c45f38ff59 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri +++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri @@ -5,7 +5,8 @@ SOURCES += \ $$PWD/projectparts.cpp \ $$PWD/projectpartqueue.cpp \ $$PWD/pchtaskgenerator.cpp \ - $$PWD/builddependenciesprovider.cpp + $$PWD/builddependenciesprovider.cpp \ + $$PWD/builddependencycollector.cpp HEADERS += \ $$PWD/pchmanagerserver.h \ @@ -32,20 +33,19 @@ HEADERS += \ $$PWD/builddependency.h \ $$PWD/modifiedtimecheckerinterface.h \ $$PWD/sourceentry.h \ - $$PWD/builddependenciesgeneratorinterface.h \ - $$PWD/builddependenciesstorage.h + $$PWD/builddependenciesstorage.h \ + $$PWD/builddependencycollector.h \ + $$PWD/builddependencygeneratorinterface.h \ + $$PWD/collectbuilddependencytoolaction.h \ + $$PWD/collectbuilddependencyaction.h \ + $$PWD/collectbuilddependencypreprocessorcallbacks.h !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ $$PWD/usedmacrosandsourcescollector.cpp \ - $$PWD/includecollector.cpp \ $$PWD/pchcreator.cpp HEADERS += \ - $$PWD/includecollector.h \ - $$PWD/collectincludestoolaction.h \ - $$PWD/collectincludesaction.h \ - $$PWD/collectincludespreprocessorcallbacks.h \ $$PWD/collectusedmacroactionfactory.h \ $$PWD/collectusedmacrosaction.h \ $$PWD/collectusedmacrosandsourcespreprocessorcallbacks.h \ diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h similarity index 64% rename from src/tools/clangpchmanagerbackend/source/collectincludesaction.h rename to src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h index 17498028b86..ff861f174f0 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h @@ -25,7 +25,7 @@ #pragma once -#include +#include #include #include @@ -36,31 +36,19 @@ namespace ClangBackEnd { -class CollectIncludesAction final : public clang::PreprocessOnlyAction +class CollectBuildDependencyAction final : public clang::PreprocessOnlyAction { public: - CollectIncludesAction(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyAction(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, std::vector &excludedIncludeUID, std::vector &alreadyIncludedFileUIDs, - UsedMacros &usedMacros, - SourcesManager &sourcesManager, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + SourcesManager &sourcesManager) + : m_buildDependency(buildDependency), m_filePathCache(filePathCache), m_excludedIncludeUID(excludedIncludeUID), m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs), - m_usedMacros(usedMacros), - m_sourcesManager(sourcesManager), - m_sourceDependencies(sourceDependencies), - m_sourceFiles(sourceFiles), - m_fileStatuses(fileStatuses) + m_sourcesManager(sourcesManager) { } @@ -71,20 +59,14 @@ public: preprocessor.SetSuppressIncludeNotFoundError(true); - auto macroPreprocessorCallbacks = new CollectIncludesPreprocessorCallbacks( - m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, + auto macroPreprocessorCallbacks = new CollectBuildDependencyPreprocessorCallbacks( + m_buildDependency, m_filePathCache, m_excludedIncludeUID, m_alreadyIncludedFileUIDs, compilerInstance.getSourceManager(), - m_usedMacros, m_sourcesManager, - compilerInstance.getPreprocessorPtr(), - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses); + compilerInstance.getPreprocessorPtr()); preprocessor.addPPCallbacks(std::unique_ptr(macroPreprocessorCallbacks)); @@ -100,17 +82,11 @@ public: } private: - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + BuildDependency &m_buildDependency; const FilePathCachingInterface &m_filePathCache; std::vector &m_excludedIncludeUID; std::vector &m_alreadyIncludedFileUIDs; - UsedMacros &m_usedMacros; SourcesManager &m_sourcesManager; - SourceDependencies &m_sourceDependencies; - FilePathIds &m_sourceFiles; - FileStatuses &m_fileStatuses; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h similarity index 67% rename from src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h rename to src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h index 5522fa7bce3..664314e309c 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h @@ -25,6 +25,7 @@ #pragma once +#include "builddependency.h" #include "collectmacrospreprocessorcallbacks.h" #include "sourcelocationsutils.h" @@ -33,6 +34,8 @@ #include +#include + #include #include #include @@ -41,34 +44,26 @@ namespace ClangBackEnd { -class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks, +class CollectBuildDependencyPreprocessorCallbacks final : public clang::PPCallbacks, public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase { public: - CollectIncludesPreprocessorCallbacks(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyPreprocessorCallbacks(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, const std::vector &excludedIncludeUID, std::vector &alreadyIncludedFileUIDs, - const clang::SourceManager &sourceManager, - UsedMacros &usedMacros, + clang::SourceManager &sourceManager, SourcesManager &sourcesManager, - std::shared_ptr preprocessor, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(usedMacros, + std::shared_ptr preprocessor) + : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(buildDependency.usedMacros, filePathCache, sourceManager, sourcesManager, preprocessor, - sourceDependencies, - sourceFiles, - fileStatuses), - m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + buildDependency.sourceDependencies, + buildDependency.sourceFiles, + buildDependency.fileStatuses), + m_buildDependency(buildDependency), m_excludedIncludeUID(excludedIncludeUID), m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs) {} @@ -90,7 +85,7 @@ public: } void InclusionDirective(clang::SourceLocation hashLocation, - const clang::Token &/*includeToken*/, + const clang::Token & /*includeToken*/, llvm::StringRef /*fileName*/, bool /*isAngled*/, clang::CharSourceRange /*fileNameRange*/, @@ -103,20 +98,30 @@ public: if (!m_skipInclude && file) { addSourceDependency(file, hashLocation); auto fileUID = file->getUID(); - auto sourceFileUID = m_sourceManager->getFileEntryForID(m_sourceManager->getFileID(hashLocation))->getUID(); - if (isNotInExcludedIncludeUID(fileUID)) { - auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID); - if (notAlreadyIncluded.first) { - m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); - FilePath filePath = filePathFromFile(file); - if (!filePath.empty()) { - FilePathId includeId = m_filePathCache.filePathId(filePath); - m_includeIds.emplace_back(includeId); - if (isSystem(fileType) && !isInSystemHeader(hashLocation)) - m_topsSystemIncludeIds.emplace_back(includeId); - if (isInExcludedIncludeUID(sourceFileUID)) - m_topIncludeIds.emplace_back(includeId); + auto sourceFileUID = m_sourceManager + ->getFileEntryForID(m_sourceManager->getFileID(hashLocation)) + ->getUID(); + auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID); + if (notAlreadyIncluded.first) { + m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); + FilePath filePath = filePathFromFile(file); + if (!filePath.empty()) { + FilePathId includeId = m_filePathCache.filePathId(filePath); + + time_t lastModified = file->getModificationTime(); + + SourceType sourceType = SourceType::UserInclude; + if (isSystem(fileType)) { + if (isInSystemHeader(hashLocation)) + sourceType = SourceType::SystemInclude; + else + sourceType = SourceType::TopSystemInclude; + } else if (isNotInExcludedIncludeUID(fileUID) + && isInExcludedIncludeUID(sourceFileUID)) { + sourceType = SourceType::TopInclude; } + + addInclude({includeId, sourceType, lastModified}); } } } @@ -124,19 +129,12 @@ public: m_skipInclude = false; } - bool FileNotFound(clang::StringRef fileNameRef, clang::SmallVectorImpl &recoveryPath) override + bool FileNotFound(clang::StringRef /*fileNameRef*/, + clang::SmallVectorImpl &recoveryPath) override { - QTemporaryDir temporaryDirectory; - temporaryDirectory.setAutoRemove(false); - const QByteArray temporaryDirUtf8 = temporaryDirectory.path().toUtf8(); + auto dummyPath = llvm::StringRef("/dummyPath"); - const QString fileName = QString::fromUtf8(fileNameRef.data(), int(fileNameRef.size())); - QString filePath = temporaryDirectory.path() + '/' + fileName; - - ensureDirectory(temporaryDirectory.path(), fileName); - createFakeFile(filePath); - - recoveryPath.append(temporaryDirUtf8.cbegin(), temporaryDirUtf8.cend()); + recoveryPath.append(std::cbegin(dummyPath), std::cend(dummyPath)); m_skipInclude = true; @@ -189,15 +187,6 @@ public: QDir(directory).mkpath(directoryEntries.join('/')); } - void createFakeFile(const QString &filePath) - { - QFile fakeFile; - fakeFile.setFileName(filePath); - - fakeFile.open(QIODevice::ReadWrite); - fakeFile.close(); - } - bool isNotInExcludedIncludeUID(uint uid) const { return !isInExcludedIncludeUID(uid); @@ -224,10 +213,21 @@ public: return FilePath::fromNativeFilePath(absolutePath(file->getName())); } + void addInclude(SourceEntry sourceEntry) + { + auto &includes = m_buildDependency.includes; + auto found = std::lower_bound(includes.begin(), + includes.end(), + sourceEntry, + [](auto first, auto second) { return first < second; }); + + if (found == includes.end() || *found != sourceEntry) + includes.emplace(found, sourceEntry); + } + private: - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + FilePathIds m_containsMissingIncludes; + BuildDependency &m_buildDependency; const std::vector &m_excludedIncludeUID; std::vector &m_alreadyIncludedFileUIDs; bool m_skipInclude = false; diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h similarity index 57% rename from src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h rename to src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h index 7820b095fc6..4f28d0f7c82 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h @@ -25,7 +25,7 @@ #pragma once -#include "collectincludesaction.h" +#include "collectbuilddependencyaction.h" #include #include @@ -34,29 +34,17 @@ namespace ClangBackEnd { -class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory +class CollectBuildDependencyToolAction final : public clang::tooling::FrontendActionFactory { public: - CollectIncludesToolAction(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyToolAction(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, - const Utils::PathStringVector &excludedIncludes, - UsedMacros &usedMacros, - SourcesManager &sourcesManager, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + const ClangBackEnd::FilePaths &excludedIncludes, + SourcesManager &sourcesManager) + : m_buildDependency(buildDependency), m_filePathCache(filePathCache), - m_excludedIncludes(excludedIncludes), - m_usedMacros(usedMacros), - m_sourcesManager(sourcesManager), - m_sourceDependencies(sourceDependencies), - m_sourceFiles(sourceFiles), - m_fileStatuses(fileStatuses) + m_excludedFilePaths(excludedIncludes), + m_sourcesManager(sourcesManager) {} @@ -76,26 +64,21 @@ public: clang::FrontendAction *create() override { - return new CollectIncludesAction(m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, - m_filePathCache, - m_excludedIncludeUIDs, - m_alreadyIncludedFileUIDs, - m_usedMacros, - m_sourcesManager, - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses); + return new CollectBuildDependencyAction(m_buildDependency, + m_filePathCache, + m_excludedIncludeUIDs, + m_alreadyIncludedFileUIDs, + m_sourcesManager); } std::vector generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const { std::vector fileUIDs; - fileUIDs.reserve(m_excludedIncludes.size()); + fileUIDs.reserve(m_excludedFilePaths.size()); - for (const Utils::PathString &filePath : m_excludedIncludes) { - const clang::FileEntry *file = fileManager.getFile({filePath.data(), filePath.size()}, true); + for (const ClangBackEnd::FilePath &filePath : m_excludedFilePaths) { + const clang::FileEntry *file = fileManager.getFile({filePath.data(), filePath.size()}, + true); if (file) fileUIDs.push_back(file->getUID()); @@ -109,16 +92,10 @@ public: private: std::vector m_alreadyIncludedFileUIDs; std::vector m_excludedIncludeUIDs; - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + BuildDependency &m_buildDependency; const FilePathCachingInterface &m_filePathCache; - const Utils::PathStringVector &m_excludedIncludes; - UsedMacros &m_usedMacros; + const ClangBackEnd::FilePaths &m_excludedFilePaths; SourcesManager &m_sourcesManager; - SourceDependencies &m_sourceDependencies; - FilePathIds &m_sourceFiles; - FileStatuses &m_fileStatuses; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h index 9ecd4964a2c..90108bd76b1 100644 --- a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h @@ -102,7 +102,15 @@ public: auto includeFilePathId = filePathId(includeLocation); auto includedFilePathId = filePathId(file); - m_sourceDependencies.emplace_back(includeFilePathId, includedFilePathId); + SourceDependency sourceDependency{includeFilePathId, includedFilePathId}; + + auto found = std::lower_bound(m_sourceDependencies.begin(), + m_sourceDependencies.end(), + sourceDependency, + [](auto first, auto second) { return first < second; }); + + if (found == m_sourceDependencies.end() || *found != sourceDependency) + m_sourceDependencies.emplace(found, sourceDependency); } void mergeUsedMacros() diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp deleted file mode 100644 index 6ca7623cc3a..00000000000 --- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp +++ /dev/null @@ -1,103 +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. -** -****************************************************************************/ - -#include "includecollector.h" - -#include "collectincludestoolaction.h" - -#include - -#include - -namespace ClangBackEnd { - -void IncludeCollector::collect() -{ - clang::tooling::ClangTool tool = m_clangTool.createTool(); - - auto action = std::unique_ptr( - new CollectIncludesToolAction(m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, - m_filePathCache, - m_excludedIncludes, - m_usedMacros, - m_sourcesManager, - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses)); - - tool.run(action.get()); -} - -void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedIncludes) -{ -#ifdef _WIN32 - m_excludedIncludes.clear(); - m_excludedIncludes.reserve(excludedIncludes.size()); - std::transform(std::make_move_iterator(excludedIncludes.begin()), - std::make_move_iterator(excludedIncludes.end()), - std::back_inserter(m_excludedIncludes), - [] (Utils::PathString &&path) { - path.replace("/", "\\"); - return std::move(path); - }); - - -#else - m_excludedIncludes = std::move(excludedIncludes); -#endif -} - -void IncludeCollector::addFiles(const FilePathIds &filePathIds, - const Utils::SmallStringVector &arguments) -{ - m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); - m_sourceFiles.insert(m_sourceFiles.end(), filePathIds.begin(), filePathIds.end()); -} - -void IncludeCollector::addFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) -{ - addFiles({filePathId}, arguments); -} - -void IncludeCollector::addFile(FilePath filePath, - const FilePathIds &sourceFileIds, - const Utils::SmallStringVector &arguments) -{ - m_clangTool.addFiles({filePath}, arguments); - m_sourceFiles.insert(m_sourceFiles.end(), sourceFileIds.begin(), sourceFileIds.end()); -} - -void IncludeCollector::clear() -{ - m_clangTool = ClangTool(); - m_usedMacros.clear(); - m_sourceFiles.clear(); - m_fileStatuses.clear(); - m_sourceDependencies.clear(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 51e0f129fee..88acf8bb69e 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -26,7 +26,7 @@ #include "pchcreator.h" #include "environment.h" -#include "includecollector.h" +#include "builddependencycollector.h" #include "pchnotcreatederror.h" #include @@ -58,12 +58,12 @@ void append(Target &target, const Source &source) target.push_back(ValueType(std::move(entry))); } -void appendFilePathId(Utils::PathStringVector &target, +void appendFilePathId(ClangBackEnd::FilePaths &target, const ClangBackEnd::FilePathIds &source, const ClangBackEnd::FilePathCachingInterface &filePathCache) { for (FilePathId id : source) - target.emplace_back(filePathCache.filePath(id).path()); + target.emplace_back(filePathCache.filePath(id)); } Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFiles) @@ -190,23 +190,23 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaders( namespace { -std::size_t sizeOfContent(const Utils::PathStringVector &paths) +std::size_t sizeOfContent(const ClangBackEnd::FilePaths &paths) { return std::accumulate(paths.begin(), paths.end(), std::size_t(0), - [] (std::size_t size, const Utils::PathString &path) { + [] (std::size_t size, const auto &path) { const char includeTemplate[] = "#include \"\"\n"; return size + path.size() + sizeof(includeTemplate); }); } -Utils::SmallString concatContent(const Utils::PathStringVector &paths, std::size_t size) +Utils::SmallString concatContent(const ClangBackEnd::FilePaths &paths, std::size_t size) { Utils::SmallString content; content.reserve(size); - for (const Utils::PathString &path : paths) { + for (const ClangBackEnd::FilePath &path : paths) { content += "#include \""; content += path; content += "\"\n"; @@ -220,15 +220,15 @@ Utils::SmallString concatContent(const Utils::PathStringVector &paths, std::size Utils::SmallString PchCreator::generateProjectPartSourcesContent( const V2::ProjectPartContainer &projectPart) const { - Utils::PathStringVector paths = generateProjectPartSourcePaths(projectPart); + ClangBackEnd::FilePaths paths = generateProjectPartSourcePaths(projectPart); return concatContent(paths, sizeOfContent(paths)); } -Utils::PathStringVector PchCreator::generateProjectPartSourcePaths( - const V2::ProjectPartContainer &projectPart) const +ClangBackEnd::FilePaths PchCreator::generateProjectPartSourcePaths( + const V2::ProjectPartContainer &projectPart) const { - Utils::PathStringVector includeAndSources; + ClangBackEnd::FilePaths includeAndSources; includeAndSources.reserve(projectPart.sourcePathIds.size()); appendFilePathId(includeAndSources, projectPart.sourcePathIds, m_filePathCache); @@ -236,7 +236,7 @@ Utils::PathStringVector PchCreator::generateProjectPartSourcePaths( return includeAndSources; } -PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( +SourceEntries PchCreator::generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const { Utils::SmallString jointedFileContent = generateProjectPartSourcesContent(projectPart); @@ -245,9 +245,9 @@ PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart); FilePath filePath{Utils::PathString(jointedFilePath)}; - IncludeCollector collector(m_filePathCache); + BuildDependencyCollector collector(m_filePathCache); - collector.setExcludedIncludes(generateProjectPartSourcePaths(projectPart)); + collector.setExcludedFilePaths(generateProjectPartSourcePaths(projectPart)); collector.addFile(filePath, projectPart.sourcePathIds, arguments); @@ -257,7 +257,7 @@ PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( jointFile->remove(); - return {collector.takeIncludeIds(), collector.takeTopIncludeIds(), collector.takeTopsSystemIncludeIds()}; + return collector.includeIds(); } Utils::SmallString PchCreator::generateProjectPathPchHeaderFilePath( @@ -309,7 +309,7 @@ IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &proje { long long lastModified = QDateTime::currentSecsSinceEpoch(); auto includes = generateProjectPartPchIncludes(projectPart); - auto content = generatePchIncludeFileContent(includes.topIncludeIds); + auto content = generatePchIncludeFileContent(topIncludeIds(includes)); auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart); auto pchFilePath = generateProjectPartPchFilePath(projectPart); generateFileWithContent(pchIncludeFilePath, content); @@ -323,7 +323,7 @@ IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &proje m_projectPartPch.lastModified = lastModified; } - return {projectPart.projectPartId.clone(), std::move(includes.includeIds)}; + return {projectPart.projectPartId.clone(), allIncludeIds(includes)}; } void PchCreator::generatePch(const V2::ProjectPartContainer &projectPart) @@ -392,6 +392,32 @@ std::unique_ptr PchCreator::generateFileWithContent( return precompiledIncludeFile; } +FilePathIds PchCreator::topIncludeIds(const SourceEntries &includes) +{ + FilePathIds topIncludes; + topIncludes.reserve(includes.size()); + + for (SourceEntry include : includes) { + if (include.sourceType == SourceType::TopInclude) + 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); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 7f95b074cbb..34461dc16b6 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -28,6 +28,7 @@ #include "pchcreatorinterface.h" #include "idpaths.h" +#include "sourceentry.h" #include #include @@ -93,9 +94,9 @@ public: const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPartSourcesContent( const V2::ProjectPartContainer &projectPart) const; - Utils::PathStringVector generateProjectPartSourcePaths( + ClangBackEnd::FilePaths generateProjectPartSourcePaths( const V2::ProjectPartContainer &projectPart) const; - PchCreatorIncludes generateProjectPartPchIncludes( + SourceEntries generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPathPchHeaderFilePath( const V2::ProjectPartContainer &projectPart) const; @@ -113,6 +114,9 @@ public: 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); diff --git a/src/tools/clangpchmanagerbackend/source/sourceentry.h b/src/tools/clangpchmanagerbackend/source/sourceentry.h index 2a5e4ba06fd..6859e838ad8 100644 --- a/src/tools/clangpchmanagerbackend/source/sourceentry.h +++ b/src/tools/clangpchmanagerbackend/source/sourceentry.h @@ -33,9 +33,10 @@ namespace ClangBackEnd { enum class SourceType : unsigned char { - Any, TopInclude, - TopSystemInclude + TopSystemInclude, + UserInclude, + SystemInclude }; class TimeStamp @@ -62,7 +63,6 @@ public: : lastModified(lastModified), sourceId(sourceId), sourceType(static_cast(sourceType)) - {} SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified) @@ -85,10 +85,12 @@ public: && first.lastModified == second.lastModified ; } + friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); } + public: TimeStamp lastModified; FilePathId sourceId; - SourceType sourceType = SourceType::Any; + SourceType sourceType = SourceType::UserInclude; }; using SourceEntries = std::vector; diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp index abee158e49c..e2df298c8d8 100644 --- a/src/tools/clangrefactoringbackend/source/clangtool.cpp +++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp @@ -135,6 +135,8 @@ clang::tooling::ClangTool ClangTool::createTool() const tool.mapVirtualFile(toStringRef(unsavedFileContent.filePath), toStringRef(unsavedFileContent.content)); + tool.mapVirtualFile("/dummyFile", "#pragma once"); + return tool; } diff --git a/src/tools/clangrefactoringbackend/source/filestatus.h b/src/tools/clangrefactoringbackend/source/filestatus.h index d926879f657..9ade5462948 100644 --- a/src/tools/clangrefactoringbackend/source/filestatus.h +++ b/src/tools/clangrefactoringbackend/source/filestatus.h @@ -54,6 +54,12 @@ public: && first.lastModified == second.lastModified; } + friend + bool operator<(const FileStatus &first, const FileStatus &second) + { + return first.filePathId < second.filePathId; + } + public: FilePathId filePathId; off_t size; diff --git a/src/tools/clangrefactoringbackend/source/sourcedependency.h b/src/tools/clangrefactoringbackend/source/sourcedependency.h index af6db6a20ca..ce9671342ed 100644 --- a/src/tools/clangrefactoringbackend/source/sourcedependency.h +++ b/src/tools/clangrefactoringbackend/source/sourcedependency.h @@ -34,17 +34,26 @@ namespace ClangBackEnd { class SourceDependency { public: - SourceDependency(FilePathId filePathId, - FilePathId dependencyFilePathId) - : filePathId(filePathId), - dependencyFilePathId(dependencyFilePathId) + SourceDependency(FilePathId filePathId, FilePathId dependencyFilePathId) + : filePathId(filePathId) + , dependencyFilePathId(dependencyFilePathId) {} - friend - bool operator==(SourceDependency first, SourceDependency second) + friend bool operator==(SourceDependency first, SourceDependency second) { return first.filePathId == second.filePathId - && first.dependencyFilePathId == second.dependencyFilePathId; + && first.dependencyFilePathId == second.dependencyFilePathId; + } + + friend bool operator!=(SourceDependency first, SourceDependency second) + { + return !(first == second); + } + + friend bool operator<(SourceDependency first, SourceDependency second) + { + return std::tie(first.filePathId, first.dependencyFilePathId) + < std::tie(second.filePathId, second.dependencyFilePathId); } public: @@ -53,4 +62,4 @@ public: }; using SourceDependencies = std::vector; -} +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h index 161acbe7799..c833f73afbe 100644 --- a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h +++ b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h @@ -145,7 +145,7 @@ public: return SymbolIndex(reinterpret_cast(pointer)); } - void setSourceManager(const clang::SourceManager *sourceManager) + void setSourceManager(clang::SourceManager *sourceManager) { m_sourceManager = sourceManager; } diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp index 24d4b104654..e829b52d60e 100644 --- a/tests/unit/unittest/builddependenciesprovider-test.cpp +++ b/tests/unit/unittest/builddependenciesprovider-test.cpp @@ -27,7 +27,7 @@ #include "mockbuilddependenciesstorage.h" #include "mockmodifiedtimechecker.h" -#include "mockbuilddependenciesgenerator.h" +#include "mockbuilddependencygenerator.h" #include @@ -56,7 +56,7 @@ class BuildDependenciesProvider : public testing::Test protected: NiceMock mockBuildDependenciesStorage; NiceMock mockModifiedTimeChecker; - NiceMock mockBuildDependenciesGenerator; + NiceMock mockBuildDependenciesGenerator; ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, mockModifiedTimeChecker, mockBuildDependenciesGenerator}; ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1", {"--yi"}, @@ -70,13 +70,13 @@ protected: {"/er"}, {1}, {2, 3, 4}}; - SourceEntries firstSources{{1, SourceType::Any, 1}, {2, SourceType::Any, 1}, {10, SourceType::Any, 1}}; - SourceEntries secondSources{{1, SourceType::Any, 1}, {3, SourceType::Any, 1}, {8, SourceType::Any, 1}}; - SourceEntries thirdSources{{4, SourceType::Any, 1}, {8, SourceType::Any, 1}, {10, SourceType::Any, 1}}; + SourceEntries firstSources{{1, SourceType::UserInclude, 1}, {2, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; + SourceEntries secondSources{{1, SourceType::UserInclude, 1}, {3, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}}; + SourceEntries thirdSources{{4, SourceType::UserInclude, 1}, {8, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; UsedMacros firstUsedMacros{{"YI", 1}}; UsedMacros secondUsedMacros{{"LIANG", 2}, {"ER", 2}}; UsedMacros thirdUsedMacros{{"SAN", 10}}; - BuildDependency buildDependency{secondSources, {}, {}, {}}; + BuildDependency buildDependency{secondSources, {}}; }; TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTimeStampsAreUpToDate) diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp index 05d3d70887d..1100f1a634f 100644 --- a/tests/unit/unittest/builddependenciesstorage-test.cpp +++ b/tests/unit/unittest/builddependenciesstorage-test.cpp @@ -171,9 +171,9 @@ TEST_F(BuildDependenciesStorage, UpdateSources) SourceEntries entries{{1, SourceType::TopInclude, 10}, {2, SourceType::TopSystemInclude, 20}}; EXPECT_CALL(updateBuildDependencyTimeStampStatement, write(TypedEq(10), TypedEq(1))); - EXPECT_CALL(updateSourceTypeStatement, write(TypedEq(1), TypedEq(1))); + EXPECT_CALL(updateSourceTypeStatement, write(TypedEq(0), TypedEq(1))); EXPECT_CALL(updateBuildDependencyTimeStampStatement, write(TypedEq(20), TypedEq(2))); - EXPECT_CALL(updateSourceTypeStatement, write(TypedEq(2), TypedEq(2))); + EXPECT_CALL(updateSourceTypeStatement, write(TypedEq(1), TypedEq(2))); storage.updateSources(entries); } diff --git a/tests/unit/unittest/builddependencycollector-test.cpp b/tests/unit/unittest/builddependencycollector-test.cpp new file mode 100644 index 00000000000..ba94a276d4e --- /dev/null +++ b/tests/unit/unittest/builddependencycollector-test.cpp @@ -0,0 +1,635 @@ +/**************************************************************************** +** +** 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 "googletest.h" + +#include +#include +#include + +#include + +#include +#include + +using testing::AllOf; +using testing::Contains; +using testing::Not; +using testing::ElementsAre; +using testing::UnorderedElementsAre; + +using ClangBackEnd::BuildDependency; +using ClangBackEnd::FilePathId; +using ClangBackEnd::FilePathIds; +using ClangBackEnd::FilePathView; +using ClangBackEnd::SourceDependency; +using ClangBackEnd::SourceType; +using ClangBackEnd::UsedMacro; + +namespace { + +MATCHER_P2(HasInclude, 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; +} + +class BuildDependencyCollector : public ::testing::Test +{ +protected: + BuildDependencyCollector() + { + setFilePathCache(&filePathCache); + + collector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + collector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + collector.addUnsavedFiles({{{TESTDATA_DIR, "BuildDependencyCollector/project/generated_file.h"}, "#pragma once", {}}}); + + collector.setExcludedFilePaths(Utils::clone(excludePaths)); + emptyCollector.setExcludedFilePaths(Utils::clone(excludePaths)); + } + + ~BuildDependencyCollector() + { + setFilePathCache(nullptr); + } + + FilePathId id(const Utils::SmallStringView &path) const + { + return filePathCache.filePathId(FilePathView{path}); + } + + static off_t fileSize(Utils::SmallStringView filePath) + { + return QFileInfo(QString(filePath)).size(); + } + + static std::time_t lastModified(Utils::SmallStringView filePath) + { + return QFileInfo(QString(filePath)).lastModified().toTime_t(); + } + + ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const + { + return {id(filePath), fileSize(filePath), lastModified(filePath), false}; + } + + static + FilePathIds filteredIncludes(const ClangBackEnd::SourceEntries &includes, + ClangBackEnd::SourceType includeType) + { + FilePathIds filteredIncludes; + + for (const ClangBackEnd::SourceEntry &include : includes) { + if (include.sourceType == includeType) + filteredIncludes.push_back(include.sourceId); + } + + return filteredIncludes; + } + + static + FilePathIds topIncludes(const ClangBackEnd::SourceEntries &includes) + { + return filteredIncludes(includes, ClangBackEnd::SourceType::TopInclude); + } + + static + FilePathIds systemTopIncludes(const ClangBackEnd::SourceEntries &includes) + { + return filteredIncludes(includes, ClangBackEnd::SourceType::TopSystemInclude); + } + + static + FilePathIds userIncludes(const ClangBackEnd::SourceEntries &includes) + { + return filteredIncludes(includes, ClangBackEnd::SourceType::UserInclude); + } + + static + FilePathIds allIncludes(const ClangBackEnd::SourceEntries &includes) + { + FilePathIds filteredIncludes; + + for (const ClangBackEnd::SourceEntry &include : includes) + filteredIncludes.push_back(include.sourceId); + + return filteredIncludes; + } + +protected: + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; + ClangBackEnd::BuildDependencyCollector collector{filePathCache}; + ClangBackEnd::BuildDependencyCollector emptyCollector{filePathCache}; + ClangBackEnd::FilePaths excludePaths = {TESTDATA_DIR "/builddependencycollector/project/main.cpp", + TESTDATA_DIR "/builddependencycollector/project/main2.cpp", + TESTDATA_DIR "/builddependencycollector/project/header1.h", + TESTDATA_DIR "/builddependencycollector/project/header2.h", + TESTDATA_DIR "/builddependencycollector/project/generated_file.h"}; +}; + +TEST_F(BuildDependencyCollector, IncludesExternalHeader) +{ + collector.collect(); + + ASSERT_THAT(allIncludes(collector.includeIds()), + AllOf(Contains(id(TESTDATA_DIR "/builddependencycollector/external/external1.h")), + Contains(id(TESTDATA_DIR "/builddependencycollector/external/external2.h")), + Contains(id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h")), + Contains(id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h")))); +} + +TEST_F(BuildDependencyCollector, InternalHeaderAreUserIncludes) +{ + collector.collect(); + + ASSERT_THAT(userIncludes(collector.includeIds()), Contains(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"))); +} + +TEST_F(BuildDependencyCollector, NoDuplicate) +{ + collector.collect(); + + ASSERT_THAT(allIncludes(collector.includeIds()), + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"))); +} + +TEST_F(BuildDependencyCollector, IncludesAreSorted) +{ + collector.collect(); + + ASSERT_THAT(allIncludes(collector.includeIds()), + ElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))); +} + +TEST_F(BuildDependencyCollector, If) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/if.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(allIncludes(emptyCollector.includeIds()), + ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/true.h"))); +} + +TEST_F(BuildDependencyCollector, LocalPath) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(allIncludes(emptyCollector.includeIds()), + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"))); +} + +TEST_F(BuildDependencyCollector, IgnoreMissingFile) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/missingfile.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(allIncludes(emptyCollector.includeIds()), + UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"))); +} + +TEST_F(BuildDependencyCollector, IncludesOnlyTopExternalHeader) +{ + collector.collect(); + + ASSERT_THAT(topIncludes(collector.includeIds()), + UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"))); +} + +TEST_F(BuildDependencyCollector, TopIncludeInIfMacro) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/if.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + emptyCollector.setExcludedFilePaths({TESTDATA_DIR "/builddependencycollector/project/if.cpp"}); + + emptyCollector.collect(); + + ASSERT_THAT(topIncludes(emptyCollector.includeIds()), + ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/true.h"))); +} + +TEST_F(BuildDependencyCollector, TopIncludeWithLocalPath) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(topIncludes(emptyCollector.includeIds()), + UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"))); +} + +TEST_F(BuildDependencyCollector, TopIncludesIgnoreMissingFile) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/missingfile.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + emptyCollector.setExcludedFilePaths({TESTDATA_DIR "/builddependencycollector/project/missingfile.cpp"}); + + emptyCollector.collect(); + + ASSERT_THAT(topIncludes(emptyCollector.includeIds()), + UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"))); +} + +TEST_F(BuildDependencyCollector, SourceFiles) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.sourceFiles(), + UnorderedElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"), + id(TESTDATA_DIR "/symbolscollector_header1.h"), + id(TESTDATA_DIR "/symbolscollector_header2.h"))); +} + +TEST_F(BuildDependencyCollector, MainFileInSourceFiles) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + ASSERT_THAT(emptyCollector.sourceFiles(), + ElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"))); +} + +TEST_F(BuildDependencyCollector, ResetMainFileInSourceFiles) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + ASSERT_THAT(emptyCollector.sourceFiles(), + ElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"))); +} + +TEST_F(BuildDependencyCollector, DontDuplicateSourceFiles) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + emptyCollector.collect(); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.sourceFiles(), + UnorderedElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"), + id(TESTDATA_DIR "/symbolscollector_header1.h"), + id(TESTDATA_DIR "/symbolscollector_header2.h"))); +} + +TEST_F(BuildDependencyCollector, ClearSourceFiles) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.clear(); + + ASSERT_THAT(emptyCollector.sourceFiles(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, ClearFileStatus) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + emptyCollector.collect(); + + emptyCollector.clear(); + + ASSERT_THAT(emptyCollector.fileStatuses(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, ClearUsedMacros) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_defines.h"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + emptyCollector.collect(); + + emptyCollector.clear(); + + ASSERT_THAT(emptyCollector.usedMacros(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, ClearSourceDependencies) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main2.cpp"), {"cc", "-I" TESTDATA_DIR}); + emptyCollector.collect(); + + emptyCollector.clear(); + + ASSERT_THAT(emptyCollector.sourceDependencies(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, DontCollectSourceFilesAfterFilesAreCleared) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.clear(); + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.sourceFiles(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, DontCollectFileStatusAfterFilesAreCleared) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.clear(); + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.fileStatuses(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, DontCollectUsedMacrosAfterFilesAreCleared) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.clear(); + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.usedMacros(), IsEmpty()); +} + + +TEST_F(BuildDependencyCollector, DontCollectSourceDependenciesAfterFilesAreCleared) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.clear(); + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.sourceDependencies(), IsEmpty()); +} + +TEST_F(BuildDependencyCollector, CollectUsedMacrosWithExternalDefine) +{ + auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); + emptyCollector.addFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.usedMacros(), + ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), + Eq(UsedMacro{"IF_DEFINE", fileId}), + Eq(UsedMacro{"__clang__", fileId}), + Eq(UsedMacro{"CLASS_EXPORT", fileId}), + Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), + Eq(UsedMacro{"MACRO_EXPANSION", fileId}), + Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); +} + +TEST_F(BuildDependencyCollector, CollectUsedMacrosWithoutExternalDefine) +{ + auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); + emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.usedMacros(), + ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), + Eq(UsedMacro{"IF_DEFINE", fileId}), + Eq(UsedMacro{"__clang__", fileId}), + Eq(UsedMacro{"CLASS_EXPORT", fileId}), + Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), + Eq(UsedMacro{"MACRO_EXPANSION", fileId}), + Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); +} + +TEST_F(BuildDependencyCollector, DontCollectHeaderGuards) +{ + auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); + emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.usedMacros(), + Not(Contains(Eq(UsedMacro{"SYMBOLSCOLLECTOR_DEFINES_H", fileId})))); +} + +TEST_F(BuildDependencyCollector, DISABLED_DontCollectDynamicLibraryExports) +{ + auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); + emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.usedMacros(), + Not(Contains(Eq(UsedMacro{"CLASS_EXPORT", fileId})))); +} + +TEST_F(BuildDependencyCollector, CollectFileStatuses) +{ + emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system"}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.fileStatuses(), + ElementsAre( + fileStatus(TESTDATA_DIR "/symbolscollector_main.cpp"), + fileStatus(TESTDATA_DIR "/symbolscollector_header1.h"), + fileStatus(TESTDATA_DIR "/symbolscollector_header2.h"))); +} + +TEST_F(BuildDependencyCollector, CollectSourceDependencies) +{ + auto mainFileId = id(TESTDATA_DIR "/symbolscollector_main2.cpp"); + auto header1FileId = id(TESTDATA_DIR "/symbolscollector_header1.h"); + auto header2FileId = id(TESTDATA_DIR "/symbolscollector_header2.h"); + auto header3FileId = id(TESTDATA_DIR "/symbolscollector_header3.h"); + emptyCollector.addFile(mainFileId, {"cc", "-I" TESTDATA_DIR}); + + emptyCollector.collect(); + + ASSERT_THAT(emptyCollector.sourceDependencies(), + UnorderedElementsAre(SourceDependency(mainFileId, header1FileId), + SourceDependency(mainFileId, header3FileId), + SourceDependency(header3FileId, header2FileId), + SourceDependency(header1FileId, header2FileId))); +} + +TEST_F(BuildDependencyCollector, Create) +{ + 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")}}; + + auto buildDependency = collector.create(projectPart); + + ASSERT_THAT( + buildDependency, + AllOf( + Field(&BuildDependency::fileStatuses, + UnorderedElementsAre( + fileStatus(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + fileStatus(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + fileStatus(TESTDATA_DIR + "/builddependencycollector/external/indirect_external.h"), + fileStatus(TESTDATA_DIR + "/builddependencycollector/external/indirect_external2.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/system/indirect_system2.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), + fileStatus(TESTDATA_DIR "/builddependencycollector/project/macros.h"))), + Field(&BuildDependency::includes, + UnorderedElementsAre( + HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + SourceType::UserInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + SourceType::UserInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + SourceType::TopInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + SourceType::TopInclude), + HasInclude(id(TESTDATA_DIR + "/builddependencycollector/external/indirect_external.h"), + SourceType::UserInclude), + HasInclude(id(TESTDATA_DIR + "/builddependencycollector/external/indirect_external2.h"), + SourceType::UserInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + SourceType::TopInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + SourceType::TopSystemInclude), + HasInclude(id(TESTDATA_DIR + "/builddependencycollector/system/indirect_system.h"), + SourceType::SystemInclude), + HasInclude(id(TESTDATA_DIR + "/builddependencycollector/system/indirect_system2.h"), + SourceType::SystemInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), + SourceType::UserInclude), + HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/macros.h"), + SourceType::UserInclude))), + Field(&BuildDependency::usedMacros, + UnorderedElementsAre( + UsedMacro{"DEFINE", + id(TESTDATA_DIR "/builddependencycollector/project/macros.h")}, + UsedMacro{"IFDEF", + id(TESTDATA_DIR "/builddependencycollector/project/macros.h")}, + UsedMacro{"DEFINED", + id(TESTDATA_DIR "/builddependencycollector/project/macros.h")})), + Field(&BuildDependency::sourceFiles, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external3.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"), + id(TESTDATA_DIR "/builddependencycollector/system/indirect_system2.h"), + id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), + id(TESTDATA_DIR "/builddependencycollector/project/macros.h"))), + Field( + &BuildDependency::sourceDependencies, + UnorderedElementsAre( + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/builddependencycollector/project/header1.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR + "/builddependencycollector/project/missingfile.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR + "/builddependencycollector/external/external1.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR + "/builddependencycollector/external/external2.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/builddependencycollector/system/system1.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/builddependencycollector/project/macros.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR + "/builddependencycollector/external/external3.h")), + SourceDependency(id(TESTDATA_DIR + "/builddependencycollector/project/missingfile.h"), + id(TESTDATA_DIR + "/builddependencycollector/external/external1.h")), + SourceDependency(id(TESTDATA_DIR + "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR + "/builddependencycollector/external/indirect_external.h")), + SourceDependency(id(TESTDATA_DIR + "/builddependencycollector/external/indirect_external.h"), + id(TESTDATA_DIR + "/builddependencycollector/external/indirect_external2.h")), + SourceDependency(id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR + "/builddependencycollector/system/indirect_system.h")), + SourceDependency(id(TESTDATA_DIR + "/builddependencycollector/system/indirect_system.h"), + id(TESTDATA_DIR + "/builddependencycollector/system/indirect_system2.h")))))); +} +} // namespace diff --git a/tests/unit/unittest/data/includecollector/external/external1.h b/tests/unit/unittest/data/builddependencycollector/external/external1.h similarity index 100% rename from tests/unit/unittest/data/includecollector/external/external1.h rename to tests/unit/unittest/data/builddependencycollector/external/external1.h diff --git a/tests/unit/unittest/data/includecollector/external/external2.h b/tests/unit/unittest/data/builddependencycollector/external/external2.h similarity index 100% rename from tests/unit/unittest/data/includecollector/external/external2.h rename to tests/unit/unittest/data/builddependencycollector/external/external2.h diff --git a/tests/unit/unittest/data/includecollector/external/external3.h b/tests/unit/unittest/data/builddependencycollector/external/external3.h similarity index 100% rename from tests/unit/unittest/data/includecollector/external/external3.h rename to tests/unit/unittest/data/builddependencycollector/external/external3.h diff --git a/tests/unit/unittest/data/includecollector/external/indirect_external.h b/tests/unit/unittest/data/builddependencycollector/external/indirect_external.h similarity index 100% rename from tests/unit/unittest/data/includecollector/external/indirect_external.h rename to tests/unit/unittest/data/builddependencycollector/external/indirect_external.h diff --git a/tests/unit/unittest/data/includecollector/external/indirect_external2.h b/tests/unit/unittest/data/builddependencycollector/external/indirect_external2.h similarity index 100% rename from tests/unit/unittest/data/includecollector/external/indirect_external2.h rename to tests/unit/unittest/data/builddependencycollector/external/indirect_external2.h diff --git a/tests/unit/unittest/data/includecollector/project/false.h b/tests/unit/unittest/data/builddependencycollector/project/false.h similarity index 100% rename from tests/unit/unittest/data/includecollector/project/false.h rename to tests/unit/unittest/data/builddependencycollector/project/false.h diff --git a/tests/unit/unittest/data/includecollector/project/faulty.cpp b/tests/unit/unittest/data/builddependencycollector/project/faulty.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/faulty.cpp rename to tests/unit/unittest/data/builddependencycollector/project/faulty.cpp diff --git a/tests/unit/unittest/data/includecollector/project/faulty.h b/tests/unit/unittest/data/builddependencycollector/project/faulty.h similarity index 100% rename from tests/unit/unittest/data/includecollector/project/faulty.h rename to tests/unit/unittest/data/builddependencycollector/project/faulty.h diff --git a/tests/unit/unittest/data/includecollector/project/header1.h b/tests/unit/unittest/data/builddependencycollector/project/header1.h similarity index 100% rename from tests/unit/unittest/data/includecollector/project/header1.h rename to tests/unit/unittest/data/builddependencycollector/project/header1.h diff --git a/tests/unit/unittest/data/includecollector/project/header2.h b/tests/unit/unittest/data/builddependencycollector/project/header2.h similarity index 100% rename from tests/unit/unittest/data/includecollector/project/header2.h rename to tests/unit/unittest/data/builddependencycollector/project/header2.h diff --git a/tests/unit/unittest/data/includecollector/project/if.cpp b/tests/unit/unittest/data/builddependencycollector/project/if.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/if.cpp rename to tests/unit/unittest/data/builddependencycollector/project/if.cpp diff --git a/tests/unit/unittest/data/builddependencycollector/project/macros.h b/tests/unit/unittest/data/builddependencycollector/project/macros.h new file mode 100644 index 00000000000..3b7d254ad87 --- /dev/null +++ b/tests/unit/unittest/data/builddependencycollector/project/macros.h @@ -0,0 +1,11 @@ +#pragma once + +#define DEFINE + +#ifdef IFDEF +#endif + +#if defined(DEFINED) +#endif +DEFINE + diff --git a/tests/unit/unittest/data/includecollector/project/main.cpp b/tests/unit/unittest/data/builddependencycollector/project/main.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/main.cpp rename to tests/unit/unittest/data/builddependencycollector/project/main.cpp diff --git a/tests/unit/unittest/data/includecollector/project/main2.cpp b/tests/unit/unittest/data/builddependencycollector/project/main2.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/main2.cpp rename to tests/unit/unittest/data/builddependencycollector/project/main2.cpp diff --git a/tests/unit/unittest/data/includecollector/project/main3.cpp b/tests/unit/unittest/data/builddependencycollector/project/main3.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/main3.cpp rename to tests/unit/unittest/data/builddependencycollector/project/main3.cpp diff --git a/tests/unit/unittest/data/builddependencycollector/project/main4.cpp b/tests/unit/unittest/data/builddependencycollector/project/main4.cpp new file mode 100644 index 00000000000..ff215f43d77 --- /dev/null +++ b/tests/unit/unittest/data/builddependencycollector/project/main4.cpp @@ -0,0 +1,9 @@ +#include +#include +#include "missingfile.h" +#include "missingfile.h" +#include +#include <../external/external1.h> +#include <../external/external2.h> +#include +#include "macros.h" diff --git a/tests/unit/unittest/data/includecollector/project/missingfile.cpp b/tests/unit/unittest/data/builddependencycollector/project/missingfile.cpp similarity index 100% rename from tests/unit/unittest/data/includecollector/project/missingfile.cpp rename to tests/unit/unittest/data/builddependencycollector/project/missingfile.cpp diff --git a/tests/unit/unittest/data/builddependencycollector/project/missingfile.h b/tests/unit/unittest/data/builddependencycollector/project/missingfile.h new file mode 100644 index 00000000000..1ac1ed43d7c --- /dev/null +++ b/tests/unit/unittest/data/builddependencycollector/project/missingfile.h @@ -0,0 +1,8 @@ +#pragma once + +#include "missing_file.moc" +#include "foo/missing_file.moc" +#include +#include + +#include "external1.h" diff --git a/tests/unit/unittest/data/includecollector/project/true.h b/tests/unit/unittest/data/builddependencycollector/project/true.h similarity index 100% rename from tests/unit/unittest/data/includecollector/project/true.h rename to tests/unit/unittest/data/builddependencycollector/project/true.h diff --git a/tests/unit/unittest/data/includecollector/system/indirect_system.h b/tests/unit/unittest/data/builddependencycollector/system/indirect_system.h similarity index 100% rename from tests/unit/unittest/data/includecollector/system/indirect_system.h rename to tests/unit/unittest/data/builddependencycollector/system/indirect_system.h diff --git a/tests/unit/unittest/data/includecollector/system/indirect_system2.h b/tests/unit/unittest/data/builddependencycollector/system/indirect_system2.h similarity index 100% rename from tests/unit/unittest/data/includecollector/system/indirect_system2.h rename to tests/unit/unittest/data/builddependencycollector/system/indirect_system2.h diff --git a/tests/unit/unittest/data/includecollector/system/system1.h b/tests/unit/unittest/data/builddependencycollector/system/system1.h similarity index 100% rename from tests/unit/unittest/data/includecollector/system/system1.h rename to tests/unit/unittest/data/builddependencycollector/system/system1.h diff --git a/tests/unit/unittest/data/includecollector/system/system2.h b/tests/unit/unittest/data/builddependencycollector/system/system2.h similarity index 100% rename from tests/unit/unittest/data/includecollector/system/system2.h rename to tests/unit/unittest/data/builddependencycollector/system/system2.h diff --git a/tests/unit/unittest/data/includecollector/system/system3.h b/tests/unit/unittest/data/builddependencycollector/system/system3.h similarity index 100% rename from tests/unit/unittest/data/includecollector/system/system3.h rename to tests/unit/unittest/data/builddependencycollector/system/system3.h diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 186858dc86b..be0018ef3d6 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -66,6 +66,10 @@ #include #include +namespace { +ClangBackEnd::FilePathCaching *filePathCache = nullptr; +} + void PrintTo(const Utf8String &text, ::std::ostream *os) { *os << text; @@ -171,7 +175,10 @@ namespace ClangBackEnd { std::ostream &operator<<(std::ostream &out, const FilePathId &id) { - return out << "(" << id.filePathId << ")"; + if (filePathCache) + return out << "(" << id.filePathId << ", " << filePathCache->filePath(id) << ")"; + + return out << id.filePathId; } std::ostream &operator<<(std::ostream &out, const FilePathView &filePathView) @@ -1014,10 +1021,13 @@ std::ostream &operator<<(std::ostream &out, const PchTask &task) std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency) { - return out << "(" - << dependency.includes << ", " - << dependency.topsSystemIncludeIds << ", " - << dependency.topIncludeIds << ")"; + return out << "(\n" + << "includes: " << dependency.includes << ",\n" + << "usedMacros: " << dependency.usedMacros << ",\n" + << "fileStatuses: " << dependency.fileStatuses << ",\n" + << "sourceFiles: " << dependency.sourceFiles << ",\n" + << "sourceDependencies: " << dependency.sourceDependencies << ",\n" + << ")"; } const char *sourceTypeString(SourceType sourceType) @@ -1025,9 +1035,14 @@ const char *sourceTypeString(SourceType sourceType) using ClangBackEnd::SymbolTag; switch (sourceType) { - case SourceType::Any: return "Any"; - case SourceType::TopInclude: return "TopInclude"; - case SourceType::TopSystemInclude: return "TopSystemInclude"; + case SourceType::TopInclude: + return "TopInclude"; + case SourceType::TopSystemInclude: + return "TopSystemInclude"; + case SourceType::SystemInclude: + return "SystemInclude"; + case SourceType::UserInclude: + return "UserInclude"; } return ""; @@ -1131,3 +1146,8 @@ std::ostream &operator<<(std::ostream &out, const Usage &usage) return out << "(" << usage.path << ", " << usage.line << ", " << usage.column <<")"; } } // namespace CppTools + +void setFilePathCache(ClangBackEnd::FilePathCaching *cache) +{ + filePathCache = cache; +} diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index 7eca6cf9a19..fe7e4e3405b 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -173,6 +173,7 @@ class PchCreatorIncludes; class PchTask; class BuildDependency; class SourceEntry; +class FilePathCaching; std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); @@ -289,3 +290,5 @@ class Usage; std::ostream &operator<<(std::ostream &out, const Usage &usage); } // namespace CppTools + +void setFilePathCache(ClangBackEnd::FilePathCaching *filePathCache); diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp deleted file mode 100644 index 8fff80c0b14..00000000000 --- a/tests/unit/unittest/includecollector-test.cpp +++ /dev/null @@ -1,422 +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. -** -****************************************************************************/ - -#include "googletest.h" - -#include -#include -#include - -#include - -#include -#include - -using testing::AllOf; -using testing::Contains; -using testing::Not; -using testing::ElementsAre; -using testing::UnorderedElementsAre; - -using ClangBackEnd::FilePathId; -using ClangBackEnd::FilePathIds; -using ClangBackEnd::FilePathView; -using ClangBackEnd::SourceDependency; -using ClangBackEnd::UsedMacro; - -namespace { - -class IncludeCollector : public ::testing::Test -{ -protected: - void SetUp() - { - collector.addFile(id(TESTDATA_DIR "/includecollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - collector.addFile(id(TESTDATA_DIR "/includecollector/project/main2.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - collector.addUnsavedFiles({{{TESTDATA_DIR, "includecollector/project/generated_file.h"}, "#pragma once", {}}}); - - collector.setExcludedIncludes(excludePaths.clone()); - emptyCollector.setExcludedIncludes(excludePaths.clone()); - } - - FilePathId id(const Utils::SmallStringView &path) const - { - return filePathCache.filePathId(FilePathView{path}); - } - - static off_t fileSize(Utils::SmallStringView filePath) - { - return QFileInfo(QString(filePath)).size(); - } - - static std::time_t lastModified(Utils::SmallStringView filePath) - { - return QFileInfo(QString(filePath)).lastModified().toTime_t(); - } - - ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const - { - return {id(filePath), fileSize(filePath), lastModified(filePath), false}; - } -protected: - Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; - ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; - ClangBackEnd::FilePathCaching filePathCache{database}; - ClangBackEnd::IncludeCollector collector{filePathCache}; - ClangBackEnd::IncludeCollector emptyCollector{filePathCache}; - Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector/project/main.cpp", - TESTDATA_DIR "/includecollector/project/main2.cpp", - TESTDATA_DIR "/includecollector/project/header1.h", - TESTDATA_DIR "/includecollector/project/header2.h", - TESTDATA_DIR "/includecollector/project/generated_file.h"}; -}; - -TEST_F(IncludeCollector, IncludesExternalHeader) -{ - collector.collect(); - - ASSERT_THAT(collector.takeIncludeIds(), - AllOf(Contains(id(TESTDATA_DIR "/includecollector/external/external1.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/external2.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/indirect_external.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/indirect_external2.h")))); -} - -TEST_F(IncludeCollector, DoesNotIncludesInternalHeader) -{ - collector.collect(); - - ASSERT_THAT(collector.takeIncludeIds(), Not(Contains(id(TESTDATA_DIR "/includecollector/project/header1.h")))); -} - -TEST_F(IncludeCollector, NoDuplicate) -{ - collector.collect(); - - ASSERT_THAT(collector.takeIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"), - id(TESTDATA_DIR "/includecollector/external/external2.h"), - id(TESTDATA_DIR "/includecollector/external/external3.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external2.h"))); -} - -TEST_F(IncludeCollector, IncludesAreSorted) -{ - collector.collect(); - - ASSERT_THAT(collector.takeIncludeIds(), - SizeIs(5)); -} - -TEST_F(IncludeCollector, If) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/if.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeIncludeIds(), - ElementsAre(id(TESTDATA_DIR "/includecollector/project/true.h"))); -} - -TEST_F(IncludeCollector, LocalPath) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"), - id(TESTDATA_DIR "/includecollector/external/external2.h"), - id(TESTDATA_DIR "/includecollector/external/external3.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external2.h"))); -} - -TEST_F(IncludeCollector, IgnoreMissingFile) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/missingfile.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external.h"), - id(TESTDATA_DIR "/includecollector/external/indirect_external2.h"))); -} - -TEST_F(IncludeCollector, IncludesOnlyTopExternalHeader) -{ - collector.collect(); - - ASSERT_THAT(collector.takeTopIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"), - id(TESTDATA_DIR "/includecollector/external/external2.h"), - id(TESTDATA_DIR "/includecollector/external/external3.h"))); -} - -TEST_F(IncludeCollector, TopIncludeInIfMacro) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/if.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - emptyCollector.setExcludedIncludes({TESTDATA_DIR "/includecollector/project/if.cpp"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeTopIncludeIds(), - ElementsAre(id(TESTDATA_DIR "/includecollector/project/true.h"))); -} - -TEST_F(IncludeCollector, TopIncludeWithLocalPath) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeTopIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"), - id(TESTDATA_DIR "/includecollector/external/external2.h"), - id(TESTDATA_DIR "/includecollector/external/external3.h"))); -} - -TEST_F(IncludeCollector, TopIncludesIgnoreMissingFile) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/includecollector/project/missingfile.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - emptyCollector.setExcludedIncludes({TESTDATA_DIR "/includecollector/project/missingfile.cpp"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.takeTopIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector/external/external1.h"))); -} - -TEST_F(IncludeCollector, SourceFiles) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.sourceFiles(), - UnorderedElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"), - id(TESTDATA_DIR "/symbolscollector_header1.h"), - id(TESTDATA_DIR "/symbolscollector_header2.h"))); -} - -TEST_F(IncludeCollector, MainFileInSourceFiles) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - ASSERT_THAT(emptyCollector.sourceFiles(), - ElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"))); -} - -TEST_F(IncludeCollector, ResetMainFileInSourceFiles) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - ASSERT_THAT(emptyCollector.sourceFiles(), - ElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"))); -} - -TEST_F(IncludeCollector, DontDuplicateSourceFiles) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - emptyCollector.collect(); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.sourceFiles(), - UnorderedElementsAre(id(TESTDATA_DIR "/symbolscollector_main.cpp"), - id(TESTDATA_DIR "/symbolscollector_header1.h"), - id(TESTDATA_DIR "/symbolscollector_header2.h"))); -} - -TEST_F(IncludeCollector, ClearSourceFiles) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.clear(); - - ASSERT_THAT(emptyCollector.sourceFiles(), IsEmpty()); -} - -TEST_F(IncludeCollector, ClearFileStatus) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - emptyCollector.collect(); - - emptyCollector.clear(); - - ASSERT_THAT(emptyCollector.fileStatuses(), IsEmpty()); -} - -TEST_F(IncludeCollector, ClearUsedMacros) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_defines.h"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - emptyCollector.collect(); - - emptyCollector.clear(); - - ASSERT_THAT(emptyCollector.usedMacros(), IsEmpty()); -} - -TEST_F(IncludeCollector, ClearSourceDependencies) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main2.cpp"), {"cc", "-I" TESTDATA_DIR}); - emptyCollector.collect(); - - emptyCollector.clear(); - - ASSERT_THAT(emptyCollector.sourceDependencies(), IsEmpty()); -} - -TEST_F(IncludeCollector, DontCollectSourceFilesAfterFilesAreCleared) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.clear(); - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.sourceFiles(), IsEmpty()); -} - -TEST_F(IncludeCollector, DontCollectFileStatusAfterFilesAreCleared) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.clear(); - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.fileStatuses(), IsEmpty()); -} - -TEST_F(IncludeCollector, DontCollectUsedMacrosAfterFilesAreCleared) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.clear(); - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.usedMacros(), IsEmpty()); -} - - -TEST_F(IncludeCollector, DontCollectSourceDependenciesAfterFilesAreCleared) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.clear(); - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.sourceDependencies(), IsEmpty()); -} - -TEST_F(IncludeCollector, CollectUsedMacrosWithExternalDefine) -{ - auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); - emptyCollector.addFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(IncludeCollector, CollectUsedMacrosWithoutExternalDefine) -{ - auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); - emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(IncludeCollector, DontCollectHeaderGuards) -{ - auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); - emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.usedMacros(), - Not(Contains(Eq(UsedMacro{"SYMBOLSCOLLECTOR_DEFINES_H", fileId})))); -} - -TEST_F(IncludeCollector, DISABLED_DontCollectDynamicLibraryExports) -{ - auto fileId = id(TESTDATA_DIR "/symbolscollector_defines.h"); - emptyCollector.addFile(fileId, {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.usedMacros(), - Not(Contains(Eq(UsedMacro{"CLASS_EXPORT", fileId})))); -} - -TEST_F(IncludeCollector, CollectFileStatuses) -{ - emptyCollector.addFile(id(TESTDATA_DIR "/symbolscollector_main.cpp"), {"cc", "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system"}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.fileStatuses(), - ElementsAre( - fileStatus(TESTDATA_DIR "/symbolscollector_main.cpp"), - fileStatus(TESTDATA_DIR "/symbolscollector_header1.h"), - fileStatus(TESTDATA_DIR "/symbolscollector_header2.h"))); -} - -TEST_F(IncludeCollector, CollectSourceDependencies) -{ - auto mainFileId = id(TESTDATA_DIR "/symbolscollector_main2.cpp"); - auto header1FileId = id(TESTDATA_DIR "/symbolscollector_header1.h"); - auto header2FileId = id(TESTDATA_DIR "/symbolscollector_header2.h"); - auto header3FileId = id(TESTDATA_DIR "/symbolscollector_header3.h"); - emptyCollector.addFile(mainFileId, {"cc", "-I" TESTDATA_DIR}); - - emptyCollector.collect(); - - ASSERT_THAT(emptyCollector.sourceDependencies(), - UnorderedElementsAre(SourceDependency(mainFileId, header1FileId), - SourceDependency(mainFileId, header3FileId), - SourceDependency(header3FileId, header2FileId), - SourceDependency(header1FileId, header2FileId))); -} - -} diff --git a/tests/unit/unittest/mockbuilddependenciesgenerator.h b/tests/unit/unittest/mockbuilddependencygenerator.h similarity index 90% rename from tests/unit/unittest/mockbuilddependenciesgenerator.h rename to tests/unit/unittest/mockbuilddependencygenerator.h index 832c37f0bf9..91b8a1422d2 100644 --- a/tests/unit/unittest/mockbuilddependenciesgenerator.h +++ b/tests/unit/unittest/mockbuilddependencygenerator.h @@ -27,9 +27,9 @@ #include "googletest.h" -#include +#include -class MockBuildDependenciesGenerator : public ClangBackEnd::BuildDependenciesGeneratorInterface +class MockBuildDependencyGenerator : public ClangBackEnd::BuildDependencyGeneratorInterface { public: MOCK_METHOD1(create, diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 29056203e31..2929f2e3942 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -43,21 +43,33 @@ namespace { +using ClangBackEnd::FilePath; using ClangBackEnd::FilePathId; +using ClangBackEnd::FilePathIds; +using ClangBackEnd::FilePathView; using ClangBackEnd::GeneratedFiles; using ClangBackEnd::IdPaths; using ClangBackEnd::ProjectPartPch; -using ClangBackEnd::V2::ProjectPartContainer; +using ClangBackEnd::SourceEntries; +using ClangBackEnd::SourceEntry; +using ClangBackEnd::SourceType; using ClangBackEnd::V2::FileContainer; -using ClangBackEnd::FilePath; -using ClangBackEnd::FilePathIds; -using ClangBackEnd::FilePathView; +using ClangBackEnd::V2::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))) +{ + const ClangBackEnd::SourceEntry &entry = arg; + return entry.sourceId == sourceId && entry.sourceType == sourceType; +} + class PchCreator: public ::testing::Test { protected: @@ -74,27 +86,27 @@ protected: protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; - FilePath main1Path = TESTDATA_DIR "/includecollector/project/main3.cpp"; - FilePath main2Path = TESTDATA_DIR "/includecollector/project/main2.cpp"; - FilePath header1Path = TESTDATA_DIR "/includecollector/project/header1.h"; - FilePath header2Path = TESTDATA_DIR "/includecollector/project/header2.h"; - Utils::SmallStringView generatedFileName = "includecollector/project/generated_file.h"; - FilePath generatedFilePath = TESTDATA_DIR "/includecollector/project/generated_file.h"; + FilePath main1Path = TESTDATA_DIR "/builddependencycollector/project/main3.cpp"; + FilePath main2Path = TESTDATA_DIR "/builddependencycollector/project/main2.cpp"; + FilePath header1Path = TESTDATA_DIR "/builddependencycollector/project/header1.h"; + FilePath header2Path = TESTDATA_DIR "/builddependencycollector/project/header2.h"; + Utils::SmallStringView generatedFileName = "builddependencycollector/project/generated_file.h"; + FilePath generatedFilePath = TESTDATA_DIR "/builddependencycollector/project/generated_file.h"; TestEnvironment environment; FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}}; NiceMock mockPchManagerClient; NiceMock mockClangPathWatcher; ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient, mockClangPathWatcher}; ProjectPartContainer projectPart1{"project1", - {"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system", "-Wno-pragma-once-outside-header"}, + {"-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"}}, - {TESTDATA_DIR "/includecollector/external", TESTDATA_DIR "/includecollector/project"}, + {TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"}, {id(header1Path)}, {id(main1Path)}}; ProjectPartContainer projectPart2{"project2", - {"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-x", "c++-header", "-Wno-pragma-once-outside-header"}, + {"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-x", "c++-header", "-Wno-pragma-once-outside-header"}, {{"DEFINE", "1"}}, - {TESTDATA_DIR "/includecollector/external", TESTDATA_DIR "/includecollector/project"}, + {TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"}, {id(header2Path)}, {id(main2Path)}}; }; @@ -112,7 +124,7 @@ TEST_F(PchCreator, CreateProjectPartCommandLine) { auto commandLine = creator.generateProjectPartCommandLine(projectPart1); - ASSERT_THAT(commandLine, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/includecollector/external", "-I", TESTDATA_DIR "/includecollector/project", "-isystem", TESTDATA_DIR "/includecollector/system", "-Wno-pragma-once-outside-header")); + 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) @@ -135,37 +147,45 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludes) auto includeIds = creator.generateProjectPartPchIncludes(projectPart1); - ASSERT_THAT(includeIds, - AllOf( - Field(&PchCreatorIncludes::includeIds, - AllOf(Contains(id(TESTDATA_DIR "/includecollector/external/external1.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/external2.h")), - Contains(id(TESTDATA_DIR "/includecollector/project/header2.h")), - Contains(id(TESTDATA_DIR "/includecollector/system/system1.h")))), - Field(&PchCreatorIncludes::topSystemIncludeIds, - AllOf(Contains(id(TESTDATA_DIR "/includecollector/system/system1.h")), - Not(Contains(id(TESTDATA_DIR "/includecollector/system/indirect_system.h"))))), - Field(&PchCreatorIncludes::topIncludeIds, - AllOf(Contains(id(TESTDATA_DIR "/includecollector/external/external1.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/external2.h")))))); + ASSERT_THAT( + includeIds, + AllOf( + Contains(HasIdAndType( + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + SourceType::TopInclude)), + 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::TopInclude)), + Contains(HasIdAndType( + id(TESTDATA_DIR + "/builddependencycollector/external/external2.h"), + SourceType::TopInclude)))); } TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent) { auto includes = creator.generateProjectPartPchIncludes(projectPart1); - auto content = creator.generatePchIncludeFileContent(includes.topIncludeIds); + auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes)); ASSERT_THAT(std::string(content), - AllOf(HasSubstr("#include \"" TESTDATA_DIR "/includecollector/project/header2.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/includecollector/external/external1.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/includecollector/external/external2.h\"\n"))); + AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"), + HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external1.h\"\n"), + HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n"))); } TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile) { auto includes = creator.generateProjectPartPchIncludes(projectPart1); - auto content = creator.generatePchIncludeFileContent(includes.topIncludeIds); + auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes)); auto pchIncludeFilePath = creator.generateProjectPathPchHeaderFilePath(projectPart1); auto file = creator.generateFileWithContent(pchIncludeFilePath, content); file->open(QIODevice::ReadOnly); @@ -173,9 +193,9 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile) auto fileContent = file->readAll(); ASSERT_THAT(fileContent.toStdString(), - AllOf(HasSubstr("#include \"" TESTDATA_DIR "/includecollector/project/header2.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/includecollector/external/external1.h\"\n"), - HasSubstr("#include \"" TESTDATA_DIR "/includecollector/external/external2.h\"\n"))); + AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"), + HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external1.h\"\n"), + HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n"))); } TEST_F(PchCreator, CreateProjectPartPchCompilerArguments) @@ -235,9 +255,9 @@ TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts) ASSERT_THAT(creator.takeProjectIncludes(), AllOf(Field(&IdPaths::id, "project1"), - Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/includecollector/project/header2.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/external1.h")), - Contains(id(TESTDATA_DIR "/includecollector/external/external2.h")))))); + 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) @@ -276,7 +296,7 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesNoPchForProjectPart {{"DEFINE", "1"}}, {"/includes"}, {}, - {id(TESTDATA_DIR "/includecollector/project/faulty.cpp")}}; + {id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")}}; creator.generatePch(faultyProjectPart); @@ -290,15 +310,14 @@ TEST_F(PchCreator, CreateProjectPartSourcesContent) { auto content = creator.generateProjectPartSourcesContent(projectPart1); - ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/includecollector/project/main3.cpp\"\n")); + 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 "/includecollector/project/main3.cpp\"\n")); + ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/builddependencycollector/project/main3.cpp\"\n")); } - } diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 443d6a37b20..153c71b510f 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -74,10 +74,10 @@ protected: NiceMock mockPchManagerClient; SmallString projectPartId1 = "project1"; SmallString projectPartId2 = "project2"; - PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp"; - PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp"; - PathString header1Path = TESTDATA_DIR "/includecollector_header1.h"; - PathString header2Path = TESTDATA_DIR "/includecollector_header2.h"; + PathString main1Path = TESTDATA_DIR "/BuildDependencyCollector_main3.cpp"; + PathString main2Path = TESTDATA_DIR "/BuildDependencyCollector_main2.cpp"; + 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"}, diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp index 248803cc4b0..dcc0e6207ef 100644 --- a/tests/unit/unittest/pchtaskgenerator-test.cpp +++ b/tests/unit/unittest/pchtaskgenerator-test.cpp @@ -49,8 +49,8 @@ protected: {"/yi"}, {{1, 1}}, {{1, 2}}}; - SourceEntries firstSources{{1, SourceType::Any, 1}, {2, SourceType::Any, 1}, {10, SourceType::Any, 1}}; - BuildDependency buildDependency{firstSources, {}, {}, {}}; + SourceEntries firstSources{{1, SourceType::UserInclude, 1}, {2, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}}; + BuildDependency buildDependency{firstSources, {}}; }; TEST_F(PchTaskGenerator, Create) diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index fef72b47e43..8cd1ab8ef31 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -162,7 +162,7 @@ protected: ClangBackEnd::FilePathId main2PathId{filePathId(TESTDATA_DIR "/symbolindexer_main2.cpp")}; ClangBackEnd::FilePathId header2PathId{filePathId(TESTDATA_DIR "/symbolindexer_header1.h")}; ClangBackEnd::FilePathId header1PathId{filePathId(TESTDATA_DIR "/symbolindexer_header2.h")}; - PathString generatedFileName = "includecollector_generated_file.h"; + PathString generatedFileName = "BuildDependencyCollector_generated_file.h"; ClangBackEnd::FilePathId generatedFilePathId21; ProjectPartContainer projectPart1{"project1", {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index c8ecdb66e53..3c17ef126ad 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -106,7 +106,8 @@ SOURCES += \ pchtaskgenerator-test.cpp \ compilationdatabaseutils-test.cpp \ builddependenciesprovider-test.cpp \ - builddependenciesstorage-test.cpp + builddependenciesstorage-test.cpp \ + builddependencycollector-test.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -172,7 +173,6 @@ SOURCES += \ clangqueryprojectfindfilter-test.cpp \ clangquery-test.cpp \ gtest-clang-printing.cpp \ - includecollector-test.cpp \ pchcreator-test.cpp \ refactoringclientserverinprocess-test.cpp \ refactoringclient-test.cpp \ @@ -252,8 +252,8 @@ HEADERS += \ mocktaskscheduler.h \ mockbuilddependenciesprovider.h \ mockmodifiedtimechecker.h \ - mockbuilddependenciesgenerator.h \ - mockbuilddependenciesstorage.h + mockbuilddependenciesstorage.h \ + mockbuilddependencygenerator.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \