forked from qt-creator/qt-creator
ClangCodeModel: Remove libclang-based diagnostics and highlighting
Change-Id: Ib7c423884b76c27a6350ddea611919d3352fb80e Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -25,8 +25,6 @@ add_qtc_plugin(ClangCodeModel
|
||||
clangcompletioncontextanalyzer.cpp clangcompletioncontextanalyzer.h
|
||||
clangconstants.h
|
||||
clangdclient.cpp clangdclient.h
|
||||
clangdiagnosticfilter.cpp clangdiagnosticfilter.h
|
||||
clangdiagnosticmanager.cpp clangdiagnosticmanager.h
|
||||
clangdiagnostictooltipwidget.cpp clangdiagnostictooltipwidget.h
|
||||
clangdquickfixfactory.cpp clangdquickfixfactory.h
|
||||
clangdqpropertyhighlighter.cpp clangdqpropertyhighlighter.h
|
||||
@@ -36,8 +34,6 @@ add_qtc_plugin(ClangCodeModel
|
||||
clangfixitoperationsextractor.cpp clangfixitoperationsextractor.h
|
||||
clangfunctionhintmodel.cpp clangfunctionhintmodel.h
|
||||
clangdlocatorfilters.cpp clangdlocatorfilters.h
|
||||
clanghighlightingresultreporter.cpp clanghighlightingresultreporter.h
|
||||
clangisdiagnosticrelatedtolocation.h
|
||||
clangmodelmanagersupport.cpp clangmodelmanagersupport.h
|
||||
clangpreprocessorassistproposalitem.cpp clangpreprocessorassistproposalitem.h
|
||||
clangprojectsettings.cpp clangprojectsettings.h
|
||||
|
@@ -301,12 +301,6 @@ void BackendCommunicator::documentsChangedWithRevisionCheck(const FileContainer
|
||||
}
|
||||
}
|
||||
|
||||
void BackendCommunicator::requestAnnotations(const FileContainer &fileContainer)
|
||||
{
|
||||
const RequestAnnotationsMessage message(fileContainer);
|
||||
m_sender->requestAnnotations(message);
|
||||
}
|
||||
|
||||
QFuture<CppEditor::CursorInfo> BackendCommunicator::requestReferences(
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
|
@@ -91,7 +91,6 @@ public:
|
||||
qint32 funcNameStartLine = -1,
|
||||
qint32 funcNameStartColumn = -1);
|
||||
void cancelCompletions(TextEditor::IAssistProcessor *processor);
|
||||
void requestAnnotations(const ClangBackEnd::FileContainer &fileContainer);
|
||||
QFuture<CppEditor::CursorInfo> requestReferences(
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
|
@@ -207,22 +207,6 @@ void BackendReceiver::annotations(const ClangBackEnd::AnnotationsMessage &messag
|
||||
<< message.diagnostics.size() << "diagnostics" << message.tokenInfos.size()
|
||||
<< "token infos" << message.skippedPreprocessorRanges.size()
|
||||
<< "skipped preprocessor ranges";
|
||||
|
||||
auto processor = ClangEditorDocumentProcessor::get(message.fileContainer.filePath);
|
||||
if (!processor)
|
||||
return;
|
||||
|
||||
const quint32 documentRevision = message.fileContainer.documentRevision;
|
||||
if (message.onlyTokenInfos) {
|
||||
processor->updateTokenInfos(message.tokenInfos, documentRevision);
|
||||
return;
|
||||
}
|
||||
processor->updateCodeWarnings(message.diagnostics,
|
||||
message.firstHeaderErrorDiagnostic,
|
||||
documentRevision);
|
||||
processor->updateHighlighting(message.tokenInfos,
|
||||
message.skippedPreprocessorRanges,
|
||||
documentRevision);
|
||||
}
|
||||
|
||||
static
|
||||
|
@@ -56,10 +56,6 @@ QtcPlugin {
|
||||
"clangconstants.h",
|
||||
"clangdclient.cpp",
|
||||
"clangdclient.h",
|
||||
"clangdiagnosticfilter.cpp",
|
||||
"clangdiagnosticfilter.h",
|
||||
"clangdiagnosticmanager.cpp",
|
||||
"clangdiagnosticmanager.h",
|
||||
"clangdiagnostictooltipwidget.cpp",
|
||||
"clangdiagnostictooltipwidget.h",
|
||||
"clangdlocatorfilters.cpp",
|
||||
@@ -78,9 +74,6 @@ QtcPlugin {
|
||||
"clangfixitoperationsextractor.h",
|
||||
"clangfunctionhintmodel.cpp",
|
||||
"clangfunctionhintmodel.h",
|
||||
"clanghighlightingresultreporter.cpp",
|
||||
"clanghighlightingresultreporter.h",
|
||||
"clangisdiagnosticrelatedtolocation.h",
|
||||
"clangmodelmanagersupport.cpp",
|
||||
"clangmodelmanagersupport.h",
|
||||
"clangpreprocessorassistproposalitem.cpp",
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "clangcompletionassistprocessor.h"
|
||||
#include "clangcompletioncontextanalyzer.h"
|
||||
#include "clangdiagnosticmanager.h"
|
||||
#include "clangconstants.h"
|
||||
#include "clangdqpropertyhighlighter.h"
|
||||
#include "clangmodelmanagersupport.h"
|
||||
#include "clangpreprocessorassistproposalitem.h"
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
#include <texteditor/basefilefind.h>
|
||||
#include <texteditor/codeassist/assistinterface.h>
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
@@ -1613,7 +1614,7 @@ public:
|
||||
void hideDiagnostics(const Utils::FilePath &filePath) override
|
||||
{
|
||||
DiagnosticManager::hideDiagnostics(filePath);
|
||||
ClangDiagnosticManager::clearTaskHubIssues();
|
||||
TaskHub::clearTasks(Constants::TASK_CATEGORY_DIAGNOSTICS);
|
||||
}
|
||||
|
||||
QList<Diagnostic> filteredDiagnostics(const QList<Diagnostic> &diagnostics) const override
|
||||
|
@@ -1,188 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangdiagnosticfilter.h"
|
||||
|
||||
#include <cppeditor/cppprojectfile.h>
|
||||
|
||||
#include <utf8stringvector.h>
|
||||
|
||||
namespace {
|
||||
|
||||
bool isWarningOrNote(ClangBackEnd::DiagnosticSeverity severity)
|
||||
{
|
||||
using ClangBackEnd::DiagnosticSeverity;
|
||||
switch (severity) {
|
||||
case DiagnosticSeverity::Ignored:
|
||||
case DiagnosticSeverity::Note:
|
||||
case DiagnosticSeverity::Warning: return true;
|
||||
case DiagnosticSeverity::Error:
|
||||
case DiagnosticSeverity::Fatal: return false;
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
bool isBlackListedHeaderDiagnostic(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
bool isHeaderFile)
|
||||
{
|
||||
static const Utf8StringVector blackList{
|
||||
Utf8StringLiteral("warning: #pragma once in main file"),
|
||||
Utf8StringLiteral("warning: #include_next in primary source file")
|
||||
};
|
||||
|
||||
return isHeaderFile && blackList.contains(diagnostic.text);
|
||||
}
|
||||
|
||||
bool isBlackListedQtDiagnostic(const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
static const Utf8StringVector blackList{
|
||||
// From Q_OBJECT:
|
||||
Utf8StringLiteral("warning: "
|
||||
"'metaObject' overrides a member function but is not marked 'override'"),
|
||||
Utf8StringLiteral("warning: "
|
||||
"'qt_metacast' overrides a member function but is not marked 'override'"),
|
||||
Utf8StringLiteral("warning: "
|
||||
"'qt_metacall' overrides a member function but is not marked 'override'"),
|
||||
};
|
||||
|
||||
return blackList.contains(diagnostic.text);
|
||||
}
|
||||
|
||||
template <class Condition>
|
||||
QVector<ClangBackEnd::DiagnosticContainer>
|
||||
filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const Condition &condition)
|
||||
{
|
||||
QVector<ClangBackEnd::DiagnosticContainer> filteredDiagnostics;
|
||||
|
||||
std::copy_if(diagnostics.cbegin(),
|
||||
diagnostics.cend(),
|
||||
std::back_inserter(filteredDiagnostics),
|
||||
condition);
|
||||
|
||||
return filteredDiagnostics;
|
||||
}
|
||||
|
||||
template <class Condition>
|
||||
void
|
||||
filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const Condition &condition,
|
||||
QVector<ClangBackEnd::DiagnosticContainer> &filteredDiagnostic)
|
||||
{
|
||||
std::copy_if(diagnostics.cbegin(),
|
||||
diagnostics.cend(),
|
||||
std::back_inserter(filteredDiagnostic),
|
||||
condition);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
void ClangDiagnosticFilter::filterDocumentRelatedWarnings(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
||||
{
|
||||
using namespace CppEditor;
|
||||
const bool isHeaderFile = ProjectFile::isHeader(ProjectFile::classify(m_filePath));
|
||||
|
||||
const auto isLocalWarning = [this, isHeaderFile]
|
||||
(const ClangBackEnd::DiagnosticContainer &diagnostic) {
|
||||
return isWarningOrNote(diagnostic.severity)
|
||||
&& !isBlackListedHeaderDiagnostic(diagnostic, isHeaderFile)
|
||||
&& !isBlackListedQtDiagnostic(diagnostic)
|
||||
&& diagnostic.location.filePath == m_filePath;
|
||||
};
|
||||
|
||||
m_warningDiagnostics = filterDiagnostics(diagnostics, isLocalWarning);
|
||||
}
|
||||
|
||||
void ClangDiagnosticFilter::filterDocumentRelatedErrors(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
||||
{
|
||||
const auto isLocalWarning = [this] (const ClangBackEnd::DiagnosticContainer &diagnostic) {
|
||||
return !isWarningOrNote(diagnostic.severity)
|
||||
&& diagnostic.location.filePath == m_filePath;
|
||||
};
|
||||
|
||||
m_errorDiagnostics = filterDiagnostics(diagnostics, isLocalWarning);
|
||||
}
|
||||
|
||||
void ClangDiagnosticFilter::filterFixits()
|
||||
{
|
||||
const auto hasFixIts = [] (const ClangBackEnd::DiagnosticContainer &diagnostic) {
|
||||
return diagnostic.fixIts.size() > 0;
|
||||
};
|
||||
|
||||
m_fixItdiagnostics.clear();
|
||||
filterDiagnostics(m_warningDiagnostics, hasFixIts, m_fixItdiagnostics);
|
||||
filterDiagnostics(m_errorDiagnostics, hasFixIts, m_fixItdiagnostics);
|
||||
|
||||
for (const auto &warningDiagnostic : m_warningDiagnostics)
|
||||
filterDiagnostics(warningDiagnostic.children, hasFixIts, m_fixItdiagnostics);
|
||||
for (const auto &warningDiagnostic : m_errorDiagnostics)
|
||||
filterDiagnostics(warningDiagnostic.children, hasFixIts, m_fixItdiagnostics);
|
||||
}
|
||||
|
||||
ClangDiagnosticFilter::ClangDiagnosticFilter(const QString &filePath)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
void ClangDiagnosticFilter::filter(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
||||
{
|
||||
filterDocumentRelatedWarnings(diagnostics);
|
||||
filterDocumentRelatedErrors(diagnostics);
|
||||
filterFixits();
|
||||
}
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> ClangDiagnosticFilter::takeWarnings()
|
||||
{
|
||||
auto diagnostics = m_warningDiagnostics;
|
||||
m_warningDiagnostics.clear();
|
||||
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> ClangDiagnosticFilter::takeErrors()
|
||||
{
|
||||
auto diagnostics = m_errorDiagnostics;
|
||||
m_errorDiagnostics.clear();
|
||||
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> ClangDiagnosticFilter::takeFixIts()
|
||||
{
|
||||
auto diagnostics = m_fixItdiagnostics;
|
||||
m_fixItdiagnostics.clear();
|
||||
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
||||
|
@@ -1,60 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <clangsupport/diagnosticcontainer.h>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
class ClangDiagnosticFilter
|
||||
{
|
||||
public:
|
||||
ClangDiagnosticFilter(const QString &filePath);
|
||||
|
||||
void filter(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> takeWarnings();
|
||||
QVector<ClangBackEnd::DiagnosticContainer> takeErrors();
|
||||
QVector<ClangBackEnd::DiagnosticContainer> takeFixIts();
|
||||
|
||||
private:
|
||||
void filterDocumentRelatedWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||
void filterDocumentRelatedErrors(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||
void filterFixits();
|
||||
|
||||
private:
|
||||
const QString m_filePath;
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics;
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics;
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_fixItdiagnostics;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -1,504 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangconstants.h"
|
||||
#include "clangdiagnosticfilter.h"
|
||||
#include "clangdiagnosticmanager.h"
|
||||
#include "clangisdiagnosticrelatedtolocation.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
|
||||
#include <cppeditor/cppeditorconstants.h>
|
||||
|
||||
#include <projectexplorer/taskhub.h>
|
||||
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
|
||||
#include <utils/textutils.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/proxyaction.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/theme/theme.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QTextBlock>
|
||||
|
||||
namespace {
|
||||
|
||||
QTextEdit::ExtraSelection createExtraSelections(const QTextCharFormat &mainformat,
|
||||
const QTextCursor &cursor)
|
||||
{
|
||||
QTextEdit::ExtraSelection extraSelection;
|
||||
|
||||
extraSelection.format = mainformat;
|
||||
extraSelection.cursor = cursor;
|
||||
|
||||
return extraSelection;
|
||||
}
|
||||
|
||||
void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
QTextDocument *textDocument,
|
||||
const QTextCharFormat &contextFormat,
|
||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||
{
|
||||
for (auto &&range : diagnostic.ranges) {
|
||||
QTextCursor cursor(textDocument);
|
||||
cursor.setPosition(::Utils::Text::positionInText(textDocument,
|
||||
range.start.line,
|
||||
range.start.column));
|
||||
cursor.setPosition(::Utils::Text::positionInText(textDocument,
|
||||
range.end.line,
|
||||
range.end.column),
|
||||
QTextCursor::KeepAnchor);
|
||||
|
||||
auto extraSelection = createExtraSelections(contextFormat, cursor);
|
||||
|
||||
extraSelections.push_back(std::move(extraSelection));
|
||||
}
|
||||
}
|
||||
|
||||
QChar selectionEndChar(const QChar startSymbol)
|
||||
{
|
||||
if (startSymbol == '"')
|
||||
return QLatin1Char('"');
|
||||
if (startSymbol == '<')
|
||||
return QLatin1Char('>');
|
||||
return {};
|
||||
}
|
||||
|
||||
void selectToLocationEnd(QTextCursor &cursor)
|
||||
{
|
||||
const QTextBlock textBlock = cursor.document()->findBlock(cursor.position());
|
||||
const QString simplifiedStr = textBlock.text().simplified();
|
||||
if (!simplifiedStr.startsWith("#include") && !simplifiedStr.startsWith("# include")) {
|
||||
// General case, not the line with #include
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
return;
|
||||
}
|
||||
|
||||
const QChar endChar = selectionEndChar(cursor.document()->characterAt(cursor.position()));
|
||||
if (endChar.isNull()) {
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
} else {
|
||||
const int endPosition = textBlock.text().indexOf(endChar, cursor.position()
|
||||
- textBlock.position() + 1);
|
||||
if (endPosition >= 0)
|
||||
cursor.setPosition(textBlock.position() + endPosition + 1, QTextCursor::KeepAnchor);
|
||||
else
|
||||
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||
}
|
||||
}
|
||||
|
||||
QTextCursor createSelectionCursor(QTextDocument *textDocument,
|
||||
const ClangBackEnd::SourceLocationContainer &sourceLocationContainer)
|
||||
{
|
||||
QTextCursor cursor(textDocument);
|
||||
cursor.setPosition(::Utils::Text::positionInText(textDocument,
|
||||
sourceLocationContainer.line,
|
||||
sourceLocationContainer.column));
|
||||
selectToLocationEnd(cursor);
|
||||
|
||||
if (!cursor.hasSelection()) {
|
||||
cursor.setPosition(::Utils::Text::positionInText(textDocument,
|
||||
sourceLocationContainer.line,
|
||||
sourceLocationContainer.column) - 1);
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void addSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
QTextDocument *textDocument,
|
||||
const QTextCharFormat &mainFormat,
|
||||
const QTextCharFormat &contextFormat,
|
||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||
{
|
||||
for (auto &&diagnostic : diagnostics) {
|
||||
auto cursor = createSelectionCursor(textDocument, diagnostic.location);
|
||||
auto extraSelection = createExtraSelections(mainFormat, cursor);
|
||||
|
||||
addRangeSelections(diagnostic, textDocument, contextFormat, extraSelections);
|
||||
|
||||
extraSelections.push_back(std::move(extraSelection));
|
||||
}
|
||||
}
|
||||
|
||||
void addWarningSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
QTextDocument *textDocument,
|
||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||
{
|
||||
const auto fontSettings = TextEditor::TextEditorSettings::fontSettings();
|
||||
|
||||
QTextCharFormat warningFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING);
|
||||
|
||||
QTextCharFormat warningContextFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING_CONTEXT);
|
||||
|
||||
addSelections(diagnostics, textDocument, warningFormat, warningContextFormat, extraSelections);
|
||||
}
|
||||
|
||||
void addErrorSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
QTextDocument *textDocument,
|
||||
QList<QTextEdit::ExtraSelection> &extraSelections)
|
||||
{
|
||||
const auto fontSettings = TextEditor::TextEditorSettings::fontSettings();
|
||||
|
||||
QTextCharFormat errorFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR);
|
||||
QTextCharFormat errorContextFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR_CONTEXT);
|
||||
|
||||
addSelections(diagnostics, textDocument, errorFormat, errorContextFormat, extraSelections);
|
||||
}
|
||||
|
||||
ClangBackEnd::SourceLocationContainer toSourceLocation(QTextDocument *textDocument, int position)
|
||||
{
|
||||
int line, column;
|
||||
if (Utils::Text::convertPosition(textDocument, position, &line, &column))
|
||||
return ClangBackEnd::SourceLocationContainer(Utf8String(), line, column);
|
||||
|
||||
return ClangBackEnd::SourceLocationContainer();
|
||||
}
|
||||
|
||||
ClangBackEnd::SourceRangeContainer toSourceRange(const QTextCursor &cursor)
|
||||
{
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
QTextDocument *textDocument = cursor.document();
|
||||
|
||||
return SourceRangeContainer(toSourceLocation(textDocument, cursor.anchor()),
|
||||
toSourceLocation(textDocument, cursor.position()));
|
||||
}
|
||||
|
||||
bool isDiagnosticAtLocation(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
uint line,
|
||||
uint column,
|
||||
QTextDocument *textDocument)
|
||||
{
|
||||
using namespace ClangCodeModel::Internal;
|
||||
|
||||
const ClangBackEnd::SourceLocationContainer &location = diagnostic.location;
|
||||
const QTextCursor cursor = createSelectionCursor(textDocument, location);
|
||||
const ClangBackEnd::SourceRangeContainer cursorRange = toSourceRange(cursor);
|
||||
|
||||
return isDiagnosticRelatedToLocation(diagnostic, {cursorRange}, line, column);
|
||||
}
|
||||
|
||||
QTextCursor cursorAtLastPositionOfLine(QTextDocument *textDocument, int lineNumber)
|
||||
{
|
||||
const QTextBlock textBlock = textDocument->findBlockByNumber(lineNumber - 1);
|
||||
QTC_ASSERT(textBlock.isValid(), return QTextCursor());
|
||||
|
||||
const int lastPositionOfLine = textBlock.position() + textBlock.length() - 1;
|
||||
|
||||
QTextCursor textCursor(textDocument);
|
||||
textCursor.setPosition(lastPositionOfLine);
|
||||
|
||||
return textCursor;
|
||||
}
|
||||
|
||||
QString tooltipForFixItAvailableMarker()
|
||||
{
|
||||
QString text = QCoreApplication::translate("ClangCodeModel::Internal::ClangDiagnosticManager", "Inspect available fixits");
|
||||
|
||||
Core::Command *command = Core::ActionManager::command(TextEditor::Constants::QUICKFIX_THIS);
|
||||
if (command)
|
||||
text = Utils::ProxyAction::stringWithAppendedShortcut(text, command->keySequence());
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
TextEditor::RefactorMarker createFixItAvailableMarker(QTextDocument *textDocument, int lineNumber)
|
||||
{
|
||||
TextEditor::RefactorMarker marker;
|
||||
marker.tooltip = tooltipForFixItAvailableMarker();
|
||||
marker.cursor = cursorAtLastPositionOfLine(textDocument, lineNumber);
|
||||
marker.callback = [marker](TextEditor::TextEditorWidget *editor) {
|
||||
int line, column;
|
||||
if (Utils::Text::convertPosition(marker.cursor.document(),
|
||||
marker.cursor.position(), &line, &column)) {
|
||||
editor->setTextCursor(marker.cursor);
|
||||
editor->invokeAssist(TextEditor::QuickFix);
|
||||
}
|
||||
};
|
||||
marker.type = CppEditor::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID;
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
ClangDiagnosticManager::ClangDiagnosticManager(TextEditor::TextDocument *textDocument)
|
||||
: m_textDocument(textDocument)
|
||||
{
|
||||
m_textMarkDelay.setInterval(1500);
|
||||
m_textMarkDelay.setSingleShot(true);
|
||||
}
|
||||
|
||||
ClangDiagnosticManager::~ClangDiagnosticManager()
|
||||
{
|
||||
cleanMarks();
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::cleanMarks()
|
||||
{
|
||||
for (ClangTextMark *textMark : m_clangTextMarks) {
|
||||
m_textDocument->removeMark(textMark);
|
||||
delete textMark;
|
||||
}
|
||||
m_clangTextMarks.clear();
|
||||
}
|
||||
void ClangDiagnosticManager::generateTextMarks()
|
||||
{
|
||||
QObject::disconnect(&m_textMarkDelay, &QTimer::timeout, nullptr, nullptr);
|
||||
cleanMarks();
|
||||
m_clangTextMarks.reserve(m_warningDiagnostics.size() + m_errorDiagnostics.size());
|
||||
addClangTextMarks(m_warningDiagnostics);
|
||||
addClangTextMarks(m_errorDiagnostics);
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::generateFixItAvailableMarkers()
|
||||
{
|
||||
m_fixItAvailableMarkers.clear();
|
||||
|
||||
if (!m_fullVisualization)
|
||||
return;
|
||||
|
||||
QSet<int> lineNumbersWithFixItMarker;
|
||||
addFixItAvailableMarker(m_warningDiagnostics, lineNumbersWithFixItMarker);
|
||||
addFixItAvailableMarker(m_errorDiagnostics, lineNumbersWithFixItMarker);
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::addTask(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
bool isChild)
|
||||
{
|
||||
using namespace ProjectExplorer;
|
||||
using ::Utils::FilePath;
|
||||
|
||||
Task::TaskType taskType = ProjectExplorer::Task::TaskType::Unknown;
|
||||
FilePath iconPath;
|
||||
QIcon icon;
|
||||
|
||||
if (!isChild) {
|
||||
switch (diagnostic.severity) {
|
||||
case ClangBackEnd::DiagnosticSeverity::Fatal:
|
||||
case ClangBackEnd::DiagnosticSeverity::Error:
|
||||
taskType = Task::TaskType::Error;
|
||||
icon = ::Utils::Icons::CODEMODEL_ERROR.icon();
|
||||
break;
|
||||
case ClangBackEnd::DiagnosticSeverity::Warning:
|
||||
taskType = Task::TaskType::Warning;
|
||||
icon = ::Utils::Icons::CODEMODEL_WARNING.icon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TaskHub::addTask(Task(taskType,
|
||||
diagnosticCategoryPrefixRemoved(diagnostic.text.toString()),
|
||||
FilePath::fromString(diagnostic.location.filePath.toString()),
|
||||
diagnostic.location.line,
|
||||
Constants::TASK_CATEGORY_DIAGNOSTICS,
|
||||
icon,
|
||||
Task::NoOptions));
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::clearTaskHubIssues()
|
||||
{
|
||||
ProjectExplorer::TaskHub::clearTasks(Constants::TASK_CATEGORY_DIAGNOSTICS);
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::generateTaskHubIssues()
|
||||
{
|
||||
if (!m_fullVisualization)
|
||||
return;
|
||||
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> diagnostics = m_errorDiagnostics
|
||||
+ m_warningDiagnostics;
|
||||
for (const ClangBackEnd::DiagnosticContainer &diagnostic : diagnostics) {
|
||||
addTask(diagnostic);
|
||||
for (const ClangBackEnd::DiagnosticContainer &child : diagnostic.children)
|
||||
addTask(child, /*isChild = */ true);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QTextEdit::ExtraSelection> ClangDiagnosticManager::takeExtraSelections()
|
||||
{
|
||||
auto extraSelections = m_extraSelections;
|
||||
|
||||
m_extraSelections.clear();
|
||||
|
||||
return extraSelections;
|
||||
}
|
||||
|
||||
TextEditor::RefactorMarkers ClangDiagnosticManager::takeFixItAvailableMarkers()
|
||||
{
|
||||
TextEditor::RefactorMarkers fixItAvailableMarkers = m_fixItAvailableMarkers;
|
||||
|
||||
m_fixItAvailableMarkers.clear();
|
||||
|
||||
return fixItAvailableMarkers;
|
||||
}
|
||||
|
||||
TextEditor::TextMarks ClangDiagnosticManager::diagnosticTextMarksAt(uint line, uint column) const
|
||||
{
|
||||
QList<TextEditor::TextMark *> textMarks;
|
||||
|
||||
for (ClangTextMark *textMark : m_clangTextMarks) {
|
||||
if (isDiagnosticAtLocation(textMark->diagnostic(), line, column, m_textDocument->document()))
|
||||
textMarks << textMark;
|
||||
}
|
||||
|
||||
return textMarks;
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::invalidateDiagnostics()
|
||||
{
|
||||
m_textMarkDelay.start();
|
||||
if (m_diagnosticsInvalidated)
|
||||
return;
|
||||
|
||||
m_diagnosticsInvalidated = true;
|
||||
for (ClangTextMark *textMark : m_clangTextMarks) {
|
||||
textMark->setColor(::Utils::Theme::Color::IconsDisabledColor);
|
||||
textMark->updateIcon(/*valid=*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::clearDiagnosticsWithFixIts()
|
||||
{
|
||||
m_fixItdiagnostics.clear();
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::generateEditorSelections()
|
||||
{
|
||||
m_extraSelections.clear();
|
||||
m_extraSelections.reserve(int(m_warningDiagnostics.size() + m_errorDiagnostics.size()));
|
||||
|
||||
if (!m_fullVisualization)
|
||||
return;
|
||||
|
||||
addWarningSelections(m_warningDiagnostics, m_textDocument->document(), m_extraSelections);
|
||||
addErrorSelections(m_errorDiagnostics, m_textDocument->document(), m_extraSelections);
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::processNewDiagnostics(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &allDiagnostics,
|
||||
bool fullVisualization)
|
||||
{
|
||||
m_diagnosticsInvalidated = false;
|
||||
m_fullVisualization = fullVisualization;
|
||||
filterDiagnostics(allDiagnostics);
|
||||
|
||||
generateEditorSelections();
|
||||
generateFixItAvailableMarkers();
|
||||
if (m_firstDiagnostics) {
|
||||
m_firstDiagnostics = false;
|
||||
generateTextMarks();
|
||||
} else if (!m_textMarkDelay.isActive()) {
|
||||
generateTextMarks();
|
||||
} else {
|
||||
QObject::connect(&m_textMarkDelay, &QTimer::timeout, [this]() {
|
||||
generateTextMarks();
|
||||
});
|
||||
}
|
||||
|
||||
clearTaskHubIssues();
|
||||
generateTaskHubIssues();
|
||||
}
|
||||
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &
|
||||
ClangDiagnosticManager::diagnosticsWithFixIts() const
|
||||
{
|
||||
return m_fixItdiagnostics;
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::addClangTextMarks(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
||||
{
|
||||
for (const ClangBackEnd::DiagnosticContainer &diagnostic : diagnostics) {
|
||||
const auto onMarkRemoved = [this](const ClangTextMark *mark) {
|
||||
const auto it = std::remove(m_clangTextMarks.begin(), m_clangTextMarks.end(), mark);
|
||||
m_clangTextMarks.erase(it, m_clangTextMarks.end());
|
||||
delete mark;
|
||||
};
|
||||
auto textMark = new ClangTextMark(::Utils::FilePath::fromString(filePath()),
|
||||
diagnostic,
|
||||
onMarkRemoved,
|
||||
m_fullVisualization,
|
||||
this);
|
||||
m_clangTextMarks.push_back(textMark);
|
||||
m_textDocument->addMark(textMark);
|
||||
}
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::addFixItAvailableMarker(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
QSet<int> &lineNumbersWithFixItMarker)
|
||||
{
|
||||
for (auto &&diagnostic : diagnostics) {
|
||||
for (auto &&fixit : diagnostic.fixIts) {
|
||||
const ClangBackEnd::SourceLocationContainer &location = fixit.range.start;
|
||||
const int line = int(location.line);
|
||||
|
||||
if (location.filePath == filePath() && !lineNumbersWithFixItMarker.contains(line)) {
|
||||
const TextEditor::RefactorMarker marker
|
||||
= createFixItAvailableMarker(m_textDocument->document(), line);
|
||||
|
||||
lineNumbersWithFixItMarker.insert(line);
|
||||
m_fixItAvailableMarkers.append(marker);
|
||||
}
|
||||
}
|
||||
|
||||
addFixItAvailableMarker(diagnostic.children, lineNumbersWithFixItMarker);
|
||||
}
|
||||
}
|
||||
|
||||
QString ClangDiagnosticManager::filePath() const
|
||||
{
|
||||
return m_textDocument->filePath().toString();
|
||||
}
|
||||
|
||||
void ClangDiagnosticManager::filterDiagnostics(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
|
||||
{
|
||||
ClangDiagnosticFilter filter(filePath());
|
||||
filter.filter(diagnostics);
|
||||
|
||||
m_warningDiagnostics = filter.takeWarnings();
|
||||
m_errorDiagnostics = filter.takeErrors();
|
||||
m_fixItdiagnostics = filter.takeFixIts();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -1,98 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangtextmark.h"
|
||||
|
||||
#include <texteditor/refactoroverlay.h>
|
||||
|
||||
#include <clangsupport/diagnosticcontainer.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QTextEdit>
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace TextEditor { class TextDocument; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
class ClangDiagnosticManager
|
||||
{
|
||||
public:
|
||||
ClangDiagnosticManager(TextEditor::TextDocument *textDocument);
|
||||
~ClangDiagnosticManager();
|
||||
|
||||
void processNewDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &allDiagnostics,
|
||||
bool fullVisualization);
|
||||
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnosticsWithFixIts() const;
|
||||
QList<QTextEdit::ExtraSelection> takeExtraSelections();
|
||||
TextEditor::RefactorMarkers takeFixItAvailableMarkers();
|
||||
|
||||
QList<TextEditor::TextMark *> diagnosticTextMarksAt(uint line, uint column) const;
|
||||
bool diagnosticsInvalidated() const { return m_diagnosticsInvalidated; }
|
||||
|
||||
void invalidateDiagnostics();
|
||||
void clearDiagnosticsWithFixIts();
|
||||
|
||||
static void clearTaskHubIssues();
|
||||
void generateTaskHubIssues();
|
||||
void cleanMarks();
|
||||
|
||||
static void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic, bool isChild = false);
|
||||
|
||||
private:
|
||||
QString filePath() const;
|
||||
void filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||
void generateEditorSelections();
|
||||
void generateTextMarks();
|
||||
void generateFixItAvailableMarkers();
|
||||
void addClangTextMarks(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||
void addFixItAvailableMarker(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
QSet<int> &lineNumbersWithFixItMarker);
|
||||
|
||||
private:
|
||||
TextEditor::TextDocument *m_textDocument;
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics;
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics;
|
||||
QVector<ClangBackEnd::DiagnosticContainer> m_fixItdiagnostics;
|
||||
QList<QTextEdit::ExtraSelection> m_extraSelections;
|
||||
TextEditor::RefactorMarkers m_fixItAvailableMarkers;
|
||||
std::vector<ClangTextMark *> m_clangTextMarks;
|
||||
bool m_firstDiagnostics = true;
|
||||
bool m_diagnosticsInvalidated = false;
|
||||
bool m_fullVisualization = false;
|
||||
QTimer m_textMarkDelay;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "clangdiagnostictooltipwidget.h"
|
||||
|
||||
#include "clangdiagnosticmanager.h"
|
||||
#include "clangfixitoperation.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
|
@@ -36,7 +36,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
class ClangDiagnosticManager;
|
||||
|
||||
class ClangDiagnosticWidget {
|
||||
public:
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include "clangfixitoperation.h"
|
||||
#include "clangfixitoperationsextractor.h"
|
||||
#include "clangmodelmanagersupport.h"
|
||||
#include "clanghighlightingresultreporter.h"
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <diagnosticcontainer.h>
|
||||
@@ -72,12 +71,10 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *document)
|
||||
: BaseEditorDocumentProcessor(document->document(), document->filePath().toString())
|
||||
, m_document(*document)
|
||||
, m_diagnosticManager(document)
|
||||
, m_communicator(communicator)
|
||||
, m_parser(new ClangEditorDocumentParser(document->filePath().toString()))
|
||||
, m_parserRevision(0)
|
||||
, m_semanticHighlighter(document)
|
||||
, m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
|
||||
, m_builtinProcessor(document)
|
||||
{
|
||||
m_updateBackendDocumentTimer.setSingleShot(true);
|
||||
m_updateBackendDocumentTimer.setInterval(350);
|
||||
@@ -93,6 +90,11 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
||||
this, &ClangEditorDocumentProcessor::cppDocumentUpdated);
|
||||
connect(&m_builtinProcessor, &CppEditor::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
|
||||
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
|
||||
connect(&m_builtinProcessor, &CppEditor::BuiltinEditorDocumentProcessor::codeWarningsUpdated,
|
||||
this, &ClangEditorDocumentProcessor::codeWarningsUpdated);
|
||||
m_builtinProcessor.setSemanticHighlightingChecker([this] {
|
||||
return !ClangModelManagerSupport::instance()->clientForFile(m_document.filePath());
|
||||
});
|
||||
|
||||
m_parserSynchronizer.setCancelOnWait(true);
|
||||
}
|
||||
@@ -141,10 +143,7 @@ void ClangEditorDocumentProcessor::semanticRehighlight()
|
||||
return;
|
||||
if (ClangModelManagerSupport::instance()->clientForFile(m_document.filePath()))
|
||||
return;
|
||||
|
||||
m_semanticHighlighter.updateFormatMapFromFontSettings();
|
||||
if (m_projectPart)
|
||||
requestAnnotationsFromBackend();
|
||||
m_builtinProcessor.semanticRehighlight();
|
||||
}
|
||||
|
||||
CppEditor::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
|
||||
@@ -187,142 +186,12 @@ void ClangEditorDocumentProcessor::clearProjectPart()
|
||||
return m_diagnosticConfigId;
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateCodeWarnings(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||
uint documentRevision)
|
||||
{
|
||||
if (ClangModelManagerSupport::instance()->clientForFile(m_document.filePath()))
|
||||
return;
|
||||
|
||||
if (documentRevision == revision()) {
|
||||
if (m_invalidationState == InvalidationState::Scheduled)
|
||||
m_invalidationState = InvalidationState::Canceled;
|
||||
m_diagnosticManager.processNewDiagnostics(diagnostics, m_isProjectFile);
|
||||
const auto codeWarnings = m_diagnosticManager.takeExtraSelections();
|
||||
const auto fixitAvailableMarkers = m_diagnosticManager.takeFixItAvailableMarkers();
|
||||
const auto creator = creatorForHeaderErrorDiagnosticWidget(firstHeaderErrorDiagnostic);
|
||||
|
||||
emit codeWarningsUpdated(revision(),
|
||||
codeWarnings,
|
||||
creator,
|
||||
fixitAvailableMarkers);
|
||||
}
|
||||
}
|
||||
namespace {
|
||||
|
||||
TextEditor::BlockRange
|
||||
toTextEditorBlock(QTextDocument *textDocument,
|
||||
const ClangBackEnd::SourceRangeContainer &sourceRangeContainer)
|
||||
{
|
||||
return {::Utils::Text::positionInText(textDocument,
|
||||
sourceRangeContainer.start.line,
|
||||
sourceRangeContainer.start.column),
|
||||
::Utils::Text::positionInText(textDocument,
|
||||
sourceRangeContainer.end.line,
|
||||
sourceRangeContainer.end.column)};
|
||||
}
|
||||
|
||||
QList<TextEditor::BlockRange>
|
||||
toTextEditorBlocks(QTextDocument *textDocument,
|
||||
const QVector<ClangBackEnd::SourceRangeContainer> &ifdefedOutRanges)
|
||||
{
|
||||
QList<TextEditor::BlockRange> blockRanges;
|
||||
blockRanges.reserve(ifdefedOutRanges.size());
|
||||
|
||||
for (const auto &range : ifdefedOutRanges)
|
||||
blockRanges.append(toTextEditorBlock(textDocument, range));
|
||||
|
||||
return blockRanges;
|
||||
}
|
||||
}
|
||||
|
||||
const QVector<ClangBackEnd::TokenInfoContainer>
|
||||
&ClangEditorDocumentProcessor::tokenInfos() const
|
||||
{
|
||||
return m_tokenInfos;
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::clearTaskHubIssues()
|
||||
{
|
||||
ClangDiagnosticManager::clearTaskHubIssues();
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::generateTaskHubIssues()
|
||||
{
|
||||
m_diagnosticManager.generateTaskHubIssues();
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::clearTextMarks(const Utils::FilePath &filePath)
|
||||
{
|
||||
if (ClangEditorDocumentProcessor * const proc = get(filePath.toString())) {
|
||||
proc->m_diagnosticManager.cleanMarks();
|
||||
emit proc->codeWarningsUpdated(proc->revision(), {}, {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateHighlighting(
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||
uint documentRevision)
|
||||
{
|
||||
if (ClangModelManagerSupport::instance()->clientForFile(m_document.filePath()))
|
||||
return;
|
||||
if (documentRevision == revision()) {
|
||||
const auto skippedPreprocessorBlocks = toTextEditorBlocks(textDocument(), skippedPreprocessorRanges);
|
||||
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
|
||||
|
||||
m_semanticHighlighter.setHighlightingRunner(
|
||||
[tokenInfos]() { return highlightResults(tokenInfos); });
|
||||
m_semanticHighlighter.run();
|
||||
}
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateTokenInfos(
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
uint documentRevision)
|
||||
{
|
||||
if (documentRevision != revision())
|
||||
return;
|
||||
m_tokenInfos = tokenInfos;
|
||||
emit tokenInfosUpdated();
|
||||
}
|
||||
|
||||
static int currentLine(const TextEditor::AssistInterface &assistInterface)
|
||||
{
|
||||
int line, column;
|
||||
::Utils::Text::convertPosition(assistInterface.textDocument(), assistInterface.position(),
|
||||
&line, &column);
|
||||
return line;
|
||||
}
|
||||
|
||||
TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOperations(
|
||||
const TextEditor::AssistInterface &assistInterface)
|
||||
{
|
||||
ClangFixItOperationsExtractor extractor(m_diagnosticManager.diagnosticsWithFixIts());
|
||||
|
||||
return extractor.extract(assistInterface.filePath().toString(), currentLine(assistInterface));
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::editorDocumentTimerRestarted()
|
||||
{
|
||||
m_updateBackendDocumentTimer.stop(); // Wait for the next call to run().
|
||||
m_invalidationState = InvalidationState::Scheduled;
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::invalidateDiagnostics()
|
||||
{
|
||||
if (m_invalidationState != InvalidationState::Canceled)
|
||||
m_diagnosticManager.invalidateDiagnostics();
|
||||
m_invalidationState = InvalidationState::Off;
|
||||
}
|
||||
|
||||
TextEditor::TextMarks ClangEditorDocumentProcessor::diagnosticTextMarksAt(uint line,
|
||||
uint column) const
|
||||
{
|
||||
return m_diagnosticManager.diagnosticTextMarksAt(line, column);
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::setParserConfig(
|
||||
const CppEditor::BaseEditorDocumentParser::Configuration &config)
|
||||
{
|
||||
@@ -413,11 +282,6 @@ QFuture<CppEditor::ToolTipInfo> ClangEditorDocumentProcessor::toolTipInfo(const
|
||||
static_cast<quint32>(column));
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::clearDiagnosticsWithFixIts()
|
||||
{
|
||||
m_diagnosticManager.clearDiagnosticsWithFixIts();
|
||||
}
|
||||
|
||||
ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const QString &filePath)
|
||||
{
|
||||
return qobject_cast<ClangEditorDocumentProcessor*>(
|
||||
@@ -492,35 +356,6 @@ void ClangEditorDocumentProcessor::updateBackendDocumentIfProjectPartExists()
|
||||
}
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::requestAnnotationsFromBackend()
|
||||
{
|
||||
const auto fileContainer = fileContainerWithDocumentContent();
|
||||
m_communicator.requestAnnotations(fileContainer);
|
||||
}
|
||||
|
||||
CppEditor::BaseEditorDocumentProcessor::HeaderErrorDiagnosticWidgetCreator
|
||||
ClangEditorDocumentProcessor::creatorForHeaderErrorDiagnosticWidget(
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic)
|
||||
{
|
||||
if (firstHeaderErrorDiagnostic.text.isEmpty())
|
||||
return CppEditor::BaseEditorDocumentProcessor::HeaderErrorDiagnosticWidgetCreator();
|
||||
|
||||
return [firstHeaderErrorDiagnostic]() {
|
||||
auto vbox = new QVBoxLayout;
|
||||
vbox->setContentsMargins(10, 0, 0, 2);
|
||||
vbox->setSpacing(2);
|
||||
|
||||
vbox->addWidget(ClangDiagnosticWidget::createWidget({firstHeaderErrorDiagnostic},
|
||||
ClangDiagnosticWidget::InfoBar, {},
|
||||
"libclang"));
|
||||
|
||||
auto widget = new QWidget;
|
||||
widget->setLayout(vbox);
|
||||
|
||||
return widget;
|
||||
};
|
||||
}
|
||||
|
||||
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer(
|
||||
const QByteArray &codecName) const
|
||||
{
|
||||
|
@@ -25,11 +25,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangdiagnosticmanager.h"
|
||||
#include "clangeditordocumentparser.h"
|
||||
|
||||
#include <clangsupport/sourcerangecontainer.h>
|
||||
|
||||
#include <cppeditor/builtineditordocumentprocessor.h>
|
||||
#include <cppeditor/semantichighlighter.h>
|
||||
|
||||
#include <utils/futuresynchronizer.h>
|
||||
#include <utils/id.h>
|
||||
@@ -72,22 +72,6 @@ public:
|
||||
|
||||
::Utils::Id diagnosticConfigId() const;
|
||||
|
||||
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||
uint documentRevision);
|
||||
void updateHighlighting(const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||
uint documentRevision);
|
||||
void updateTokenInfos(const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
uint documentRevision);
|
||||
|
||||
TextEditor::QuickFixOperations
|
||||
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
|
||||
|
||||
void invalidateDiagnostics() override;
|
||||
|
||||
TextEditor::TextMarks diagnosticTextMarksAt(uint line, uint column) const;
|
||||
|
||||
void editorDocumentTimerRestarted() override;
|
||||
|
||||
void setParserConfig(const CppEditor::BaseEditorDocumentParser::Configuration &config) override;
|
||||
@@ -102,15 +86,6 @@ public:
|
||||
|
||||
void closeBackendDocument();
|
||||
|
||||
void clearDiagnosticsWithFixIts();
|
||||
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos() const;
|
||||
|
||||
static void clearTaskHubIssues();
|
||||
void generateTaskHubIssues();
|
||||
|
||||
static void clearTextMarks(const Utils::FilePath &filePath);
|
||||
|
||||
public:
|
||||
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
||||
|
||||
@@ -125,10 +100,7 @@ private:
|
||||
void updateBackendProjectPartAndDocument();
|
||||
void updateBackendDocument(const CppEditor::ProjectPart &projectPart);
|
||||
void updateBackendDocumentIfProjectPartExists();
|
||||
void requestAnnotationsFromBackend();
|
||||
|
||||
HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget(
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic);
|
||||
ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const;
|
||||
ClangBackEnd::FileContainer fileContainerWithOptionsAndDocumentContent(
|
||||
const QStringList &compilationArguments,
|
||||
@@ -137,7 +109,6 @@ private:
|
||||
|
||||
private:
|
||||
TextEditor::TextDocument &m_document;
|
||||
ClangDiagnosticManager m_diagnosticManager;
|
||||
BackendCommunicator &m_communicator;
|
||||
QSharedPointer<ClangEditorDocumentParser> m_parser;
|
||||
CppEditor::ProjectPart::ConstPtr m_projectPart;
|
||||
@@ -148,8 +119,6 @@ private:
|
||||
unsigned m_parserRevision;
|
||||
enum class InvalidationState { Off, Scheduled, Canceled } m_invalidationState;
|
||||
|
||||
QVector<ClangBackEnd::TokenInfoContainer> m_tokenInfos;
|
||||
CppEditor::SemanticHighlighter m_semanticHighlighter;
|
||||
CppEditor::BuiltinEditorDocumentProcessor m_builtinProcessor;
|
||||
Utils::FutureSynchronizer m_parserSynchronizer;
|
||||
};
|
||||
|
@@ -1,224 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clanghighlightingresultreporter.h"
|
||||
|
||||
#include <clangsupport/tokeninfocontainer.h>
|
||||
#include <cppeditor/semantichighlighter.h>
|
||||
#include <texteditor/semantichighlighter.h>
|
||||
#include <texteditor/textstyles.h>
|
||||
#include <utils/runextensions.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace {
|
||||
|
||||
TextEditor::TextStyle toTextStyle(ClangBackEnd::HighlightingType type)
|
||||
{
|
||||
using ClangBackEnd::HighlightingType;
|
||||
|
||||
switch (type) {
|
||||
case HighlightingType::Keyword:
|
||||
return TextEditor::C_KEYWORD;
|
||||
case HighlightingType::Function:
|
||||
return TextEditor::C_FUNCTION;
|
||||
case HighlightingType::VirtualFunction:
|
||||
return TextEditor::C_VIRTUAL_METHOD;
|
||||
case HighlightingType::Type:
|
||||
return TextEditor::C_TYPE;
|
||||
case HighlightingType::PrimitiveType:
|
||||
return TextEditor::C_PRIMITIVE_TYPE;
|
||||
case HighlightingType::LocalVariable:
|
||||
return TextEditor::C_LOCAL;
|
||||
case HighlightingType::Parameter:
|
||||
return TextEditor::C_PARAMETER;
|
||||
case HighlightingType::Field:
|
||||
case HighlightingType::QtProperty:
|
||||
return TextEditor::C_FIELD;
|
||||
case HighlightingType::GlobalVariable:
|
||||
return TextEditor::C_GLOBAL;
|
||||
case HighlightingType::Enumeration:
|
||||
return TextEditor::C_ENUMERATION;
|
||||
case HighlightingType::Label:
|
||||
return TextEditor::C_LABEL;
|
||||
case HighlightingType::Preprocessor:
|
||||
case HighlightingType::PreprocessorDefinition:
|
||||
case HighlightingType::PreprocessorExpansion:
|
||||
return TextEditor::C_PREPROCESSOR;
|
||||
case HighlightingType::Punctuation:
|
||||
return TextEditor::C_PUNCTUATION;
|
||||
case HighlightingType::Declaration:
|
||||
return TextEditor::C_DECLARATION;
|
||||
case HighlightingType::FunctionDefinition:
|
||||
return TextEditor::C_FUNCTION_DEFINITION;
|
||||
case HighlightingType::OutputArgument:
|
||||
return TextEditor::C_OUTPUT_ARGUMENT;
|
||||
case HighlightingType::Operator:
|
||||
return TextEditor::C_OPERATOR;
|
||||
case HighlightingType::OverloadedOperator:
|
||||
return TextEditor::C_OVERLOADED_OPERATOR;
|
||||
case HighlightingType::Comment:
|
||||
return TextEditor::C_COMMENT;
|
||||
case HighlightingType::StringLiteral:
|
||||
return TextEditor::C_STRING;
|
||||
case HighlightingType::NumberLiteral:
|
||||
return TextEditor::C_NUMBER;
|
||||
case HighlightingType::Invalid:
|
||||
QTC_CHECK(false); // never called
|
||||
return TextEditor::C_TEXT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
bool ignore(ClangBackEnd::HighlightingType type)
|
||||
{
|
||||
using ClangBackEnd::HighlightingType;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
break;
|
||||
case HighlightingType::Namespace:
|
||||
case HighlightingType::Class:
|
||||
case HighlightingType::Struct:
|
||||
case HighlightingType::Enum:
|
||||
case HighlightingType::Union:
|
||||
case HighlightingType::TypeAlias:
|
||||
case HighlightingType::Typedef:
|
||||
case HighlightingType::ObjectiveCClass:
|
||||
case HighlightingType::ObjectiveCCategory:
|
||||
case HighlightingType::ObjectiveCProtocol:
|
||||
case HighlightingType::ObjectiveCInterface:
|
||||
case HighlightingType::ObjectiveCImplementation:
|
||||
case HighlightingType::ObjectiveCProperty:
|
||||
case HighlightingType::ObjectiveCMethod:
|
||||
case HighlightingType::TemplateTypeParameter:
|
||||
case HighlightingType::TemplateTemplateParameter:
|
||||
case HighlightingType::AngleBracketOpen:
|
||||
case HighlightingType::AngleBracketClose:
|
||||
case HighlightingType::DoubleAngleBracketClose:
|
||||
case HighlightingType::TernaryIf:
|
||||
case HighlightingType::TernaryElse:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TextEditor::TextStyles toTextStyles(ClangBackEnd::HighlightingTypes types)
|
||||
{
|
||||
TextEditor::TextStyles textStyles;
|
||||
textStyles.mixinStyles.initializeElements();
|
||||
|
||||
textStyles.mainStyle = toTextStyle(types.mainHighlightingType);
|
||||
|
||||
for (ClangBackEnd::HighlightingType type : types.mixinHighlightingTypes) {
|
||||
if (!ignore(type))
|
||||
textStyles.mixinStyles.push_back(toTextStyle(type));
|
||||
}
|
||||
|
||||
return textStyles;
|
||||
}
|
||||
|
||||
TextEditor::HighlightingResult toHighlightingResult(
|
||||
const ClangBackEnd::TokenInfoContainer &tokenInfo)
|
||||
{
|
||||
using ClangBackEnd::HighlightingType;
|
||||
const auto textStyles = toTextStyles(tokenInfo.types);
|
||||
TextEditor::HighlightingResult result(tokenInfo.line, tokenInfo.column, tokenInfo.length,
|
||||
textStyles);
|
||||
if (tokenInfo.types.mixinHighlightingTypes.contains(HighlightingType::AngleBracketOpen))
|
||||
result.kind = CppEditor::SemanticHighlighter::AngleBracketOpen;
|
||||
else if (tokenInfo.types.mixinHighlightingTypes.contains(HighlightingType::AngleBracketClose))
|
||||
result.kind = CppEditor::SemanticHighlighter::AngleBracketClose;
|
||||
else if (tokenInfo.types.mixinHighlightingTypes.contains(HighlightingType::DoubleAngleBracketClose))
|
||||
result.kind = CppEditor::SemanticHighlighter::DoubleAngleBracketClose;
|
||||
else if (tokenInfo.types.mixinHighlightingTypes.contains(HighlightingType::TernaryIf))
|
||||
result.kind = CppEditor::SemanticHighlighter::TernaryIf;
|
||||
else if (tokenInfo.types.mixinHighlightingTypes.contains(HighlightingType::TernaryElse))
|
||||
result.kind = CppEditor::SemanticHighlighter::TernaryElse;
|
||||
return result;
|
||||
}
|
||||
|
||||
void highlightResultsImpl(QFutureInterface<TextEditor::HighlightingResult> &fi,
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
int chunkSize)
|
||||
{
|
||||
if (fi.isCanceled())
|
||||
return;
|
||||
|
||||
QVector<TextEditor::HighlightingResult> chunksToReport;
|
||||
chunksToReport.reserve(chunkSize + 1);
|
||||
|
||||
using ClangBackEnd::HighlightingType;
|
||||
bool flushRequested = false;
|
||||
int flushLine = 0;
|
||||
|
||||
auto reportAndClearCurrentChunks = [&] {
|
||||
flushRequested = false;
|
||||
flushLine = 0;
|
||||
|
||||
if (!chunksToReport.isEmpty()) {
|
||||
fi.reportResults(chunksToReport);
|
||||
chunksToReport.erase(chunksToReport.begin(), chunksToReport.end());
|
||||
}
|
||||
};
|
||||
|
||||
auto reportChunkWise = [&](const TextEditor::HighlightingResult &highlightingResult) {
|
||||
if (chunksToReport.size() >= chunkSize) {
|
||||
if (flushRequested && highlightingResult.line != flushLine) {
|
||||
reportAndClearCurrentChunks();
|
||||
} else if (!flushRequested) {
|
||||
flushRequested = true;
|
||||
flushLine = highlightingResult.line;
|
||||
}
|
||||
}
|
||||
|
||||
chunksToReport.append(highlightingResult);
|
||||
};
|
||||
|
||||
for (const auto &tokenInfo : tokenInfos)
|
||||
reportChunkWise(toHighlightingResult(tokenInfo));
|
||||
|
||||
if (fi.isCanceled())
|
||||
return;
|
||||
|
||||
reportAndClearCurrentChunks();
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
QFuture<TextEditor::HighlightingResult> highlightResults(
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
int chunkSize)
|
||||
{
|
||||
return Utils::runAsync(highlightResultsImpl, tokenInfos, chunkSize);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -1,42 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFuture>
|
||||
#include <QVector>
|
||||
|
||||
namespace TextEditor { class HighlightingResult; }
|
||||
namespace ClangBackEnd { class TokenInfoContainer; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
QFuture<TextEditor::HighlightingResult> highlightResults(
|
||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||
int chunkSize = 100);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -1,78 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <clangsupport/diagnosticcontainer.h>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static bool isWithinRange(const ClangBackEnd::SourceRangeContainer &range,
|
||||
int line,
|
||||
int column)
|
||||
{
|
||||
const ClangBackEnd::SourceLocationContainer &startLocation = range.start;
|
||||
const ClangBackEnd::SourceLocationContainer &endLocation = range.end;
|
||||
|
||||
return startLocation.line <= line
|
||||
&& startLocation.column <= column
|
||||
&& line <= endLocation.line
|
||||
&& column <= endLocation.column;
|
||||
}
|
||||
|
||||
static bool isWithinOneRange(const QVector<ClangBackEnd::SourceRangeContainer> &ranges,
|
||||
int line,
|
||||
int column)
|
||||
{
|
||||
for (const ClangBackEnd::SourceRangeContainer &range : ranges) {
|
||||
if (isWithinRange(range, line, column))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDiagnosticRelatedToLocation(const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
const QVector<ClangBackEnd::SourceRangeContainer> &additionalRanges,
|
||||
int line,
|
||||
int column)
|
||||
{
|
||||
const ClangBackEnd::SourceLocationContainer &location = diagnostic.location;
|
||||
|
||||
if (location.line == line && location.column == column)
|
||||
return true;
|
||||
|
||||
if (isWithinOneRange(additionalRanges, line, column))
|
||||
return true;
|
||||
|
||||
if (isWithinOneRange(diagnostic.ranges, line, column))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
@@ -62,6 +62,7 @@
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
|
||||
#include <clangsupport/filecontainer.h>
|
||||
#include <utils/algorithm.h>
|
||||
@@ -260,14 +261,13 @@ void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
|
||||
m_communicator.documentVisibilityChanged();
|
||||
|
||||
// Update task hub issues for current CppEditorDocument
|
||||
ClangEditorDocumentProcessor::clearTaskHubIssues();
|
||||
ProjectExplorer::TaskHub::clearTasks(Constants::TASK_CATEGORY_DIAGNOSTICS);
|
||||
if (!editor || !editor->document() || !cppModelManager()->isCppEditor(editor))
|
||||
return;
|
||||
|
||||
const ::Utils::FilePath filePath = editor->document()->filePath();
|
||||
if (auto processor = ClangEditorDocumentProcessor::get(filePath.toString())) {
|
||||
processor->semanticRehighlight();
|
||||
processor->generateTaskHubIssues();
|
||||
if (const auto client = clientForFile(filePath))
|
||||
client->updateParserConfig(filePath, processor->parserConfig());
|
||||
}
|
||||
@@ -404,7 +404,6 @@ void ClangModelManagerSupport::updateLanguageClient(
|
||||
|| currentClient->state() != Client::Initialized
|
||||
|| project->isKnownFile(doc->filePath())) {
|
||||
LanguageClientManager::openDocumentWithClient(doc, client);
|
||||
ClangEditorDocumentProcessor::clearTextMarks(doc->filePath());
|
||||
hasDocuments = true;
|
||||
}
|
||||
}
|
||||
@@ -496,7 +495,6 @@ void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
|
||||
&& (currentClient == client || currentClient->project())) {
|
||||
continue;
|
||||
}
|
||||
ClangEditorDocumentProcessor::clearTextMarks(doc->filePath());
|
||||
if (!ClangdSettings::instance().sizeIsOkay(doc->filePath()))
|
||||
continue;
|
||||
client->openDocument(doc);
|
||||
@@ -632,15 +630,6 @@ void ClangModelManagerSupport::onCppDocumentReloadFinishedOnTranslationUnit(bool
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
void clearDiagnosticFixIts(const QString &filePath)
|
||||
{
|
||||
auto processor = ClangEditorDocumentProcessor::get(filePath);
|
||||
if (processor)
|
||||
processor->clearDiagnosticsWithFixIts();
|
||||
}
|
||||
}
|
||||
|
||||
void ClangModelManagerSupport::onCppDocumentContentsChangedOnTranslationUnit(int position,
|
||||
int /*charsRemoved*/,
|
||||
int /*charsAdded*/)
|
||||
@@ -650,8 +639,6 @@ void ClangModelManagerSupport::onCppDocumentContentsChangedOnTranslationUnit(int
|
||||
m_communicator.updateChangeContentStartPosition(document->filePath().toString(),
|
||||
position);
|
||||
m_communicator.documentsChangedIfNotCurrentDocument(document);
|
||||
|
||||
clearDiagnosticFixIts(document->filePath().toString());
|
||||
}
|
||||
|
||||
void ClangModelManagerSupport::onCppDocumentAboutToReloadOnUnsavedFile()
|
||||
|
@@ -39,6 +39,8 @@
|
||||
#include <cppeditor/cpptoolsreuse.h>
|
||||
#include <cppeditor/cppcodemodelsettings.h>
|
||||
|
||||
#include <projectexplorer/taskhub.h>
|
||||
|
||||
#include <utils/fadingindicator.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/theme/theme.h>
|
||||
@@ -53,9 +55,9 @@
|
||||
#include <QString>
|
||||
|
||||
using namespace CppEditor;
|
||||
using namespace ClangCodeModel::Internal;
|
||||
using namespace LanguageClient;
|
||||
using namespace LanguageServerProtocol;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ClangCodeModel {
|
||||
@@ -63,26 +65,7 @@ namespace Internal {
|
||||
|
||||
namespace {
|
||||
|
||||
bool isWarningOrNote(ClangBackEnd::DiagnosticSeverity severity)
|
||||
{
|
||||
using ClangBackEnd::DiagnosticSeverity;
|
||||
switch (severity) {
|
||||
case DiagnosticSeverity::Ignored:
|
||||
case DiagnosticSeverity::Note:
|
||||
case DiagnosticSeverity::Warning: return true;
|
||||
case DiagnosticSeverity::Error:
|
||||
case DiagnosticSeverity::Fatal: return false;
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
static Id categoryForSeverity(ClangBackEnd::DiagnosticSeverity severity)
|
||||
{
|
||||
return isWarningOrNote(severity) ? Constants::CLANG_WARNING : Constants::CLANG_ERROR;
|
||||
}
|
||||
|
||||
ProjectExplorer::Project *projectForCurrentEditor()
|
||||
Project *projectForCurrentEditor()
|
||||
{
|
||||
const QString filePath = currentCppEditorDocumentFilePath();
|
||||
if (filePath.isEmpty())
|
||||
@@ -134,7 +117,7 @@ void disableDiagnosticInConfig(ClangDiagnosticConfig &config,
|
||||
ClangDiagnosticConfig diagnosticConfig(const ClangProjectSettings &projectSettings,
|
||||
const CppCodeModelSettings &globalSettings)
|
||||
{
|
||||
ProjectExplorer::Project *project = projectForCurrentEditor();
|
||||
Project *project = projectForCurrentEditor();
|
||||
QTC_ASSERT(project, return {});
|
||||
|
||||
// Get config id
|
||||
@@ -148,7 +131,7 @@ ClangDiagnosticConfig diagnosticConfig(const ClangProjectSettings &projectSettin
|
||||
return configsModel.configWithId(currentConfigId);
|
||||
}
|
||||
|
||||
bool isDiagnosticConfigChangable(ProjectExplorer::Project *project,
|
||||
bool isDiagnosticConfigChangable(Project *project,
|
||||
const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
if (!project)
|
||||
@@ -168,7 +151,7 @@ bool isDiagnosticConfigChangable(ProjectExplorer::Project *project,
|
||||
|
||||
void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
ProjectExplorer::Project *project = projectForCurrentEditor();
|
||||
Project *project = projectForCurrentEditor();
|
||||
QTC_ASSERT(project, return );
|
||||
|
||||
// Get settings
|
||||
@@ -211,90 +194,6 @@ void disableDiagnosticInCurrentProjectConfig(const ClangBackEnd::DiagnosticConta
|
||||
FadingIndicator::SmallText);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ClangTextMark::ClangTextMark(const FilePath &fileName,
|
||||
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
const RemovedFromEditorHandler &removedHandler,
|
||||
bool fullVisualization, const ClangDiagnosticManager *diagMgr)
|
||||
: TextEditor::TextMark(fileName,
|
||||
int(diagnostic.location.line),
|
||||
categoryForSeverity(diagnostic.severity))
|
||||
, m_diagnostic(diagnostic)
|
||||
, m_removedFromEditorHandler(removedHandler)
|
||||
, m_diagMgr(diagMgr)
|
||||
{
|
||||
setSettingsPage(CppEditor::Constants::CPP_CODE_MODEL_SETTINGS_ID);
|
||||
|
||||
const bool warning = isWarningOrNote(diagnostic.severity);
|
||||
setDefaultToolTip(warning ? QApplication::translate("Clang Code Model Marks", "Code Model Warning")
|
||||
: QApplication::translate("Clang Code Model Marks", "Code Model Error"));
|
||||
setPriority(warning ? TextEditor::TextMark::NormalPriority
|
||||
: TextEditor::TextMark::HighPriority);
|
||||
updateIcon();
|
||||
if (fullVisualization) {
|
||||
setLineAnnotation(diagnosticCategoryPrefixRemoved(diagnostic.text.toString()));
|
||||
setColor(warning ? Theme::CodeModel_Warning_TextMarkColor
|
||||
: Theme::CodeModel_Error_TextMarkColor);
|
||||
}
|
||||
|
||||
// Copy to clipboard action
|
||||
QVector<QAction *> actions;
|
||||
QAction *action = new QAction();
|
||||
action->setIcon(QIcon::fromTheme("edit-copy", Icons::COPY.icon()));
|
||||
action->setToolTip(QApplication::translate("Clang Code Model Marks", "Copy to Clipboard"));
|
||||
QObject::connect(action, &QAction::triggered, [diagnostic]() {
|
||||
const QString text = ClangDiagnosticWidget::createText({diagnostic},
|
||||
ClangDiagnosticWidget::InfoBar);
|
||||
QApplication::clipboard()->setText(text, QClipboard::Clipboard);
|
||||
});
|
||||
actions << action;
|
||||
|
||||
// Remove diagnostic warning action
|
||||
ProjectExplorer::Project *project = projectForCurrentEditor();
|
||||
if (project && isDiagnosticConfigChangable(project, diagnostic)) {
|
||||
action = new QAction();
|
||||
action->setIcon(Icons::BROKEN.icon());
|
||||
action->setToolTip(QApplication::translate("Clang Code Model Marks",
|
||||
"Disable Diagnostic in Current Project"));
|
||||
QObject::connect(action, &QAction::triggered, [diagnostic]() {
|
||||
disableDiagnosticInCurrentProjectConfig(diagnostic);
|
||||
});
|
||||
actions << action;
|
||||
}
|
||||
|
||||
setActions(actions);
|
||||
}
|
||||
|
||||
void ClangTextMark::updateIcon(bool valid)
|
||||
{
|
||||
using namespace Icons;
|
||||
if (isWarningOrNote(m_diagnostic.severity))
|
||||
setIcon(valid ? CODEMODEL_WARNING.icon() : CODEMODEL_DISABLED_WARNING.icon());
|
||||
else
|
||||
setIcon(valid ? CODEMODEL_ERROR.icon() : CODEMODEL_DISABLED_ERROR.icon());
|
||||
}
|
||||
|
||||
bool ClangTextMark::addToolTipContent(QLayout *target) const
|
||||
{
|
||||
const auto canApplyFixIt = [diag = m_diagnostic, diagMgr = m_diagMgr, c = color()] {
|
||||
return c != Utils::Theme::Color::IconsDisabledColor
|
||||
&& !diagMgr->diagnosticsInvalidated()
|
||||
&& diagMgr->diagnosticsWithFixIts().contains(diag);
|
||||
};
|
||||
QWidget *widget = ClangDiagnosticWidget::createWidget(
|
||||
{m_diagnostic}, ClangDiagnosticWidget::ToolTip, canApplyFixIt, "libclang");
|
||||
target->addWidget(widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClangTextMark::removedFromEditor()
|
||||
{
|
||||
QTC_ASSERT(m_removedFromEditorHandler, return);
|
||||
m_removedFromEditorHandler(this);
|
||||
}
|
||||
|
||||
ClangBackEnd::DiagnosticSeverity convertSeverity(DiagnosticSeverity src)
|
||||
{
|
||||
if (src == DiagnosticSeverity::Error)
|
||||
@@ -383,6 +282,36 @@ ClangBackEnd::DiagnosticContainer convertDiagnostic(const ClangdDiagnostic &src,
|
||||
return target;
|
||||
}
|
||||
|
||||
void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
Task::TaskType taskType = Task::TaskType::Unknown;
|
||||
QIcon icon;
|
||||
|
||||
switch (diagnostic.severity) {
|
||||
case ClangBackEnd::DiagnosticSeverity::Fatal:
|
||||
case ClangBackEnd::DiagnosticSeverity::Error:
|
||||
taskType = Task::TaskType::Error;
|
||||
icon = ::Utils::Icons::CODEMODEL_ERROR.icon();
|
||||
break;
|
||||
case ClangBackEnd::DiagnosticSeverity::Warning:
|
||||
taskType = Task::TaskType::Warning;
|
||||
icon = ::Utils::Icons::CODEMODEL_WARNING.icon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TaskHub::addTask(Task(taskType,
|
||||
diagnosticCategoryPrefixRemoved(diagnostic.text.toString()),
|
||||
FilePath::fromString(diagnostic.location.filePath.toString()),
|
||||
diagnostic.location.line,
|
||||
Constants::TASK_CATEGORY_DIAGNOSTICS,
|
||||
icon,
|
||||
Task::NoOptions));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ClangdTextMark::ClangdTextMark(const FilePath &filePath,
|
||||
const Diagnostic &diagnostic,
|
||||
bool isProjectFile,
|
||||
@@ -404,7 +333,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
|
||||
setLineAnnotation(diagnostic.message());
|
||||
setColor(isError ? Theme::CodeModel_Error_TextMarkColor
|
||||
: Theme::CodeModel_Warning_TextMarkColor);
|
||||
ClangDiagnosticManager::addTask(m_diagnostic);
|
||||
addTask(m_diagnostic);
|
||||
}
|
||||
|
||||
// Copy to clipboard action
|
||||
@@ -420,7 +349,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
|
||||
actions << action;
|
||||
|
||||
// Remove diagnostic warning action
|
||||
ProjectExplorer::Project *project = projectForCurrentEditor();
|
||||
Project *project = projectForCurrentEditor();
|
||||
if (project && isDiagnosticConfigChangable(project, m_diagnostic)) {
|
||||
action = new QAction();
|
||||
action->setIcon(Icons::BROKEN.icon());
|
||||
|
@@ -40,31 +40,6 @@ namespace LanguageClient { class Client; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
class ClangDiagnosticManager;
|
||||
|
||||
class ClangTextMark : public TextEditor::TextMark
|
||||
{
|
||||
public:
|
||||
using RemovedFromEditorHandler = std::function<void(ClangTextMark *)>;
|
||||
|
||||
ClangTextMark(const ::Utils::FilePath &fileName,
|
||||
const ClangBackEnd::DiagnosticContainer &diagnostic,
|
||||
const RemovedFromEditorHandler &removedHandler,
|
||||
bool fullVisualization,
|
||||
const ClangDiagnosticManager *diagMgr);
|
||||
|
||||
ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; }
|
||||
void updateIcon(bool valid = true);
|
||||
|
||||
private:
|
||||
bool addToolTipContent(QLayout *target) const override;
|
||||
void removedFromEditor() override;
|
||||
|
||||
private:
|
||||
ClangBackEnd::DiagnosticContainer m_diagnostic;
|
||||
RemovedFromEditorHandler m_removedFromEditorHandler;
|
||||
const ClangDiagnosticManager * const m_diagMgr;
|
||||
};
|
||||
|
||||
class ClangdTextMark : public TextEditor::TextMark
|
||||
{
|
||||
|
@@ -157,16 +157,12 @@ QList<TextEditor::BlockRange> toTextEditorBlocks(
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *document,
|
||||
bool enableSemanticHighlighter)
|
||||
BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(TextEditor::TextDocument *document)
|
||||
: BaseEditorDocumentProcessor(document->document(), document->filePath().toString())
|
||||
, m_parser(new BuiltinEditorDocumentParser(document->filePath().toString(),
|
||||
indexerFileSizeLimitInMb()))
|
||||
, m_codeWarningsUpdated(false)
|
||||
, m_semanticHighlighter(enableSemanticHighlighter
|
||||
? new SemanticHighlighter(document)
|
||||
: nullptr)
|
||||
, m_semanticHighlighter(new SemanticHighlighter(document))
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
@@ -176,7 +172,6 @@ BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
|
||||
config.usePrecompiledHeaders = cms->pchUsage() != CppCodeModelSettings::PchUse_None;
|
||||
m_parser->setConfiguration(config);
|
||||
|
||||
if (m_semanticHighlighter) {
|
||||
m_semanticHighlighter->setHighlightingRunner(
|
||||
[this]() -> QFuture<TextEditor::HighlightingResult> {
|
||||
const SemanticInfo semanticInfo = m_semanticInfoUpdater.semanticInfo();
|
||||
@@ -187,7 +182,6 @@ BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
|
||||
this, &BuiltinEditorDocumentProcessor::onCodeWarningsUpdated);
|
||||
return checkSymbols->start();
|
||||
});
|
||||
}
|
||||
|
||||
connect(m_parser.data(), &BuiltinEditorDocumentParser::projectPartInfoUpdated,
|
||||
this, &BaseEditorDocumentProcessor::projectPartInfoUpdated);
|
||||
@@ -229,7 +223,7 @@ void BuiltinEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force)
|
||||
|
||||
void BuiltinEditorDocumentProcessor::semanticRehighlight()
|
||||
{
|
||||
if (m_semanticHighlighter && m_semanticInfoUpdater.semanticInfo().doc) {
|
||||
if (m_semanticInfoUpdater.semanticInfo().doc) {
|
||||
if (const CPlusPlus::Document::Ptr document = m_documentSnapshot.document(filePath())) {
|
||||
m_codeWarnings = toTextEditorSelections(document->diagnosticMessages(), textDocument());
|
||||
m_codeWarningsUpdated = false;
|
||||
@@ -275,6 +269,12 @@ QFuture<SymbolInfo> BuiltinEditorDocumentProcessor::requestFollowSymbol(int, int
|
||||
return futureInterface.future();
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentProcessor::setSemanticHighlightingChecker(
|
||||
const SemanticHighlightingChecker &checker)
|
||||
{
|
||||
m_semanticHighlightingChecker = checker;
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentProcessor::onParserFinished(CPlusPlus::Document::Ptr document,
|
||||
CPlusPlus::Snapshot snapshot)
|
||||
{
|
||||
@@ -312,7 +312,7 @@ void BuiltinEditorDocumentProcessor::onSemanticInfoUpdated(const SemanticInfo se
|
||||
|
||||
emit semanticInfoUpdated(semanticInfo);
|
||||
|
||||
if (m_semanticHighlighter)
|
||||
if (!m_semanticHighlightingChecker || m_semanticHighlightingChecker())
|
||||
m_semanticHighlighter->run();
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include "cppsemanticinfoupdater.h"
|
||||
#include "semantichighlighter.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace CppEditor {
|
||||
|
||||
class CPPEDITOR_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor
|
||||
@@ -38,8 +40,7 @@ class CPPEDITOR_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumen
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BuiltinEditorDocumentProcessor(TextEditor::TextDocument *document,
|
||||
bool enableSemanticHighlighter = true);
|
||||
BuiltinEditorDocumentProcessor(TextEditor::TextDocument *document);
|
||||
~BuiltinEditorDocumentProcessor() override;
|
||||
|
||||
// BaseEditorDocumentProcessor interface
|
||||
@@ -55,6 +56,9 @@ public:
|
||||
QFuture<CursorInfo> requestLocalReferences(const QTextCursor &) override;
|
||||
QFuture<SymbolInfo> requestFollowSymbol(int, int) override;
|
||||
|
||||
using SemanticHighlightingChecker = std::function<bool()>;
|
||||
void setSemanticHighlightingChecker(const SemanticHighlightingChecker &checker);
|
||||
|
||||
private:
|
||||
void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
|
||||
void onSemanticInfoUpdated(const SemanticInfo semanticInfo);
|
||||
@@ -73,6 +77,7 @@ private:
|
||||
|
||||
SemanticInfoUpdater m_semanticInfoUpdater;
|
||||
QScopedPointer<SemanticHighlighter> m_semanticHighlighter;
|
||||
SemanticHighlightingChecker m_semanticHighlightingChecker;
|
||||
};
|
||||
|
||||
} // namespace CppEditor
|
||||
|
@@ -182,7 +182,6 @@ extend_qtc_test(unittest
|
||||
clangcodemodelserver-test.cpp
|
||||
clangcompletecodejob-test.cpp
|
||||
clangcompletioncontextanalyzer-test.cpp
|
||||
clangdiagnosticfilter-test.cpp
|
||||
clangdocumentprocessors-test.cpp
|
||||
clangdocumentprocessor-test.cpp
|
||||
clangdocuments-test.cpp
|
||||
@@ -190,7 +189,6 @@ extend_qtc_test(unittest
|
||||
clangdocument-test.cpp
|
||||
clangfixitoperation-test.cpp
|
||||
clangfollowsymbol-test.cpp
|
||||
clangisdiagnosticrelatedtolocation-test.cpp
|
||||
clangjobqueue-test.cpp
|
||||
clangjobs-test.cpp
|
||||
clangparsesupportivetranslationunitjob-test.cpp
|
||||
@@ -213,7 +211,6 @@ extend_qtc_test(unittest
|
||||
diagnostic-test.cpp
|
||||
fixit-test.cpp
|
||||
gtest-clang-printing.cpp gtest-clang-printing.h
|
||||
highlightingresultreporter-test.cpp
|
||||
readexporteddiagnostics-test.cpp
|
||||
skippedsourceranges-test.cpp
|
||||
sourcelocation-test.cpp
|
||||
@@ -422,11 +419,8 @@ extend_qtc_test(unittest
|
||||
clangactivationsequenceprocessor.cpp clangactivationsequenceprocessor.h
|
||||
clangcompletionchunkstotextconverter.cpp clangcompletionchunkstotextconverter.h
|
||||
clangcompletioncontextanalyzer.cpp clangcompletioncontextanalyzer.h
|
||||
clangdiagnosticfilter.cpp clangdiagnosticfilter.h
|
||||
clangfixitoperation.cpp clangfixitoperation.h
|
||||
clanghighlightingresultreporter.cpp clanghighlightingresultreporter.h
|
||||
clanguiheaderondiskmanager.cpp clanguiheaderondiskmanager.h
|
||||
clangisdiagnosticrelatedtolocation.h
|
||||
)
|
||||
|
||||
find_package(yaml-cpp QUIET MODULE)
|
||||
|
@@ -1,238 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <clangdiagnosticfilter.h>
|
||||
#include <diagnosticcontainer.h>
|
||||
#include <fixitcontainer.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::Contains;
|
||||
using ::testing::Not;
|
||||
|
||||
using ClangBackEnd::DiagnosticContainer;
|
||||
using ClangBackEnd::FixItContainer;
|
||||
using ClangBackEnd::SourceLocationContainer;
|
||||
using ClangBackEnd::SourceRangeContainer;
|
||||
|
||||
DiagnosticContainer createDiagnostic(const QString &text,
|
||||
ClangBackEnd::DiagnosticSeverity severity,
|
||||
const QString &filePath,
|
||||
QVector<DiagnosticContainer> children = QVector<DiagnosticContainer>(),
|
||||
bool addFixItContainer = false)
|
||||
{
|
||||
QVector<FixItContainer> fixIts;
|
||||
if (addFixItContainer)
|
||||
fixIts.append(FixItContainer(Utf8StringLiteral("("), {{filePath, 1, 1}, {filePath, 1, 2}}));
|
||||
|
||||
return DiagnosticContainer(
|
||||
text,
|
||||
Utf8StringLiteral(""),
|
||||
{},
|
||||
severity,
|
||||
{filePath, 0u, 0u},
|
||||
{},
|
||||
fixIts,
|
||||
children
|
||||
);
|
||||
}
|
||||
|
||||
const QString mainFileHeaderPath = QString::fromUtf8(TESTDATA_DIR "/someHeader.h");
|
||||
const QString mainFilePath = QString::fromUtf8(TESTDATA_DIR "/diagnostic_erroneous_source.cpp");
|
||||
const QString headerFilePath = QString::fromUtf8(TESTDATA_DIR "/diagnostic_erroneous_header.cpp");
|
||||
|
||||
DiagnosticContainer warningFromHeader()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("warning: control reaches end of non-void function"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
headerFilePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer errorFromHeader()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("C++ requires a type specifier for all declarations"),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
headerFilePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer warningFromMainFile()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("warning: enumeration value 'Three' not handled in switch"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
mainFilePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer pragmaOnceWarningInHeader()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("warning: #pragma once in main file"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
mainFileHeaderPath);
|
||||
}
|
||||
|
||||
DiagnosticContainer includeNextInPrimarySourceFileWarningInHeader()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("warning: #include_next in primary source file"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
mainFileHeaderPath);
|
||||
}
|
||||
|
||||
DiagnosticContainer errorFromMainFile()
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("error: void function 'g' should not return a value"),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
mainFilePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer fixIt1(const QString &filePath)
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("note: place parentheses around the assignment to silence this warning"),
|
||||
ClangBackEnd::DiagnosticSeverity::Note,
|
||||
filePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer fixIt2(const QString &filePath)
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("note: use '==' to turn this assignment into an equality comparison"),
|
||||
ClangBackEnd::DiagnosticSeverity::Note,
|
||||
filePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer createDiagnosticWithFixIt(const QString &filePath)
|
||||
{
|
||||
return createDiagnostic(
|
||||
QStringLiteral("warning: using the result of an assignment as a condition without parentheses"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
filePath,
|
||||
{fixIt1(filePath), fixIt2(filePath)},
|
||||
true);
|
||||
}
|
||||
|
||||
DiagnosticContainer warningFromMainFileWithFixits()
|
||||
{
|
||||
return createDiagnosticWithFixIt(mainFilePath);
|
||||
}
|
||||
|
||||
DiagnosticContainer warningFromHeaderFileWithFixits()
|
||||
{
|
||||
return createDiagnosticWithFixIt(headerFilePath);
|
||||
}
|
||||
|
||||
class ClangDiagnosticFilter : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
ClangCodeModel::Internal::ClangDiagnosticFilter clangDiagnosticFilter{mainFilePath};
|
||||
};
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, WarningsFromMainFileAreLetThrough)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromMainFile()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeWarnings(),Contains(warningFromMainFile()));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, WarningsFromHeaderAreIgnored)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromHeader()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeWarnings(), Not(Contains(warningFromHeader())));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, ErrorsFromMainFileAreLetThrough)
|
||||
{
|
||||
clangDiagnosticFilter.filter({errorFromMainFile()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeErrors(), Contains(errorFromMainFile()));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, ErrorsFromHeaderAreIgnored)
|
||||
{
|
||||
clangDiagnosticFilter.filter({errorFromHeader()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeErrors(), Not(Contains(errorFromHeader())));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, FixItsFromMainFileAreLetThrough)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromMainFileWithFixits()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeFixIts(), Contains(warningFromMainFileWithFixits()));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, FixItsFromHeaderAreIgnored)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromHeaderFileWithFixits()});
|
||||
|
||||
ASSERT_THAT(clangDiagnosticFilter.takeFixIts(),
|
||||
Not(Contains(warningFromHeaderFileWithFixits())));
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, WarningsAreEmptyAfterTaking)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromMainFile()});
|
||||
|
||||
clangDiagnosticFilter.takeWarnings();
|
||||
|
||||
ASSERT_TRUE(clangDiagnosticFilter.takeWarnings().isEmpty());
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, IgnoreCertainWarningsInHeaderFiles)
|
||||
{
|
||||
ClangCodeModel::Internal::ClangDiagnosticFilter myClangDiagnosticFilter{mainFileHeaderPath};
|
||||
|
||||
myClangDiagnosticFilter.filter({pragmaOnceWarningInHeader(),
|
||||
includeNextInPrimarySourceFileWarningInHeader()});
|
||||
|
||||
ASSERT_TRUE(myClangDiagnosticFilter.takeWarnings().isEmpty());
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, ErrorsAreEmptyAfterTaking)
|
||||
{
|
||||
clangDiagnosticFilter.filter({errorFromMainFile()});
|
||||
|
||||
clangDiagnosticFilter.takeErrors();
|
||||
|
||||
ASSERT_TRUE(clangDiagnosticFilter.takeErrors().isEmpty());
|
||||
}
|
||||
|
||||
TEST_F(ClangDiagnosticFilter, FixItssAreEmptyAfterTaking)
|
||||
{
|
||||
clangDiagnosticFilter.filter({warningFromMainFileWithFixits()});
|
||||
|
||||
clangDiagnosticFilter.takeFixIts();
|
||||
|
||||
ASSERT_TRUE(clangDiagnosticFilter.takeFixIts().isEmpty());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
@@ -1,146 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <clangisdiagnosticrelatedtolocation.h>
|
||||
#include <diagnosticcontainer.h>
|
||||
|
||||
using ClangBackEnd::DiagnosticContainer;
|
||||
using ClangBackEnd::SourceLocationContainer;
|
||||
using ClangBackEnd::SourceRangeContainer;
|
||||
using ClangCodeModel::Internal::isDiagnosticRelatedToLocation;
|
||||
|
||||
namespace {
|
||||
|
||||
SourceRangeContainer createRange(uint startLine,
|
||||
uint startColumn,
|
||||
uint endLine,
|
||||
uint endColumn)
|
||||
{
|
||||
const SourceLocationContainer startLocation(Utf8String(), startLine, startColumn);
|
||||
const SourceLocationContainer endLocation(Utf8String(), endLine, endColumn);
|
||||
|
||||
return SourceRangeContainer(startLocation, endLocation);
|
||||
}
|
||||
|
||||
DiagnosticContainer createDiagnosticWithLocation(uint line, uint column)
|
||||
{
|
||||
const SourceLocationContainer location(Utf8String(), line, column);
|
||||
|
||||
return DiagnosticContainer(Utf8String(),
|
||||
Utf8String(),
|
||||
std::pair<Utf8String, Utf8String>(),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
location,
|
||||
QVector<SourceRangeContainer>(),
|
||||
QVector<ClangBackEnd::FixItContainer>(),
|
||||
QVector<DiagnosticContainer>());
|
||||
}
|
||||
|
||||
DiagnosticContainer createDiagnosticWithRange(uint startLine,
|
||||
uint startColumn,
|
||||
uint endLine,
|
||||
uint endColumn)
|
||||
{
|
||||
const SourceRangeContainer range = createRange(startLine, startColumn, endLine, endColumn);
|
||||
|
||||
return DiagnosticContainer(Utf8String(),
|
||||
Utf8String(),
|
||||
std::pair<Utf8String, Utf8String>(),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
SourceLocationContainer(),
|
||||
{range},
|
||||
QVector<ClangBackEnd::FixItContainer>(),
|
||||
QVector<DiagnosticContainer>());
|
||||
}
|
||||
|
||||
class ClangIsDiagnosticRelatedToLocation : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
ClangIsDiagnosticRelatedToLocation() {}
|
||||
|
||||
protected:
|
||||
const QVector<SourceRangeContainer> emptyRanges;
|
||||
};
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, MatchLocation)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithLocation(5, 5);
|
||||
|
||||
ASSERT_TRUE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 5));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, DoNotMatchLocation)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithLocation(5, 5);
|
||||
|
||||
ASSERT_FALSE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 4));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, MatchStartRange)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithRange(5, 5, 5, 10);
|
||||
|
||||
ASSERT_TRUE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 5));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, MatchWithinRange)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithRange(5, 5, 5, 10);
|
||||
|
||||
ASSERT_TRUE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 7));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, MatchEndRange)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithRange(5, 5, 5, 10);
|
||||
|
||||
ASSERT_TRUE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 10));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, DoNoMatchBeforeRangeStart)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithRange(5, 5, 5, 10);
|
||||
|
||||
ASSERT_FALSE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 4));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, DoNoMatchAfterRangeEnd)
|
||||
{
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithRange(5, 5, 5, 10);
|
||||
|
||||
ASSERT_FALSE(isDiagnosticRelatedToLocation(diagnostic, emptyRanges, 5, 11));
|
||||
}
|
||||
|
||||
TEST_F(ClangIsDiagnosticRelatedToLocation, MatchInAdditionalRange)
|
||||
{
|
||||
const QVector<SourceRangeContainer> additionalRanges{createRange(5, 5, 5, 10)};
|
||||
const DiagnosticContainer diagnostic = createDiagnosticWithLocation(1, 1);
|
||||
|
||||
ASSERT_TRUE(isDiagnosticRelatedToLocation(diagnostic, additionalRanges, 5, 7));
|
||||
}
|
||||
|
||||
} // anonymous
|
@@ -1,164 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "googletest.h"
|
||||
#include "unittest-utility-functions.h"
|
||||
|
||||
#include <chunksreportedmonitor.h>
|
||||
#include <clangdocument.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <cursor.h>
|
||||
#include <tokeninfocontainer.h>
|
||||
#include <tokenprocessor.h>
|
||||
#include <clanghighlightingresultreporter.h>
|
||||
#include <unsavedfiles.h>
|
||||
|
||||
using ClangBackEnd::Cursor;
|
||||
using ClangBackEnd::TokenProcessor;
|
||||
using ClangBackEnd::TokenInfoContainer;
|
||||
using ClangBackEnd::HighlightingType;
|
||||
using ClangBackEnd::Document;
|
||||
using ClangBackEnd::Documents;
|
||||
using ClangBackEnd::UnsavedFiles;
|
||||
using ClangBackEnd::ChunksReportedMonitor;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Data {
|
||||
UnsavedFiles unsavedFiles;
|
||||
Documents documents{unsavedFiles};
|
||||
Document document{Utf8StringLiteral(TESTDATA_DIR "/highlightingmarks.cpp"),
|
||||
UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")}),
|
||||
Utf8StringVector(),
|
||||
documents};
|
||||
};
|
||||
|
||||
class HighlightingResultReporter : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
|
||||
protected:
|
||||
static Data *d;
|
||||
};
|
||||
|
||||
QVector<TokenInfoContainer> noTokenInfos()
|
||||
{
|
||||
return QVector<TokenInfoContainer>();
|
||||
}
|
||||
|
||||
QVector<TokenInfoContainer> generateTokenInfos(uint count)
|
||||
{
|
||||
auto container = QVector<TokenInfoContainer>();
|
||||
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
const uint line = i + 1;
|
||||
ClangBackEnd::HighlightingTypes types;
|
||||
types.mainHighlightingType = ClangBackEnd::HighlightingType::Type;
|
||||
container.append(TokenInfoContainer(line, 1, 1, types));
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, StartAndFinish)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(noTokenInfos());
|
||||
|
||||
future.waitForFinished();
|
||||
ASSERT_THAT(future.isFinished(), true);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportNothingIfNothingToReport)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(generateTokenInfos(0));
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 0L);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportSingleResultAsOneChunk)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(generateTokenInfos(1), 1);
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 1L);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportRestIfChunkSizeNotReached)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(generateTokenInfos(1), 100);
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 1L);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportChunksWithoutRest)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(generateTokenInfos(4), 1);
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportSingleChunkAndRest)
|
||||
{
|
||||
auto future = ClangCodeModel::Internal::highlightResults(generateTokenInfos(5), 2);
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
|
||||
}
|
||||
|
||||
TEST_F(HighlightingResultReporter, ReportCompleteLines)
|
||||
{
|
||||
ClangBackEnd::HighlightingTypes types;
|
||||
types.mainHighlightingType = ClangBackEnd::HighlightingType::Type;
|
||||
QVector<TokenInfoContainer> tokenInfos {
|
||||
TokenInfoContainer(1, 1, 1, types),
|
||||
TokenInfoContainer(1, 2, 1, types),
|
||||
TokenInfoContainer(2, 1, 1, types),
|
||||
};
|
||||
|
||||
auto future = ClangCodeModel::Internal::highlightResults(tokenInfos, 1);
|
||||
|
||||
ChunksReportedMonitor monitor(future);
|
||||
ASSERT_THAT(monitor.resultsReadyCounter(), 2L);
|
||||
}
|
||||
|
||||
Data *HighlightingResultReporter::d;
|
||||
|
||||
void HighlightingResultReporter::SetUpTestCase()
|
||||
{
|
||||
d = new Data;
|
||||
}
|
||||
|
||||
void HighlightingResultReporter::TearDownTestCase()
|
||||
{
|
||||
delete d;
|
||||
d = nullptr;
|
||||
}
|
||||
|
||||
} // anonymous
|
@@ -204,14 +204,12 @@ Project {
|
||||
"clangcompareoperators.h",
|
||||
"clangcompletecodejob-test.cpp",
|
||||
"clangcompletioncontextanalyzer-test.cpp",
|
||||
"clangdiagnosticfilter-test.cpp",
|
||||
"clangdocument-test.cpp",
|
||||
"clangdocumentprocessor-test.cpp",
|
||||
"clangdocumentprocessors-test.cpp",
|
||||
"clangdocuments-test.cpp",
|
||||
"clangfixitoperation-test.cpp",
|
||||
"clangfollowsymbol-test.cpp",
|
||||
"clangisdiagnosticrelatedtolocation-test.cpp",
|
||||
"clangjobqueue-test.cpp",
|
||||
"clangjobs-test.cpp",
|
||||
"clangparsesupportivetranslationunitjob-test.cpp",
|
||||
@@ -235,7 +233,6 @@ Project {
|
||||
"fixit-test.cpp",
|
||||
"gtest-clang-printing.cpp",
|
||||
"gtest-clang-printing.h",
|
||||
"highlightingresultreporter-test.cpp",
|
||||
"readexporteddiagnostics-test.cpp",
|
||||
"skippedsourceranges-test.cpp",
|
||||
"sourcelocation-test.cpp",
|
||||
@@ -403,13 +400,8 @@ Project {
|
||||
"clangcompletionchunkstotextconverter.h",
|
||||
"clangcompletioncontextanalyzer.cpp",
|
||||
"clangcompletioncontextanalyzer.h",
|
||||
"clangdiagnosticfilter.cpp",
|
||||
"clangdiagnosticfilter.h",
|
||||
"clangfixitoperation.cpp",
|
||||
"clangfixitoperation.h",
|
||||
"clanghighlightingresultreporter.cpp",
|
||||
"clanghighlightingresultreporter.h",
|
||||
"clangisdiagnosticrelatedtolocation.h",
|
||||
"clanguiheaderondiskmanager.cpp",
|
||||
"clanguiheaderondiskmanager.h",
|
||||
]
|
||||
|
Reference in New Issue
Block a user