Clang: Integrate highlighting results from backend

Change-Id: I2c3fb69aabfe075bde76d63eafc2ca370f17493c
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
Marco Bubke
2015-11-18 17:07:44 +01:00
committed by Nikolai Kosjar
parent eb2457869d
commit 7ce9ef9db4
61 changed files with 1855 additions and 393 deletions

View File

@@ -42,10 +42,13 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
$$PWD/sourcelocationcontainer.cpp \
$$PWD/fixitcontainer.cpp \
$$PWD/requestdiagnosticsmessage.cpp \
$$PWD/requesthighlightingmessage.cpp \
$$PWD/registerunsavedfilesforeditormessage.cpp \
$$PWD/unregisterunsavedfilesforeditormessage.cpp \
$$PWD/updatetranslationunitsforeditormessage.cpp \
$$PWD/updatevisibletranslationunitsmessage.cpp
$$PWD/updatevisibletranslationunitsmessage.cpp \
$$PWD/highlightingchangedmessage.cpp \
$$PWD/highlightingmarkcontainer.cpp
HEADERS += \
$$PWD/ipcserverinterface.h \
@@ -84,9 +87,12 @@ HEADERS += \
$$PWD/sourcelocationcontainer.h \
$$PWD/fixitcontainer.h \
$$PWD/requestdiagnosticsmessage.h \
$$PWD/requesthighlightingmessage.h \
$$PWD/registerunsavedfilesforeditormessage.h \
$$PWD/unregisterunsavedfilesforeditormessage.h \
$$PWD/updatetranslationunitsforeditormessage.h \
$$PWD/updatevisibletranslationunitsmessage.h
$$PWD/updatevisibletranslationunitsmessage.h \
$$PWD/highlightingchangedmessage.h \
$$PWD/highlightingmarkcontainer.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -43,6 +43,9 @@
#include "diagnosticschangedmessage.h"
#include "registerunsavedfilesforeditormessage.h"
#include "requestdiagnosticsmessage.h"
#include "requesthighlightingmessage.h"
#include "highlightingchangedmessage.h"
#include "highlightingmarkcontainer.h"
#include "projectpartsdonotexistmessage.h"
#include "sourcelocationcontainer.h"
#include "sourcerangecontainer.h"
@@ -83,6 +86,9 @@ void Messages::registerMessages()
registerMetaType<RequestDiagnosticsMessage>();
registerMetaType<DiagnosticsChangedMessage>();
registerMetaType<RequestHighlightingMessage>();
registerMetaType<HighlightingChangedMessage>();
registerMetaType<UpdateVisibleTranslationUnitsMessage>();
registerMetaType<CompleteCodeMessage>();
@@ -94,6 +100,7 @@ void Messages::registerMessages()
// Containers
registerMetaType<DiagnosticContainer>();
registerMetaType<HighlightingMarkContainer>();
registerMetaType<FileContainer>();
registerMetaType<ProjectPartContainer>();
registerMetaType<SourceLocationContainer>();

View File

