ClangCodeModel: Consider the case of a restarted client

We must not assume the initialized() signal comes only once.

Task-number: QTCREATORBUG-27596
Change-Id: Ife19657b7e0701a0e0dc10806e230bd1744a20aa
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-08-09 16:44:58 +02:00
parent 5db3d507dd
commit 93fbef4de6

View File

@@ -160,6 +160,20 @@ static void checkSystemForClangdSuitability()
Core::ICore::infoBar()->addInfo(info); Core::ICore::infoBar()->addInfo(info);
} }
static void updateParserConfig(ClangdClient *client)
{
if (!client->reachable())
return;
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()))
client->updateParserConfig(filePath, processor->parserConfig());
}
}
ClangModelManagerSupport::ClangModelManagerSupport() ClangModelManagerSupport::ClangModelManagerSupport()
{ {
QTC_CHECK(!m_instance); QTC_CHECK(!m_instance);
@@ -399,6 +413,12 @@ void ClangModelManagerSupport::updateLanguageClient(
if (Client * const oldClient = clientForProject(project)) if (Client * const oldClient = clientForProject(project))
LanguageClientManager::shutdownClient(oldClient); LanguageClientManager::shutdownClient(oldClient);
ClangdClient * const client = createClient(project, jsonDbDir); ClangdClient * const client = createClient(project, jsonDbDir);
connect(client, &Client::shadowDocumentSwitched, this,
[](const Utils::FilePath &fp) {
ClangdClient::handleUiHeaderChange(fp.fileName());
});
connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
client, [client] { updateParserConfig(client); });
connect(client, &Client::initialized, this, [this, client, project, projectInfo, jsonDbDir] { connect(client, &Client::initialized, this, [this, client, project, projectInfo, jsonDbDir] {
using namespace ProjectExplorer; using namespace ProjectExplorer;
if (!SessionManager::hasProject(project)) if (!SessionManager::hasProject(project))
@@ -410,25 +430,15 @@ void ClangModelManagerSupport::updateLanguageClient(
if (!newProjectInfo || *newProjectInfo != *projectInfo) if (!newProjectInfo || *newProjectInfo != *projectInfo)
return; 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. // Acquaint the client with all open C++ documents for this project.
bool hasDocuments = false; bool hasDocuments = false;
const ClangdSettings settings(ClangdProjectSettings(project).settings()); const ClangdSettings settings(ClangdProjectSettings(project).settings());
for (TextEditor::TextDocument * const doc : allCppDocuments()) { for (TextEditor::TextDocument * const doc : allCppDocuments()) {
Client * const currentClient = LanguageClientManager::clientForDocument(doc); Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (currentClient == client) {
hasDocuments = true;
continue;
}
if (!settings.sizeIsOkay(doc->filePath())) if (!settings.sizeIsOkay(doc->filePath()))
continue; continue;
const Project * const docProject = SessionManager::projectForFile(doc->filePath()); const Project * const docProject = SessionManager::projectForFile(doc->filePath());
@@ -457,17 +467,8 @@ void ClangModelManagerSupport::updateLanguageClient(
++it; ++it;
} }
} }
connect(client, &Client::shadowDocumentSwitched, this,
[](const Utils::FilePath &fp) {
ClangdClient::handleUiHeaderChange(fp.fileName());
});
if (client->state() == Client::Initialized) updateParserConfig(client);
updateParserConfig();
else
connect(client, &Client::initialized, client, updateParserConfig);
connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
client, updateParserConfig);
if (hasDocuments) if (hasDocuments)
return; return;