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

@@ -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;