Clang: Add UpdateTranslationUnitsForEditorMessage

If an editor is changing all translation units independent of their project
part they must be updated too. So we introduce a new message to update all
translation units with the same file path.

Change-Id: I70d0ea2bbca9fa880111ff7219573e54f3277026
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Marco Bubke
2015-10-13 15:56:41 +02:00
parent b1dced66d7
commit 250c8d662b
37 changed files with 673 additions and 106 deletions

View File

@@ -45,7 +45,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
$$PWD/fixitcontainer.cpp \ $$PWD/fixitcontainer.cpp \
$$PWD/requestdiagnosticsmessage.cpp \ $$PWD/requestdiagnosticsmessage.cpp \
$$PWD/registerunsavedfilesforeditormessage.cpp \ $$PWD/registerunsavedfilesforeditormessage.cpp \
$$PWD/unregisterunsavedfilesforeditormessage.cpp $$PWD/unregisterunsavedfilesforeditormessage.cpp \
$$PWD/updatetranslationunitsforeditormessage.cpp
HEADERS += \ HEADERS += \
$$PWD/ipcserverinterface.h \ $$PWD/ipcserverinterface.h \
@@ -85,6 +86,7 @@ HEADERS += \
$$PWD/fixitcontainer.h \ $$PWD/fixitcontainer.h \
$$PWD/requestdiagnosticsmessage.h \ $$PWD/requestdiagnosticsmessage.h \
$$PWD/registerunsavedfilesforeditormessage.h \ $$PWD/registerunsavedfilesforeditormessage.h \
$$PWD/unregisterunsavedfilesforeditormessage.h $$PWD/unregisterunsavedfilesforeditormessage.h \
$$PWD/updatetranslationunitsforeditormessage.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -44,7 +44,6 @@
#endif #endif
namespace ClangBackEnd { namespace ClangBackEnd {
CMBIPC_EXPORT void registerTypes();
enum class DiagnosticSeverity // one to one mapping of the clang enum numbers enum class DiagnosticSeverity // one to one mapping of the clang enum numbers
{ {

View File

@@ -48,6 +48,7 @@
#include "sourcerangecontainer.h" #include "sourcerangecontainer.h"
#include "translationunitdoesnotexistmessage.h" #include "translationunitdoesnotexistmessage.h"
#include "unregisterunsavedfilesforeditormessage.h" #include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include <QDataStream> #include <QDataStream>
@@ -137,6 +138,10 @@ void Messages::registerMessages()
qRegisterMetaType<UnregisterUnsavedFilesForEditorMessage>(); qRegisterMetaType<UnregisterUnsavedFilesForEditorMessage>();
qRegisterMetaTypeStreamOperators<UnregisterUnsavedFilesForEditorMessage>(); qRegisterMetaTypeStreamOperators<UnregisterUnsavedFilesForEditorMessage>();
QMetaType::registerComparators<UnregisterUnsavedFilesForEditorMessage>(); QMetaType::registerComparators<UnregisterUnsavedFilesForEditorMessage>();
qRegisterMetaType<UpdateTranslationUnitsForEditorMessage>();
qRegisterMetaTypeStreamOperators<UpdateTranslationUnitsForEditorMessage>();
QMetaType::registerComparators<UpdateTranslationUnitsForEditorMessage>();
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -37,6 +37,7 @@ namespace ClangBackEnd {
class IpcServerInterface; class IpcServerInterface;
class RegisterTranslationUnitForEditorMessage; class RegisterTranslationUnitForEditorMessage;
class UpdateTranslationUnitsForEditorMessage;
class RegisterProjectPartsForEditorMessage; class RegisterProjectPartsForEditorMessage;
class UnregisterTranslationUnitsForEditorMessage; class UnregisterTranslationUnitsForEditorMessage;
class UnregisterProjectPartsForEditorMessage; class UnregisterProjectPartsForEditorMessage;

View File

@@ -38,6 +38,7 @@
#include "registerunsavedfilesforeditormessage.h" #include "registerunsavedfilesforeditormessage.h"
#include "requestdiagnosticsmessage.h" #include "requestdiagnosticsmessage.h"
#include "unregisterunsavedfilesforeditormessage.h" #include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include <QDebug> #include <QDebug>
#include <QVariant> #include <QVariant>
@@ -48,6 +49,7 @@ void IpcServerInterface::dispatch(const QVariant &message)
{ {
static const int endMessageType = QMetaType::type("ClangBackEnd::EndMessage"); static const int endMessageType = QMetaType::type("ClangBackEnd::EndMessage");
static const int registerTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterTranslationUnitForEditorMessage"); static const int registerTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterTranslationUnitForEditorMessage");
static const int updateTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::UpdateTranslationUnitsForEditorMessage");
static const int unregisterTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterTranslationUnitsForEditorMessage"); static const int unregisterTranslationUnitsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterTranslationUnitsForEditorMessage");
static const int registerProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterProjectPartsForEditorMessage"); static const int registerProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::RegisterProjectPartsForEditorMessage");
static const int unregisterProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterProjectPartsForEditorMessage"); static const int unregisterProjectPartsForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterProjectPartsForEditorMessage");
@@ -62,6 +64,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
end(); end();
else if (type == registerTranslationUnitsForEditorMessageType) else if (type == registerTranslationUnitsForEditorMessageType)
registerTranslationUnitsForEditor(message.value<RegisterTranslationUnitForEditorMessage>()); registerTranslationUnitsForEditor(message.value<RegisterTranslationUnitForEditorMessage>());
else if (type == updateTranslationUnitsForEditorMessageType)
updateTranslationUnitsForEditor(message.value<UpdateTranslationUnitsForEditorMessage>());
else if (type == unregisterTranslationUnitsForEditorMessageType) else if (type == unregisterTranslationUnitsForEditorMessageType)
unregisterTranslationUnitsForEditor(message.value<UnregisterTranslationUnitsForEditorMessage>()); unregisterTranslationUnitsForEditor(message.value<UnregisterTranslationUnitsForEditorMessage>());
else if (type == registerProjectPartsForEditorMessageType) else if (type == registerProjectPartsForEditorMessageType)

View File

@@ -46,6 +46,7 @@ public:
virtual void end() = 0; virtual void end() = 0;
virtual void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) = 0; virtual void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) = 0;
virtual void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) = 0;
virtual void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) = 0; virtual void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) = 0;
virtual void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) = 0; virtual void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) = 0;
virtual void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) = 0; virtual void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) = 0;

View File

