aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2022-02-08 11:49:37 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2022-02-10 12:58:30 +0000
commit6ede8b3bc0e96453e7c5725718b200cb8ac9b30f (patch)
treef50fa4dec3ebb5461b60b821ea071214ea68c888
parent959e2b0124d5629f8a0703eb0f633e86fe89ebaf (diff)
ClangCodeModel: Support parse contexts with clangd
Fixes: QTCREATORBUG-27009 Change-Id: I177db0658d545211b940623cae071db91e82ddb4 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
-rw-r--r--src/plugins/clangcodemodel/clangdclient.cpp35
-rw-r--r--src/plugins/clangcodemodel/clangdclient.h4
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp6
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.h3
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.cpp38
-rw-r--r--src/plugins/cppeditor/baseeditordocumentparser.h7
6 files changed, 90 insertions, 3 deletions
diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp
index 48cb1bf13b..5988d04d40 100644
--- a/src/plugins/clangcodemodel/clangdclient.cpp
+++ b/src/plugins/clangcodemodel/clangdclient.cpp
@@ -1142,6 +1142,7 @@ public:
std::unordered_map<TextDocument *, CppEditor::SemanticHighlighter *> highlighters;
QHash<TextDocument *, QPair<QList<ExpandedSemanticToken>, int>> previousTokens;
+ QHash<Utils::FilePath, CppEditor::BaseEditorDocumentParser::Configuration> parserConfigs;
// The ranges of symbols referring to virtual functions, with document version,
// as extracted by the highlighting procedure.
@@ -1468,6 +1469,7 @@ void ClangdClient::handleDocumentClosed(TextDocument *doc)
d->astCache.remove(doc);
d->previousTokens.remove(doc);
d->virtualRanges.remove(doc);
+ d->parserConfigs.remove(doc->filePath());
}
QTextCursor ClangdClient::adjustedCursorForHighlighting(const QTextCursor &cursor,
@@ -1625,6 +1627,39 @@ void ClangdClient::handleUiHeaderChange(const QString &fileName)
}
}
+void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
+ const CppEditor::BaseEditorDocumentParser::Configuration &config)
+{
+ if (config.preferredProjectPartId.isEmpty())
+ return;
+
+ CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
+ if (cachedConfig == config)
+ return;
+ cachedConfig = config;
+
+ // TODO: Also handle editorDefines (and usePrecompiledHeaders?)
+ const auto projectPart = CppEditor::CppModelManager::instance()
+ ->projectPartForId(config.preferredProjectPartId);
+ if (!projectPart)
+ return;
+ const CppEditor::ClangDiagnosticConfig projectWarnings = warningsConfigForProject(project());
+ const QStringList projectOptions = optionsForProject(project());
+ QJsonObject cdbChanges;
+ QStringList args = createClangOptions(*projectPart, filePath.toString(), projectWarnings,
+ projectOptions);
+ args.prepend("clang");
+ args.append(filePath.toString());
+ QJsonObject value;
+ value.insert("workingDirectory", filePath.parentDir().toString());
+ value.insert("compilationCommand", QJsonArray::fromStringList(args));
+ cdbChanges.insert(filePath.toUserOutput(), value);
+ const QJsonObject settings({qMakePair(QString("compilationDatabaseChanges"), cdbChanges)});
+ DidChangeConfigurationParams configChangeParams;
+ configChangeParams.setSettings(settings);
+ sendContent(DidChangeConfigurationNotification(configChangeParams));
+}
+
void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations)
{
const auto refData = runningFindUsages.find(key);
diff --git a/src/plugins/clangcodemodel/clangdclient.h b/src/plugins/clangcodemodel/clangdclient.h
index 92ca40d0ff..cc4b6aa71e 100644
--- a/src/plugins/clangcodemodel/clangdclient.h
+++ b/src/plugins/clangcodemodel/clangdclient.h
@@ -25,6 +25,7 @@
#pragma once
+#include <cppeditor/baseeditordocumentparser.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/refactoringengineinterface.h>
#include <languageclient/client.h>
@@ -88,6 +89,9 @@ public:
static void handleUiHeaderChange(const QString &fileName);
+ void updateParserConfig(const Utils::FilePath &filePath,
+ const CppEditor::BaseEditorDocumentParser::Configuration &config);
+
signals:
void indexingFinished();
void foundReferences(const QList<Core::SearchResultItem> &items);
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
index 2461120d9a..1b2027139f 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
@@ -328,6 +328,12 @@ void ClangEditorDocumentProcessor::setParserConfig(
{
m_parser->setConfiguration(config);
m_builtinProcessor.parser()->setConfiguration(config);
+ emit parserConfigChanged(Utils::FilePath::fromString(filePath()), config);
+}
+
+CppEditor::BaseEditorDocumentParser::Configuration ClangEditorDocumentProcessor::parserConfig() const
+{
+ return m_parser->configuration();
}
static bool isCursorOnIdentifier(const QTextCursor &textCursor)
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
index 532c134b40..7111eee4c8 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
@@ -91,6 +91,7 @@ public:
void editorDocumentTimerRestarted() override;
void setParserConfig(const CppEditor::BaseEditorDocumentParser::Configuration &config) override;
+ CppEditor::BaseEditorDocumentParser::Configuration parserConfig() const;
QFuture<CppEditor::CursorInfo> cursorInfo(const CppEditor::CursorInfoParams &params) override;
QFuture<CppEditor::CursorInfo> requestLocalReferences(const QTextCursor &cursor) override;
@@ -115,6 +116,8 @@ public:
signals:
void tokenInfosUpdated();
+ void parserConfigChanged(const Utils::FilePath &filePath,
+ const CppEditor::BaseEditorDocumentParser::Configuration &config);
private:
void onParserFinished();
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
index 1d8a3f8af2..7ceb40011f 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
@@ -217,7 +217,15 @@ bool ClangModelManagerSupport::supportsLocalUses(const TextEditor::TextDocument
CppEditor::BaseEditorDocumentProcessor *ClangModelManagerSupport::createEditorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument)
{
- return new ClangEditorDocumentProcessor(m_communicator, baseTextDocument);
+ const auto processor = new ClangEditorDocumentProcessor(m_communicator, baseTextDocument);
+ const auto handleConfigChange = [this](const Utils::FilePath &fp,
+ const BaseEditorDocumentParser::Configuration &config) {
+ if (const auto client = clientForFile(fp))
+ client->updateParserConfig(fp, config);
+ };
+ connect(processor, &ClangEditorDocumentProcessor::parserConfigChanged,
+ this, handleConfigChange);
+ return processor;
}
void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
@@ -233,6 +241,8 @@ void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
if (auto processor = ClangEditorDocumentProcessor::get(filePath.toString())) {
processor->semanticRehighlight();
processor->generateTaskHubIssues();
+ if (const auto client = clientForFile(filePath))
+ client->updateParserConfig(filePath, processor->parserConfig());
}
}
@@ -342,16 +352,38 @@ void ClangModelManagerSupport::updateLanguageClient(
if (!newProjectInfo || *newProjectInfo != *projectInfo)
return;
+ const auto updateParserConfig = [client] {
+ if (const auto editor = TextEditor::BaseTextEditor::currentTextEditor()) {
+ if (!client->documentOpen(editor->textDocument()))
+ return;
+ const Utils::FilePath filePath = editor->textDocument()->filePath();
+ if (const auto processor = ClangEditorDocumentProcessor::get(
+ filePath.toString())) {
+ const CppEditor::BaseEditorDocumentParser::Configuration config
+ = processor->parserConfig();
+ client->updateParserConfig(filePath, config);
+ }
+ }
+ };
+
// Acquaint the client with all open C++ documents for this project.
bool hasDocuments = false;
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) {
- if (!project->isKnownFile(editor->textDocument()->filePath()))
+ const Utils::FilePath filePath = editor->textDocument()->filePath();
+ if (!project->isKnownFile(filePath))
continue;
LanguageClientManager::openDocumentWithClient(editor->textDocument(), client);
- ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath());
+ ClangEditorDocumentProcessor::clearTextMarks(filePath);
hasDocuments = true;
}
+ if (client->state() == Client::Initialized)
+ updateParserConfig();
+ else
+ connect(client, &Client::initialized, client, updateParserConfig);
+ connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
+ client, updateParserConfig);
+
if (hasDocuments)
return;
diff --git a/src/plugins/cppeditor/baseeditordocumentparser.h b/src/plugins/cppeditor/baseeditordocumentparser.h
index 2e10d56178..2f48058b8b 100644
--- a/src/plugins/cppeditor/baseeditordocumentparser.h
+++ b/src/plugins/cppeditor/baseeditordocumentparser.h
@@ -50,6 +50,13 @@ public:
bool usePrecompiledHeaders = false;
QByteArray editorDefines;
QString preferredProjectPartId;
+
+ bool operator==(const Configuration &other)
+ {
+ return usePrecompiledHeaders == other.usePrecompiledHeaders
+ && editorDefines == other.editorDefines
+ && preferredProjectPartId == other.preferredProjectPartId;
+ }
};
struct UpdateParams {