diff options
| author | Marco Bubke <marco.bubke@theqtcompany.com> | 2015-04-15 18:02:37 +0200 |
|---|---|---|
| committer | Marco Bubke <marco.bubke@theqtcompany.com> | 2015-04-20 11:32:29 +0000 |
| commit | f49cf4892e47b50adf40826e6f4fb9ece77b4c74 (patch) | |
| tree | 50768836969e27fe304a4638577e32c6905127d5 | |
| parent | 75be3e0f54fac9790fc8e2974735e9208dc9e007 (diff) | |
| download | qt-creator-f49cf4892e47b50adf40826e6f4fb9ece77b4c74.tar.gz | |
Add unsaved files
Change-Id: I18125404b37ce4ebc35d0e94ee491da50c10b9cf
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
8 files changed, 337 insertions, 3 deletions
diff --git a/src/libs/sqlite/source/utf8string.cpp b/src/libs/sqlite/source/utf8string.cpp index bb6b745f89..4ff55a66bd 100644 --- a/src/libs/sqlite/source/utf8string.cpp +++ b/src/libs/sqlite/source/utf8string.cpp @@ -198,6 +198,10 @@ bool operator ==(const Utf8String &first, const Utf8String &second) return first.byteArray == second.byteArray; } +bool operator ==(const Utf8String &first, const char *second) +{ + return first.byteArray == second; +} bool operator <(const Utf8String &first, const Utf8String &second) { diff --git a/src/libs/sqlite/source/utf8string.h b/src/libs/sqlite/source/utf8string.h index bcb33c1be1..960f007148 100644 --- a/src/libs/sqlite/source/utf8string.h +++ b/src/libs/sqlite/source/utf8string.h @@ -47,6 +47,7 @@ class SQLITE_EXPORT Utf8String friend SQLITE_EXPORT bool operator !=(const Utf8String &first, const Utf8String &second); friend SQLITE_EXPORT bool operator ==(const Utf8String &first, const Utf8String &second); + friend SQLITE_EXPORT bool operator ==(const Utf8String &first, const char *second); friend SQLITE_EXPORT bool operator <(const Utf8String &first, const Utf8String &second); friend SQLITE_EXPORT QDataStream &operator<<(QDataStream &datastream, const Utf8String &text); @@ -103,6 +104,7 @@ SQLITE_EXPORT const Utf8String operator +(const Utf8String &first, const Utf8Str SQLITE_EXPORT bool operator !=(const Utf8String &first, const Utf8String &second); SQLITE_EXPORT bool operator ==(const Utf8String &first, const Utf8String &second); +SQLITE_EXPORT bool operator ==(const Utf8String &first, const char *second); SQLITE_EXPORT bool operator <(const Utf8String &first, const Utf8String &second); SQLITE_EXPORT QDataStream &operator<<(QDataStream &datastream, const Utf8String &text); diff --git a/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri b/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri index 2df7cbad5f..f3193e08e1 100644 --- a/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri +++ b/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri @@ -9,7 +9,8 @@ HEADERS += clangipcserver.h \ $$PWD/translationunitfilenotexits.h \ $$PWD/codecompletefailedexception.h \ $$PWD/clangcodecompleteresults.h \ - $$PWD/codecompletionsextractor.h + $$PWD/codecompletionsextractor.h \ + $$PWD/unsavedfiles.h SOURCES += clangipcserver.cpp \ codecompleter.cpp \ @@ -19,4 +20,5 @@ SOURCES += clangipcserver.cpp \ $$PWD/translationunitfilenotexits.cpp \ $$PWD/codecompletefailedexception.cpp \ $$PWD/clangcodecompleteresults.cpp \ - $$PWD/codecompletionsextractor.cpp + $$PWD/codecompletionsextractor.cpp \ + $$PWD/unsavedfiles.cpp diff --git a/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp b/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp new file mode 100644 index 0000000000..f6c66f00d2 --- /dev/null +++ b/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "unsavedfiles.h" + + +#include <cstring> + +namespace CodeModelBackEnd { + +void UnsavedFiles::update(const QVector<FileContainer> &fileContainers) +{ + for (const FileContainer &fileContainer : fileContainers) + updateCXUnsavedFileWithFileContainer(fileContainer); +} + +void UnsavedFiles::clear() +{ + for (const CXUnsavedFile &cxUnsavedFile : cxUnsavedFiles_) + deleteCXUnsavedFile(cxUnsavedFile); + + cxUnsavedFiles_.clear(); +} + +int UnsavedFiles::unsavedFilesCount() const +{ + return cxUnsavedFiles_.size(); +} + +CXUnsavedFile *UnsavedFiles::cxUnsavedFiles() const +{ + return cxUnsavedFiles_.data(); +} + +const std::vector<CXUnsavedFile> &UnsavedFiles::cxUnsavedFileVector() const +{ + return cxUnsavedFiles_; +} + +const CXUnsavedFile UnsavedFiles::createCxUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent) +{ + char *cxUnsavedFilePath = new char[filePath.byteSize() + 1]; + char *cxUnsavedFileContent = new char[fileContent.byteSize() + 1]; + + std::memcpy(cxUnsavedFilePath, filePath.constData(), filePath.byteSize() + 1); + std::memcpy(cxUnsavedFileContent, fileContent.constData(), fileContent.byteSize() + 1); + + return CXUnsavedFile { cxUnsavedFilePath, cxUnsavedFileContent, ulong(fileContent.byteSize())}; +} + +void UnsavedFiles::deleteCXUnsavedFile(const CXUnsavedFile &cxUnsavedFile) +{ + delete [] cxUnsavedFile.Contents; + delete [] cxUnsavedFile.Filename; +} + +void UnsavedFiles::updateCXUnsavedFileWithFileContainer(const FileContainer &fileContainer) +{ + if (fileContainer.hasUnsavedFileContent()) { + addOrUpdateCXUnsavedFile(fileContainer); + } else { + removeCXUnsavedFile(fileContainer); + } +} + +void UnsavedFiles::removeCXUnsavedFile(const FileContainer &fileContainer) +{ + const Utf8String filePath = fileContainer.filePath(); + auto isSameFile = [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; }; + + cxUnsavedFiles_.erase(std::remove_if(cxUnsavedFiles_.begin(), cxUnsavedFiles_.end(), isSameFile), cxUnsavedFiles_.end()); +} + +void UnsavedFiles::addOrUpdateCXUnsavedFile(const FileContainer &fileContainer) +{ + const Utf8String filePath = fileContainer.filePath(); + const Utf8String fileContent = fileContainer.unsavedFileContent(); + auto isSameFile = [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; }; + + auto cxUnsavedFileIterator = std::find_if(cxUnsavedFiles_.begin(), cxUnsavedFiles_.end(), isSameFile); + if (cxUnsavedFileIterator == cxUnsavedFiles_.end()) + cxUnsavedFiles_.push_back(createCxUnsavedFile(filePath, fileContent)); + else { + deleteCXUnsavedFile(*cxUnsavedFileIterator); + *cxUnsavedFileIterator = createCxUnsavedFile(filePath, fileContent); + } +} + + +} // namespace CodeModelBackEnd + diff --git a/src/tools/codemodelbackend/ipcsource/unsavedfiles.h b/src/tools/codemodelbackend/ipcsource/unsavedfiles.h new file mode 100644 index 0000000000..ff49d24667 --- /dev/null +++ b/src/tools/codemodelbackend/ipcsource/unsavedfiles.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CODEMODELBACKEND_UNSAVEDFILES_H +#define CODEMODELBACKEND_UNSAVEDFILES_H + +#include <filecontainer.h> + +#include <vector> +#include <QVector> + +#include <clang-c/Index.h> + +namespace CodeModelBackEnd { + +class UnsavedFiles +{ +public: + void update(const QVector<FileContainer> &fileContainers); + void clear(); + + int unsavedFilesCount() const; + + CXUnsavedFile *cxUnsavedFiles() const; + const std::vector<CXUnsavedFile> &cxUnsavedFileVector() const; + +private: + const CXUnsavedFile createCxUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent); + void deleteCXUnsavedFile(const CXUnsavedFile &cxUnsavedFile); + void updateCXUnsavedFileWithFileContainer(const FileContainer &fileContainer); + void removeCXUnsavedFile(const FileContainer &fileContainer); + void addOrUpdateCXUnsavedFile(const FileContainer &fileContainer); + +private: + mutable std::vector<CXUnsavedFile> cxUnsavedFiles_; +}; + +} // namespace CodeModelBackEnd + +#endif // CODEMODELBACKEND_UNSAVEDFILES_H diff --git a/tests/unit/codemodelbackend/unittest/unittest.pro b/tests/unit/codemodelbackend/unittest/unittest.pro index 3f5e085bb0..b7eb5f9981 100644 --- a/tests/unit/codemodelbackend/unittest/unittest.pro +++ b/tests/unit/codemodelbackend/unittest/unittest.pro @@ -53,7 +53,8 @@ SOURCES += main.cpp \ clangstringtest.cpp \ translationunittest.cpp \ clangcodecompleteresultstest.cpp \ - codecompletionsextractortest.cpp + codecompletionsextractortest.cpp \ + unsavedfilestest.cpp HEADERS += \ gtest-qt-printing.h \ diff --git a/tests/unit/codemodelbackend/unittest/unsavedfilestest.cpp b/tests/unit/codemodelbackend/unittest/unsavedfilestest.cpp new file mode 100644 index 0000000000..eb5c5f3d36 --- /dev/null +++ b/tests/unit/codemodelbackend/unittest/unsavedfilestest.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "gtest/gtest.h" +#include "gmock/gmock-matchers.h" +#include "gmock/gmock.h" + +#include <unsavedfiles.h> +#include <filecontainer.h> + +#include <QVector> + +using CodeModelBackEnd::UnsavedFiles; +using CodeModelBackEnd::FileContainer; + +using ::testing::IsNull; +using ::testing::NotNull; + +namespace { + +bool operator ==(const CodeModelBackEnd::FileContainer &fileContainer, const CXUnsavedFile &cxUnsavedFile) +{ + return fileContainer.filePath() == Utf8String::fromUtf8(cxUnsavedFile.Filename) + && fileContainer.unsavedFileContent() == Utf8String(cxUnsavedFile.Contents, cxUnsavedFile.Length); +} + +bool fileContainersContainsCxUnsavedFile(const QVector<FileContainer> &fileContainers, const CXUnsavedFile &cxUnsavedFile) +{ + for (const FileContainer &fileContainer : fileContainers) + if (fileContainer == cxUnsavedFile) + return true; + + return false; +} + +MATCHER_P(HasUnsavedFiles, fileContainers, "") +{ + if (arg.unsavedFilesCount() != fileContainers.size()) { + *result_listener << "unsaved count is " << arg.unsavedFilesCount() << " and not " << fileContainers.size(); + return false; + } + + for (const CXUnsavedFile &cxUnsavedFile : arg.cxUnsavedFileVector()) { + if (!fileContainersContainsCxUnsavedFile(fileContainers, cxUnsavedFile)) + return false; + } + + return true; +} + +class UnsavedFiles : public ::testing::Test +{ +protected: + void TearDown() override; + +protected: + ::UnsavedFiles unsavedFiles; +}; + +void UnsavedFiles::TearDown() +{ + unsavedFiles.clear(); +} + +TEST_F(UnsavedFiles, DoNothingForUpdateWithNormalFile) +{ + QVector<FileContainer> fileContainers({FileContainer(Utf8StringLiteral("file.cpp"))}); + + unsavedFiles.update(fileContainers); + + ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>())); +} + +TEST_F(UnsavedFiles, AddUnsavedFileForUpdateWithUnsavedContent) +{ + QVector<FileContainer> fileContainers({FileContainer(Utf8StringLiteral("file.cpp")), + FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo"), true)}); + unsavedFiles.update(fileContainers); + + ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>({FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo"), true)}))); +} + +TEST_F(UnsavedFiles, RemoveUnsavedFileForUpdateWithUnsavedContent) +{ + QVector<FileContainer> fileContainers({FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo"), true), + FileContainer(Utf8StringLiteral("file.cpp"))}); + + unsavedFiles.update(fileContainers); + + ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>())); +} + +TEST_F(UnsavedFiles, ExchangeUnsavedFileForUpdateWithUnsavedContent) +{ + QVector<FileContainer> fileContainers({FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo"), true), + FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo2"), true)}); + unsavedFiles.update(fileContainers); + + ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>({FileContainer(Utf8StringLiteral("file.cpp"), Utf8StringLiteral("foo2"), true)}))); +} + +} + + + diff --git a/tests/unit/codemodelbackend/unittest/utf8test.cpp b/tests/unit/codemodelbackend/unittest/utf8test.cpp index 7ab10f0a2a..19b33fcbc0 100644 --- a/tests/unit/codemodelbackend/unittest/utf8test.cpp +++ b/tests/unit/codemodelbackend/unittest/utf8test.cpp @@ -211,3 +211,11 @@ TEST(Utf8, PlusAssignmentOperator) ASSERT_THAT(text, Utf8StringLiteral("foobar")); } + +TEST(Utf8, CompareCharPointer) +{ + Utf8String text("foo", 3); + + ASSERT_TRUE(text == "foo"); + ASSERT_FALSE(text == "foo2"); +} |