@@ -41,6 +41,7 @@
#include <registerunsavedfilesforeditormessage.h> #include <registerunsavedfilesforeditormessage.h>
#include <requestdiagnosticsmessage.h> #include <requestdiagnosticsmessage.h>
#include <unregisterunsavedfilesforeditormessage.h> #include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <QLocalServer> #include <QLocalServer>
#include <QLocalSocket> #include <QLocalSocket>
@@ -78,6 +79,11 @@ void IpcServerProxy::registerTranslationUnitsForEditor(const RegisterTranslation
writeMessageBlock.write(QVariant::fromValue(message)); writeMessageBlock.write(QVariant::fromValue(message));
} }
void IpcServerProxy::updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message)
{
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcServerProxy::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) void IpcServerProxy::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
{ {
writeMessageBlock.write(QVariant::fromValue(message)); writeMessageBlock.write(QVariant::fromValue(message));

View File

@@ -57,6 +57,7 @@ public:
void end() override; void end() override;
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override; void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override;
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override;
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override; void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override;
void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override; void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override;
void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override; void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override;

View File

@@ -0,0 +1,99 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 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 "updatetranslationunitsforeditormessage.h"
#include "container_common.h"
#include <QDataStream>
#include <QDebug>
#include <ostream>
namespace ClangBackEnd {
UpdateTranslationUnitsForEditorMessage::UpdateTranslationUnitsForEditorMessage(const QVector<FileContainer> &fileContainers)
: fileContainers_(fileContainers)
{
}
const QVector<FileContainer> &UpdateTranslationUnitsForEditorMessage::fileContainers() const
{
return fileContainers_;
}
QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message)
{
out << message.fileContainers_;
return out;
}
QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message)
{
in >> message.fileContainers_;
return in;
}
bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second)
{
return first.fileContainers_ == second.fileContainers_;
}
bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second)
{
return compareContainer(first.fileContainers_, second.fileContainers_);
}
QDebug operator<<(QDebug debug, const UpdateTranslationUnitsForEditorMessage &message)
{
debug.nospace() << "UpdateTranslationUnitsForEditorMessage(";
for (const FileContainer &fileContainer : message.fileContainers())
debug.nospace() << fileContainer<< ", ";
debug.nospace() << ")";
return debug;
}
void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os)
{
*os << "UpdateTranslationUnitsForEditorMessage(";
for (const FileContainer &fileContainer : message.fileContainers())
PrintTo(fileContainer, os);
*os << ")";
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 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 CLANGBACKEND_UPDATEFILEFOREDITOR_H
#define CLANGBACKEND_UPDATEFILEFOREDITOR_H
#include "filecontainer.h"
#include <QMetaType>
#include <QVector>
namespace ClangBackEnd {
class CMBIPC_EXPORT UpdateTranslationUnitsForEditorMessage
{
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message);
friend CMBIPC_EXPORT bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
friend CMBIPC_EXPORT bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
friend void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os);
public:
UpdateTranslationUnitsForEditorMessage() = default;
UpdateTranslationUnitsForEditorMessage(const QVector<FileContainer> &fileContainers);
const QVector<FileContainer> &fileContainers() const;
private:
QVector<FileContainer> fileContainers_;
};
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateTranslationUnitsForEditorMessage &message);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateTranslationUnitsForEditorMessage &message);
CMBIPC_EXPORT bool operator==(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
CMBIPC_EXPORT bool operator<(const UpdateTranslationUnitsForEditorMessage &first, const UpdateTranslationUnitsForEditorMessage &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const UpdateTranslationUnitsForEditorMessage &message);
void PrintTo(const UpdateTranslationUnitsForEditorMessage &message, ::std::ostream* os);
} // namespace ClangBackEnd
Q_DECLARE_METATYPE(ClangBackEnd::UpdateTranslationUnitsForEditorMessage)
#endif // CLANGBACKEND_UPDATEFILEFOREDITOR_H

View File

@@ -66,6 +66,7 @@
#include <clangbackendipc/projectpartsdonotexistmessage.h> #include <clangbackendipc/projectpartsdonotexistmessage.h>
#include <clangbackendipc/translationunitdoesnotexistmessage.h> #include <clangbackendipc/translationunitdoesnotexistmessage.h>
#include <clangbackendipc/unregisterunsavedfilesforeditormessage.h> #include <clangbackendipc/unregisterunsavedfilesforeditormessage.h>
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
#include <cplusplus/Icons.h> #include <cplusplus/Icons.h>
@@ -194,6 +195,7 @@ public:
void end() override; void end() override;
void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override;
void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override;
void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override;
void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override;
void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override;
@@ -218,6 +220,12 @@ void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitF
m_connection.serverProxy().registerTranslationUnitsForEditor(message); m_connection.serverProxy().registerTranslationUnitsForEditor(message);
} }
void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message)
{
QTC_CHECK(m_connection.isConnected());
m_connection.serverProxy().updateTranslationUnitsForEditor(message);
}
void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
{ {
QTC_CHECK(m_connection.isConnected()); QTC_CHECK(m_connection.isConnected());
@@ -368,6 +376,16 @@ void IpcCommunicator::registerProjectsParts(const QList<CppTools::ProjectPart::P
registerProjectPartsForEditor(projectPartContainers); registerProjectPartsForEditor(projectPartContainers);
} }
void IpcCommunicator::registerTranslationUnit(TextEditor::TextDocument *document)
{
const QString filePath = document->filePath().toString();
const QString projectPartId = Utils::projectPartIdForFile(filePath);
registerTranslationUnitsForEditor({{Utf8String(filePath),
Utf8String(projectPartId),
uint(document->document()->revision())}});
}
void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath) void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath)
{ {
const auto document = CppTools::CppModelManager::instance()->cppEditorDocument(filePath); const auto document = CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
@@ -388,34 +406,33 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath); return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
} }
bool documentHasChanged(const QString &filePath, const QString &projectPartId) bool documentHasChanged(const QString &filePath)
{ {
auto *document = cppDocument(filePath); auto *document = cppDocument(filePath);
if (document) if (document)
return document->sendTracker(projectPartId).shouldSendRevision(document->revision()); return document->sendTracker().shouldSendRevision(document->revision());
return true; return true;
} }
void setLastSentDocumentRevision(const QString &filePath, void setLastSentDocumentRevision(const QString &filePath,
const QString &projectPartId,
uint revision) uint revision)
{ {
auto *document = cppDocument(filePath); auto *document = cppDocument(filePath);
if (document) if (document)
document->sendTracker(projectPartId).setLastSentRevision(int(revision)); document->sendTracker().setLastSentRevision(int(revision));
} }
} }
void IpcCommunicator::updateTranslationUnit(const QString &filePath, void IpcCommunicator::registerTranslationUnit(const QString &filePath,
const QByteArray &contents, const QByteArray &contents,
uint documentRevision) uint documentRevision)
{ {
const QString projectPartId = Utils::projectPartIdForFile(filePath); const QString projectPartId = Utils::projectPartIdForFile(filePath);
if (documentHasChanged(filePath, projectPartId)) { if (documentHasChanged(filePath)) {
const bool hasUnsavedContent = true; const bool hasUnsavedContent = true;
registerTranslationUnitsForEditor({{filePath, registerTranslationUnitsForEditor({{filePath,
@@ -424,18 +441,30 @@ void IpcCommunicator::updateTranslationUnit(const QString &filePath,
hasUnsavedContent, hasUnsavedContent,
documentRevision}}); documentRevision}});
setLastSentDocumentRevision(filePath, projectPartId, documentRevision); setLastSentDocumentRevision(filePath, documentRevision);
} }
} }
void IpcCommunicator::updateTranslationUnit(const QString &filePath,
const QByteArray &contents,
uint documentRevision)
{
const bool hasUnsavedContent = true;
updateTranslationUnitsForEditor({{filePath,
Utf8String(),
Utf8String::fromByteArray(contents),
hasUnsavedContent,
documentRevision}});
}
void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision) void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision)
{ {
const QString projectPartId = Utils::projectPartIdForFile(filePath);
const bool hasUnsavedContent = true; const bool hasUnsavedContent = true;
// TODO: Send new only if changed // TODO: Send new only if changed
registerUnsavedFilesForEditor({{filePath, registerUnsavedFilesForEditor({{filePath,
projectPartId, Utf8String(),
Utf8String::fromByteArray(contents), Utf8String::fromByteArray(contents),
hasUnsavedContent, hasUnsavedContent,
documentRevision}}); documentRevision}});
@@ -446,15 +475,14 @@ void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
if (m_sendMode == IgnoreSendRequests) if (m_sendMode == IgnoreSendRequests)
return; return;
if (documentHasChanged(fileContainer.filePath(), fileContainer.projectPartId())) { if (documentHasChanged(fileContainer.filePath())) {
registerTranslationUnitsForEditor({fileContainer}); updateTranslationUnitsForEditor({fileContainer});
const RequestDiagnosticsMessage message(fileContainer); const RequestDiagnosticsMessage message(fileContainer);
qCDebug(log) << ">>>" << message; qCDebug(log) << ">>>" << message;
m_ipcSender->requestDiagnostics(message); m_ipcSender->requestDiagnostics(message);
setLastSentDocumentRevision(fileContainer.filePath(), setLastSentDocumentRevision(fileContainer.filePath(),
fileContainer.projectPartId(),
fileContainer.documentRevision()); fileContainer.documentRevision());
} }
} }
@@ -474,10 +502,8 @@ void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath,
{ {
auto *document = cppDocument(filePath); auto *document = cppDocument(filePath);
if (document) { if (document)
const QString projectPartId = Utils::projectPartIdForFile(filePath); document->sendTracker().applyContentChange(position);
document->sendTracker(projectPartId).applyContentChange(position);
}
} }
void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document) void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document)
@@ -551,6 +577,16 @@ void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fi
m_ipcSender->registerTranslationUnitsForEditor(message); m_ipcSender->registerTranslationUnitsForEditor(message);
} }
void IpcCommunicator::updateTranslationUnitsForEditor(const IpcCommunicator::FileContainers &fileContainers)
{
if (m_sendMode == IgnoreSendRequests)
return;
const UpdateTranslationUnitsForEditorMessage message(fileContainers);
qCDebug(log) << ">>>" << message;
m_ipcSender->updateTranslationUnitsForEditor(message);
}
void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers) void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers)
{ {
if (m_sendMode == IgnoreSendRequests) if (m_sendMode == IgnoreSendRequests)

View File

@@ -53,6 +53,7 @@ class DiagnosticsChangedMessage;
namespace TextEditor { namespace TextEditor {
class TextEditorWidget; class TextEditorWidget;
class TextDocument;
} }
namespace ClangCodeModel { namespace ClangCodeModel {
@@ -96,6 +97,7 @@ public:
virtual void end() = 0; virtual void end() = 0;
virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0; virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0;
virtual void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) = 0;
virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0; virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0;
virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0; virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0;
virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0; virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0;
@@ -118,6 +120,7 @@ public:
IpcCommunicator(); IpcCommunicator();
void registerTranslationUnitsForEditor(const FileContainers &fileContainers); void registerTranslationUnitsForEditor(const FileContainers &fileContainers);
void updateTranslationUnitsForEditor(const FileContainers &fileContainers);
void unregisterTranslationUnitsForEditor(const FileContainers &fileContainers); void unregisterTranslationUnitsForEditor(const FileContainers &fileContainers);
void registerProjectPartsForEditor(const ProjectPartContainers &projectPartContainers); void registerProjectPartsForEditor(const ProjectPartContainers &projectPartContainers);
void unregisterProjectPartsForEditor(const QStringList &projectPartIds); void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
@@ -130,6 +133,8 @@ public:
void registerProjectsParts(const QList<CppTools::ProjectPart::Ptr> projectParts); void registerProjectsParts(const QList<CppTools::ProjectPart::Ptr> projectParts);
void registerTranslationUnit(TextEditor::TextDocument *document);
void registerTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
void updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document); void updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document);
void updateTranslationUnit(Core::IDocument *document); void updateTranslationUnit(Core::IDocument *document);
void updateUnsavedFile(Core::IDocument *document); void updateUnsavedFile(Core::IDocument *document);

View File

@@ -670,15 +670,14 @@ ClangCompletionAssistProcessor::unsavedFileContent(const QByteArray &customFileC
return info; return info;
} }
void ClangCompletionAssistProcessor::sendFileContent(const QString &projectPartId, void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFileContent)
const QByteArray &customFileContent)
{ {
// TODO: Revert custom modification after the completions // TODO: Revert custom modification after the completions
const UnsavedFileContentInfo info = unsavedFileContent(customFileContent); const UnsavedFileContentInfo info = unsavedFileContent(customFileContent);
IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator(); IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator();
ipcCommunicator.registerTranslationUnitsForEditor({{m_interface->fileName(), ipcCommunicator.updateTranslationUnitsForEditor({{m_interface->fileName(),
projectPartId, Utf8String(),
Utf8String::fromByteArray(info.unsavedContent), Utf8String::fromByteArray(info.unsavedContent),
info.isDocumentModified, info.isDocumentModified,
uint(m_interface->textDocument()->revision())}}); uint(m_interface->textDocument()->revision())}});
@@ -690,14 +689,13 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
} }
bool shouldSendDocumentForCompletion(const QString &filePath, bool shouldSendDocumentForCompletion(const QString &filePath,
const QString &projectPartId,
int completionPosition) int completionPosition)
{ {
auto *document = cppDocument(filePath); auto *document = cppDocument(filePath);
if (document) { if (document) {
auto &sendTracker = document->sendTracker(projectPartId); auto &sendTracker = document->sendTracker();
return sendTracker.shouldSendRevisionWithCompletionPosition(document->revision(), return sendTracker.shouldSendRevisionWithCompletionPosition(int(document->revision()),
completionPosition); completionPosition);
} }
@@ -705,14 +703,13 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
} }
void setLastCompletionPositionAndDocumentRevision(const QString &filePath, void setLastCompletionPositionAndDocumentRevision(const QString &filePath,
const QString &projectPartId,
int completionPosition) int completionPosition)
{ {
auto *document = cppDocument(filePath); auto *document = cppDocument(filePath);
if (document) { if (document) {
document->sendTracker(projectPartId).setLastCompletionPosition(completionPosition); document->sendTracker().setLastCompletionPosition(completionPosition);
document->sendTracker(projectPartId).setLastSentRevision(document->revision()); document->sendTracker().setLastSentRevision(document->revision());
} }
} }
@@ -737,13 +734,13 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
++column; ++column;
const QString filePath = m_interface->fileName(); const QString filePath = m_interface->fileName();
const QString projectPartId = projectPartIdForEditorDocument(filePath);
if (shouldSendDocumentForCompletion(filePath, projectPartId, position)) { if (shouldSendDocumentForCompletion(filePath, position)) {
sendFileContent(projectPartId, customFileContent); sendFileContent(customFileContent);
setLastCompletionPositionAndDocumentRevision(filePath, projectPartId, position); setLastCompletionPositionAndDocumentRevision(filePath, position);
} }
const QString projectPartId = projectPartIdForEditorDocument(filePath);
m_interface->ipcCommunicator().completeCode(this, m_interface->ipcCommunicator().completeCode(this,
filePath, filePath,
uint(line), uint(line),

View File

@@ -83,7 +83,7 @@ private:
}; };
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const; UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
void sendFileContent(const QString &projectPartId, const QByteArray &customFileContent); void sendFileContent(const QByteArray &customFileContent);
void sendCompletionRequest(int position, const QByteArray &customFileContent); void sendCompletionRequest(int position, const QByteArray &customFileContent);
void handleAvailableCompletions(const CodeCompletions &completions); void handleAvailableCompletions(const CodeCompletions &completions);

