From a6d1f7594c0faba4aae53f79462c957db947dbba Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 27 Jul 2022 12:28:40 +0200 Subject: [PATCH] ClangCodeModel: Fix documents getting opened in wrong clangd This amends 96be267a6e4a4c7439bffd4c5d557ca7f20554c2, which contained a wrong assumption: Just because a ClangdClient has an associated project does not mean that all documents currently open in this client belong to its project. The opposite often happens at session loading. For example: - We load a session with two projects. - Qt Creator restores the documents and starts loading the projects. - The latter happens asynchronously and takes longer, so initially the fallback client claims the documents. - The smaller project finishes first and now grabs all the open documents whose files belong to it, as well as those that don't correspond to any project (as per 8ad7ab2d2a7fefcd3a9ef3ff2f0ef7e5fe792417). This includes all documents belonging to the second project, because that one has not finished loading yet, so its files are not associated with a project at the moment. - Finally the second project finishes loading. Now we must "steal back" all its documents that are currently open in the first ClangdClient. This is what this patch does. We also now explicitly close the document in the previous client as part of the hand-over, which is conceptually the right thing to do and should eliminate any potential "ghost diagnostics". Change-Id: I3d9f5ce503cc7ee47ece757d81851b85a16b639d Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- .../clangmodelmanagersupport.cpp | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 361bf191929..a1dc290a02b 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -428,16 +428,18 @@ void ClangModelManagerSupport::updateLanguageClient( bool hasDocuments = false; const ClangdSettings settings(ClangdProjectSettings(project).settings()); for (TextEditor::TextDocument * const doc : allCppDocuments()) { - const Client * const currentClient = LanguageClientManager::clientForDocument(doc); + Client * const currentClient = LanguageClientManager::clientForDocument(doc); if (!settings.sizeIsOkay(doc->filePath())) continue; + const Project * const docProject = SessionManager::projectForFile(doc->filePath()); if (currentClient && currentClient->project() - && currentClient->project() != project) { + && currentClient->project() != project + && currentClient->project() == docProject) { continue; } - if (const Project * const docProject - = SessionManager::projectForFile(doc->filePath()); - !docProject || docProject == project) { + if (!docProject || docProject == project) { + if (currentClient) + currentClient->closeDocument(doc); LanguageClientManager::openDocumentWithClient(doc, client); hasDocuments = true; } @@ -543,15 +545,18 @@ void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client) if (!client) return; for (TextEditor::TextDocument * const doc : allCppDocuments()) { - if (Client * const currentClient = LanguageClientManager::clientForDocument(doc); - currentClient && currentClient->state() == Client::Initialized + Client * const currentClient = LanguageClientManager::clientForDocument(doc); + if (currentClient && currentClient->state() == Client::Initialized && (currentClient == client || currentClient->project())) { continue; } if (!ClangdSettings::instance().sizeIsOkay(doc->filePath())) continue; - if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) + if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) { + if (currentClient) + currentClient->closeDocument(doc); LanguageClientManager::openDocumentWithClient(doc, client); + } } }