@@ -0,0 +1,119 @@
/****************************************************************************
**
** 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 "highlightingchangedmessage.h"
#include "container_common.h"
#include <QDataStream>
#include <QDebug>
#include <ostream>
namespace ClangBackEnd {
HighlightingChangedMessage::HighlightingChangedMessage(const FileContainer &file,
const QVector<HighlightingMarkContainer> &highlightingMarks,
const QVector<SourceRangeContainer> &skippedPreprocessorRanges)
: file_(file),
highlightingMarks_(highlightingMarks),
skippedPreprocessorRanges_(skippedPreprocessorRanges)
{
}
const FileContainer &HighlightingChangedMessage::file() const
{
return file_;
}
const QVector<HighlightingMarkContainer> &HighlightingChangedMessage::highlightingMarks() const
{
return highlightingMarks_;
}
const QVector<SourceRangeContainer> &HighlightingChangedMessage::skippedPreprocessorRanges() const
{
return skippedPreprocessorRanges_;
}
QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message)
{
out << message.file_;
out << message.highlightingMarks_;
out << message.skippedPreprocessorRanges_;
return out;
}
QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message)
{
in >> message.file_;
in >> message.highlightingMarks_;
in >> message.skippedPreprocessorRanges_;
return in;
}
bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second)
{
return first.file_ == second.file_
&& first.highlightingMarks_ == second.highlightingMarks_
&& first.skippedPreprocessorRanges_ == second.skippedPreprocessorRanges_;
}
bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second)
{
return first.file_ < second.file_
&& compareContainer(first.highlightingMarks_, second.highlightingMarks_)
&& compareContainer(first.skippedPreprocessorRanges_, second.skippedPreprocessorRanges_);
}
QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message)
{
debug.nospace() << "HighlightingChangedMessage("
<< message.file_
<< ", " << message.highlightingMarks_.size()
<< ", " << message.skippedPreprocessorRanges_.size()
<< ")";
return debug;
}
void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os)
{
*os << "HighlightingChangedMessage(";
PrintTo(message.file(), os);
*os << "," << message.highlightingMarks().size();
*os << "," << message.skippedPreprocessorRanges().size();
*os << ")";
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,80 @@
/****************************************************************************
**
** 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_HIGHLIGHTINGCHANGEDMESSAGE_H
#define CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H
#include "clangbackendipc_global.h"
#include "filecontainer.h"
#include "highlightingmarkcontainer.h"
#include "sourcerangecontainer.h"
#include <QVector>
namespace ClangBackEnd {
class CMBIPC_EXPORT HighlightingChangedMessage
{
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message);
friend CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
friend CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message);
friend void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os);
public:
HighlightingChangedMessage() = default;
HighlightingChangedMessage(const FileContainer &file,
const QVector<HighlightingMarkContainer> &highlightingMarks,
const QVector<SourceRangeContainer> &skippedPreprocessorRanges);
const FileContainer &file() const;
const QVector<HighlightingMarkContainer> &highlightingMarks() const;
const QVector<SourceRangeContainer> &skippedPreprocessorRanges() const;
private:
FileContainer file_;
QVector<HighlightingMarkContainer> highlightingMarks_;
QVector<SourceRangeContainer> skippedPreprocessorRanges_;
};
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message);
CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message);
void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os);
} // namespace ClangBackEnd
Q_DECLARE_METATYPE(ClangBackEnd::HighlightingChangedMessage)
#endif // CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H

View File

@@ -0,0 +1,173 @@
/****************************************************************************
**
** 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 "highlightingmarkcontainer.h"
#include <QDataStream>
#include <QDebug>
#include <ostream>
namespace ClangBackEnd {
HighlightingMarkContainer::HighlightingMarkContainer(uint line,
uint column,
uint length,
HighlightingType type)
: line_(line),
column_(column),
length_(length),
type_(type)
{
}
uint HighlightingMarkContainer::line() const
{
return line_;
}
uint HighlightingMarkContainer::column() const
{
return column_;
}
uint HighlightingMarkContainer::length() const
{
return length_;
}
HighlightingType HighlightingMarkContainer::type() const
{
return type_;
}
quint32 &HighlightingMarkContainer::typeAsInt()
{
return reinterpret_cast<quint32&>(type_);
}
QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container)
{
out << container.line_;
out << container.column_;
out << container.length_;
out << quint32(container.type_);
return out;
}
QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container)
{
in >> container.line_;
in >> container.column_;
in >> container.length_;
in >> container.typeAsInt();
return in;
}
bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second)
{
return first.line_ == second.line_
&& first.column_ == second.column_
&& first.length_ == second.length_
&& first.type_ == second.type_;
}
bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second)
{
if (first.line() == second.line()) {
if (first.column() == second.column()) {
if (first.length() == second.length())
return first.type() < second.type();
return first.length() < second.length();
}
return first.column() < second.column();
}
return first.line() < second.line();
}
#define RETURN_TEXT_FOR_CASE(enumValue) case HighlightingType::enumValue: return #enumValue
static const char *highlightingTypeToCStringLiteral(HighlightingType type)
{
switch (type) {
RETURN_TEXT_FOR_CASE(Invalid);
RETURN_TEXT_FOR_CASE(Comment);
RETURN_TEXT_FOR_CASE(Keyword);
RETURN_TEXT_FOR_CASE(StringLiteral);
RETURN_TEXT_FOR_CASE(NumberLiteral);
RETURN_TEXT_FOR_CASE(Function);
RETURN_TEXT_FOR_CASE(VirtualFunction);
RETURN_TEXT_FOR_CASE(Type);
RETURN_TEXT_FOR_CASE(LocalVariable);
RETURN_TEXT_FOR_CASE(GlobalVariable);
RETURN_TEXT_FOR_CASE(Field);
RETURN_TEXT_FOR_CASE(Enumeration);
RETURN_TEXT_FOR_CASE(Operator);
RETURN_TEXT_FOR_CASE(Preprocessor);
RETURN_TEXT_FOR_CASE(Label);
RETURN_TEXT_FOR_CASE(OutputArgument);
RETURN_TEXT_FOR_CASE(PreprocessorDefinition);
RETURN_TEXT_FOR_CASE(PreprocessorExpansion);
default: return "UnhandledHighlightingType";
}
}
#undef RETURN_TEXT_FOR_CASE
QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container)
{
debug.nospace() << "HighlightingMarkContainer("
<< container.line() << ", "
<< container.column() << ", "
<< container.length() << ", "
<< highlightingTypeToCStringLiteral(container.type()) << ", "
<< ")";
return debug;
}
void PrintTo(HighlightingType highlightingType, std::ostream *os)
{
*os << highlightingTypeToCStringLiteral(highlightingType);
}
void PrintTo(const HighlightingMarkContainer& container, ::std::ostream *os)
{
*os << "HighlightingMarkContainer("
<< container.line() << ", "
<< container.column() << ", "
<< container.length() << ", ";
PrintTo(container.type(), os);
*os << ")";
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** 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_HIGHLIGHTINGMARKCONTAINER_H
#define CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H
#include "clangbackendipc_global.h"
#include <QMetaType>
namespace ClangBackEnd {
class CMBIPC_EXPORT HighlightingMarkContainer
{
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container);
friend CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
friend CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
public:
HighlightingMarkContainer() = default;
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingType type);
uint line() const;
uint column() const;
uint length() const;
HighlightingType type() const;
private:
quint32 &typeAsInt();
private:
uint line_;
uint column_;
uint length_;
HighlightingType type_;
};
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container);
CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container);
CMBIPC_EXPORT void PrintTo(HighlightingType highlightingType, ::std::ostream *os);
void PrintTo(const HighlightingMarkContainer &container, ::std::ostream *os);
} // namespace ClangBackEnd
Q_DECLARE_METATYPE(ClangBackEnd::HighlightingMarkContainer)
#endif // CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H

View File

@@ -80,5 +80,11 @@ void IpcClientDispatcher::diagnosticsChanged(const DiagnosticsChangedMessage &me
client->diagnosticsChanged(message);
}
void IpcClientDispatcher::highlightingChanged(const HighlightingChangedMessage &message)
{
for (auto *client : clients)
client->highlightingChanged(message);
}
} // namespace ClangBackEnd

View File

@@ -49,6 +49,7 @@ public:
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
void highlightingChanged(const HighlightingChangedMessage &message) override;
private:
QVector<IpcClientInterface*> clients;

View File

@@ -35,6 +35,7 @@
#include "projectpartsdonotexistmessage.h"
#include "translationunitdoesnotexistmessage.h"
#include "diagnosticschangedmessage.h"
#include "highlightingchangedmessage.h"
#include <QDebug>
#include <QVariant>
@@ -50,6 +51,7 @@ void IpcClientInterface::dispatch(const QVariant &message)
static const int translationUnitDoesNotExistMessage = QMetaType::type("ClangBackEnd::TranslationUnitDoesNotExistMessage");
static const int projectPartsDoNotExistMessage = QMetaType::type("ClangBackEnd::ProjectPartsDoNotExistMessage");
static const int diagnosticsChangedMessage = QMetaType::type("ClangBackEnd::DiagnosticsChangedMessage");
static const int highlightingChangedMessage = QMetaType::type("ClangBackEnd::HighlightingChangedMessage");
int type = message.userType();
@@ -65,6 +67,8 @@ void IpcClientInterface::dispatch(const QVariant &message)
projectPartsDoNotExist(message.value<ProjectPartsDoNotExistMessage>());
else if (type == diagnosticsChangedMessage)
diagnosticsChanged(message.value<DiagnosticsChangedMessage>());
else if (type == highlightingChangedMessage)
highlightingChanged(message.value<HighlightingChangedMessage>());
else
qWarning() << "Unknown IpcClientMessage";
}

View File

@@ -51,6 +51,8 @@ class RequestDiagnosticsMessage;
class RegisterUnsavedFilesForEditorMessage;
class UnregisterUnsavedFilesForEditorMessage;
class UpdateVisibleTranslationUnitsMessage;
class RequestHighlightingMessage;
class HighlightingChangedMessage;
class CMBIPC_EXPORT IpcClientInterface : public IpcInterface
{
@@ -63,6 +65,7 @@ public:
virtual void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) = 0;
virtual void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) = 0;
virtual void diagnosticsChanged(const DiagnosticsChangedMessage &message) = 0;
virtual void highlightingChanged(const HighlightingChangedMessage &message) = 0;
};
} // namespace ClangBackEnd

View File

@@ -35,6 +35,7 @@
#include "cmbechomessage.h"
#include "cmbregistertranslationunitsforeditormessage.h"
#include "diagnosticschangedmessage.h"
#include "highlightingchangedmessage.h"
#include "ipcserverinterface.h"
#include "projectpartsdonotexistmessage.h"
#include "translationunitdoesnotexistmessage.h"
@@ -104,6 +105,11 @@ void IpcClientProxy::diagnosticsChanged(const DiagnosticsChangedMessage &message
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcClientProxy::highlightingChanged(const HighlightingChangedMessage &message)
{
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcClientProxy::readMessages()
{
for (const QVariant &message : readMessageBlock.readAll())

View File

@@ -63,6 +63,7 @@ public:
void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override;
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
void diagnosticsChanged(const DiagnosticsChangedMessage &message) override;
void highlightingChanged(const HighlightingChangedMessage &message) override;
void readMessages();

View File

@@ -37,6 +37,7 @@
#include "cmbunregistertranslationunitsforeditormessage.h"
#include "registerunsavedfilesforeditormessage.h"
#include "requestdiagnosticsmessage.h"
#include "requesthighlightingmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
@@ -58,9 +59,9 @@ void IpcServerInterface::dispatch(const QVariant &message)
static const int unregisterUnsavedFilesForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterUnsavedFilesForEditorMessage");
static const int completeCodeMessageType = QMetaType::type("ClangBackEnd::CompleteCodeMessage");
static const int requestDiagnosticsMessageType = QMetaType::type("ClangBackEnd::RequestDiagnosticsMessage");
static const int requestHighlightingTypeMessage = QMetaType::type("ClangBackEnd::RequestHighlightingMessage");
static const int updateVisibleTranslationUnitsMessageType = QMetaType::type("ClangBackEnd::UpdateVisibleTranslationUnitsMessage");
int type = message.userType();
if (type == endMessageType)
@@ -83,6 +84,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
completeCode(message.value<CompleteCodeMessage>());
else if (type == requestDiagnosticsMessageType)
requestDiagnostics(message.value<RequestDiagnosticsMessage>());
else if (type == requestHighlightingTypeMessage)
requestHighlighting(message.value<RequestHighlightingMessage>());
else if (type == updateVisibleTranslationUnitsMessageType)
updateVisibleTranslationUnits(message.value<UpdateVisibleTranslationUnitsMessage>());
else

View File

@@ -54,6 +54,7 @@ public:
virtual void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) = 0;
virtual void completeCode(const CompleteCodeMessage &message) = 0;
virtual void requestDiagnostics(const RequestDiagnosticsMessage &message) = 0;
virtual void requestHighlighting(const RequestHighlightingMessage &message) = 0;
virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0;
void addClient(IpcClientInterface *client);

View File

@@ -40,6 +40,7 @@
#include <ipcclientinterface.h>
#include <registerunsavedfilesforeditormessage.h>
#include <requestdiagnosticsmessage.h>
#include <requesthighlightingmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
@@ -120,6 +121,11 @@ void IpcServerProxy::requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMe
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcServerProxy::requestHighlighting(const RequestHighlightingMessage &message)
{
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
writeMessageBlock.write(QVariant::fromValue(message));

View File

@@ -65,7 +65,9 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void requestHighlighting(const RequestHighlightingMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
void readMessages();
void resetCounter();

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** 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 "requesthighlightingmessage.h"
#include <QDataStream>
#include <QDebug>
#include <ostream>
namespace ClangBackEnd {
RequestHighlightingMessage::RequestHighlightingMessage(const FileContainer &file)
: fileContainer_(file)
{
}
const FileContainer RequestHighlightingMessage::fileContainer() const
{
return fileContainer_;
}
QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message)
{
out << message.fileContainer_;
return out;
}
QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message)
{
in >> message.fileContainer_;
return in;
}
bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second)
{
return first.fileContainer_ == second.fileContainer_;
}
bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second)
{
return first.fileContainer_ < second.fileContainer_;
}
QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message)
{
debug.nospace() << "RequestHighlightingMessage("
<< message.fileContainer()
<< ")";
return debug;
}
void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os)
{
*os << message.fileContainer().filePath().constData()
<< "(" << message.fileContainer().projectPartId().constData() << ")";
}
} // 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 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_REQUESTHIGHLIGHTING_H
#define CLANGBACKEND_REQUESTHIGHLIGHTING_H
#include "filecontainer.h"
namespace ClangBackEnd {
class CMBIPC_EXPORT RequestHighlightingMessage
{
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message);
friend CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
friend CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message);
friend void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os);
public:
RequestHighlightingMessage() = default;
RequestHighlightingMessage(const FileContainer &fileContainer);
const FileContainer fileContainer() const;
private:
FileContainer fileContainer_;
};
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message);
CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message);
void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os);
} // namespace ClangBackEnd
Q_DECLARE_METATYPE(ClangBackEnd::RequestHighlightingMessage)
#endif // CLANGBACKEND_REQUESTHIGHLIGHTING_H

View File

@@ -48,6 +48,7 @@
#include <texteditor/texteditor.h>
#include <clangbackendipc/diagnosticschangedmessage.h>
#include <clangbackendipc/highlightingchangedmessage.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
@@ -62,6 +63,7 @@
#include <clangbackendipc/cmbmessages.h>
#include <clangbackendipc/registerunsavedfilesforeditormessage.h>
#include <clangbackendipc/requestdiagnosticsmessage.h>
#include <clangbackendipc/requesthighlightingmessage.h>
#include <clangbackendipc/filecontainer.h>
#include <clangbackendipc/projectpartsdonotexistmessage.h>
#include <clangbackendipc/translationunitdoesnotexistmessage.h>
@@ -174,6 +176,24 @@ void IpcReceiver::diagnosticsChanged(const DiagnosticsChangedMessage &message)
}
}
void IpcReceiver::highlightingChanged(const HighlightingChangedMessage &message)
{
qCDebug(log) << "<<< HighlightingChangedMessage with"
<< message.highlightingMarks().size() << "items";
auto processor = ClangEditorDocumentProcessor::get(message.file().filePath());
if (processor && processor->projectPart()) {
const QString highlightingProjectPartId = message.file().projectPartId();
const QString documentProjectPartId = processor->projectPart()->id();
if (highlightingProjectPartId == documentProjectPartId) {
processor->updateHighlighting(message.highlightingMarks(),
message.skippedPreprocessorRanges(),
message.file().documentRevision());
}
}
}
void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message)
{
QTC_CHECK(!"Got TranslationUnitDoesNotExistMessage");
@@ -203,6 +223,7 @@ public:
void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override;
void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override;
void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) override;
private:
ClangBackEnd::ConnectionClient &m_connection;
@@ -268,6 +289,12 @@ void IpcSender::requestDiagnostics(const RequestDiagnosticsMessage &message)
m_connection.serverProxy().requestDiagnostics(message);
}
void IpcSender::requestHighlighting(const RequestHighlightingMessage &message)
{
QTC_CHECK(m_connection.isConnected());
m_connection.serverProxy().requestHighlighting(message);
}
IpcCommunicator::IpcCommunicator()
: m_connection(&m_ipcReceiver)
, m_ipcSender(new IpcSender(m_connection))
@@ -446,33 +473,50 @@ void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArra
documentRevision}});
}
void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
void IpcCommunicator::requestDiagnosticsAndHighlighting(const FileContainer &fileContainer,
DocumentChangedCheck documentChangedCheck)
{
if (m_sendMode == IgnoreSendRequests)
return;
if (documentHasChanged(fileContainer.filePath())) {
updateTranslationUnitsForEditor({fileContainer});
const RequestDiagnosticsMessage message(fileContainer);
qCDebug(log) << ">>>" << message;
m_ipcSender->requestDiagnostics(message);
setLastSentDocumentRevision(fileContainer.filePath(),
fileContainer.documentRevision());
if (documentChangedCheck == DocumentChangedCheck::RevisionCheck) {
if (documentHasChanged(fileContainer.filePath())) {
updateTranslationUnitsForEditor({fileContainer});
requestDiagnostics(fileContainer);
requestHighlighting(fileContainer);
setLastSentDocumentRevision(fileContainer.filePath(),
fileContainer.documentRevision());
}
} else {
requestDiagnostics(fileContainer);
requestHighlighting(fileContainer);
}
}
void IpcCommunicator::requestDiagnostics(Core::IDocument *document)
void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
{
const RequestDiagnosticsMessage message(fileContainer);
qCDebug(log) << ">>>" << message;
m_ipcSender->requestDiagnostics(message);
}
void IpcCommunicator::requestHighlighting(const FileContainer &fileContainer)
{
const RequestHighlightingMessage message(fileContainer);
qCDebug(log) << ">>>" << message;
m_ipcSender->requestHighlighting(message);
}
void IpcCommunicator::requestDiagnosticsAndHighlighting(Core::IDocument *document)
{
const auto textDocument = qobject_cast<TextDocument*>(document);
const auto filePath = textDocument->filePath().toString();
const QString projectPartId = Utils::projectPartIdForFile(filePath);
requestDiagnostics(FileContainer(filePath,
projectPartId,
Utf8StringVector(),
textDocument->document()->revision()));
requestDiagnosticsAndHighlighting(FileContainer(filePath,
projectPartId,
Utf8StringVector(),
textDocument->document()->revision()));
}
void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position)

View File

@@ -81,6 +81,7 @@ private:
void echo(const ClangBackEnd::EchoMessage &message) override;
void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override;
void diagnosticsChanged(const ClangBackEnd::DiagnosticsChangedMessage &message) override;
void highlightingChanged(const ClangBackEnd::HighlightingChangedMessage &message) override;
void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &message) override;
void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &message) override;
@@ -105,6 +106,7 @@ public:
virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0;
virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0;
virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0;
virtual void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) = 0;
};
class IpcCommunicator : public QObject
@@ -116,6 +118,8 @@ public:
using FileContainers = QVector<ClangBackEnd::FileContainer>;
using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>;
enum class DocumentChangedCheck { NoCheck, RevisionCheck };
public:
IpcCommunicator();
@@ -140,8 +144,9 @@ public:
void updateUnsavedFileFromCppEditorDocument(const QString &filePath);
void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
void requestDiagnostics(Core::IDocument *document);
void requestDiagnosticsAndHighlighting(const ClangBackEnd::FileContainer &fileContainer,
DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck);
void requestDiagnosticsAndHighlighting(Core::IDocument *document);
void updateChangeContentStartPosition(const QString &filePath, int position);
void registerFallbackProjectPart();
@@ -162,6 +167,9 @@ private:
void registerCurrentCppEditorDocuments();
void registerCurrentCodeModelUiHeaders();
void requestHighlighting(const ClangBackEnd::FileContainer &fileContainer);
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
void onBackendRestarted();
void onEditorAboutToClose(Core::IEditor *editor);
void onCoreAboutToClose();

View File

@@ -41,6 +41,7 @@ SOURCES += \
cxprettyprinter.cpp \
diagnostic.cpp \
fastindexer.cpp \
highlightingmarksreporter.cpp \
pchinfo.cpp \
pchmanager.cpp \
raii/scopedclangoptions.cpp \
@@ -86,6 +87,7 @@ HEADERS += \
cxraii.h \
diagnostic.h \
fastindexer.h \
highlightingmarksreporter.h \
pchinfo.h \
pchmanager.h \
raii/scopedclangoptions.h \

View File

@@ -81,6 +81,8 @@ QtcPlugin {
files: [
"cppcreatemarkers.cpp",
"cppcreatemarkers.h",
"highlightingmarksreporter.cpp",
"highlightingmarksreporter.h",
]
}

View File

@@ -58,11 +58,6 @@ static void initializeTextMarks()
Utils::Theme::ClangCodeModel_Error_TextMarkColor);
}
ClangCodeModelPlugin::ClangCodeModelPlugin()
{
qRegisterMetaType<CppTools::ProjectPart::Ptr>();
}
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
Q_UNUSED(arguments)

View File

@@ -50,8 +50,6 @@ class ClangCodeModelPlugin: public ExtensionSystem::IPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ClangCodeModel.json")
public:
ClangCodeModelPlugin();
bool initialize(const QStringList &arguments, QString *errorMessage);
void extensionsInitialized();

View File

@@ -5,11 +5,13 @@ SOURCES += $$PWD/completionchunkstotextconverter.cpp \
$$PWD/activationsequencecontextprocessor.cpp \
$$PWD/clangcompletioncontextanalyzer.cpp \
$$PWD/clangdiagnosticfilter.cpp \
$$PWD/clangfixitoperation.cpp
$$PWD/clangfixitoperation.cpp \
$$PWD/highlightingmarksreporter.cpp
HEADERS += $$PWD/completionchunkstotextconverter.h \
$$PWD/activationsequenceprocessor.h \
$$PWD/activationsequencecontextprocessor.h \
$$PWD/clangcompletioncontextanalyzer.h \
$$PWD/clangdiagnosticfilter.h \
$$PWD/clangfixitoperation.h
$$PWD/clangfixitoperation.h \
$$PWD/highlightingmarksreporter.h

View File

@@ -29,111 +29,22 @@
****************************************************************************/
#include "clangeditordocumentparser.h"
#include "clangutils.h"
#include "pchinfo.h"
#include "pchmanager.h"
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojects.h>
#include <cpptools/cppworkingcopy.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <QLoggingCategory>
static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.clangeditordocumentparser")
namespace {
QStringList createOptions(const QString &filePath,
const CppTools::ProjectPart::Ptr &part,
bool includeSpellCheck = false)
{
using namespace ClangCodeModel;
QStringList options;
if (part.isNull())
return options;
if (includeSpellCheck)
options += QLatin1String("-fspell-checking");
options += ClangCodeModel::Utils::createClangOptions(part, filePath);
if (Internal::PchInfo::Ptr pchInfo = Internal::PchManager::instance()->pchInfo(part))
options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()));
return options;
}
QString messageLine(const QStringList &options, const QString &fileName)
{
const QStringList allOptions = QStringList(options)
<< QLatin1String("-fsyntax-only") << fileName;
QStringList allOptionsQuoted;
foreach (const QString &option, allOptions)
allOptionsQuoted.append(QLatin1Char('\'') + option + QLatin1Char('\''));
return ::Utils::HostOsInfo::withExecutableSuffix(QLatin1String("clang"))
+ QLatin1Char(' ') + allOptionsQuoted.join(QLatin1Char(' '));
}
} // anonymous namespace
namespace ClangCodeModel {
ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
: BaseEditorDocumentParser(filePath)
, m_marker(new ClangCodeModel::SemanticMarker)
{
BaseEditorDocumentParser::Configuration config = configuration();
config.stickToPreviousProjectPart = false;
setConfiguration(config);
}
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info)
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &)
{
QTC_ASSERT(m_marker, return);
// Determine project part
State state_ = state();
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
setState(state_);
emit projectPartDetermined(state_.projectPart);
// Determine message line arguments
const QStringList options = createOptions(filePath(), state_.projectPart, true);
qCDebug(log, "Reparse options (cmd line equivalent): %s",
messageLine(options, filePath()).toUtf8().constData());
// Run
QTime t; t.start();
QMutexLocker lock(m_marker->mutex());
m_marker->setFileName(filePath());
m_marker->setCompilationOptions(options);
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(info.workingCopy,
info.modifiedFiles);
m_marker->reparse(unsavedFiles);
qCDebug(log) << "Reparse took" << t.elapsed() << "ms.";
}
QList<Diagnostic> ClangEditorDocumentParser::diagnostics() const
{
QTC_ASSERT(m_marker, return QList<Diagnostic>());
QMutexLocker(m_marker->mutex());
return m_marker->diagnostics();
}
QList<SemanticMarker::Range> ClangEditorDocumentParser::ifdefedOutBlocks() const
{
QTC_ASSERT(m_marker, return QList<SemanticMarker::Range>());
QMutexLocker(m_marker->mutex());
return m_marker->ifdefedOutBlocks();
}
SemanticMarker::Ptr ClangEditorDocumentParser::semanticMarker() const
{
return m_marker;
}
} // namespace ClangCodeModel