View File

@@ -31,6 +31,7 @@
#include "clangcompletionassistprovider.h" #include "clangcompletionassistprovider.h"
#include "clangcompletionassistprocessor.h" #include "clangcompletionassistprocessor.h"
#include "clangeditordocumentprocessor.h"
#include "clangutils.h" #include "clangutils.h"
#include "pchmanager.h" #include "pchmanager.h"
@@ -70,9 +71,8 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
int position, int position,
TextEditor::AssistReason reason) const TextEditor::AssistReason reason) const
{ {
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFile(filePath); const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath);
QTC_ASSERT(!projectPart.isNull(), return 0); if (projectPart) {
const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart); const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart);
return new ClangCompletionAssistInterface(m_ipcCommunicator, return new ClangCompletionAssistInterface(m_ipcCommunicator,
textEditorWidget, textEditorWidget,
@@ -84,5 +84,8 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
projectPart->languageFeatures); projectPart->languageFeatures);
} }
return 0;
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -30,6 +30,8 @@
#include "clangutils.h" #include "clangutils.h"
#include "clangeditordocumentprocessor.h"
#include <clang-c/Index.h> #include <clang-c/Index.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -264,6 +266,13 @@ ProjectPart::Ptr projectPartForFile(const QString &filePath)
return ProjectPart::Ptr(); return ProjectPart::Ptr();
} }
ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath)
{
if (const auto processor = ClangEditorDocumentProcessor::get(filePath))
return processor->projectPart();
return ProjectPart::Ptr();
}
bool isProjectPartValid(const ProjectPart::Ptr projectPart) bool isProjectPartValid(const ProjectPart::Ptr projectPart)
{ {
if (projectPart) if (projectPart)

View File

@@ -54,6 +54,7 @@ QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
QStringList createPCHInclusionOptions(const QString &pchFile); QStringList createPCHInclusionOptions(const QString &pchFile);
CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath); CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
bool isProjectPartValid(const CppTools::ProjectPart::Ptr projectPart); bool isProjectPartValid(const CppTools::ProjectPart::Ptr projectPart);
QString projectPartIdForFile(const QString &filePath); QString projectPartIdForFile(const QString &filePath);

View File

@@ -61,6 +61,7 @@
#include <clangbackendipc/cmbunregisterprojectsforeditormessage.h> #include <clangbackendipc/cmbunregisterprojectsforeditormessage.h>
#include <clangbackendipc/cmbunregistertranslationunitsforeditormessage.h> #include <clangbackendipc/cmbunregistertranslationunitsforeditormessage.h>
#include <clangbackendipc/registerunsavedfilesforeditormessage.h> #include <clangbackendipc/registerunsavedfilesforeditormessage.h>
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
#include <utils/changeset.h> #include <utils/changeset.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -319,8 +320,16 @@ QString toString(const RegisterTranslationUnitForEditorMessage &message)
ts << "RegisterTranslationUnitForEditorMessage\n" ts << "RegisterTranslationUnitForEditorMessage\n"
<< toString(message.fileContainers()); << toString(message.fileContainers());
return out; return out;
}
return QLatin1String("RegisterTranslationUnitForEditorMessage\n"); QString toString(const UpdateTranslationUnitsForEditorMessage &message)
{
QString out;
QTextStream ts(&out);
ts << "UpdateTranslationUnitForEditorMessage\n"
<< toString(message.fileContainers());
return out;
} }
QString toString(const UnregisterTranslationUnitsForEditorMessage &) QString toString(const UnregisterTranslationUnitsForEditorMessage &)
@@ -356,8 +365,6 @@ QString toString(const RegisterUnsavedFilesForEditorMessage &message)
ts << "RegisterUnsavedFilesForEditorMessage\n" ts << "RegisterUnsavedFilesForEditorMessage\n"
<< toString(message.fileContainers()); << toString(message.fileContainers());
return out; return out;
return QLatin1String("RegisterUnsavedFilesForEditorMessage\n");
} }
QString toString(const UnregisterUnsavedFilesForEditorMessage &) QString toString(const UnregisterUnsavedFilesForEditorMessage &)
@@ -384,6 +391,9 @@ public:
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override
{ senderLog.append(toString(message)); } { senderLog.append(toString(message)); }
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override
{ senderLog.append(toString(message)); }
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override
{ senderLog.append(toString(message)); } { senderLog.append(toString(message)); }

