diff options
author | Marco Bubke <marco.bubke@theqtcompany.com> | 2015-05-21 11:56:51 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2015-05-21 10:06:27 +0000 |
commit | b056d4ef7a56ce31750f6fd552a1983954a389d8 (patch) | |
tree | df979986aac388843e12dffa5280a8d355f9944f | |
parent | 5b036bf32bdd3517bd6935f102afb37d2b252835 (diff) | |
download | qt-creator-b056d4ef7a56ce31750f6fd552a1983954a389d8.tar.gz |
improve removal of translation units and projects
Change-Id: I0f81cd3e9d0fdbecc1c0d082fc5b2cb9aa6645a4
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
11 files changed, 182 insertions, 35 deletions
diff --git a/src/libs/sqlite/source/utf8stringvector.h b/src/libs/sqlite/source/utf8stringvector.h index a8c60da2fc..0745dc000d 100644 --- a/src/libs/sqlite/source/utf8stringvector.h +++ b/src/libs/sqlite/source/utf8stringvector.h @@ -53,10 +53,24 @@ public: static void registerType(); + inline bool removeFast(const Utf8String &valueToBeRemoved); + protected: int totalByteSize() const; }; +bool Utf8StringVector::removeFast(const Utf8String &valueToBeRemoved) +{ + auto position = std::remove(begin(), end(), valueToBeRemoved); + + bool hasEntry = position != end(); + + erase(position, end()); + + return hasEntry; +} + + SQLITE_EXPORT QDebug operator<<(QDebug debug, const Utf8StringVector &textVector); SQLITE_EXPORT void PrintTo(const Utf8StringVector &textVector, ::std::ostream* os); diff --git a/src/tools/codemodelbackend/ipcsource/projects.cpp b/src/tools/codemodelbackend/ipcsource/projects.cpp index 1887f6bfd0..807f80fa25 100644 --- a/src/tools/codemodelbackend/ipcsource/projects.cpp +++ b/src/tools/codemodelbackend/ipcsource/projects.cpp @@ -46,22 +46,27 @@ void Projects::remove(const Utf8StringVector &projectFilePaths) { Utf8StringVector processedProjectFilePaths = projectFilePaths; - auto removeBeginIterator = std::remove_if(projects.begin(), projects.end(), [&processedProjectFilePaths] (const Project &project) { - return processedProjectFilePaths.removeOne(project.projectFilePath()); + auto removeBeginIterator = std::remove_if(projects_.begin(), projects_.end(), [&processedProjectFilePaths] (const Project &project) { + return processedProjectFilePaths.removeFast(project.projectFilePath()); }); + std::for_each(removeBeginIterator, projects_.end(), [](Project &project) { project.clearProjectFilePath(); }); + projects_.erase(removeBeginIterator, projects_.end()); + if (!processedProjectFilePaths.isEmpty()) throw ProjectDoesNotExistException(processedProjectFilePaths); +} - std::for_each(removeBeginIterator, projects.end(), [](Project &project) { project.clearProjectFilePath(); }); - projects.erase(removeBeginIterator, projects.end()); +bool Projects::hasProject(const Utf8String &projectFilePath) const +{ + return findProject(projectFilePath) != projects_.cend(); } const Project &Projects::project(const Utf8String &projectFilePath) const { const auto findIterator = findProject(projectFilePath); - if (findIterator == projects.cend()) + if (findIterator == projects_.cend()) throw ProjectDoesNotExistException({projectFilePath}); return *findIterator; @@ -69,23 +74,28 @@ const Project &Projects::project(const Utf8String &projectFilePath) const std::vector<Project>::const_iterator Projects::findProject(const Utf8String &projectFilePath) const { - return std::find_if(projects.begin(), projects.end(), [projectFilePath] (const Project &project) { + return std::find_if(projects_.begin(), projects_.end(), [projectFilePath] (const Project &project) { return project.projectFilePath() == projectFilePath; }); } std::vector<Project>::iterator Projects::findProject(const Utf8String &projectFilePath) { - return std::find_if(projects.begin(), projects.end(), [projectFilePath] (const Project &project) { + return std::find_if(projects_.begin(), projects_.end(), [projectFilePath] (const Project &project) { return project.projectFilePath() == projectFilePath; }); } +const std::vector<Project> &Projects::projects() const +{ + return projects_; +} + void Projects::createOrUpdateProject(const ProjectContainer &projectContainer) { auto findIterator = findProject(projectContainer.filePath()); - if (findIterator == projects.cend()) - projects.push_back(Project(projectContainer)); + if (findIterator == projects_.cend()) + projects_.push_back(Project(projectContainer)); else findIterator->setArguments(projectContainer.arguments()); } diff --git a/src/tools/codemodelbackend/ipcsource/projects.h b/src/tools/codemodelbackend/ipcsource/projects.h index dab6feb0a5..7b2b262532 100644 --- a/src/tools/codemodelbackend/ipcsource/projects.h +++ b/src/tools/codemodelbackend/ipcsource/projects.h @@ -45,16 +45,20 @@ public: void createOrUpdate(const QVector<ProjectContainer> &projectConainers); void remove(const Utf8StringVector &projectFilePaths); + bool hasProject(const Utf8String &projectFilePath) const; + const Project &project(const Utf8String &projectFilePath) const; std::vector<Project>::const_iterator findProject(const Utf8String &projectFilePath) const; std::vector<Project>::iterator findProject(const Utf8String &projectFilePath); + const std::vector<Project> &projects() const; + private: void createOrUpdateProject(const ProjectContainer &projectConainer); private: - std::vector<Project> projects; + std::vector<Project> projects_; }; } // namespace CodeModelbackEnd diff --git a/src/tools/codemodelbackend/ipcsource/translationunit.cpp b/src/tools/codemodelbackend/ipcsource/translationunit.cpp index be09145c12..b8f9b7ca07 100644 --- a/src/tools/codemodelbackend/ipcsource/translationunit.cpp +++ b/src/tools/codemodelbackend/ipcsource/translationunit.cpp @@ -219,5 +219,10 @@ TranslationUnit &TranslationUnit::operator =(TranslationUnit &&other) return *this; } +bool operator ==(const TranslationUnit &first, const TranslationUnit &second) +{ + return first.filePath() == second.filePath() && first.projectFilePath() == second.projectFilePath(); +} + } // namespace CodeModelBackEnd diff --git a/src/tools/codemodelbackend/ipcsource/translationunit.h b/src/tools/codemodelbackend/ipcsource/translationunit.h index c504c3b2c3..2127c34018 100644 --- a/src/tools/codemodelbackend/ipcsource/translationunit.h +++ b/src/tools/codemodelbackend/ipcsource/translationunit.h @@ -90,6 +90,8 @@ private: mutable std::shared_ptr<TranslationUnitData> d; }; +bool operator ==(const TranslationUnit &first, const TranslationUnit &second); + } // namespace CodeModelBackEnd #endif // CODEMODELBACKEND_TRANSLATIONUNIT_H diff --git a/src/tools/codemodelbackend/ipcsource/translationunits.cpp b/src/tools/codemodelbackend/ipcsource/translationunits.cpp index 156165488c..2e9c12cfc8 100644 --- a/src/tools/codemodelbackend/ipcsource/translationunits.cpp +++ b/src/tools/codemodelbackend/ipcsource/translationunits.cpp @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal @@ -32,9 +32,21 @@ #include <projects.h> #include <translationunitdoesnotexistsexception.h> +#include <projectdoesnotexistsexception.h> namespace CodeModelBackEnd { +bool operator ==(const FileContainer &fileContainer, const TranslationUnit &translationUnit) +{ + return fileContainer.filePath() == translationUnit.filePath() && fileContainer.projectFilePath() == translationUnit.projectFilePath(); +} + +bool operator ==(const TranslationUnit &translationUnit, const FileContainer &fileContainer) +{ + return fileContainer == translationUnit; +} + + TranslationUnits::TranslationUnits(Projects &projects, UnsavedFiles &unsavedFiles) : projects(projects), unsavedFiles(unsavedFiles) @@ -47,24 +59,33 @@ void TranslationUnits::createOrUpdate(const QVector<FileContainer> &fileContaine createOrUpdateTranslationUnit(fileContainer); } +static bool removeFromFileContainer(QVector<FileContainer> &fileContainers, const TranslationUnit &translationUnit) +{ + auto position = std::remove(fileContainers.begin(), fileContainers.end(), translationUnit); + + bool entryIsRemoved = position != fileContainers.end(); + + fileContainers.erase(position, fileContainers.end()); + + return entryIsRemoved; +} + + void TranslationUnits::remove(const QVector<FileContainer> &fileContainers) { - auto lastRemoveBeginIterator = translationUnits.end(); + checkIfProjectsExists(fileContainers); - for (const FileContainer &fileContainer : fileContainers) { - checkIfProjectExists(fileContainer.projectFilePath()); + QVector<FileContainer> processedFileContainers = fileContainers; - auto removeBeginIterator = std::remove_if(translationUnits.begin(), lastRemoveBeginIterator, [fileContainer] (const TranslationUnit &translationUnit) { - return fileContainer.filePath() == translationUnit.filePath() && fileContainer.projectFilePath() == translationUnit.projectFilePath(); - }); + auto removeBeginIterator = std::remove_if(translationUnits_.begin(), translationUnits_.end(), [&processedFileContainers] (const TranslationUnit &translationUnit) { + return removeFromFileContainer(processedFileContainers, translationUnit); + }); - if (removeBeginIterator == lastRemoveBeginIterator) - throw TranslationUnitDoesNotExistException(fileContainer); + translationUnits_.erase(removeBeginIterator, translationUnits_.end()); - lastRemoveBeginIterator = removeBeginIterator; - } + if (!processedFileContainers.isEmpty()) + throw TranslationUnitDoesNotExistException(processedFileContainers.first()); - translationUnits.erase(lastRemoveBeginIterator, translationUnits.end()); } const TranslationUnit &TranslationUnits::translationUnit(const Utf8String &filePath, const Utf8String &projectFilePath) const @@ -73,36 +94,52 @@ const TranslationUnit &TranslationUnits::translationUnit(const Utf8String &fileP auto findIterator = findTranslationUnit(filePath, projectFilePath); - if (findIterator == translationUnits.end()) + if (findIterator == translationUnits_.end()) throw TranslationUnitDoesNotExistException(FileContainer(filePath, projectFilePath)); return *findIterator; } +const std::vector<TranslationUnit> &TranslationUnits::translationUnits() const +{ + return translationUnits_; +} + void TranslationUnits::createOrUpdateTranslationUnit(const FileContainer &fileContainer) { auto findIterator = findTranslationUnit(fileContainer); - if (findIterator == translationUnits.end()) - translationUnits.push_back(TranslationUnit(fileContainer.filePath(), unsavedFiles, projects.project(fileContainer.projectFilePath()))); + if (findIterator == translationUnits_.end()) + translationUnits_.push_back(TranslationUnit(fileContainer.filePath(), unsavedFiles, projects.project(fileContainer.projectFilePath()))); } std::vector<TranslationUnit>::iterator TranslationUnits::findTranslationUnit(const FileContainer &fileContainer) { - return std::find_if(translationUnits.begin(), translationUnits.end(), [fileContainer] (const TranslationUnit &translationUnit) { - return fileContainer.filePath() == translationUnit.filePath() && fileContainer.projectFilePath() == translationUnit.projectFilePath(); - }); + return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer); } std::vector<TranslationUnit>::const_iterator TranslationUnits::findTranslationUnit(const Utf8String &filePath, const Utf8String &projectFilePath) const { - return std::find_if(translationUnits.begin(), translationUnits.end(), [filePath, projectFilePath] (const TranslationUnit &translationUnit) { - return filePath == translationUnit.filePath() && projectFilePath == translationUnit.projectFilePath(); - }); + FileContainer fileContainer(filePath, projectFilePath); + return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer); } -void TranslationUnits::checkIfProjectExists(const Utf8String &projectFilePath) const +void TranslationUnits::checkIfProjectExists(const Utf8String &projectFileName) const { - projects.project(projectFilePath); + projects.project(projectFileName); +} + +void TranslationUnits::checkIfProjectsExists(const QVector<FileContainer> &fileContainers) const +{ + Utf8StringVector notExistingProjects; + + for (const FileContainer &fileContainer : fileContainers) { + if (!projects.hasProject(fileContainer.projectFilePath())) + notExistingProjects.push_back(fileContainer.projectFilePath()); + } + + if (!notExistingProjects.isEmpty()) + throw ProjectDoesNotExistException(notExistingProjects); + } } // namespace CodeModelBackEnd diff --git a/src/tools/codemodelbackend/ipcsource/translationunits.h b/src/tools/codemodelbackend/ipcsource/translationunits.h index 3d693dd44c..eb370422ae 100644 --- a/src/tools/codemodelbackend/ipcsource/translationunits.h +++ b/src/tools/codemodelbackend/ipcsource/translationunits.h @@ -53,14 +53,18 @@ public: const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectFilePath) const; + const std::vector<TranslationUnit> &translationUnits() const; + private: void createOrUpdateTranslationUnit(const FileContainer &fileContainer); std::vector<TranslationUnit>::iterator findTranslationUnit(const FileContainer &fileContainer); std::vector<TranslationUnit>::const_iterator findTranslationUnit(const Utf8String &filePath, const Utf8String &projectFilePath) const; - void checkIfProjectExists(const Utf8String &projectFilePath) const; + void checkIfProjectExists(const Utf8String &projectFileName) const; + void checkIfProjectsExists(const QVector<FileContainer> &fileContainers) const; + private: - std::vector<TranslationUnit> translationUnits; + std::vector<TranslationUnit> translationUnits_; Projects &projects; UnsavedFiles &unsavedFiles; }; diff --git a/tests/unit/codemodelbackend/unittest/projecttest.cpp b/tests/unit/codemodelbackend/unittest/projecttest.cpp index 3473f70d4d..0db7386f23 100644 --- a/tests/unit/codemodelbackend/unittest/projecttest.cpp +++ b/tests/unit/codemodelbackend/unittest/projecttest.cpp @@ -45,6 +45,7 @@ using testing::StrEq; using testing::Pointwise; using testing::Contains; using testing::Gt; +using testing::Not; namespace { @@ -149,4 +150,36 @@ TEST(Project, ProjectFilePathIsEmptyfterRemoving) ASSERT_TRUE(project.projectFilePath().isEmpty()); } + +TEST(Project, ThrowsForNotExistingProjectButRemovesAllExistingProject) +{ + CodeModelBackEnd::ProjectContainer projectContainer(Utf8StringLiteral("pathToProject.pro")); + CodeModelBackEnd::Projects projects; + projects.createOrUpdate({projectContainer}); + CodeModelBackEnd::Project project = *projects.findProject(Utf8StringLiteral("pathToProject.pro")); + + EXPECT_THROW(projects.remove({Utf8StringLiteral("doesnotexist.pro"), projectContainer.filePath()}), CodeModelBackEnd::ProjectDoesNotExistException); + + ASSERT_THAT(projects.projects(), Not(Contains(project))); +} + +TEST(Project, HasProject) +{ + CodeModelBackEnd::ProjectContainer projectContainer(Utf8StringLiteral("pathToProject.pro")); + CodeModelBackEnd::Projects projects; + projects.createOrUpdate({projectContainer}); + + ASSERT_TRUE(projects.hasProject(projectContainer.filePath())); +} + +TEST(Project, DoNotHasProject) +{ + CodeModelBackEnd::ProjectContainer projectContainer(Utf8StringLiteral("pathToProject.pro")); + CodeModelBackEnd::Projects projects; + projects.createOrUpdate({projectContainer}); + + ASSERT_FALSE(projects.hasProject(Utf8StringLiteral("doesnotexist.pro"))); +} + + } diff --git a/tests/unit/codemodelbackend/unittest/translationunitstest.cpp b/tests/unit/codemodelbackend/unittest/translationunitstest.cpp index 3e9e94cc79..04e1732b40 100644 --- a/tests/unit/codemodelbackend/unittest/translationunitstest.cpp +++ b/tests/unit/codemodelbackend/unittest/translationunitstest.cpp @@ -54,6 +54,8 @@ using CodeModelBackEnd::Project; using testing::IsNull; using testing::NotNull; using testing::Gt; +using testing::Not; +using testing::Contains; namespace { @@ -148,6 +150,18 @@ TEST_F(TranslationUnits, Remove) CodeModelBackEnd::TranslationUnitDoesNotExistException); } +TEST_F(TranslationUnits, RemoveAllValidIfExceptionIsThrown) +{ + CodeModelBackEnd::FileContainer fileContainer(filePath, projectFilePath); + translationUnits.createOrUpdate({fileContainer}); + + ASSERT_THROW(translationUnits.remove({CodeModelBackEnd::FileContainer(Utf8StringLiteral("dontextist.pro"), projectFilePath), fileContainer}), + CodeModelBackEnd::TranslationUnitDoesNotExistException); + + ASSERT_THAT(translationUnits.translationUnits(), + Not(Contains(TranslationUnit(filePath, unsavedFiles, projects.project(projectFilePath))))); +} + } diff --git a/tests/unit/codemodelbackend/unittest/translationunittest.cpp b/tests/unit/codemodelbackend/unittest/translationunittest.cpp index a79c23c471..b6158632a8 100644 --- a/tests/unit/codemodelbackend/unittest/translationunittest.cpp +++ b/tests/unit/codemodelbackend/unittest/translationunittest.cpp @@ -131,6 +131,7 @@ TEST(TranslationUnit, TimeStampIsUpdatedAsNewCxTranslationUnitIsGenerated) ASSERT_THAT(translationUnit.lastChangeTimePoint(), Gt(lastChangeTimePoint)); } + //TEST(TranslationUnit, ThrowParseErrorForWrongArguments) //{ // Project project(Utf8StringLiteral("/path/to/projectfile")); diff --git a/tests/unit/codemodelbackend/unittest/utf8test.cpp b/tests/unit/codemodelbackend/unittest/utf8test.cpp index 19b33fcbc0..6ca4aa7ea3 100644 --- a/tests/unit/codemodelbackend/unittest/utf8test.cpp +++ b/tests/unit/codemodelbackend/unittest/utf8test.cpp @@ -219,3 +219,26 @@ TEST(Utf8, CompareCharPointer) ASSERT_TRUE(text == "foo"); ASSERT_FALSE(text == "foo2"); } + +TEST(Utf8, RemoveFastFromVectorFailed) +{ + Utf8StringVector values({Utf8StringLiteral("a"), + Utf8StringLiteral("b"), + Utf8StringLiteral("c"), + Utf8StringLiteral("d")}); + + ASSERT_FALSE(values.removeFast(Utf8StringLiteral("e"))); +} + +TEST(Utf8, RemoveFastFromVector) +{ + Utf8StringVector values({Utf8StringLiteral("a"), + Utf8StringLiteral("b"), + Utf8StringLiteral("c"), + Utf8StringLiteral("d")}); + + bool removed = values.removeFast(Utf8StringLiteral("b")); + + ASSERT_TRUE(removed); + ASSERT_THAT(values, Not(Contains(Utf8StringLiteral("b")))); +} |