View File

@@ -31,12 +31,8 @@
#ifndef CLANGEDITORDOCUMENTPARSER_H
#define CLANGEDITORDOCUMENTPARSER_H
#include "semanticmarker.h"
#include <cpptools/baseeditordocumentparser.h>
namespace CppTools { class WorkingCopy; }
namespace ClangCodeModel {
class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
@@ -46,17 +42,8 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
public:
ClangEditorDocumentParser(const QString &filePath);
QList<Diagnostic> diagnostics() const;
QList<SemanticMarker::Range> ifdefedOutBlocks() const;
SemanticMarker::Ptr semanticMarker() const;
signals:
void projectPartDetermined(CppTools::ProjectPart::Ptr projectPart);
private:
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) override;
SemanticMarker::Ptr m_marker;
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &) override;
};
} // namespace ClangCodeModel

View File

@@ -36,6 +36,7 @@
#include "clangutils.h"
#include "cppcreatemarkers.h"
#include "diagnostic.h"
#include "highlightingmarksreporter.h"
#include "pchinfo.h"
#include <diagnosticcontainer.h>
@@ -59,22 +60,6 @@
#include <QTextBlock>
namespace {
typedef CPlusPlus::Document::DiagnosticMessage CppToolsDiagnostic;
QList<TextEditor::BlockRange> toTextEditorBlocks(
const QList<ClangCodeModel::SemanticMarker::Range> &ranges)
{
QList<TextEditor::BlockRange> result;
result.reserve(ranges.size());
foreach (const ClangCodeModel::SemanticMarker::Range &range, ranges)
result.append(TextEditor::BlockRange(range.first, range.last));
return result;
}
} // anonymous namespace
namespace ClangCodeModel {
namespace Internal {
@@ -89,26 +74,12 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
, m_semanticHighlighter(document)
, m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
{
connect(m_parser.data(), &ClangEditorDocumentParser::projectPartDetermined,
this, &ClangEditorDocumentProcessor::onParserDeterminedProjectPart);
// Forwarding the semantic info from the builtin processor enables us to provide all
// editor (widget) related features that are not yet implemented by the clang plugin.
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::cppDocumentUpdated,
this, &ClangEditorDocumentProcessor::cppDocumentUpdated);
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
m_semanticHighlighter.setHighlightingRunner(
[this]() -> QFuture<TextEditor::HighlightingResult> {
const int firstLine = 1;
const int lastLine = baseTextDocument()->document()->blockCount();
CreateMarkers *createMarkers = CreateMarkers::create(m_parser->semanticMarker(),
baseTextDocument()->filePath().toString(),
firstLine, lastLine);
return createMarkers->start();
});
}
ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
@@ -125,7 +96,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
void ClangEditorDocumentProcessor::run()
{
requestDiagnostics();
requestDiagnosticsAndHighlighting();
// Run clang parser
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
@@ -153,7 +124,7 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force)
void ClangEditorDocumentProcessor::semanticRehighlight()
{
m_semanticHighlighter.updateFormatMapFromFontSettings();
m_semanticHighlighter.run();
requestDiagnosticsAndHighlighting(DocumentChangedCheck::NoCheck);
}
CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
@@ -201,6 +172,36 @@ void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector<ClangBackEnd
}
}
static QList<TextEditor::BlockRange>
toTextEditorBlocks(const QVector<ClangBackEnd::SourceRangeContainer> &ifdefedOutRanges)
{
QList<TextEditor::BlockRange> blockRanges;
blockRanges.reserve(ifdefedOutRanges.size());
for (const auto &range : ifdefedOutRanges)
blockRanges.append(TextEditor::BlockRange(range.start().offset(),range.end().offset()));
return blockRanges;
}
void ClangEditorDocumentProcessor::updateHighlighting(
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
uint documentRevision)
{
if (documentRevision == revision()) {
const auto skippedPreprocessorBlocks = toTextEditorBlocks(skippedPreprocessorRanges);
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
m_semanticHighlighter.setHighlightingRunner(
[highlightingMarks]() {
auto *reporter = new HighlightingMarksReporter(highlightingMarks);
return reporter->start();
});
m_semanticHighlighter.run();
}
}
static int currentLine(const TextEditor::AssistInterface &assistInterface)
{
int line, column;
@@ -240,36 +241,24 @@ static bool isProjectPartLoadedOrIsFallback(CppTools::ProjectPart::Ptr projectPa
&& (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartLoaded(projectPart));
}
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor(
CppTools::ProjectPart::Ptr projectPart)
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor()
{
QTC_ASSERT(projectPart, return);
const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPart();
if (isProjectPartLoadedOrIsFallback(projectPart)) {
updateTranslationUnitForEditor(projectPart.data());
requestDiagnostics(projectPart.data());
requestDiagnosticsAndHighlighting(projectPart.data());
m_projectPart = projectPart;
}
}
void ClangEditorDocumentProcessor::onParserDeterminedProjectPart(
CppTools::ProjectPart::Ptr projectPart)
{
updateProjectPartAndTranslationUnitForEditor(projectPart);
}
void ClangEditorDocumentProcessor::onParserFinished()
{
if (revision() != m_parserRevision)
return;
// Emit ifdefed out blocks
const auto ifdefoutBlocks = toTextEditorBlocks(m_parser->ifdefedOutBlocks());
emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks);
// Run semantic highlighter
m_semanticHighlighter.run();
updateProjectPartAndTranslationUnitForEditor();
}
void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart)
@@ -287,25 +276,38 @@ void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::Proj
}
}
void ClangEditorDocumentProcessor::requestDiagnostics(CppTools::ProjectPart *projectPart)
void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart)
{
if (!m_projectPart || projectPart->id() != m_projectPart->id()) {
IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
ipcCommunicator.requestDiagnostics({fileContainer(projectPart)});
const ClangBackEnd::FileContainer fileContainer_ = fileContainer(projectPart);
ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer_);
}
}
void ClangEditorDocumentProcessor::requestDiagnostics()
IpcCommunicator::DocumentChangedCheck
toIpcCommunicatorDocumentChangedCheck(ClangEditorDocumentProcessor::DocumentChangedCheck condition)
{
return condition == ClangEditorDocumentProcessor::DocumentChangedCheck::RevisionCheck
? IpcCommunicator::DocumentChangedCheck::RevisionCheck
: IpcCommunicator::DocumentChangedCheck::NoCheck;
}
void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck)
{
// Get diagnostics
if (m_projectPart) {
auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator();
ipcCommunicator.requestDiagnostics({filePath(),
m_projectPart->id(),
baseTextDocument()->plainText(),
true,
revision()});
const ClangBackEnd::FileContainer fileContainer(filePath(),
m_projectPart->id(),
baseTextDocument()->plainText(),
true,
revision());
const auto documentCheck = toIpcCommunicatorDocumentChangedCheck(documentChangedCheck);
ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer, documentCheck);
}
}

