forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.6'
Conflicts: share/qtcreator/qml-type-descriptions/qmlproject.qmltypes src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp Change-Id: I35fb652f29a98a798be7c8b4b4c2e581eb175fb6
This commit is contained in:
@@ -368,26 +368,23 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences(
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
QTextDocument *textDocument,
|
||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||
{
|
||||
const RequestReferencesMessage message(fileContainer, line, column);
|
||||
m_sender->requestReferences(message);
|
||||
|
||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument,
|
||||
localUses);
|
||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), localUses);
|
||||
}
|
||||
|
||||
QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences(
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
QTextDocument *textDocument)
|
||||
quint32 column)
|
||||
{
|
||||
const RequestReferencesMessage message(fileContainer, line, column, true);
|
||||
m_sender->requestReferences(message);
|
||||
|
||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
|
||||
return m_receiver.addExpectedReferencesMessage(message.ticketNumber());
|
||||
}
|
||||
|
||||
QFuture<CppTools::ToolTipInfo> BackendCommunicator::requestToolTip(
|
||||
|
||||
@@ -75,13 +75,11 @@ public:
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
QTextDocument *textDocument,
|
||||
const LocalUseMap &localUses);
|
||||
QFuture<CppTools::CursorInfo> requestLocalReferences(
|
||||
const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
QTextDocument *textDocument);
|
||||
quint32 column);
|
||||
QFuture<CppTools::ToolTipInfo> requestToolTip(const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column);
|
||||
|
||||
@@ -101,16 +101,14 @@ void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidge
|
||||
|
||||
QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage(
|
||||
quint64 ticket,
|
||||
QTextDocument *textDocument,
|
||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||
{
|
||||
QTC_CHECK(textDocument);
|
||||
QTC_CHECK(!m_referencesTable.contains(ticket));
|
||||
|
||||
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
||||
futureInterface.reportStarted();
|
||||
|
||||
const ReferencesEntry entry{futureInterface, textDocument, localUses};
|
||||
const ReferencesEntry entry{futureInterface, localUses};
|
||||
m_referencesTable.insert(ticket, entry);
|
||||
|
||||
return futureInterface.future();
|
||||
@@ -221,24 +219,17 @@ void BackendReceiver::documentAnnotationsChanged(const DocumentAnnotationsChange
|
||||
}
|
||||
|
||||
static
|
||||
CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument,
|
||||
const SourceRangeContainer &sourceRange)
|
||||
CppTools::CursorInfo::Range toCursorInfoRange(const SourceRangeContainer &sourceRange)
|
||||
{
|
||||
const SourceLocationContainer start = sourceRange.start();
|
||||
const SourceLocationContainer end = sourceRange.end();
|
||||
const unsigned length = end.column() - start.column();
|
||||
|
||||
const QTextBlock block = textDocument.findBlockByNumber(static_cast<int>(start.line()) - 1);
|
||||
const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(),
|
||||
static_cast<int>(start.column()));
|
||||
const uint column = start.column() - static_cast<uint>(shift);
|
||||
|
||||
return CppTools::CursorInfo::Range(start.line(), column, length);
|
||||
return CppTools::CursorInfo::Range(start.line(), start.column(), length);
|
||||
}
|
||||
|
||||
static
|
||||
CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
||||
const CppTools::SemanticInfo::LocalUseMap &localUses,
|
||||
CppTools::CursorInfo toCursorInfo(const CppTools::SemanticInfo::LocalUseMap &localUses,
|
||||
const ReferencesMessage &message)
|
||||
{
|
||||
CppTools::CursorInfo result;
|
||||
@@ -246,7 +237,7 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
||||
|
||||
result.areUseRangesForLocalVariable = message.isLocalVariable();
|
||||
for (const SourceRangeContainer &reference : references)
|
||||
result.useRanges.append(toCursorInfoRange(textDocument, reference));
|
||||
result.useRanges.append(toCursorInfoRange(reference));
|
||||
|
||||
result.useRanges.reserve(references.size());
|
||||
result.localUses = localUses;
|
||||
@@ -284,8 +275,7 @@ void BackendReceiver::references(const ReferencesMessage &message)
|
||||
if (futureInterface.isCanceled())
|
||||
return; // Editor document closed or a new request was issued making this result outdated.
|
||||
|
||||
QTC_ASSERT(entry.textDocument, return);
|
||||
futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message));
|
||||
futureInterface.reportResult(toCursorInfo(entry.localUses, message));
|
||||
futureInterface.reportFinished();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ public:
|
||||
|
||||
QFuture<CppTools::CursorInfo>
|
||||
addExpectedReferencesMessage(quint64 ticket,
|
||||
QTextDocument *textDocument,
|
||||
const CppTools::SemanticInfo::LocalUseMap &localUses
|
||||
= CppTools::SemanticInfo::LocalUseMap());
|
||||
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
|
||||
@@ -82,13 +81,10 @@ private:
|
||||
struct ReferencesEntry {
|
||||
ReferencesEntry() = default;
|
||||
ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface,
|
||||
QTextDocument *textDocument,
|
||||
const CppTools::SemanticInfo::LocalUseMap &localUses)
|
||||
: futureInterface(futureInterface)
|
||||
, textDocument(textDocument)
|
||||
, localUses(localUses) {}
|
||||
QFutureInterface<CppTools::CursorInfo> futureInterface;
|
||||
QPointer<QTextDocument> textDocument;
|
||||
CppTools::SemanticInfo::LocalUseMap localUses;
|
||||
};
|
||||
QHash<quint64, ReferencesEntry> m_referencesTable;
|
||||
|
||||
@@ -559,7 +559,8 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
|
||||
int line = -1, column = -1;
|
||||
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
|
||||
const QTextBlock block = m_interface->textDocument()->findBlock(position);
|
||||
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
|
||||
const QString stringOnTheLeft = block.text().left(column);
|
||||
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||
return {line, column};
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,7 @@ int positionInText(QTextDocument *textDocument,
|
||||
{
|
||||
auto textBlock = textDocument->findBlockByNumber(
|
||||
static_cast<int>(sourceLocationContainer.line()) - 1);
|
||||
int column = static_cast<int>(sourceLocationContainer.column()) - 1;
|
||||
column -= ClangCodeModel::Utils::extraUtf8CharsShift(textBlock.text(), column);
|
||||
const int column = static_cast<int>(sourceLocationContainer.column()) - 1;
|
||||
return textBlock.position() + column;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "clangdiagnostictooltipwidget.h"
|
||||
#include "clangfixitoperation.h"
|
||||
#include "clangfixitoperationsextractor.h"
|
||||
#include "clangmodelmanagersupport.h"
|
||||
#include "clangtokeninfosreporter.h"
|
||||
#include "clangprojectsettings.h"
|
||||
#include "clangutils.h"
|
||||
@@ -66,6 +67,12 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static ClangProjectSettings &getProjectSettings(ProjectExplorer::Project *project)
|
||||
{
|
||||
QTC_CHECK(project);
|
||||
return ModelManagerSupportClang::instance()->projectSettings(project);
|
||||
}
|
||||
|
||||
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
||||
BackendCommunicator &communicator,
|
||||
TextEditor::TextDocument *document)
|
||||
@@ -174,6 +181,11 @@ void ClangEditorDocumentProcessor::clearProjectPart()
|
||||
m_projectPart.clear();
|
||||
}
|
||||
|
||||
Core::Id ClangEditorDocumentProcessor::diagnosticConfigId() const
|
||||
{
|
||||
return m_diagnosticConfigId;
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateCodeWarnings(
|
||||
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||
@@ -331,20 +343,19 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m
|
||||
{
|
||||
int line, column;
|
||||
convertPosition(params.textCursor, &line, &column);
|
||||
++column; // for 1-based columns
|
||||
|
||||
if (!isCursorOnIdentifier(params.textCursor))
|
||||
return defaultCursorInfoFuture();
|
||||
|
||||
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1);
|
||||
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column);
|
||||
const QString stringOnTheLeft = block.text().left(column);
|
||||
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
|
||||
const CppTools::SemanticInfo::LocalUseMap localUses
|
||||
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);
|
||||
|
||||
return m_communicator.requestReferences(simpleFileContainer(),
|
||||
static_cast<quint32>(line),
|
||||
static_cast<quint32>(column),
|
||||
textDocument(),
|
||||
localUses);
|
||||
}
|
||||
|
||||
@@ -361,8 +372,7 @@ QFuture<CppTools::CursorInfo> ClangEditorDocumentProcessor::requestLocalReferenc
|
||||
|
||||
return m_communicator.requestLocalReferences(simpleFileContainer(),
|
||||
static_cast<quint32>(line),
|
||||
static_cast<quint32>(column),
|
||||
textDocument());
|
||||
static_cast<quint32>(column));
|
||||
}
|
||||
|
||||
QFuture<CppTools::SymbolInfo>
|
||||
@@ -437,6 +447,7 @@ public:
|
||||
}
|
||||
|
||||
const QStringList &options() const { return m_options; }
|
||||
const Core::Id &diagnosticConfigId() const { return m_diagnosticConfigId; }
|
||||
|
||||
private:
|
||||
void addLanguageOptions()
|
||||
@@ -458,21 +469,28 @@ private:
|
||||
void addDiagnosticOptions()
|
||||
{
|
||||
if (m_projectPart.project) {
|
||||
ClangProjectSettings projectSettings(m_projectPart.project);
|
||||
ClangProjectSettings &projectSettings = getProjectSettings(m_projectPart.project);
|
||||
if (!projectSettings.useGlobalConfig()) {
|
||||
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
||||
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||
if (configsModel.hasConfigWithId(warningConfigId)) {
|
||||
m_options.append(
|
||||
configsModel.configWithId(warningConfigId).commandLineWarnings());
|
||||
addDiagnosticOptionsForConfig(configsModel.configWithId(warningConfigId));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_options.append(
|
||||
CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings());
|
||||
addDiagnosticOptionsForConfig(CppTools::codeModelSettings()->clangDiagnosticConfig());
|
||||
}
|
||||
|
||||
void addDiagnosticOptionsForConfig(const CppTools::ClangDiagnosticConfig &diagnosticConfig)
|
||||
{
|
||||
m_diagnosticConfigId = diagnosticConfig.id();
|
||||
|
||||
m_options.append(diagnosticConfig.clangOptions());
|
||||
addClangTidyOptions(diagnosticConfig.clangTidyChecks());
|
||||
addClazyOptions(diagnosticConfig.clazyChecks());
|
||||
}
|
||||
|
||||
void addXclangArg(const QString &argName, const QString &argValue = QString())
|
||||
@@ -485,24 +503,22 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void addTidyOptions()
|
||||
void addClangTidyOptions(const QString &checks)
|
||||
{
|
||||
const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks();
|
||||
if (tidyChecks.isEmpty())
|
||||
if (checks.isEmpty())
|
||||
return;
|
||||
|
||||
addXclangArg("-add-plugin", "clang-tidy");
|
||||
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'");
|
||||
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + checks + "'");
|
||||
}
|
||||
|
||||
void addClazyOptions()
|
||||
void addClazyOptions(const QString &checks)
|
||||
{
|
||||
const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks();
|
||||
if (clazyChecks.isEmpty())
|
||||
if (checks.isEmpty())
|
||||
return;
|
||||
|
||||
addXclangArg("-add-plugin", "clang-lazy");
|
||||
addXclangArg("-plugin-arg-clang-lazy", clazyChecks);
|
||||
addXclangArg("-plugin-arg-clang-lazy", checks);
|
||||
|
||||
// NOTE: we already use -isystem for all include paths to make libclang skip diagnostics for
|
||||
// all of them. That means that ignore-included-files will not change anything unless we decide
|
||||
@@ -515,10 +531,7 @@ private:
|
||||
if (!m_projectPart.project)
|
||||
m_options.append(ClangProjectSettings::globalCommandLineOptions());
|
||||
else
|
||||
m_options.append(ClangProjectSettings{m_projectPart.project}.commandLineOptions());
|
||||
|
||||
addTidyOptions();
|
||||
addClazyOptions();
|
||||
m_options.append(getProjectSettings(m_projectPart.project).commandLineOptions());
|
||||
}
|
||||
|
||||
void addPrecompiledHeaderOptions()
|
||||
@@ -541,6 +554,7 @@ private:
|
||||
const QString &m_filePath;
|
||||
const CppTools::ProjectPart &m_projectPart;
|
||||
|
||||
Core::Id m_diagnosticConfigId;
|
||||
QStringList m_options;
|
||||
};
|
||||
} // namespace
|
||||
@@ -563,6 +577,7 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(
|
||||
}
|
||||
|
||||
const FileOptionsBuilder fileOptions(filePath(), projectPart);
|
||||
m_diagnosticConfigId = fileOptions.diagnosticConfigId();
|
||||
m_communicator.registerTranslationUnitsForEditor(
|
||||
{fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())});
|
||||
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "clangdiagnosticmanager.h"
|
||||
#include "clangeditordocumentparser.h"
|
||||
|
||||
#include <coreplugin/id.h>
|
||||
#include <cpptools/builtineditordocumentprocessor.h>
|
||||
#include <cpptools/semantichighlighter.h>
|
||||
|
||||
@@ -67,6 +68,8 @@ public:
|
||||
CppTools::ProjectPart::Ptr projectPart() const;
|
||||
void clearProjectPart();
|
||||
|
||||
Core::Id diagnosticConfigId() const;
|
||||
|
||||
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
|
||||
uint documentRevision);
|
||||
@@ -120,6 +123,7 @@ private:
|
||||
BackendCommunicator &m_communicator;
|
||||
QSharedPointer<ClangEditorDocumentParser> m_parser;
|
||||
CppTools::ProjectPart::Ptr m_projectPart;
|
||||
Core::Id m_diagnosticConfigId;
|
||||
bool m_isProjectFile = false;
|
||||
QFutureWatcher<void> m_parserWatcher;
|
||||
QTimer m_updateTranslationUnitTimer;
|
||||
|
||||
@@ -133,7 +133,10 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
|
||||
m_reportPriority = report;
|
||||
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
|
||||
QObject::connect(m_futureWatcher.data(), &QFutureWatcherBase::finished, [this]() {
|
||||
processToolTipInfo(m_futureWatcher->result());
|
||||
if (m_futureWatcher->isCanceled())
|
||||
m_reportPriority(Priority_None);
|
||||
else
|
||||
processToolTipInfo(m_futureWatcher->result());
|
||||
});
|
||||
m_futureWatcher->setFuture(future);
|
||||
return;
|
||||
|
||||
@@ -30,22 +30,27 @@
|
||||
#include "clangutils.h"
|
||||
#include "clangfollowsymbol.h"
|
||||
#include "clanghoverhandler.h"
|
||||
#include "clangprojectsettings.h"
|
||||
#include "clangrefactoringengine.h"
|
||||
#include "clangcurrentdocumentfilter.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cppfollowsymbolundercursor.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <cpptools/editordocumenthandle.h>
|
||||
#include <cpptools/projectinfo.h>
|
||||
|
||||
#include <texteditor/quickfix.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <clangsupport/cmbregisterprojectsforeditormessage.h>
|
||||
#include <clangsupport/filecontainer.h>
|
||||
#include <clangsupport/projectpartcontainer.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
@@ -100,11 +105,22 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
||||
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
|
||||
this, &ModelManagerSupportClang::onProjectPartsRemoved);
|
||||
|
||||
auto *sessionManager = ProjectExplorer::SessionManager::instance();
|
||||
connect(sessionManager, &ProjectExplorer::SessionManager::projectAdded,
|
||||
this, &ModelManagerSupportClang::onProjectAdded);
|
||||
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
|
||||
this, &ModelManagerSupportClang::onAboutToRemoveProject);
|
||||
|
||||
CppTools::CppCodeModelSettings *settings = CppTools::codeModelSettings().data();
|
||||
connect(settings, &CppTools::CppCodeModelSettings::clangDiagnosticConfigsInvalidated,
|
||||
this, &ModelManagerSupportClang::onDiagnosticConfigsInvalidated);
|
||||
|
||||
m_communicator.registerFallbackProjectPart();
|
||||
}
|
||||
|
||||
ModelManagerSupportClang::~ModelManagerSupportClang()
|
||||
{
|
||||
QTC_CHECK(m_projectSettings.isEmpty());
|
||||
m_instance = 0;
|
||||
}
|
||||
|
||||
@@ -336,6 +352,52 @@ void ModelManagerSupportClang::onTextMarkContextMenuRequested(TextEditor::TextEd
|
||||
}
|
||||
}
|
||||
|
||||
using ClangEditorDocumentProcessors = QVector<ClangEditorDocumentProcessor *>;
|
||||
static ClangEditorDocumentProcessors clangProcessors()
|
||||
{
|
||||
ClangEditorDocumentProcessors result;
|
||||
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments())
|
||||
result.append(qobject_cast<ClangEditorDocumentProcessor *>(editorDocument->processor()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ClangEditorDocumentProcessors
|
||||
clangProcessorsWithProject(const ProjectExplorer::Project *project)
|
||||
{
|
||||
return ::Utils::filtered(clangProcessors(), [project](ClangEditorDocumentProcessor *p) {
|
||||
return p->hasProjectPart() && p->projectPart()->project == project;
|
||||
});
|
||||
}
|
||||
|
||||
static void updateProcessors(const ClangEditorDocumentProcessors &processors)
|
||||
{
|
||||
CppTools::CppModelManager *modelManager = cppModelManager();
|
||||
for (ClangEditorDocumentProcessor *processor : processors)
|
||||
modelManager->cppEditorDocument(processor->filePath())->resetProcessor();
|
||||
modelManager->updateCppEditorDocuments(/*projectsUpdated=*/ false);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onProjectAdded(ProjectExplorer::Project *project)
|
||||
{
|
||||
QTC_ASSERT(!m_projectSettings.value(project), return);
|
||||
|
||||
auto *settings = new Internal::ClangProjectSettings(project);
|
||||
connect(settings, &Internal::ClangProjectSettings::changed, [project]() {
|
||||
updateProcessors(clangProcessorsWithProject(project));
|
||||
});
|
||||
|
||||
m_projectSettings.insert(project, settings);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onAboutToRemoveProject(ProjectExplorer::Project *project)
|
||||
{
|
||||
ClangProjectSettings * const settings = m_projectSettings.value(project);
|
||||
QTC_ASSERT(settings, return);
|
||||
m_projectSettings.remove(project);
|
||||
delete settings;
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *project)
|
||||
{
|
||||
QTC_ASSERT(project, return);
|
||||
@@ -355,21 +417,25 @@ void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectP
|
||||
}
|
||||
}
|
||||
|
||||
static QVector<ClangEditorDocumentProcessor *>
|
||||
static ClangEditorDocumentProcessors clangProcessorsWithDiagnosticConfig(
|
||||
const QVector<Core::Id> &configIds)
|
||||
{
|
||||
return ::Utils::filtered(clangProcessors(), [configIds](ClangEditorDocumentProcessor *p) {
|
||||
return configIds.contains(p->diagnosticConfigId());
|
||||
});
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds)
|
||||
{
|
||||
updateProcessors(clangProcessorsWithDiagnosticConfig(configIds));
|
||||
}
|
||||
|
||||
static ClangEditorDocumentProcessors
|
||||
clangProcessorsWithProjectParts(const QStringList &projectPartIds)
|
||||
{
|
||||
QVector<ClangEditorDocumentProcessor *> result;
|
||||
|
||||
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments()) {
|
||||
auto *processor = editorDocument->processor();
|
||||
auto *clangProcessor = qobject_cast<ClangEditorDocumentProcessor *>(processor);
|
||||
if (clangProcessor && clangProcessor->hasProjectPart()) {
|
||||
if (projectPartIds.contains(clangProcessor->projectPart()->id()))
|
||||
result.append(clangProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return ::Utils::filtered(clangProcessors(), [projectPartIds](ClangEditorDocumentProcessor *p) {
|
||||
return p->hasProjectPart() && projectPartIds.contains(p->projectPart()->id());
|
||||
});
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
|
||||
@@ -398,6 +464,12 @@ QString ModelManagerSupportClang::dummyUiHeaderOnDiskPath(const QString &filePat
|
||||
return m_uiHeaderOnDiskManager.mapPath(filePath);
|
||||
}
|
||||
|
||||
ClangProjectSettings &ModelManagerSupportClang::projectSettings(
|
||||
ProjectExplorer::Project *project) const
|
||||
{
|
||||
return *m_projectSettings.value(project);
|
||||
}
|
||||
|
||||
QString ModelManagerSupportClang::dummyUiHeaderOnDiskDirPath() const
|
||||
{
|
||||
return m_uiHeaderOnDiskManager.directoryPath();
|
||||
|
||||
@@ -40,7 +40,10 @@ class QMenu;
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core { class IDocument; }
|
||||
namespace Core {
|
||||
class IDocument;
|
||||
class Id;
|
||||
} // namespace Core
|
||||
namespace TextEditor { class TextEditorWidget; }
|
||||
namespace CppTools {
|
||||
class FollowSymbolInterface;
|
||||
@@ -50,6 +53,8 @@ class RefactoringEngineInterface;
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
class ClangProjectSettings;
|
||||
|
||||
class ModelManagerSupportClang:
|
||||
public QObject,
|
||||
public CppTools::ModelManagerSupport
|
||||
@@ -71,6 +76,8 @@ public:
|
||||
QString dummyUiHeaderOnDiskDirPath() const;
|
||||
QString dummyUiHeaderOnDiskPath(const QString &filePath) const;
|
||||
|
||||
ClangProjectSettings &projectSettings(ProjectExplorer::Project *project) const;
|
||||
|
||||
static ModelManagerSupportClang *instance();
|
||||
|
||||
private:
|
||||
@@ -93,9 +100,14 @@ private:
|
||||
int lineNumber,
|
||||
QMenu *menu);
|
||||
|
||||
void onProjectAdded(ProjectExplorer::Project *project);
|
||||
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
||||
|
||||
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
||||
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
||||
|
||||
void onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds);
|
||||
|
||||
void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds);
|
||||
|
||||
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
||||
@@ -111,6 +123,8 @@ private:
|
||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
|
||||
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
|
||||
|
||||
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;
|
||||
};
|
||||
|
||||
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
|
||||
|
||||
@@ -42,6 +42,25 @@ static QString warningConfigIdKey()
|
||||
static QString customCommandLineKey()
|
||||
{ return QLatin1String("ClangCodeModel.CustomCommandLineKey"); }
|
||||
|
||||
static bool useGlobalConfigFromSettings(ProjectExplorer::Project *project)
|
||||
{
|
||||
const QVariant useGlobalConfigVariant = project->namedSettings(useGlobalConfigKey());
|
||||
return useGlobalConfigVariant.isValid() ? useGlobalConfigVariant.toBool() : true;
|
||||
}
|
||||
|
||||
static Core::Id warningConfigIdFromSettings(ProjectExplorer::Project *project)
|
||||
{
|
||||
return Core::Id::fromSetting(project->namedSettings(warningConfigIdKey()));
|
||||
}
|
||||
|
||||
static QStringList customCommandLineFromSettings(ProjectExplorer::Project *project)
|
||||
{
|
||||
QStringList options = project->namedSettings(customCommandLineKey()).toStringList();
|
||||
if (options.empty())
|
||||
options = ClangProjectSettings::globalCommandLineOptions();
|
||||
return options;
|
||||
}
|
||||
|
||||
ClangProjectSettings::ClangProjectSettings(ProjectExplorer::Project *project)
|
||||
: m_project(project)
|
||||
{
|
||||
@@ -88,23 +107,27 @@ void ClangProjectSettings::setCommandLineOptions(const QStringList &options)
|
||||
|
||||
void ClangProjectSettings::load()
|
||||
{
|
||||
const QVariant useGlobalConfigVariant = m_project->namedSettings(useGlobalConfigKey());
|
||||
const bool useGlobalConfig = useGlobalConfigVariant.isValid()
|
||||
? useGlobalConfigVariant.toBool()
|
||||
: true;
|
||||
|
||||
setUseGlobalConfig(useGlobalConfig);
|
||||
setWarningConfigId(Core::Id::fromSetting(m_project->namedSettings(warningConfigIdKey())));
|
||||
m_customCommandLineOptions = m_project->namedSettings(customCommandLineKey()).toStringList();
|
||||
if (m_customCommandLineOptions.empty())
|
||||
m_customCommandLineOptions = globalCommandLineOptions();
|
||||
setUseGlobalConfig(useGlobalConfigFromSettings(m_project));
|
||||
setWarningConfigId(warningConfigIdFromSettings(m_project));
|
||||
m_customCommandLineOptions = customCommandLineFromSettings(m_project);
|
||||
}
|
||||
|
||||
void ClangProjectSettings::store()
|
||||
{
|
||||
bool settingsChanged = false;
|
||||
if (useGlobalConfig() != useGlobalConfigFromSettings(m_project))
|
||||
settingsChanged = true;
|
||||
if (warningConfigId() != warningConfigIdFromSettings(m_project))
|
||||
settingsChanged = true;
|
||||
if (commandLineOptions() != customCommandLineFromSettings(m_project))
|
||||
settingsChanged = true;
|
||||
|
||||
m_project->setNamedSettings(useGlobalConfigKey(), useGlobalConfig());
|
||||
m_project->setNamedSettings(warningConfigIdKey(), warningConfigId().toSetting());
|
||||
m_project->setNamedSettings(customCommandLineKey(), m_customCommandLineOptions);
|
||||
|
||||
if (settingsChanged)
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QStringList ClangProjectSettings::globalCommandLineOptions()
|
||||
|
||||
@@ -59,6 +59,9 @@ public:
|
||||
|
||||
static QStringList globalCommandLineOptions();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
ProjectExplorer::Project *m_project;
|
||||
bool m_useGlobalConfig = true;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "clangprojectsettingswidget.h"
|
||||
|
||||
#include "clangmodelmanagersupport.h"
|
||||
#include "clangprojectsettings.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -52,7 +53,7 @@ static Core::Id configIdForProject(ClangProjectSettings &projectSettings)
|
||||
}
|
||||
|
||||
ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project *project)
|
||||
: m_projectSettings(project)
|
||||
: m_projectSettings(ModelManagerSupportClang::instance()->projectSettings(project))
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
@@ -76,6 +77,8 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project
|
||||
connect(m_ui.clangSettings,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &ClangProjectSettingsWidget::onClangSettingsChanged);
|
||||
connect(project, &ProjectExplorer::Project::aboutToSaveSettings,
|
||||
this, &ClangProjectSettingsWidget::onAboutToSaveProjectSettings);
|
||||
|
||||
m_ui.diagnosticConfigurationGroupBox->layout()->addWidget(m_diagnosticConfigWidget);
|
||||
}
|
||||
@@ -86,7 +89,6 @@ void ClangProjectSettingsWidget::onCurrentWarningConfigChanged(const Core::Id &c
|
||||
if (m_projectSettings.useGlobalConfig())
|
||||
return;
|
||||
m_projectSettings.setWarningConfigId(currentConfigId);
|
||||
m_projectSettings.store();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
||||
@@ -97,7 +99,6 @@ void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
||||
const QSharedPointer<CppTools::CppCodeModelSettings> codeModelSettings
|
||||
= CppTools::codeModelSettings();
|
||||
codeModelSettings->setClangCustomDiagnosticConfigs(customConfigs);
|
||||
codeModelSettings->toSettings(Core::ICore::settings());
|
||||
|
||||
connectToCppCodeModelSettingsChanged();
|
||||
}
|
||||
@@ -115,16 +116,19 @@ void ClangProjectSettingsWidget::onDelayedTemplateParseClicked(bool checked)
|
||||
options.removeAll(QLatin1String{ClangProjectSettings::NoDelayedTemplateParsing});
|
||||
options.append(extraFlag);
|
||||
m_projectSettings.setCommandLineOptions(options);
|
||||
m_projectSettings.store();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onClangSettingsChanged(int index)
|
||||
{
|
||||
m_projectSettings.setUseGlobalConfig(index == 0 ? true : false);
|
||||
m_projectSettings.store();
|
||||
syncOtherWidgetsToComboBox();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onAboutToSaveProjectSettings()
|
||||
{
|
||||
CppTools::codeModelSettings()->toSettings(Core::ICore::settings());
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::syncOtherWidgetsToComboBox()
|
||||
{
|
||||
const QStringList options = m_projectSettings.commandLineOptions();
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
void onCustomWarningConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
||||
void onDelayedTemplateParseClicked(bool);
|
||||
void onClangSettingsChanged(int index);
|
||||
void onAboutToSaveProjectSettings();
|
||||
void refreshDiagnosticConfigsWidgetFromSettings();
|
||||
void connectToCppCodeModelSettingsChanged();
|
||||
void disconnectFromCppCodeModelSettingsChanged();
|
||||
@@ -58,7 +59,7 @@ private:
|
||||
|
||||
private:
|
||||
Ui::ClangProjectSettingsWidget m_ui;
|
||||
ClangProjectSettings m_projectSettings;
|
||||
ClangProjectSettings &m_projectSettings;
|
||||
QPointer<CppTools::ClangDiagnosticConfigsWidget> m_diagnosticConfigWidget;
|
||||
};
|
||||
|
||||
|
||||
@@ -190,31 +190,5 @@ void setLastSentDocumentRevision(const QString &filePath, uint revision)
|
||||
document->sendTracker().setLastSentRevision(int(revision));
|
||||
}
|
||||
|
||||
// CLANG-UPGRADE-CHECK: Workaround still needed?
|
||||
// Remove once clang reports correct columns for lines with multi-byte utf8.
|
||||
int extraUtf8CharsShift(const QString &str, int column)
|
||||
{
|
||||
int shift = 0;
|
||||
const QByteArray byteArray = str.toUtf8();
|
||||
for (int i = 0; i < qMin(str.length(), column); ++i) {
|
||||
const uchar firstByte = static_cast<uchar>(byteArray.at(i));
|
||||
// Skip different amount of bytes depending on value
|
||||
if (firstByte < 0xC0) {
|
||||
continue;
|
||||
} else if (firstByte < 0xE0) {
|
||||
++shift;
|
||||
++i;
|
||||
} else if (firstByte < 0xF0) {
|
||||
shift += 2;
|
||||
i += 2;
|
||||
} else {
|
||||
shift += 3;
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Clang
|
||||
|
||||
@@ -47,7 +47,5 @@ CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &fil
|
||||
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
||||
QString projectPartIdForFile(const QString &filePath);
|
||||
|
||||
int extraUtf8CharsShift(const QString &str, int column);
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Clang
|
||||
|
||||
Reference in New Issue
Block a user