View File

@@ -58,9 +58,9 @@ void CppEditorDocumentHandle::setNeedsRefresh(bool needsRefresh)
m_needsRefresh = needsRefresh; m_needsRefresh = needsRefresh;
} }
SendDocumentTracker &CppEditorDocumentHandle::sendTracker(const QString &projectPartId) SendDocumentTracker &CppEditorDocumentHandle::sendTracker()
{ {
return m_documentRevisionManagements[projectPartId]; return m_sendTracker;
} }
} // namespace CppTools } // namespace CppTools

View File

@@ -34,7 +34,6 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include "senddocumenttracker.h" #include "senddocumenttracker.h"
#include <QMap>
#include <QString> #include <QString>
namespace CppTools { namespace CppTools {
@@ -59,10 +58,10 @@ public:
virtual void resetProcessor() = 0; virtual void resetProcessor() = 0;
SendDocumentTracker &sendTracker(const QString &projectPartId); SendDocumentTracker &sendTracker();
private: private:
QMap<QString, SendDocumentTracker> m_documentRevisionManagements; SendDocumentTracker m_sendTracker;
bool m_needsRefresh; bool m_needsRefresh;
}; };

View File

@@ -23,7 +23,8 @@ HEADERS += $$PWD/clangipcserver.h \
$$PWD/sourcerange.h \ $$PWD/sourcerange.h \
$$PWD/fixit.h \ $$PWD/fixit.h \
$$PWD/diagnosticsetiterator.h \ $$PWD/diagnosticsetiterator.h \
$$PWD/clangfilesystemwatcher.h $$PWD/clangfilesystemwatcher.h \
$$PWD/translationunitalreadyexistsexception.h
SOURCES += $$PWD/clangipcserver.cpp \ SOURCES += $$PWD/clangipcserver.cpp \
$$PWD/codecompleter.cpp \ $$PWD/codecompleter.cpp \
@@ -47,4 +48,5 @@ SOURCES += $$PWD/clangipcserver.cpp \
$$PWD/sourcelocation.cpp \ $$PWD/sourcelocation.cpp \
$$PWD/sourcerange.cpp \ $$PWD/sourcerange.cpp \
$$PWD/fixit.cpp \ $$PWD/fixit.cpp \
$$PWD/clangfilesystemwatcher.cpp $$PWD/clangfilesystemwatcher.cpp \
$$PWD/translationunitalreadyexistsexception.cpp

View File

@@ -53,6 +53,7 @@
#include <projectpartsdonotexistmessage.h> #include <projectpartsdonotexistmessage.h>
#include <translationunitdoesnotexistmessage.h> #include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h> #include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
@@ -103,12 +104,9 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis
TIME_SCOPE_DURATION("ClangIpcServer::registerTranslationUnitsForEditor"); TIME_SCOPE_DURATION("ClangIpcServer::registerTranslationUnitsForEditor");
try { try {
const auto newerFileContainers = translationUnits.newerFileContainers(message.fileContainers()); translationUnits.create(message.fileContainers());
if (newerFileContainers.size() > 0) { unsavedFiles.createOrUpdate(message.fileContainers());
unsavedFiles.createOrUpdate(newerFileContainers);
translationUnits.createOrUpdate(newerFileContainers);
sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval); sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval);
}
} catch (const ProjectPartDoNotExistException &exception) { } catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
} catch (const std::exception &exception) { } catch (const std::exception &exception) {
@@ -116,13 +114,33 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis
} }
} }
void ClangIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message)
{
TIME_SCOPE_DURATION("ClangIpcServer::updateTranslationUnitsForEditor");
try {
const auto newerFileContainers = translationUnits.newerFileContainers(message.fileContainers());
if (newerFileContainers.size() > 0) {
translationUnits.update(newerFileContainers);
unsavedFiles.createOrUpdate(newerFileContainers);
sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval);
}
} catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
} catch (const TranslationUnitDoesNotExistException &exception) {
client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer()));
} catch (const std::exception &exception) {
qWarning() << "Error in ClangIpcServer::updateTranslationUnitsForEditor:" << exception.what();
}
}
void ClangIpcServer::unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) void ClangIpcServer::unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message)
{ {
TIME_SCOPE_DURATION("ClangIpcServer::unregisterTranslationUnitsForEditor"); TIME_SCOPE_DURATION("ClangIpcServer::unregisterTranslationUnitsForEditor");
try { try {
unsavedFiles.remove(message.fileContainers());
translationUnits.remove(message.fileContainers()); translationUnits.remove(message.fileContainers());
unsavedFiles.remove(message.fileContainers());
} catch (const TranslationUnitDoesNotExistException &exception) { } catch (const TranslationUnitDoesNotExistException &exception) {
client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer())); client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer()));
} catch (const ProjectPartDoNotExistException &exception) { } catch (const ProjectPartDoNotExistException &exception) {
@@ -225,6 +243,11 @@ void ClangIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message
} }
} }
const TranslationUnits &ClangIpcServer::translationUnitsForTestOnly() const
{
return translationUnits;
}
void ClangIpcServer::startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath) void ClangIpcServer::startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath)
{ {
if (!translationUnits.hasTranslationUnit(filePath)) if (!translationUnits.hasTranslationUnit(filePath))

View File

@@ -53,6 +53,7 @@ public:
void end() override; void end() override;
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override; void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override;
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override;
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override; void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override;
void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override; void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override;
void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override; void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override;
@@ -61,6 +62,8 @@ public:
void completeCode(const CompleteCodeMessage &message) override; void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override; void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
const TranslationUnits &translationUnitsForTestOnly() const;
private: private:
void startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); void startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath);

View File