View File

@@ -43,6 +43,7 @@
namespace ClangBackEnd {
class DiagnosticContainer;
class HighlightingMarkContainer;
class FileContainer;
}
@@ -75,6 +76,9 @@ public:
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
uint documentRevision);
void updateHighlighting(const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
uint documentRevision);
TextEditor::QuickFixOperations
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
@@ -84,17 +88,17 @@ public:
void clearDiagnosticsWithFixIts();
public:
enum class DocumentChangedCheck { NoCheck, RevisionCheck };
static ClangEditorDocumentProcessor *get(const QString &filePath);
private slots:
void onParserDeterminedProjectPart(CppTools::ProjectPart::Ptr projectPart);
void onParserFinished();
private:
void updateProjectPartAndTranslationUnitForEditor(CppTools::ProjectPart::Ptr projectPart);
void updateProjectPartAndTranslationUnitForEditor();
void updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart);
void requestDiagnostics(CppTools::ProjectPart *projectPart);
void requestDiagnostics();
void requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart);
void requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck);
ClangBackEnd::FileContainer fileContainer(CppTools::ProjectPart *projectPart) const;
private:

View File

@@ -193,7 +193,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool
if (success) {
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
m_ipcCommunicator.requestDiagnostics(textDocument);
m_ipcCommunicator.requestDiagnosticsAndHighlighting(textDocument);
}
}

View File

@@ -0,0 +1,155 @@
/****************************************************************************
**
** 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 "highlightingmarksreporter.h"
#include <cpptools/semantichighlighter.h>
#include <QFuture>
namespace {
CppTools::SemanticHighlighter::Kind toCppToolsSemanticHighlighterKind(
ClangBackEnd::HighlightingType type)
{
using ClangBackEnd::HighlightingType;
using CppTools::SemanticHighlighter;
switch (type) {
case HighlightingType::Keyword:
return SemanticHighlighter::PseudoKeywordUse;
case HighlightingType::Function:
return SemanticHighlighter::FunctionUse;
case HighlightingType::VirtualFunction:
return SemanticHighlighter::VirtualMethodUse;
case HighlightingType::Type:
return SemanticHighlighter::TypeUse;
case HighlightingType::LocalVariable:
return SemanticHighlighter::LocalUse;
case HighlightingType::Field:
return SemanticHighlighter::FieldUse;
case HighlightingType::GlobalVariable:
return SemanticHighlighter::Unknown;
case HighlightingType::Enumeration:
return SemanticHighlighter::EnumerationUse;
case HighlightingType::Label:
return SemanticHighlighter::LabelUse;
case HighlightingType::Preprocessor:
return SemanticHighlighter::MacroUse;
default:
return SemanticHighlighter::Unknown;
}
Q_UNREACHABLE();
}
TextEditor::HighlightingResult toHighlightingResult(
const ClangBackEnd::HighlightingMarkContainer &highlightingMark)
{
const auto highlighterKind = toCppToolsSemanticHighlighterKind(highlightingMark.type());
return TextEditor::HighlightingResult(highlightingMark.line(),
highlightingMark.column(),
highlightingMark.length(),
highlighterKind);
}
} // anonymous
namespace ClangCodeModel {
HighlightingMarksReporter::HighlightingMarksReporter(
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks)
: m_highlightingMarks(highlightingMarks)
{
m_chunksToReport.reserve(m_chunkSize + 1);
}
void HighlightingMarksReporter::reportChunkWise(
const TextEditor::HighlightingResult &highlightingResult)
{
if (m_chunksToReport.size() >= m_chunkSize) {
if (m_flushRequested && highlightingResult.line != m_flushLine) {
reportAndClearCurrentChunks();
} else if (!m_flushRequested) {
m_flushRequested = true;
m_flushLine = highlightingResult.line;
}
}
m_chunksToReport.append(highlightingResult);
}
void HighlightingMarksReporter::reportAndClearCurrentChunks()
{
m_flushRequested = false;
m_flushLine = 0;
if (!m_chunksToReport.isEmpty()) {
reportResults(m_chunksToReport);
m_chunksToReport.erase(m_chunksToReport.begin(), m_chunksToReport.end());
}
}
void HighlightingMarksReporter::setChunkSize(int chunkSize)
{
m_chunkSize = chunkSize;
}
void HighlightingMarksReporter::run()
{
run_internal();
reportFinished();
}
void HighlightingMarksReporter::run_internal()
{
if (isCanceled())
return;
for (const auto &highlightingMark : m_highlightingMarks)
reportChunkWise(toHighlightingResult(highlightingMark));
if (isCanceled())
return;
reportAndClearCurrentChunks();
}
QFuture<TextEditor::HighlightingResult> HighlightingMarksReporter::start()
{
this->setRunnable(this);
this->reportStarted();
QFuture<TextEditor::HighlightingResult> future = this->future();
QThreadPool::globalInstance()->start(this, QThread::LowestPriority);
return future;
}
} // namespace ClangCodeModel

View File

@@ -0,0 +1,80 @@
/****************************************************************************
**
** 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 CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H
#define CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H
#include "clang_global.h"
#include <QFutureInterface>
#include <QObject>
#include <QRunnable>
#include <QThreadPool>
#include <texteditor/semantichighlighter.h>
#include <clangbackendipc/highlightingmarkcontainer.h>
namespace ClangCodeModel {
class HighlightingMarksReporter:
public QObject,
public QRunnable,
public QFutureInterface<TextEditor::HighlightingResult>
{
Q_OBJECT
public:
HighlightingMarksReporter(const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks);
void setChunkSize(int chunkSize);
QFuture<TextEditor::HighlightingResult> start();
private:
void run() override;
void run_internal();
void reportChunkWise(const TextEditor::HighlightingResult &highlightingResult);
void reportAndClearCurrentChunks();
private:
QVector<ClangBackEnd::HighlightingMarkContainer> m_highlightingMarks;
QVector<TextEditor::HighlightingResult> m_chunksToReport;
int m_chunkSize = 100;
bool m_flushRequested = false;
unsigned m_flushLine = 0;
};
} // namespace ClangCodeModel
#endif // CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H

View File

@@ -380,6 +380,11 @@ QString toString(const RequestDiagnosticsMessage &)
return QStringLiteral("RequestDiagnosticsMessage\n");
}
QString toString(const RequestHighlightingMessage &)
{
return QStringLiteral("RequestHighlightingMessage\n");
}
class IpcSenderSpy : public IpcSenderInterface
{
public:
@@ -413,6 +418,8 @@ public:
void requestDiagnostics(const RequestDiagnosticsMessage &message) override
{ senderLog.append(toString(message)); }
void requestHighlighting(const RequestHighlightingMessage &message) override
{ senderLog.append(toString(message)); }
public:
QString senderLog;

View File

@@ -247,6 +247,4 @@ private:
} // namespace CppTools
Q_DECLARE_METATYPE(CppTools::ProjectPart::Ptr)
#endif // CPPPROJECTPART_H

View File

@@ -33,7 +33,9 @@
#include "clangfilesystemwatcher.h"
#include "codecompleter.h"
#include "diagnosticset.h"
#include "highlightinginformations.h"
#include "projectpartsdonotexistexception.h"
#include "skippedsourceranges.h"
#include "translationunitdoesnotexistexception.h"
#include "translationunitfilenotexitexception.h"
#include "translationunitisnullexception.h"
@@ -48,8 +50,10 @@
#include <cmbunregisterprojectsforeditormessage.h>
#include <cmbunregistertranslationunitsforeditormessage.h>
#include <diagnosticschangedmessage.h>
#include <highlightingchangedmessage.h>
#include <registerunsavedfilesforeditormessage.h>
#include <requestdiagnosticsmessage.h>
#include <requesthighlightingmessage.h>
#include <projectpartsdonotexistmessage.h>
#include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
@@ -62,37 +66,44 @@
namespace ClangBackEnd {
namespace {
const int sendDiagnosticsTimerInterval = 300;
const int delayedEditorUpdatesTimerInterval = 300;
}
ClangIpcServer::ClangIpcServer()
: translationUnits(projects, unsavedFiles)
{
translationUnits.setSendChangeDiagnosticsCallback([this] (const DiagnosticsChangedMessage &message)
{
client()->diagnosticsChanged(message);
});
const auto sendEditorUpdates
= [this] (const DiagnosticsChangedMessage &diagnosticsMessage,
const HighlightingChangedMessage &highlightingsMessage) {
client()->diagnosticsChanged(diagnosticsMessage);
client()->highlightingChanged(highlightingsMessage);
};
QObject::connect(&sendDiagnosticsTimer,
const auto sendDelayedEditorUpdates = [this] () {
try {
auto editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates();
if (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates)
sendDelayedEditorUpdatesTimer.setInterval(0);
else
sendDelayedEditorUpdatesTimer.stop();
} catch (const std::exception &exception) {
qWarning() << "Error in ClangIpcServer::sendDelayedEditorUpdatesTimer:" << exception.what();
}
};
const auto onFileChanged = [this] (const Utf8String &filePath) {
startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(filePath);
};
translationUnits.setSendDelayedEditorUpdatesCallback(sendEditorUpdates);
QObject::connect(&sendDelayedEditorUpdatesTimer,
&QTimer::timeout,
[this] () {
try {
auto diagnostSendState = translationUnits.sendChangedDiagnostics();
if (diagnostSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
sendDiagnosticsTimer.setInterval(0);
else
sendDiagnosticsTimer.stop();
} catch (const std::exception &exception) {
qWarning() << "Error in ClangIpcServer::sendDiagnosticsTimer:" << exception.what();
}
});
sendDelayedEditorUpdates);
QObject::connect(translationUnits.clangFileSystemWatcher(),
&ClangFileSystemWatcher::fileChanged,
[this] (const Utf8String &filePath)
{
startSendDiagnosticTimerIfFileIsNotATranslationUnit(filePath);
});
onFileChanged);
}
void ClangIpcServer::end()
@@ -107,7 +118,7 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis
try {
translationUnits.create(message.fileContainers());
unsavedFiles.createOrUpdate(message.fileContainers());
sendDiagnosticsTimer.start(0);
sendDelayedEditorUpdatesTimer.start(0);
} catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
} catch (const std::exception &exception) {
@@ -124,7 +135,7 @@ void ClangIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnit
if (newerFileContainers.size() > 0) {
translationUnits.update(newerFileContainers);
unsavedFiles.createOrUpdate(newerFileContainers);
sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval);
sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval);
}
} catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
@@ -182,7 +193,7 @@ void ClangIpcServer::registerUnsavedFilesForEditor(const RegisterUnsavedFilesFor
try {
unsavedFiles.createOrUpdate(message.fileContainers());
translationUnits.updateTranslationUnitsWithChangedDependencies(message.fileContainers());
sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval);
sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval);
} catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
} catch (const std::exception &exception) {
@@ -244,6 +255,26 @@ void ClangIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message
}
}
void ClangIpcServer::requestHighlighting(const RequestHighlightingMessage &message)
{
TIME_SCOPE_DURATION("ClangIpcServer::requestHighlighting");
try {
auto translationUnit = translationUnits.translationUnit(message.fileContainer().filePath(),
message.fileContainer().projectPartId());
client()->highlightingChanged(HighlightingChangedMessage(translationUnit.fileContainer(),
translationUnit.highlightingInformations().toHighlightingMarksContainers(),
translationUnit.skippedSourceRanges().toSourceRangeContainers()));
} catch (const TranslationUnitDoesNotExistException &exception) {
client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer()));
} catch (const ProjectPartDoNotExistException &exception) {
client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds()));
} catch (const std::exception &exception) {
qWarning() << "Error in ClangIpcServer::requestHighlighting:" << exception.what();
}
}
void ClangIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
TIME_SCOPE_DURATION("ClangIpcServer::updateVisibleTranslationUnits");
@@ -261,10 +292,10 @@ const TranslationUnits &ClangIpcServer::translationUnitsForTestOnly() const
return translationUnits;
}
void ClangIpcServer::startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath)
void ClangIpcServer::startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath)
{
if (!translationUnits.hasTranslationUnit(filePath))
sendDiagnosticsTimer.start(0);
sendDelayedEditorUpdatesTimer.start(0);
}
}

View File

@@ -61,18 +61,19 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void requestHighlighting(const RequestHighlightingMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
const TranslationUnits &translationUnitsForTestOnly() const;
private:
void startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath);
void startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath);
private:
ProjectParts projects;
UnsavedFiles unsavedFiles;
TranslationUnits translationUnits;
QTimer sendDiagnosticsTimer;
QTimer sendDelayedEditorUpdatesTimer;
};
} // namespace ClangBackEnd

View File

@@ -85,6 +85,7 @@ public:
uint documentRevision = 0;
bool needsToBeReparsed = false;
bool hasNewDiagnostics = true;
bool hasNewHighlightingInformations = true;
bool isUsedByCurrentEditor = false;
bool isVisibleInEditor = false;
};
@@ -239,6 +240,11 @@ bool TranslationUnit::hasNewDiagnostics() const
return d->hasNewDiagnostics;
}
bool TranslationUnit::hasNewHighlightingInformations() const
{
return d->hasNewHighlightingInformations;
}
DiagnosticSet TranslationUnit::diagnostics() const
{
d->hasNewDiagnostics = false;
@@ -268,6 +274,7 @@ void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath)
if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath)) {
d->needsToBeReparsed = true;
d->hasNewDiagnostics = true;
d->hasNewHighlightingInformations = true;
}
}
@@ -302,6 +309,13 @@ Cursor TranslationUnit::cursor() const
return clang_getTranslationUnitCursor(cxTranslationUnit());
}
HighlightingInformations TranslationUnit::highlightingInformations() const
{
d->hasNewHighlightingInformations = false;
return highlightingInformationsInRange(cursor().sourceRange());
}
HighlightingInformations TranslationUnit::highlightingInformationsInRange(const SourceRange &range) const
{
CXToken *cxTokens = 0;

View File

@@ -112,6 +112,7 @@ public:
bool isNeedingReparse() const;
bool hasNewDiagnostics() const;
bool hasNewHighlightingInformations() const;
DiagnosticSet diagnostics() const;
QVector<DiagnosticContainer> mainFileDiagnostics() const;
@@ -131,6 +132,7 @@ public:
Cursor cursorAt(const Utf8String &filePath, uint line, uint column) const;
Cursor cursor() const;
HighlightingInformations highlightingInformations() const;
HighlightingInformations highlightingInformationsInRange(const SourceRange &range) const;
SkippedSourceRanges skippedSourceRanges() const;

View File

@@ -28,6 +28,8 @@
**
****************************************************************************/
#include <highlightingmarkcontainer.h>
#include "clangstring.h"
#include "cursor.h"
#include "highlightinginformation.h"
@@ -81,6 +83,11 @@ QVector<HighlightingInformation> HighlightingInformation::outputFunctionArgument
return outputFunctionArguments;
}
HighlightingInformation::operator HighlightingMarkContainer() const
{
return HighlightingMarkContainer(line, column, length, type);
}
namespace {
bool isFinalFunction(const Cursor &cursor)
@@ -278,7 +285,7 @@ HighlightingType HighlightingInformation::kind(CXToken *cxToken, const Cursor &c
Q_UNREACHABLE();
}
void PrintTo(const HighlightingInformation& information, ::std::ostream *os)
void PrintTo(const HighlightingInformation &information, ::std::ostream *os)
{
*os << "type: ";
PrintTo(information.type, os);
@@ -287,30 +294,4 @@ void PrintTo(const HighlightingInformation& information, ::std::ostream *os)
<< " length: " << information.length;
}
void PrintTo(HighlightingType highlightingType, std::ostream *os)
{
switch (highlightingType) {
case HighlightingType::Invalid: *os << "Invalid"; break;
case HighlightingType::Comment: *os << "Comment"; break;
case HighlightingType::Keyword: *os << "Keyword"; break;
case HighlightingType::StringLiteral: *os << "StringLiteral"; break;
case HighlightingType::NumberLiteral: *os << "NumberLiteral"; break;
case HighlightingType::Function: *os << "Function"; break;
case HighlightingType::VirtualFunction: *os << "VirtualFunction"; break;
case HighlightingType::Type: *os << "Type"; break;
case HighlightingType::LocalVariable: *os << "LocalVariable"; break;
case HighlightingType::GlobalVariable: *os << "GlobalVariable"; break;
case HighlightingType::Field: *os << "Field"; break;
case HighlightingType::Enumeration: *os << "Enumeration"; break;
case HighlightingType::Operator: *os << "Operator"; break;
case HighlightingType::Preprocessor: *os << "Preprocessor"; break;
case HighlightingType::Label: *os << "Label"; break;
case HighlightingType::OutputArgument: *os << "OutputArgument"; break;
case HighlightingType::PreprocessorDefinition: *os << "PreprocessorDefinition"; break;
case HighlightingType::PreprocessorExpansion: *os << "PreprocessorExpansion"; break;
}
}
} // namespace ClangBackEnd

