/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/LanguageServer/Protocol/Handler/SourceGenerators/SourceGeneratorRefreshQueue.cs
77 строк
4 KB
David Barbet
Update refresh queue and add tests
15 апр 2026, 21:35
15 апр 2026, 21:35
aec8051
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServer.Handler.TextDocumentContent; using Microsoft.CodeAnalysis.Shared.TestHooks; namespace Microsoft.CodeAnalysis.LanguageServer.Handler.SourceGenerators; /// <summary> /// Refresh queue for source generated documents. Detects when source generator output may have changed /// (via execution version or dependent version checks) and sends per-URI refresh notifications to the client /// using the LSP 3.18 <c>workspace/textDocumentContent/refresh</c> mechanism. /// </summary> internal sealed class SourceGeneratorRefreshQueue( IAsynchronousOperationListenerProvider asynchronousOperationListenerProvider, LspWorkspaceRegistrationService lspWorkspaceRegistrationService, LspWorkspaceManager lspWorkspaceManager, IClientLanguageServerManager notificationManager) : AbstractTextDocumentContentRefreshQueue(asynchronousOperationListenerProvider, lspWorkspaceRegistrationService, lspWorkspaceManager, notificationManager) { protected override string Scheme => SourceGeneratedDocumentUri.Scheme; protected override async Task<bool> ShouldEnqueueRefreshNotificationAsync(WorkspaceChangeEventArgs e, CancellationToken cancellationToken) { var projectId = e.ProjectId ?? e.DocumentId?.ProjectId; if (projectId is not null) { // We have a specific changed project - do some additional checks to see if // source generators possibly changed. var oldProject = e.OldSolution.GetProject(projectId); var newProject = e.NewSolution.GetProject(projectId); // If the project has been added/removed, we need to update the generated files. if (oldProject is null || newProject is null) { return true; } // Trivial check. see if the SG version of these projects changed. If so, we definitely want to update generated files. if (e.OldSolution.GetSourceGeneratorExecutionVersion(projectId) != e.NewSolution.GetSourceGeneratorExecutionVersion(projectId)) { return true; } var configuration = e.NewSolution.Services.GetRequiredService<IWorkspaceConfigurationService>().Options; // When running in balanced mode, we do not need to refresh generated documents if only a document changed and the execution version did not. if (e.Kind is WorkspaceChangeKind.DocumentChanged && configuration.SourceGeneratorExecution == SourceGeneratorExecutionPreference.Balanced) { return false; } // More expensive check - see if the dependent versions are different. if (await oldProject.GetDependentVersionAsync(cancellationToken).ConfigureAwait(false) != await newProject.GetDependentVersionAsync(cancellationToken).ConfigureAwait(false)) { return true; } } else { // We don't have a specific project change - if this is a solution change we need to queue a refresh anyway. if (e.Kind is WorkspaceChangeKind.SolutionChanged or WorkspaceChangeKind.SolutionAdded or WorkspaceChangeKind.SolutionRemoved or WorkspaceChangeKind.SolutionReloaded or WorkspaceChangeKind.SolutionCleared) { return true; } } return false; } }