@@ -0,0 +1,65 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "translationunitalreadyexistsexception.h"
namespace ClangBackEnd {
TranslationUnitAlreadyExistsException::TranslationUnitAlreadyExistsException(const FileContainer &fileContainer)
: fileContainer_(fileContainer)
{
}
TranslationUnitAlreadyExistsException::TranslationUnitAlreadyExistsException(const Utf8String &filePath,
const Utf8String &projectPartId)
: fileContainer_(filePath, projectPartId)
{
}
const FileContainer &TranslationUnitAlreadyExistsException::fileContainer() const
{
return fileContainer_;
}
const char *TranslationUnitAlreadyExistsException::what() const Q_DECL_NOEXCEPT
{
if (what_.isEmpty()) {
what_ += Utf8StringLiteral("Translation unit '")
+ fileContainer_.filePath()
+ Utf8StringLiteral("' with the project part id '")
+ fileContainer_.projectPartId()
+ Utf8StringLiteral("' already exists!");
}
return what_.constData();
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,61 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CLANGBACKEND_TRANSLATIONUNITALREADYEXISTS_H
#define CLANGBACKEND_TRANSLATIONUNITALREADYEXISTS_H
#include <filecontainer.h>
namespace ClangBackEnd {
class TranslationUnitAlreadyExistsException : public std::exception
{
public:
TranslationUnitAlreadyExistsException(const FileContainer &fileContainer);
TranslationUnitAlreadyExistsException(const Utf8String &filePath, const Utf8String &projectPartId);
const FileContainer &fileContainer() const;
const char *what() const Q_DECL_NOEXCEPT override;
#if defined(__GNUC__) && !defined(__clang__)
# if !__GNUC_PREREQ(4,8)
~TranslationUnitAlreadyExistsException() noexcept {}
# endif
#endif
private:
FileContainer fileContainer_;
mutable Utf8String what_;
};
} // namespace ClangBackEnd
#endif // CLANGBACKEND_TRANSLATIONUNITALREADYEXISTS_H

View File

@@ -37,7 +37,7 @@ TranslationUnitDoesNotExistException::TranslationUnitDoesNotExistException(const
{ {
} }
TranslationUnitDoesNotExistException::TranslationUnitDoesNotExistException(const Utf8String filePath, const Utf8String projectPartId) TranslationUnitDoesNotExistException::TranslationUnitDoesNotExistException(const Utf8String &filePath, const Utf8String &projectPartId)
: fileContainer_(filePath, projectPartId) : fileContainer_(filePath, projectPartId)
{ {
} }
@@ -50,11 +50,11 @@ const FileContainer &TranslationUnitDoesNotExistException::fileContainer() const
const char *TranslationUnitDoesNotExistException::what() const Q_DECL_NOEXCEPT const char *TranslationUnitDoesNotExistException::what() const Q_DECL_NOEXCEPT
{ {
if (what_.isEmpty()) if (what_.isEmpty())
what_ += Utf8StringLiteral("Parse error for file ") what_ += Utf8StringLiteral("Translation unit '")
+ fileContainer_.filePath() + fileContainer_.filePath()
+ Utf8StringLiteral(" in project ") + Utf8StringLiteral("' with the project part id '")
+ fileContainer_.projectPartId() + fileContainer_.projectPartId()
+ Utf8StringLiteral("!"); + Utf8StringLiteral("' does not exits!");
return what_.constData(); return what_.constData();
} }

View File

@@ -39,7 +39,7 @@ class TranslationUnitDoesNotExistException : public std::exception
{ {
public: public:
TranslationUnitDoesNotExistException(const FileContainer &fileContainer); TranslationUnitDoesNotExistException(const FileContainer &fileContainer);
TranslationUnitDoesNotExistException(const Utf8String filePath, const Utf8String projectPartId); TranslationUnitDoesNotExistException(const Utf8String &filePath, const Utf8String &projectPartId);
const FileContainer &fileContainer() const; const FileContainer &fileContainer() const;

View File

@@ -34,6 +34,7 @@
#include <diagnosticset.h> #include <diagnosticset.h>
#include <projectpartsdonotexistexception.h> #include <projectpartsdonotexistexception.h>
#include <projects.h> #include <projects.h>
#include <translationunitalreadyexistsexception.h>
#include <translationunitdoesnotexistexception.h> #include <translationunitdoesnotexistexception.h>
#include <QDebug> #include <QDebug>
@@ -57,10 +58,22 @@ TranslationUnits::TranslationUnits(ProjectParts &projects, UnsavedFiles &unsaved
{ {
} }
void TranslationUnits::createOrUpdate(const QVector<FileContainer> &fileContainers) void TranslationUnits::create(const QVector<FileContainer> &fileContainers)
{ {
checkIfTranslationUnitsDoesNotExists(fileContainers);
for (const FileContainer &fileContainer : fileContainers) { for (const FileContainer &fileContainer : fileContainers) {
createOrUpdateTranslationUnit(fileContainer); createTranslationUnit(fileContainer);
updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
}
}
void TranslationUnits::update(const QVector<FileContainer> &fileContainers)
{
checkIfTranslationUnitsForFilePathsDoesExists(fileContainers);
for (const FileContainer &fileContainer : fileContainers) {
updateTranslationUnit(fileContainer);
updateTranslationUnitsWithChangedDependency(fileContainer.filePath()); updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
} }
} }
@@ -180,7 +193,7 @@ const ClangFileSystemWatcher *TranslationUnits::clangFileSystemWatcher() const
return &fileSystemWatcher; return &fileSystemWatcher;
} }
void TranslationUnits::createOrUpdateTranslationUnit(const FileContainer &fileContainer) void TranslationUnits::createTranslationUnit(const FileContainer &fileContainer)
{ {
TranslationUnit::FileExistsCheck checkIfFileExists = fileContainer.hasUnsavedFileContent() ? TranslationUnit::DoNotCheckIfFileExists : TranslationUnit::CheckIfFileExists; TranslationUnit::FileExistsCheck checkIfFileExists = fileContainer.hasUnsavedFileContent() ? TranslationUnit::DoNotCheckIfFileExists : TranslationUnit::CheckIfFileExists;
auto findIterator = findTranslationUnit(fileContainer); auto findIterator = findTranslationUnit(fileContainer);
@@ -190,22 +203,54 @@ void TranslationUnits::createOrUpdateTranslationUnit(const FileContainer &fileCo
*this, *this,
checkIfFileExists)); checkIfFileExists));
translationUnits_.back().setDocumentRevision(fileContainer.documentRevision()); translationUnits_.back().setDocumentRevision(fileContainer.documentRevision());
} else {
findIterator->setDocumentRevision(fileContainer.documentRevision());
} }
} }
void TranslationUnits::updateTranslationUnit(const FileContainer &fileContainer)
{
auto findIterator = findAllTranslationUnitWithFilePath(fileContainer.filePath());
if (findIterator != translationUnits_.end())
findIterator->setDocumentRevision(fileContainer.documentRevision());
}
std::vector<TranslationUnit>::iterator TranslationUnits::findTranslationUnit(const FileContainer &fileContainer) std::vector<TranslationUnit>::iterator TranslationUnits::findTranslationUnit(const FileContainer &fileContainer)
{ {
return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer); return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer);
} }
std::vector<TranslationUnit>::iterator TranslationUnits::findAllTranslationUnitWithFilePath(const Utf8String &filePath)
{
auto filePathCompare = [&filePath] (const TranslationUnit &translationUnit) {
return translationUnit.filePath() == filePath;
};
return std::find_if(translationUnits_.begin(), translationUnits_.end(), filePathCompare);
}
std::vector<TranslationUnit>::const_iterator TranslationUnits::findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const std::vector<TranslationUnit>::const_iterator TranslationUnits::findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const
{ {
FileContainer fileContainer(filePath, projectPartId); FileContainer fileContainer(filePath, projectPartId);
return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer); return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer);
} }
bool TranslationUnits::hasTranslationUnit(const FileContainer &fileContainer) const
{
auto findIterator = std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer);
return findIterator != translationUnits_.end();
}
bool TranslationUnits::hasTranslationUnitWithFilePath(const Utf8String &filePath) const
{
auto filePathCompare = [&filePath] (const TranslationUnit &translationUnit) {
return translationUnit.filePath() == filePath;
};
auto findIterator = std::find_if(translationUnits_.begin(), translationUnits_.end(), filePathCompare);
return findIterator != translationUnits_.end();
}
void TranslationUnits::checkIfProjectPartExists(const Utf8String &projectFileName) const void TranslationUnits::checkIfProjectPartExists(const Utf8String &projectFileName) const
{ {
projectParts.project(projectFileName); projectParts.project(projectFileName);
@@ -225,6 +270,22 @@ void TranslationUnits::checkIfProjectPartsExists(const QVector<FileContainer> &f
} }
void TranslationUnits::checkIfTranslationUnitsDoesNotExists(const QVector<FileContainer> &fileContainers) const
{
for (const FileContainer &fileContainer : fileContainers) {
if (hasTranslationUnit(fileContainer))
throw TranslationUnitAlreadyExistsException(fileContainer);
}
}
void TranslationUnits::checkIfTranslationUnitsForFilePathsDoesExists(const QVector<FileContainer> &fileContainers) const
{
for (const FileContainer &fileContainer : fileContainers) {
if (!hasTranslationUnitWithFilePath(fileContainer.filePath()))
throw TranslationUnitDoesNotExistException(fileContainer);
}
}
void TranslationUnits::sendDiagnosticChangedMessage(const TranslationUnit &translationUnit) void TranslationUnits::sendDiagnosticChangedMessage(const TranslationUnit &translationUnit)
{ {
if (sendDiagnosticsChangedCallback) { if (sendDiagnosticsChangedCallback) {

View File

@@ -58,7 +58,8 @@ class TranslationUnits
public: public:
TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles); TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles);
void createOrUpdate(const QVector<FileContainer> &fileContainers); void create(const QVector<FileContainer> &fileContainers);
void update(const QVector<FileContainer> &fileContainers);
void remove(const QVector<FileContainer> &fileContainers); void remove(const QVector<FileContainer> &fileContainers);
const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const; const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const;
@@ -83,11 +84,18 @@ public:
const ClangFileSystemWatcher *clangFileSystemWatcher() const; const ClangFileSystemWatcher *clangFileSystemWatcher() const;
private: private:
void createOrUpdateTranslationUnit(const FileContainer &fileContainer); void createTranslationUnit(const FileContainer &fileContainer);
void updateTranslationUnit(const FileContainer &fileContainer);
std::vector<TranslationUnit>::iterator findTranslationUnit(const FileContainer &fileContainer); std::vector<TranslationUnit>::iterator findTranslationUnit(const FileContainer &fileContainer);
std::vector<TranslationUnit>::iterator findAllTranslationUnitWithFilePath(const Utf8String &filePath);
std::vector<TranslationUnit>::const_iterator findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const; std::vector<TranslationUnit>::const_iterator findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const;
bool hasTranslationUnit(const FileContainer &fileContainer) const;
bool hasTranslationUnitWithFilePath(const Utf8String &filePath) const;
void checkIfProjectPartExists(const Utf8String &projectFileName) const; void checkIfProjectPartExists(const Utf8String &projectFileName) const;
void checkIfProjectPartsExists(const QVector<FileContainer> &fileContainers) const; void checkIfProjectPartsExists(const QVector<FileContainer> &fileContainers) const;
void checkIfTranslationUnitsDoesNotExists(const QVector<FileContainer> &fileContainers) const;
void checkIfTranslationUnitsForFilePathsDoesExists(const QVector<FileContainer> &fileContainers) const;
void sendDiagnosticChangedMessage(const TranslationUnit &translationUnit); void sendDiagnosticChangedMessage(const TranslationUnit &translationUnit);
void removeTranslationUnits(const QVector<FileContainer> &fileContainers); void removeTranslationUnits(const QVector<FileContainer> &fileContainers);

View File

@@ -42,6 +42,7 @@
#include "registerunsavedfilesforeditormessage.h" #include "registerunsavedfilesforeditormessage.h"
#include "requestdiagnosticsmessage.h" #include "requestdiagnosticsmessage.h"
#include "unregisterunsavedfilesforeditormessage.h" #include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
@@ -65,6 +66,11 @@ void EchoIpcServer::registerTranslationUnitsForEditor(const RegisterTranslationU
echoMessage(QVariant::fromValue(message)); echoMessage(QVariant::fromValue(message));
} }
void EchoIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message)
{
echoMessage(QVariant::fromValue(message));
}
void EchoIpcServer::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) void EchoIpcServer::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
{ {
echoMessage(QVariant::fromValue(message)); echoMessage(QVariant::fromValue(message));

View File

@@ -41,6 +41,7 @@ public:
void dispatch(const QVariant &message) override; void dispatch(const QVariant &message) override;
void end() override; void end() override;
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override; void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override;
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override;
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override; void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override;
void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override; void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) override;
void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override; void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) override;