View File

@@ -32,6 +32,7 @@
#define CLANGBACKEND_HIGHLIGHTINGINFORMATION_H
#include <clangbackendipc_global.h>
#include <highlightingmarkcontainer.h>
#include "cursor.h"
@@ -52,6 +53,8 @@ public:
bool hasFunctionArguments() const;
QVector<HighlightingInformation> outputFunctionArguments() const;
operator HighlightingMarkContainer() const;
private:
HighlightingType identifierKind(const Cursor &cursor) const;
HighlightingType referencedTypeKind(const Cursor &cursor) const;
@@ -71,7 +74,6 @@ private:
};
void PrintTo(const HighlightingInformation& highlightingInformation, ::std::ostream *os);
void PrintTo(HighlightingType highlightingType, ::std::ostream *os);
inline bool operator==(const HighlightingInformation &first, const HighlightingInformation &second)
{

View File

@@ -30,6 +30,10 @@
#include "highlightinginformations.h"
#include "highlightingmarkcontainer.h"
#include <QVector>
namespace ClangBackEnd {
HighlightingInformations::HighlightingInformations(CXTranslationUnit cxTranslationUnit, CXToken *tokens, uint tokensCount)
@@ -56,6 +60,20 @@ HighlightingInformations::const_iterator HighlightingInformations::end() const
return const_iterator(cxCursor.cend(), cxToken + cxTokenCount, cxTranslationUnit);
}
QVector<HighlightingMarkContainer> HighlightingInformations::toHighlightingMarksContainers() const
{
QVector<HighlightingMarkContainer> containers;
containers.reserve(size());
const auto isValidHighlightMark = [] (const HighlightingInformation &highlightMark) {
return !highlightMark.hasType(HighlightingType::Invalid);
};
std::copy_if(begin(), end(), std::back_inserter(containers), isValidHighlightMark);
return containers;
}
bool HighlightingInformations::isEmpty() const
{
return cxTokenCount == 0;

View File

@@ -40,6 +40,7 @@
namespace ClangBackEnd {
using uint = unsigned int;
class HighlightingMarkContainer;
class HighlightingInformations
{
@@ -61,6 +62,8 @@ public:
const_iterator begin() const;
const_iterator end() const;
QVector<HighlightingMarkContainer> toHighlightingMarksContainers() const;
private:
CXTranslationUnit cxTranslationUnit = nullptr;
CXToken *const cxToken = nullptr;

View File

@@ -32,8 +32,11 @@
#include <diagnosticschangedmessage.h>
#include <diagnosticset.h>
#include <highlightingchangedmessage.h>
#include <highlightinginformations.h>
#include <projectpartsdonotexistexception.h>
#include <projects.h>
#include <skippedsourceranges.h>
#include <translationunitalreadyexistsexception.h>
#include <translationunitdoesnotexistexception.h>
@@ -163,62 +166,73 @@ void TranslationUnits::updateTranslationUnitsWithChangedDependencies(const QVect
updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
}
DiagnosticSendState TranslationUnits::sendChangedDiagnostics()
EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates()
{
auto diagnosticSendState = sendChangedDiagnosticsForCurrentEditor();
if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend)
diagnosticSendState = sendChangedDiagnosticsForVisibleEditors();
if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend)
diagnosticSendState = sendChangedDiagnosticsForAll();
auto editorUpdatesSendState = sendDelayedEditorUpdatesForCurrentEditor();
if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend)
editorUpdatesSendState = sendDelayedEditorUpdatesForVisibleEditors();
if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend)
editorUpdatesSendState = sendDelayedEditorUpdatesForAll();
return diagnosticSendState;
return editorUpdatesSendState;
}
template<class Predicate>
DiagnosticSendState TranslationUnits::sendChangedDiagnostics(Predicate predicate)
EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates(Predicate predicate)
{
auto foundTranslationUnit = std::find_if(translationUnits_.begin(),
translationUnits_.end(),
predicate);
if (foundTranslationUnit != translationUnits().end()) {
sendDiagnosticChangedMessage(*foundTranslationUnit);
return DiagnosticSendState::MaybeThereAreMoreDiagnostics;
sendDelayedEditorUpdates(*foundTranslationUnit);
return EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates;
}
return DiagnosticSendState::NoDiagnosticSend;
return EditorUpdatesSendState::NoEditorUpdatesSend;
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForCurrentEditor()
namespace {
bool translationUnitHasEditorDocumentUpdates(const TranslationUnit &translationUnit)
{
auto hasDiagnosticsForCurrentEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isUsedByCurrentEditor() && translationUnit.hasNewDiagnostics();
return translationUnit.hasNewDiagnostics() || translationUnit.hasNewHighlightingInformations();
}
}
EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForCurrentEditor()
{
auto hasEditorUpdatesForCurrentEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isUsedByCurrentEditor()
&& translationUnitHasEditorDocumentUpdates(translationUnit);
};
return sendChangedDiagnostics(hasDiagnosticsForCurrentEditor);
return sendDelayedEditorUpdates(hasEditorUpdatesForCurrentEditor);
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForVisibleEditors()
EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForVisibleEditors()
{
auto hasDiagnosticsForVisibleEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isVisibleInEditor() && translationUnit.hasNewDiagnostics();
auto hasEditorUpdatesForVisibleEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isVisibleInEditor()
&& translationUnitHasEditorDocumentUpdates(translationUnit);
};
return sendChangedDiagnostics(hasDiagnosticsForVisibleEditor);
return sendDelayedEditorUpdates(hasEditorUpdatesForVisibleEditor);
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForAll()
EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForAll()
{
auto hasDiagnostics = [] (const TranslationUnit &translationUnit) {
return translationUnit.hasNewDiagnostics();
auto hasEditorUpdates = [] (const TranslationUnit &translationUnit) {
return translationUnitHasEditorDocumentUpdates(translationUnit);
};
return sendChangedDiagnostics(hasDiagnostics);
return sendDelayedEditorUpdates(hasEditorUpdates);
}
void TranslationUnits::setSendChangeDiagnosticsCallback(std::function<void(const DiagnosticsChangedMessage &)> &&callback)
void TranslationUnits::setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback)
{
sendDiagnosticsChangedCallback = std::move(callback);
sendDelayedEditorUpdatesCallback = std::move(callback);
}
QVector<FileContainer> TranslationUnits::newerFileContainers(const QVector<FileContainer> &fileContainers) const
@@ -340,13 +354,18 @@ void TranslationUnits::checkIfTranslationUnitsForFilePathsDoesExists(const QVect
}
}
void TranslationUnits::sendDiagnosticChangedMessage(const TranslationUnit &translationUnit)
void TranslationUnits::sendDelayedEditorUpdates(const TranslationUnit &translationUnit)
{
if (sendDiagnosticsChangedCallback) {
DiagnosticsChangedMessage message(translationUnit.fileContainer(),
translationUnit.mainFileDiagnostics());
if (sendDelayedEditorUpdatesCallback) {
const auto fileContainer = translationUnit.fileContainer();
DiagnosticsChangedMessage diagnosticsMessage(fileContainer,
translationUnit.mainFileDiagnostics());
HighlightingChangedMessage highlightingsMessage(fileContainer,
translationUnit.highlightingInformations().toHighlightingMarksContainers(),
translationUnit.skippedSourceRanges().toSourceRangeContainers());
sendDiagnosticsChangedCallback(std::move(message));
sendDelayedEditorUpdatesCallback(std::move(diagnosticsMessage),
std::move(highlightingsMessage));
}
}

View File

@@ -46,15 +46,20 @@ namespace ClangBackEnd {
class ProjectParts;
class UnsavedFiles;
class DiagnosticsChangedMessage;
class HighlightingChangedMessage;
enum class DiagnosticSendState
enum class EditorUpdatesSendState
{
NoDiagnosticSend,
MaybeThereAreMoreDiagnostics,
NoEditorUpdatesSend,
MaybeThereAreMoreEditorUpdates,
};
class TranslationUnits
{
public:
using DelayedEditorUpdatesCallback = std::function<void (const DiagnosticsChangedMessage &,
const HighlightingChangedMessage &)>;
public:
TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles);
@@ -78,12 +83,13 @@ public:
void updateTranslationUnitsWithChangedDependency(const Utf8String &filePath);
void updateTranslationUnitsWithChangedDependencies(const QVector<FileContainer> &fileContainers);
DiagnosticSendState sendChangedDiagnostics();
DiagnosticSendState sendChangedDiagnosticsForCurrentEditor();
DiagnosticSendState sendChangedDiagnosticsForVisibleEditors();
DiagnosticSendState sendChangedDiagnosticsForAll();
EditorUpdatesSendState sendDelayedEditorUpdatesForCurrentEditor();
EditorUpdatesSendState sendDelayedEditorUpdatesForVisibleEditors();
EditorUpdatesSendState sendDelayedEditorUpdatesForAll();
void setSendChangeDiagnosticsCallback(std::function<void(const DiagnosticsChangedMessage&)> &&callback);
EditorUpdatesSendState sendDelayedEditorUpdates();
void setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback);
QVector<FileContainer> newerFileContainers(const QVector<FileContainer> &fileContainers) const;
@@ -102,15 +108,15 @@ private:
void checkIfTranslationUnitsDoesNotExists(const QVector<FileContainer> &fileContainers) const;
void checkIfTranslationUnitsForFilePathsDoesExists(const QVector<FileContainer> &fileContainers) const;
void sendDiagnosticChangedMessage(const TranslationUnit &translationUnit);
void sendDelayedEditorUpdates(const TranslationUnit &translationUnit);
void removeTranslationUnits(const QVector<FileContainer> &fileContainers);
template<class Predicate>
DiagnosticSendState sendChangedDiagnostics(Predicate predicate);
EditorUpdatesSendState sendDelayedEditorUpdates(Predicate predicate);
private:
ClangFileSystemWatcher fileSystemWatcher;
std::function<void(const DiagnosticsChangedMessage&)> sendDiagnosticsChangedCallback;
DelayedEditorUpdatesCallback sendDelayedEditorUpdatesCallback;
std::vector<TranslationUnit> translationUnits_;
ProjectParts &projectParts;
UnsavedFiles &unsavedFiles_;

View File

@@ -41,6 +41,7 @@
#include "connectionserver.h"
#include "registerunsavedfilesforeditormessage.h"
#include "requestdiagnosticsmessage.h"
#include "requesthighlightingmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
@@ -107,6 +108,11 @@ void EchoIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message)
echoMessage(QVariant::fromValue(message));
}
void EchoIpcServer::requestHighlighting(const RequestHighlightingMessage &message)
{
echoMessage(QVariant::fromValue(message));
}
void EchoIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
echoMessage(QVariant::fromValue(message));

