ClangCodeModel: Fix documents getting opened in wrong clangd

This amends 96be267a6e, 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
8ad7ab2d2a).
      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: <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-07-27 12:28:40 +02:00
parent 9664010b44
commit a6d1f7594c

View File

@@ -428,16 +428,18 @@ void ClangModelManagerSupport::updateLanguageClient(
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()) {
const Client * const currentClient = LanguageClientManager::clientForDocument(doc); Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (!settings.sizeIsOkay(doc->filePath())) if (!settings.sizeIsOkay(doc->filePath()))
continue; continue;
const Project * const docProject = SessionManager::projectForFile(doc->filePath());
if (currentClient && currentClient->project() if (currentClient && currentClient->project()
&& currentClient->project() != project) { && currentClient->project() != project
&& currentClient->project() == docProject) {
continue; continue;
} }
if (const Project * const docProject if (!docProject || docProject == project) {
= SessionManager::projectForFile(doc->filePath()); if (currentClient)
!docProject || docProject == project) { currentClient->closeDocument(doc);
LanguageClientManager::openDocumentWithClient(doc, client); LanguageClientManager::openDocumentWithClient(doc, client);
hasDocuments = true; hasDocuments = true;
} }
@@ -543,15 +545,18 @@ void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
if (!client) if (!client)
return; return;
for (TextEditor::TextDocument * const doc : allCppDocuments()) { for (TextEditor::TextDocument * const doc : allCppDocuments()) {
if (Client * const currentClient = LanguageClientManager::clientForDocument(doc); Client * const currentClient = LanguageClientManager::clientForDocument(doc);
currentClient && currentClient->state() == Client::Initialized if (currentClient && currentClient->state() == Client::Initialized
&& (currentClient == client || currentClient->project())) { && (currentClient == client || currentClient->project())) {
continue; continue;
} }
if (!ClangdSettings::instance().sizeIsOkay(doc->filePath())) if (!ClangdSettings::instance().sizeIsOkay(doc->filePath()))
continue; continue;
if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) {
if (currentClient)
currentClient->closeDocument(doc);
LanguageClientManager::openDocumentWithClient(doc, client); LanguageClientManager::openDocumentWithClient(doc, client);
}
} }
} }