View File

@@ -46,6 +46,7 @@
#include <diagnosticschangedmessage.h> #include <diagnosticschangedmessage.h>
#include <projectpartsdonotexistmessage.h> #include <projectpartsdonotexistmessage.h>
#include <translationunitdoesnotexistmessage.h> #include <translationunitdoesnotexistmessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <QBuffer> #include <QBuffer>
#include <QFile> #include <QFile>
@@ -59,6 +60,7 @@ using testing::Property;
using testing::Contains; using testing::Contains;
using testing::Not; using testing::Not;
using testing::Eq; using testing::Eq;
using testing::PrintToString;
namespace { namespace {
@@ -73,6 +75,41 @@ using ClangBackEnd::FileContainer;
using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::TranslationUnitDoesNotExistMessage; using ClangBackEnd::TranslationUnitDoesNotExistMessage;
using ClangBackEnd::ProjectPartsDoNotExistMessage; using ClangBackEnd::ProjectPartsDoNotExistMessage;
using ClangBackEnd::UpdateTranslationUnitsForEditorMessage;
MATCHER_P3(HasDirtyTranslationUnit, filePath, projectPartId, documentRevision,
std::string(negation ? "isn't" : "is")
+ " translation unit with file path "+ PrintToString(filePath)
+ " and project " + PrintToString(projectPartId)
+ " and document revision " + PrintToString(documentRevision)
)
{
auto &&translationUnits = arg.translationUnitsForTestOnly();
try {
auto translationUnit = translationUnits.translationUnit(filePath, projectPartId);
if (translationUnit.documentRevision() == documentRevision) {
if (translationUnit.hasNewDiagnostics()) {
if (translationUnit.isNeedingReparse())
return true;
*result_listener << "isNeedingReparse is false";
return false;
}
*result_listener << "hasNewDiagnostics is false";
return false;
}
*result_listener << "revision number is " << PrintToString(translationUnit.documentRevision());
return false;
} catch (...) {
*result_listener << "has no translation unit";
return false;
}
}
class ClangIpcServer : public ::testing::Test class ClangIpcServer : public ::testing::Test
{ {
@@ -222,7 +259,7 @@ TEST_F(ClangIpcServer, GetCodeCompletionForUnsavedFile)
TEST_F(ClangIpcServer, GetNoCodeCompletionAfterRemovingUnsavedFile) TEST_F(ClangIpcServer, GetNoCodeCompletionAfterRemovingUnsavedFile)
{ {
clangServer.registerTranslationUnitsForEditor(RegisterTranslationUnitForEditorMessage({FileContainer(functionTestFilePath, projectPartId, 74)})); clangServer.updateTranslationUnitsForEditor(UpdateTranslationUnitsForEditorMessage({FileContainer(functionTestFilePath, projectPartId, 74)}));
CompleteCodeMessage completeCodeMessage(functionTestFilePath, CompleteCodeMessage completeCodeMessage(functionTestFilePath,
20, 20,
1, 1,
@@ -239,11 +276,11 @@ TEST_F(ClangIpcServer, GetNoCodeCompletionAfterRemovingUnsavedFile)
TEST_F(ClangIpcServer, GetNewCodeCompletionAfterUpdatingUnsavedFile) TEST_F(ClangIpcServer, GetNewCodeCompletionAfterUpdatingUnsavedFile)
{ {
clangServer.registerTranslationUnitsForEditor(RegisterTranslationUnitForEditorMessage({FileContainer(functionTestFilePath, clangServer.updateTranslationUnitsForEditor(UpdateTranslationUnitsForEditorMessage({{functionTestFilePath,
projectPartId, projectPartId,
unsavedContent(updatedUnsavedTestFilePath), unsavedContent(updatedUnsavedTestFilePath),
true, true,
74)})); 74}}));
CompleteCodeMessage completeCodeMessage(functionTestFilePath, CompleteCodeMessage completeCodeMessage(functionTestFilePath,
20, 20,
1, 1,
@@ -367,4 +404,9 @@ TEST_F(ClangIpcServer, TicketNumberIsForwarded)
clangServer.completeCode(completeCodeMessage); clangServer.completeCode(completeCodeMessage);
} }
TEST_F(ClangIpcServer, TranslationUnitIsDirtyAfterCreation)
{
ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 0));
}
} }

View File

@@ -52,6 +52,7 @@
#include <requestdiagnosticsmessage.h> #include <requestdiagnosticsmessage.h>
#include <translationunitdoesnotexistmessage.h> #include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h> #include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <writemessageblock.h> #include <writemessageblock.h>
#include <QBuffer> #include <QBuffer>
@@ -128,6 +129,17 @@ TEST_F(ClientServerInProcess, SendRegisterTranslationUnitForEditorMessage)
scheduleServerMessages(); scheduleServerMessages();
} }
TEST_F(ClientServerInProcess, SendUpdateTranslationUnitsForEditorMessage)
{
ClangBackEnd::UpdateTranslationUnitsForEditorMessage message({fileContainer});
EXPECT_CALL(mockIpcServer, updateTranslationUnitsForEditor(message))
.Times(1);
serverProxy.updateTranslationUnitsForEditor(message);
scheduleServerMessages();
}
TEST_F(ClientServerInProcess, SendUnregisterTranslationUnitsForEditorMessage) TEST_F(ClientServerInProcess, SendUnregisterTranslationUnitsForEditorMessage)
{ {
ClangBackEnd::UnregisterTranslationUnitsForEditorMessage message({fileContainer}); ClangBackEnd::UnregisterTranslationUnitsForEditorMessage message({fileContainer});

View File

@@ -135,7 +135,7 @@ void CodeCompleter::SetUp()
{ {
EXPECT_TRUE(includeDirectory.isValid()); EXPECT_TRUE(includeDirectory.isValid());
projects.createOrUpdate({projectPart}); projects.createOrUpdate({projectPart});
translationUnits.createOrUpdate({mainFileContainer}); translationUnits.create({mainFileContainer});
translationUnit = translationUnits.translationUnit(mainFileContainer); translationUnit = translationUnits.translationUnit(mainFileContainer);
completer = ClangBackEnd::CodeCompleter(translationUnit); completer = ClangBackEnd::CodeCompleter(translationUnit);
@@ -147,7 +147,7 @@ void CodeCompleter::SetUp()
TEST_F(CodeCompleter, FunctionInUnsavedFile) TEST_F(CodeCompleter, FunctionInUnsavedFile)
{ {
unsavedFiles.createOrUpdate({unsavedMainFileContainer}); unsavedFiles.createOrUpdate({unsavedMainFileContainer});
translationUnits.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer});
ASSERT_THAT(completer.complete(27, 1), ASSERT_THAT(completer.complete(27, 1),
AllOf(Contains(IsCodeCompletion(Utf8StringLiteral("FunctionWithArguments"), AllOf(Contains(IsCodeCompletion(Utf8StringLiteral("FunctionWithArguments"),
@@ -165,7 +165,7 @@ TEST_F(CodeCompleter, FunctionInUnsavedFile)
TEST_F(CodeCompleter, VariableInUnsavedFile) TEST_F(CodeCompleter, VariableInUnsavedFile)
{ {
unsavedFiles.createOrUpdate({unsavedMainFileContainer}); unsavedFiles.createOrUpdate({unsavedMainFileContainer});
translationUnits.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer});
ASSERT_THAT(completer.complete(27, 1), ASSERT_THAT(completer.complete(27, 1),
Contains(IsCodeCompletion(Utf8StringLiteral("VariableInUnsavedFile"), Contains(IsCodeCompletion(Utf8StringLiteral("VariableInUnsavedFile"),
@@ -175,7 +175,7 @@ TEST_F(CodeCompleter, VariableInUnsavedFile)
TEST_F(CodeCompleter, GlobalVariableInUnsavedFile) TEST_F(CodeCompleter, GlobalVariableInUnsavedFile)
{ {
unsavedFiles.createOrUpdate({unsavedMainFileContainer}); unsavedFiles.createOrUpdate({unsavedMainFileContainer});
translationUnits.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer});
ASSERT_THAT(completer.complete(27, 1), ASSERT_THAT(completer.complete(27, 1),
Contains(IsCodeCompletion(Utf8StringLiteral("GlobalVariableInUnsavedFile"), Contains(IsCodeCompletion(Utf8StringLiteral("GlobalVariableInUnsavedFile"),
@@ -185,7 +185,7 @@ TEST_F(CodeCompleter, GlobalVariableInUnsavedFile)
TEST_F(CodeCompleter, Macro) TEST_F(CodeCompleter, Macro)
{ {
unsavedFiles.createOrUpdate({unsavedMainFileContainer}); unsavedFiles.createOrUpdate({unsavedMainFileContainer});
translationUnits.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer});
ASSERT_THAT(completer.complete(27, 1), ASSERT_THAT(completer.complete(27, 1),
Contains(IsCodeCompletion(Utf8StringLiteral("Macro"), Contains(IsCodeCompletion(Utf8StringLiteral("Macro"),
@@ -209,7 +209,7 @@ TEST_F(CodeCompleter, FunctionInIncludedHeader)
TEST_F(CodeCompleter, FunctionInUnsavedIncludedHeader) TEST_F(CodeCompleter, FunctionInUnsavedIncludedHeader)
{ {
unsavedFiles.createOrUpdate({unsavedTargetHeaderFileContainer}); unsavedFiles.createOrUpdate({unsavedTargetHeaderFileContainer});
translationUnits.createOrUpdate({unsavedTargetHeaderFileContainer}); translationUnits.create({unsavedTargetHeaderFileContainer});
ASSERT_THAT(completer.complete(27, 1), ASSERT_THAT(completer.complete(27, 1),
Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderUnsaved"), Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderUnsaved"),
@@ -228,7 +228,7 @@ TEST_F(CodeCompleter, DISABLED_FunctionInChangedIncludedHeader)
TEST_F(CodeCompleter, FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) TEST_F(CodeCompleter, FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile)
{ {
unsavedFiles.createOrUpdate({unsavedMainFileContainer}); unsavedFiles.createOrUpdate({unsavedMainFileContainer});
translationUnits.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer});
copyChangedTargetHeaderToTemporaryIncludeDirecory(); copyChangedTargetHeaderToTemporaryIncludeDirecory();

View File

@@ -44,6 +44,8 @@ public:
void()); void());
MOCK_METHOD1(registerTranslationUnitsForEditor, MOCK_METHOD1(registerTranslationUnitsForEditor,
void(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message)); void(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message));
MOCK_METHOD1(updateTranslationUnitsForEditor,
void(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message));
MOCK_METHOD1(unregisterTranslationUnitsForEditor, MOCK_METHOD1(unregisterTranslationUnitsForEditor,
void(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message)); void(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message));
MOCK_METHOD1(registerProjectPartsForEditor, MOCK_METHOD1(registerProjectPartsForEditor,

View File

@@ -42,6 +42,7 @@
#include <sourcelocation.h> #include <sourcelocation.h>
#include <registerunsavedfilesforeditormessage.h> #include <registerunsavedfilesforeditormessage.h>
#include <unregisterunsavedfilesforeditormessage.h> #include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <writemessageblock.h> #include <writemessageblock.h>
#include <QBuffer> #include <QBuffer>
@@ -151,6 +152,11 @@ TEST_F(ReadAndWriteMessageBlock, CompareRegisterTranslationUnitForEditorMessage)
CompareMessage(ClangBackEnd::RegisterTranslationUnitForEditorMessage({fileContainer})); CompareMessage(ClangBackEnd::RegisterTranslationUnitForEditorMessage({fileContainer}));
} }
TEST_F(ReadAndWriteMessageBlock, CompareUpdateTranslationUnitForEditorMessage)
{
CompareMessage(ClangBackEnd::UpdateTranslationUnitsForEditorMessage({fileContainer}));
}
TEST_F(ReadAndWriteMessageBlock, CompareUnregisterFileForEditorMessage) TEST_F(ReadAndWriteMessageBlock, CompareUnregisterFileForEditorMessage)
{ {
CompareMessage(ClangBackEnd::UnregisterTranslationUnitsForEditorMessage({fileContainer})); CompareMessage(ClangBackEnd::UnregisterTranslationUnitsForEditorMessage({fileContainer}));

View File

@@ -35,6 +35,7 @@
#include <projectpartsdonotexistexception.h> #include <projectpartsdonotexistexception.h>
#include <projects.h> #include <projects.h>
#include <translationunitdoesnotexistexception.h> #include <translationunitdoesnotexistexception.h>
#include <translationunitalreadyexistsexception.h>
#include <translationunitfilenotexitexception.h> #include <translationunitfilenotexitexception.h>
#include <translationunit.h> #include <translationunit.h>
#include <translationunitisnullexception.h> #include <translationunitisnullexception.h>
@@ -115,7 +116,7 @@ TEST_F(TranslationUnits, ThrowForAddingNonExistingFile)
{ {
ClangBackEnd::FileContainer fileContainer(nonExistingFilePath, projectPartId); ClangBackEnd::FileContainer fileContainer(nonExistingFilePath, projectPartId);
ASSERT_THROW(translationUnits.createOrUpdate({fileContainer}), ASSERT_THROW(translationUnits.create({fileContainer}),
ClangBackEnd::TranslationUnitFileNotExitsException); ClangBackEnd::TranslationUnitFileNotExitsException);
} }
@@ -123,29 +124,56 @@ TEST_F(TranslationUnits, DoNotThrowForAddingNonExistingFileWithUnsavedContent)
{ {
ClangBackEnd::FileContainer fileContainer(nonExistingFilePath, projectPartId, Utf8String(), true); ClangBackEnd::FileContainer fileContainer(nonExistingFilePath, projectPartId, Utf8String(), true);
ASSERT_NO_THROW(translationUnits.createOrUpdate({fileContainer})); ASSERT_NO_THROW(translationUnits.create({fileContainer}));
} }
TEST_F(TranslationUnits, Add) TEST_F(TranslationUnits, Add)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
translationUnits.createOrUpdate({fileContainer}); translationUnits.create({fileContainer});
ASSERT_THAT(translationUnits.translationUnit(filePath, projectPartId), ASSERT_THAT(translationUnits.translationUnit(filePath, projectPartId),
IsTranslationUnit(filePath, projectPartId, 74u)); IsTranslationUnit(filePath, projectPartId, 74u));
} }
TEST_F(TranslationUnits, ThrowForCreatingAnExistingTranslationUnit)
{
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
translationUnits.create({fileContainer});
ASSERT_THROW(translationUnits.create({fileContainer}),
ClangBackEnd::TranslationUnitAlreadyExistsException);
}
TEST_F(TranslationUnits, ThrowForUpdatingANonExistingTranslationUnit)
{
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
ASSERT_THROW(translationUnits.update({fileContainer}),
ClangBackEnd::TranslationUnitDoesNotExistException);
}
TEST_F(TranslationUnits, Update)
{
ClangBackEnd::FileContainer createFileContainer(filePath, projectPartId, 74u);
ClangBackEnd::FileContainer updateFileContainer(filePath, Utf8String(), 75u);
translationUnits.create({createFileContainer});
translationUnits.update({updateFileContainer});
ASSERT_THAT(translationUnits.translationUnit(filePath, projectPartId),
IsTranslationUnit(filePath, projectPartId, 75u));
}
TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForReparse) TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForReparse)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u); ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u); ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u);
translationUnits.createOrUpdate({fileContainer, headerContainer}); translationUnits.create({fileContainer, headerContainer});
translationUnits.translationUnit(filePath, projectPartId).cxTranslationUnit(); translationUnits.translationUnit(filePath, projectPartId).cxTranslationUnit();
translationUnits.createOrUpdate({headerContainerWithUnsavedContent}); translationUnits.update({headerContainerWithUnsavedContent});
ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).isNeedingReparse()); ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).isNeedingReparse());
} }
@@ -155,10 +183,10 @@ TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForDiagnostics)
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u); ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u); ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u);
translationUnits.createOrUpdate({fileContainer, headerContainer}); translationUnits.create({fileContainer, headerContainer});
translationUnits.translationUnit(filePath, projectPartId).diagnostics(); translationUnits.translationUnit(filePath, projectPartId).diagnostics();
translationUnits.createOrUpdate({headerContainerWithUnsavedContent}); translationUnits.update({headerContainerWithUnsavedContent});
ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewDiagnostics()); ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewDiagnostics());
} }
@@ -168,7 +196,7 @@ TEST_F(TranslationUnits, RemoveFileAndCheckForDiagnostics)
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u); ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, 74u);
ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u); ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u);
translationUnits.createOrUpdate({fileContainer, headerContainer}); translationUnits.create({fileContainer, headerContainer});
translationUnits.translationUnit(filePath, projectPartId).diagnostics(); translationUnits.translationUnit(filePath, projectPartId).diagnostics();
translationUnits.remove({headerContainerWithUnsavedContent}); translationUnits.remove({headerContainerWithUnsavedContent});
@@ -179,7 +207,7 @@ TEST_F(TranslationUnits, RemoveFileAndCheckForDiagnostics)
TEST_F(TranslationUnits, DontGetNewerFileContainerIfRevisionIsTheSame) TEST_F(TranslationUnits, DontGetNewerFileContainerIfRevisionIsTheSame)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
translationUnits.createOrUpdate({fileContainer}); translationUnits.create({fileContainer});
auto newerFileContainers = translationUnits.newerFileContainers({fileContainer}); auto newerFileContainers = translationUnits.newerFileContainers({fileContainer});
@@ -190,7 +218,7 @@ TEST_F(TranslationUnits, GetNewerFileContainerIfRevisionIsDifferent)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, 74u);
ClangBackEnd::FileContainer newerContainer(filePath, projectPartId, 75u); ClangBackEnd::FileContainer newerContainer(filePath, projectPartId, 75u);
translationUnits.createOrUpdate({fileContainer}); translationUnits.create({fileContainer});
auto newerFileContainers = translationUnits.newerFileContainers({newerContainer}); auto newerFileContainers = translationUnits.newerFileContainers({newerContainer});
@@ -216,7 +244,7 @@ TEST_F(TranslationUnits, ThrowForRemovingWithWrongProjectPartFilePath)
TEST_F(TranslationUnits, Remove) TEST_F(TranslationUnits, Remove)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId);
translationUnits.createOrUpdate({fileContainer}); translationUnits.create({fileContainer});
translationUnits.remove({fileContainer}); translationUnits.remove({fileContainer});
@@ -227,7 +255,7 @@ TEST_F(TranslationUnits, Remove)
TEST_F(TranslationUnits, RemoveAllValidIfExceptionIsThrown) TEST_F(TranslationUnits, RemoveAllValidIfExceptionIsThrown)
{ {
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId); ClangBackEnd::FileContainer fileContainer(filePath, projectPartId);
translationUnits.createOrUpdate({fileContainer}); translationUnits.create({fileContainer});
ASSERT_THROW(translationUnits.remove({ClangBackEnd::FileContainer(Utf8StringLiteral("dontextist.pro"), projectPartId), fileContainer}), ASSERT_THROW(translationUnits.remove({ClangBackEnd::FileContainer(Utf8StringLiteral("dontextist.pro"), projectPartId), fileContainer}),
ClangBackEnd::TranslationUnitDoesNotExistException); ClangBackEnd::TranslationUnitDoesNotExistException);
@@ -240,7 +268,7 @@ TEST_F(TranslationUnits, RemoveAllValidIfExceptionIsThrown)
TEST_F(TranslationUnits, HasTranslationUnit) TEST_F(TranslationUnits, HasTranslationUnit)
{ {
translationUnits.createOrUpdate({{filePath, projectPartId}}); translationUnits.create({{filePath, projectPartId}});
ASSERT_TRUE(translationUnits.hasTranslationUnit(filePath)); ASSERT_TRUE(translationUnits.hasTranslationUnit(filePath));
} }