View File

@@ -49,6 +49,7 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void requestHighlighting(const RequestHighlightingMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
private:

View File

@@ -0,0 +1,68 @@
/****************************************************************************
**
** 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 TEXTEDITOR_SEMANTICHIGHLIGHTER_H
#define TEXTEDITOR_SEMANTICHIGHLIGHTER_H
namespace TextEditor {
class HighlightingResult {
public:
unsigned line;
unsigned column;
unsigned length;
int kind;
bool isValid() const
{ return line != 0; }
bool isInvalid() const
{ return line == 0; }
HighlightingResult()
: line(0), column(0), length(0), kind(0)
{}
HighlightingResult(unsigned line, unsigned column, unsigned length, int kind)
: line(line), column(column), length(length), kind(kind)
{}
bool operator==(const HighlightingResult& other) const
{
return line == other.line
&& column == other.column
&& length == other.length
&& kind == other.kind;
}
};
} // namespace TextEditor
#endif // TEXTEDITOR_SEMANTICHIGHLIGHTER_H

View File

@@ -0,0 +1,64 @@
/****************************************************************************
**
** 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 "chunksreportedmonitor.h"
#include <QSignalSpy>
namespace ClangBackEnd {
ChunksReportedMonitor::ChunksReportedMonitor(const QFuture<TextEditor::HighlightingResult> &future)
: m_future(future)
{
m_futureWatcher.setFuture(future);
connect(&m_futureWatcher, &QFutureWatcher<TextEditor::HighlightingResult>::resultsReadyAt,
this, &ChunksReportedMonitor::onResultsReadyAt);
}
bool ChunksReportedMonitor::waitUntilFinished(int timeoutInMs)
{
QSignalSpy spy(&m_futureWatcher, SIGNAL(finished()));
return spy.wait(timeoutInMs);
}
void ChunksReportedMonitor::onResultsReadyAt(int beginIndex, int endIndex)
{
Q_UNUSED(beginIndex)
Q_UNUSED(endIndex)
++m_resultsReadyCounter;
}
uint ChunksReportedMonitor::resultsReadyCounter()
{
waitUntilFinished();
return m_resultsReadyCounter;
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,63 @@
/****************************************************************************
**
** 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_CHUNKSREPORTEDMONITOR_H
#define CLANGBACKEND_CHUNKSREPORTEDMONITOR_H
#include <QObject>
#include <QFuture>
#include <QFutureWatcher>
#include <texteditor/semantichighlighter.h>
namespace ClangBackEnd {
class ChunksReportedMonitor : public QObject
{
Q_OBJECT
public:
ChunksReportedMonitor(const QFuture<TextEditor::HighlightingResult> &future);
uint resultsReadyCounter();
private:
bool waitUntilFinished(int timeoutInMs = 5000);
void onResultsReadyAt(int beginIndex, int endIndex);
private:
QFuture<TextEditor::HighlightingResult> m_future;
QFutureWatcher<TextEditor::HighlightingResult> m_futureWatcher;
uint m_resultsReadyCounter = 0;
};
} // namespace ClangBackEnd
#endif // CLANGBACKEND_CHUNKSREPORTEDMONITOR_H

View File

@@ -31,8 +31,11 @@
#include "mockipclient.h"
#include <clangipcserver.h>
#include <highlightingchangedmessage.h>
#include <highlightingmarkcontainer.h>
#include <ipcclientproxy.h>
#include <ipcserverproxy.h>
#include <requesthighlightingmessage.h>
#include <translationunitdoesnotexistexception.h>
#include <translationunitparseerrorexception.h>
@@ -43,6 +46,7 @@
#include <cmbregistertranslationunitsforeditormessage.h>
#include <cmbunregisterprojectsforeditormessage.h>
#include <cmbunregistertranslationunitsforeditormessage.h>
#include <highlightingchangedmessage.h>
#include <diagnosticschangedmessage.h>
#include <projectpartsdonotexistmessage.h>
#include <translationunitdoesnotexistmessage.h>
@@ -62,6 +66,7 @@ using testing::Contains;
using testing::Not;
using testing::Eq;
using testing::PrintToString;
using testing::_;
namespace {
@@ -78,6 +83,9 @@ using ClangBackEnd::TranslationUnitDoesNotExistMessage;
using ClangBackEnd::ProjectPartsDoNotExistMessage;
using ClangBackEnd::UpdateTranslationUnitsForEditorMessage;
using ClangBackEnd::UpdateVisibleTranslationUnitsMessage;
using ClangBackEnd::RequestHighlightingMessage;
using ClangBackEnd::HighlightingChangedMessage;
using ClangBackEnd::HighlightingMarkContainer;
MATCHER_P5(HasDirtyTranslationUnit,
filePath,
@@ -168,6 +176,18 @@ TEST_F(ClangIpcServer, GetCodeCompletion)
clangServer.completeCode(completeCodeMessage);
}
TEST_F(ClangIpcServer, RequestHighlighting)
{
RequestHighlightingMessage requestHighlightingMessage({variableTestFilePath, projectPartId});
HighlightingMarkContainer highlightingMarkContainer(1, 6, 8, ClangBackEnd::HighlightingType::Function);
EXPECT_CALL(mockIpcClient, highlightingChanged(Property(&HighlightingChangedMessage::highlightingMarks, Contains(highlightingMarkContainer))))
.Times(1);
clangServer.requestHighlighting(requestHighlightingMessage);
}
TEST_F(ClangIpcServer, GetCodeCompletionDependingOnArgumets)
{
CompleteCodeMessage completeCodeMessage(variableTestFilePath,

View File

@@ -47,9 +47,11 @@
#include <cmbunregisterprojectsforeditormessage.h>
#include <cmbunregistertranslationunitsforeditormessage.h>
#include <diagnosticschangedmessage.h>
#include <highlightingchangedmessage.h>
#include <readmessageblock.h>
#include <registerunsavedfilesforeditormessage.h>
#include <requestdiagnosticsmessage.h>
#include <requesthighlightingmessage.h>
#include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
@@ -197,6 +199,17 @@ TEST_F(ClientServerInProcess, SendRequestDiagnosticsMessage)
scheduleServerMessages();
}
TEST_F(ClientServerInProcess, SendRequestHighlightingMessage)
{
ClangBackEnd::RequestHighlightingMessage message({Utf8StringLiteral("foo.cpp"),
Utf8StringLiteral("projectId")});
EXPECT_CALL(mockIpcServer, requestHighlighting(message))
.Times(1);
serverProxy.requestHighlighting(message);
scheduleServerMessages();
}
TEST_F(ClientServerInProcess, SendCodeCompletedMessage)
{
@@ -289,6 +302,21 @@ TEST_F(ClientServerInProcess, SendDiagnosticsChangedMessage)
scheduleClientMessages();
}
TEST_F(ClientServerInProcess, SendHighlightingChangedMessage)
{
ClangBackEnd::HighlightingMarkContainer container(1, 1, 1, ClangBackEnd::HighlightingType::Keyword);
ClangBackEnd::HighlightingChangedMessage message(fileContainer,
{container},
QVector<SourceRangeContainer>());
EXPECT_CALL(mockIpcClient, highlightingChanged(message))
.Times(1);
clientProxy.highlightingChanged(message);
scheduleClientMessages();
}
ClientServerInProcess::ClientServerInProcess()
: serverProxy(&mockIpcClient, &buffer),
clientProxy(&mockIpcServer, &buffer)

View File

@@ -40,6 +40,7 @@
#include <cmbregistertranslationunitsforeditormessage.h>
#include <cmbunregisterprojectsforeditormessage.h>
#include <cmbunregistertranslationunitsforeditormessage.h>
#include <highlightingchangedmessage.h>
#include <connectionclient.h>
#include <diagnosticschangedmessage.h>
#include <projectpartsdonotexistmessage.h>

View File

@@ -144,6 +144,14 @@ TEST_F(HighlightingInformations, IteratorBeginEnd)
ASSERT_THAT(infos.end(), endIterator);
}
TEST_F(HighlightingInformations, ForFullTranslationUnitRange)
{
const auto infos = translationUnit.highlightingInformations();
ASSERT_THAT(infos, AllOf(Contains(IsHighlightingInformation(1u, 1u, 4u, HighlightingType::Keyword)),
Contains(IsHighlightingInformation(277u, 5u, 15u, HighlightingType::Function))));
}
TEST_F(HighlightingInformations, Size)
{
const auto range = translationUnit.sourceRange(5, 5, 5, 10);

View File

@@ -0,0 +1,190 @@
/****************************************************************************
**
** 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 <chunksreportedmonitor.h>
#include <clangtranslationunit.h>
#include <highlightingmarkcontainer.h>
#include <highlightingmarksreporter.h>
#include <projectpart.h>
#include <projects.h>
#include <translationunits.h>
#include <unsavedfiles.h>
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include "gtest-qt-printing.h"
using ClangBackEnd::Cursor;
using ClangBackEnd::HighlightingInformations;
using ClangBackEnd::HighlightingMarkContainer;
using ClangBackEnd::HighlightingType;
using ClangBackEnd::TranslationUnit;
using ClangBackEnd::UnsavedFiles;
using ClangBackEnd::ProjectPart;
using ClangBackEnd::ProjectParts;
using ClangBackEnd::TranslationUnits;
using ClangBackEnd::ChunksReportedMonitor;
namespace {
struct Data {
ProjectParts projects;
UnsavedFiles unsavedFiles;
TranslationUnits translationUnits{projects, unsavedFiles};
TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/highlightinginformations.cpp"),
ProjectPart(Utf8StringLiteral("projectPartId"),
{Utf8StringLiteral("-std=c++14")}),
{},
translationUnits};
};
class HighlightingMarksReporter : public ::testing::Test
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
protected:
static Data *d;
};
QVector<HighlightingMarkContainer> noHighlightingMarks()
{
return QVector<HighlightingMarkContainer>();
}
QVector<HighlightingMarkContainer> generateHighlightingMarks(uint count)
{
auto container = QVector<HighlightingMarkContainer>();
for (uint i = 0; i < count; ++i) {
const uint line = i + 1;
container.append(HighlightingMarkContainer(line, 1, 1, HighlightingType::Type));
}
return container;
}
TEST_F(HighlightingMarksReporter, StartAndFinish)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(noHighlightingMarks());
auto future = reporter->start();
future.waitForFinished();
ASSERT_THAT(future.isFinished(), true);
}
TEST_F(HighlightingMarksReporter, ReportNothingIfNothingToReport)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(0));
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 0L);
}
TEST_F(HighlightingMarksReporter, ReportSingleResultAsOneChunk)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(1));
reporter->setChunkSize(1);
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 1L);
}
TEST_F(HighlightingMarksReporter, ReportRestIfChunkSizeNotReached)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(1));
const int notReachedChunkSize = 100;
reporter->setChunkSize(notReachedChunkSize);
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 1L);
}
TEST_F(HighlightingMarksReporter, ReportChunksWithoutRest)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(4));
reporter->setChunkSize(1);
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
}
TEST_F(HighlightingMarksReporter, ReportSingleChunkAndRest)
{
auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(5));
reporter->setChunkSize(2);
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
}
TEST_F(HighlightingMarksReporter, ReportCompleteLines)
{
QVector<HighlightingMarkContainer> highlightingMarks {
HighlightingMarkContainer(1, 1, 1, HighlightingType::Type),
HighlightingMarkContainer(1, 2, 1, HighlightingType::Type),
HighlightingMarkContainer(2, 1, 1, HighlightingType::Type),
};
auto reporter = new ClangCodeModel::HighlightingMarksReporter(highlightingMarks);
reporter->setChunkSize(1);
auto future = reporter->start();
ChunksReportedMonitor monitor(future);
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
}
Data *HighlightingMarksReporter::d;
void HighlightingMarksReporter::SetUpTestCase()
{
d = new Data;
}
void HighlightingMarksReporter::TearDownTestCase()
{
delete d;
d = nullptr;
}
} // anonymous

View File

@@ -52,6 +52,8 @@ public:
void(const ClangBackEnd::ProjectPartsDoNotExistMessage &message));
MOCK_METHOD1(diagnosticsChanged,
void(const ClangBackEnd::DiagnosticsChangedMessage &message));
MOCK_METHOD1(highlightingChanged,
void(const ClangBackEnd::HighlightingChangedMessage &message));
};
#endif // MOCKIPCLIENT_H

View File

@@ -60,6 +60,8 @@ public:
void(const ClangBackEnd::CompleteCodeMessage &message));
MOCK_METHOD1(requestDiagnostics,
void(const ClangBackEnd::RequestDiagnosticsMessage &message));
MOCK_METHOD1(requestHighlighting,
void(const ClangBackEnd::RequestHighlightingMessage &message));
MOCK_METHOD1(updateVisibleTranslationUnits,
void(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message));
};

View File

@@ -27,27 +27,27 @@
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef MOCKSENDDIAGNOSTICSCALLBACK_H
#define MOCKSENDDIAGNOSTICSCALLBACK_H
#ifndef MOCKSENDEDITORUPDATESCALLBACK_H
#define MOCKSENDEDITORUPDATESCALLBACK_H
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include "gtest-qt-printing.h"
class SendDiagnosticCallback
class SendEditorUpdatesCallback
{
public:
virtual ~SendDiagnosticCallback() = default;
virtual ~SendEditorUpdatesCallback() = default;
virtual void sendDiagnostic() = 0;
virtual void sendEditorUpdates() = 0;
};
class MockSendDiagnosticCallback : public SendDiagnosticCallback
class MockSendEditorUpdatesCallback : public SendEditorUpdatesCallback
{
public:
MOCK_METHOD0(sendDiagnostic,
MOCK_METHOD0(sendEditorUpdates,
void());
};
#endif // MOCKSENDDIAGNOSTICSCALLBACK_H
#endif // MOCKSENDEDITORUPDATESCALLBACK_H

View File

@@ -37,7 +37,10 @@
#include <cmbunregistertranslationunitsforeditormessage.h>
#include <diagnosticcontainer.h>
#include <diagnosticschangedmessage.h>
#include <highlightingchangedmessage.h>
#include <highlightingmarkcontainer.h>
#include <requestdiagnosticsmessage.h>
#include <requesthighlightingmessage.h>
#include <readmessageblock.h>
#include <sourcelocation.h>
#include <registerunsavedfilesforeditormessage.h>
@@ -189,6 +192,15 @@ TEST_F(ReadAndWriteMessageBlock, CompareDiagnosticsChangedMessage)
{container}));
}
TEST_F(ReadAndWriteMessageBlock, CompareHighlightingChangedMessage)
{
ClangBackEnd::HighlightingMarkContainer container(1, 1, 1, ClangBackEnd::HighlightingType::Keyword);
CompareMessage(ClangBackEnd::HighlightingChangedMessage(fileContainer,
{container},
QVector<ClangBackEnd::SourceRangeContainer>()));
}
TEST_F(ReadAndWriteMessageBlock, CompareRegisterUnsavedFilesForEditorMessage)
{
CompareMessage(ClangBackEnd::RegisterUnsavedFilesForEditorMessage({fileContainer}));
@@ -204,6 +216,11 @@ TEST_F(ReadAndWriteMessageBlock, CompareRequestDiagnosticsMessage)
CompareMessage(ClangBackEnd::RequestDiagnosticsMessage(fileContainer));
}
TEST_F(ReadAndWriteMessageBlock, CompareRequestHighlightingMessage)
{
CompareMessage(ClangBackEnd::RequestHighlightingMessage(fileContainer));
}
TEST_F(ReadAndWriteMessageBlock, GetInvalidMessageForAPartialBuffer)
{
writeCodeCompletedMessage();

View File

@@ -30,6 +30,8 @@
#include <diagnosticset.h>
#include <filecontainer.h>
#include <highlightingchangedmessage.h>
#include <highlightinginformations.h>
#include <projectpartcontainer.h>
#include <projectpart.h>
#include <projectpartsdonotexistexception.h>
@@ -45,7 +47,7 @@
#include <clang-c/Index.h>
#include "mocksenddiagnosticscallback.h"
#include "mocksendeditorupdatescallback.h"
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
@@ -56,7 +58,8 @@ using ClangBackEnd::TranslationUnit;
using ClangBackEnd::UnsavedFiles;
using ClangBackEnd::ProjectPart;
using ClangBackEnd::DiagnosticsChangedMessage;
using ClangBackEnd::DiagnosticSendState;
using ClangBackEnd::HighlightingChangedMessage;
using ClangBackEnd::EditorUpdatesSendState;
using testing::IsNull;
using testing::NotNull;
@@ -84,15 +87,15 @@ class TranslationUnits : public ::testing::Test
{
protected:
void SetUp() override;
void sendAllDiagnostics();
void sendAllCurrentEditorDiagnostics();
void sendAllVisibleEditorsDiagnostics();
void sendAllEditorUpdates();
void sendAllEditorUpdatesForCurrentEditor();
void sendAllEditorUpdatesForVisibleEditors();
protected:
ClangBackEnd::ProjectParts projects;
ClangBackEnd::UnsavedFiles unsavedFiles;
ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
MockSendDiagnosticCallback mockSendDiagnosticCallback;
MockSendEditorUpdatesCallback mockSendEditorUpdatesCallback;
const Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp");
const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h");
const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp");
@@ -208,6 +211,32 @@ TEST_F(TranslationUnits, RemoveFileAndCheckForDiagnostics)
ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewDiagnostics());
}
TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForHighlightingInformations)
{
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u);
ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, Utf8StringVector(), 74u);
ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u);
translationUnits.create({fileContainer, headerContainer});
translationUnits.translationUnit(filePath, projectPartId).highlightingInformations();
translationUnits.update({headerContainerWithUnsavedContent});
ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewHighlightingInformations());
}
TEST_F(TranslationUnits, RemoveFileAndCheckForHighlightingInformations)
{
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u);
ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, Utf8StringVector(), 74u);
ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u);
translationUnits.create({fileContainer, headerContainer});
translationUnits.translationUnit(filePath, projectPartId).highlightingInformations();
translationUnits.remove({headerContainerWithUnsavedContent});
ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewHighlightingInformations());
}
TEST_F(TranslationUnits, DontGetNewerFileContainerIfRevisionIsTheSame)
{
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u);
@@ -345,75 +374,77 @@ TEST_F(TranslationUnits, IsNotVisibleEditorAfterBeingVisible)
ASSERT_FALSE(translationUnit.isVisibleInEditor());
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsIfThereIsNothingToSend)
TEST_F(TranslationUnits, DoNotSendEditorUpdatesIfThereIsNothingToSend)
{
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0);
sendAllDiagnostics();
sendAllEditorUpdates();
}
TEST_F(TranslationUnits, SendDiagnosticsAfterTranslationUnitCreation)
TEST_F(TranslationUnits, SendEditorUpdatessAfterTranslationUnitCreation)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2);
sendAllDiagnostics();
sendAllEditorUpdates();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsAfterGettingDiagnostics)
TEST_F(TranslationUnits, DoNotSendEditorUpdatesAfterGettingEditorUpdates)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.diagnostics();
translationUnit.diagnostics(); // Reset
translationUnit.highlightingInformations(); // Reset
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1);
sendAllDiagnostics();
sendAllEditorUpdates();
}
TEST_F(TranslationUnits, SendDiagnosticsForCurrentEditor)
TEST_F(TranslationUnits, SendEditorUpdatesForCurrentEditor)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.setIsUsedByCurrentEditor(true);
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1);
sendAllCurrentEditorDiagnostics();
sendAllEditorUpdatesForCurrentEditor();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorIfThereIsNoCurrentEditor)
TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorIfThereIsNoCurrentEditor)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0);
sendAllCurrentEditorDiagnostics();
sendAllEditorUpdatesForCurrentEditor();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorAfterGettingDiagnostics)
TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorAfterGettingEditorUpdates)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.setIsUsedByCurrentEditor(true);
translationUnit.diagnostics();
translationUnit.diagnostics(); // Reset
translationUnit.highlightingInformations(); // Reset
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0);
sendAllCurrentEditorDiagnostics();
sendAllEditorUpdatesForCurrentEditor();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForVisibleEditorIfThereAreNoVisibleEditors)
TEST_F(TranslationUnits, DoNotSendEditorUpdatesForVisibleEditorIfThereAreNoVisibleEditors)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0);
translationUnits.sendChangedDiagnosticsForVisibleEditors();
translationUnits.sendDelayedEditorUpdatesForVisibleEditors();
}
TEST_F(TranslationUnits, SendDiagnosticsForVisibleEditors)
TEST_F(TranslationUnits, SendEditorUpdatesForVisibleEditors)
{
translationUnits.create({fileContainer, headerContainer});
auto fileTranslationUnit = translationUnits.translationUnit(fileContainer);
@@ -421,55 +452,58 @@ TEST_F(TranslationUnits, SendDiagnosticsForVisibleEditors)
auto headerTranslationUnit = translationUnits.translationUnit(headerContainer);
headerTranslationUnit.setIsVisibleInEditor(true);
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2);
sendAllVisibleEditorsDiagnostics();
sendAllEditorUpdatesForVisibleEditors();
}
TEST_F(TranslationUnits, SendOnlyOneDiagnosticsForVisibleEditor)
TEST_F(TranslationUnits, SendOnlyOneEditorUpdateForVisibleEditor)
{
translationUnits.create({fileContainer, headerContainer});
auto fileTranslationUnit = translationUnits.translationUnit(fileContainer);
fileTranslationUnit.setIsVisibleInEditor(true);
auto headerTranslationUnit = translationUnits.translationUnit(headerContainer);
headerTranslationUnit.setIsVisibleInEditor(true);
headerTranslationUnit.diagnostics();
headerTranslationUnit.diagnostics(); // Reset
headerTranslationUnit.highlightingInformations(); // Reset
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1);
sendAllVisibleEditorsDiagnostics();
sendAllEditorUpdatesForVisibleEditors();
}
void TranslationUnits::SetUp()
{
projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)});
auto callback = [&] (const DiagnosticsChangedMessage &) { mockSendDiagnosticCallback.sendDiagnostic(); };
translationUnits.setSendChangeDiagnosticsCallback(callback);
auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) {
mockSendEditorUpdatesCallback.sendEditorUpdates();
};
translationUnits.setSendDelayedEditorUpdatesCallback(callback);
}
void TranslationUnits::sendAllDiagnostics()
void TranslationUnits::sendAllEditorUpdates()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnostics();
while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates)
editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates();
}
void TranslationUnits::sendAllCurrentEditorDiagnostics()
void TranslationUnits::sendAllEditorUpdatesForCurrentEditor()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnosticsForCurrentEditor();
while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates)
editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForCurrentEditor();
}
void TranslationUnits::sendAllVisibleEditorsDiagnostics()
void TranslationUnits::sendAllEditorUpdatesForVisibleEditors()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnosticsForVisibleEditors();
while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates)
editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForVisibleEditors();
}
}

View File

@@ -30,6 +30,7 @@
#include <commandlinearguments.h>
#include <diagnosticset.h>
#include <highlightinginformations.h>
#include <filecontainer.h>
#include <projectpart.h>
#include <projects.h>
@@ -194,6 +195,15 @@ TEST_F(TranslationUnit, DependedFilePaths)
Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"))));
}
TEST_F(TranslationUnit, DeletedFileShouldNotNeedReparsing)
{
auto translationUnit = createTemporaryTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnit.filePath());
ASSERT_FALSE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, NeedsNoReparseAfterCreation)
{
translationUnit.cxTranslationUnit();
@@ -201,13 +211,6 @@ TEST_F(TranslationUnit, NeedsNoReparseAfterCreation)
ASSERT_FALSE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterCreation)
{
translationUnit.cxTranslationUnit();
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, NeedsReparseAfterChangeOfMainFile)
{
translationUnit.cxTranslationUnit();
@@ -217,15 +220,6 @@ TEST_F(TranslationUnit, NeedsReparseAfterChangeOfMainFile)
ASSERT_TRUE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterChangeOfMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, NoNeedForReparsingForIndependendFile)
{
translationUnit.cxTranslationUnit();
@@ -244,15 +238,6 @@ TEST_F(TranslationUnit, NeedsReparsingForDependendFile)
ASSERT_TRUE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, NeedsReparsingForMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, NeedsNoReparsingAfterReparsing)
{
translationUnit.cxTranslationUnit();
@@ -263,6 +248,22 @@ TEST_F(TranslationUnit, NeedsNoReparsingAfterReparsing)
ASSERT_FALSE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterCreation)
{
translationUnit.cxTranslationUnit();
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterChangeOfMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, HasNoNewDiagnosticsForIndependendFile)
{
translationUnit.cxTranslationUnit();
@@ -282,32 +283,59 @@ TEST_F(TranslationUnit, HasNewDiagnosticsForDependendFile)
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, HasNewDiagnosticsForMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, HasNoNewDiagnosticsAfterGettingDiagnostics)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
translationUnit.diagnostics();
translationUnit.diagnostics(); // Reset hasNewDiagnostics
ASSERT_FALSE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, DeletedFileShouldBeNotSetDirty)
TEST_F(TranslationUnit, HasNewHighlightingInformationsAfterCreation)
{
auto translationUnit = createTemporaryTranslationUnit();
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnit.filePath());
ASSERT_TRUE(translationUnit.hasNewHighlightingInformations());
}
ASSERT_FALSE(translationUnit.isNeedingReparse());
TEST_F(TranslationUnit, HasNewHighlightingInformationsForMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewHighlightingInformations());
}
TEST_F(TranslationUnit, HasNoNewHighlightingInformationsForIndependendFile)
{
translationUnit.cxTranslationUnit();
translationUnit.highlightingInformations();
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/otherfiles.h"));
ASSERT_FALSE(translationUnit.hasNewHighlightingInformations());
}
TEST_F(TranslationUnit, HasNewHighlightingInformationsForDependendFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"));
ASSERT_TRUE(translationUnit.hasNewHighlightingInformations());
}
TEST_F(TranslationUnit, HasNoNewHighlightingInformationsAfterGettingHighlightingInformations)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
translationUnit.highlightingInformations();
ASSERT_FALSE(translationUnit.hasNewHighlightingInformations());
}
::TranslationUnit TranslationUnit::createTemporaryTranslationUnit()

View File

@@ -56,7 +56,9 @@ SOURCES += \
senddocumenttrackertest.cpp \
cursortest.cpp \
highlightinginformationstest.cpp \
skippedsourcerangestest.cpp
skippedsourcerangestest.cpp \
highlightingmarksreportertest.cpp \
chunksreportedmonitor.cpp
HEADERS += \
gtest-qt-printing.h \
@@ -64,6 +66,7 @@ HEADERS += \
mockipcserver.h \
spydummy.h \
matcher-diagnosticcontainer.h \
mocksenddiagnosticscallback.h
chunksreportedmonitor.h \
mocksendeditorupdatescallback.h
OTHER_FILES += $$files(data/*)