From a7157e2cf1c00a1dbdfc8b95b0404cdc2972fbd1 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Tue, 25 Nov 2025 00:22:57 +1000 Subject: [PATCH] update project diagnostics for active document immediately --- .../Features/Analysis/RoslynAnalysis.cs | 20 +++++++++++++++---- .../Features/CodeEditor/SharpIdeCodeEdit.cs | 8 +++++++- src/SharpIDE.Godot/NodeExtensions.cs | 5 +++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs b/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs index 390579b..406ddee 100644 --- a/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs +++ b/src/SharpIDE.Application/Features/Analysis/RoslynAnalysis.cs @@ -301,15 +301,27 @@ public class RoslynAnalysis(ILogger logger, BuildService buildSe // Performance improvements of ~15% have been observed with a large solution (100+ projects) by parallelizing this with Task.WhenAll, however it seems much heavier (14700K crashes sometimes 😅) so re-evaluate later foreach (var project in _sharpIdeSolutionModel!.AllProjects) { - var projectDiagnostics = await GetProjectDiagnostics(project, cancellationToken); - // TODO: only add and remove diffs - project.Diagnostics.RemoveRange(project.Diagnostics); - project.Diagnostics.AddRange(projectDiagnostics); + await UpdateProjectDiagnostics(project, cancellationToken); } timer.Stop(); _logger.LogInformation("RoslynAnalysis: Solution diagnostics updated in {ElapsedMilliseconds}ms", timer.ElapsedMilliseconds); } + public async Task UpdateProjectDiagnostics(SharpIdeProjectModel project, CancellationToken cancellationToken = default) + { + var projectDiagnostics = await GetProjectDiagnostics(project, cancellationToken); + // TODO: only add and remove diffs + project.Diagnostics.RemoveRange(project.Diagnostics); + project.Diagnostics.AddRange(projectDiagnostics); + } + + public async Task UpdateProjectDiagnosticsForFile(SharpIdeFile sharpIdeFile, CancellationToken cancellationToken = default) + { + var project = ((IChildSharpIdeNode) sharpIdeFile).GetNearestProjectNode(); + Guard.Against.Null(project); + await UpdateProjectDiagnostics(project, cancellationToken); + } + public async Task> GetProjectDiagnostics(SharpIdeProjectModel projectModel, CancellationToken cancellationToken = default) { using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetProjectDiagnostics)}"); diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs index 552d889..df17ffc 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs +++ b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs @@ -104,16 +104,22 @@ public partial class SharpIdeCodeEdit : CodeEdit if (_fileDeleted) return; GD.Print($"[{_currentFile.Name}] Solution altered, updating project diagnostics for file"); var newCt = _solutionAlteredCancellationTokenSeries.CreateNext(); + var hasFocus = this.InvokeAsync(HasFocus); var documentSyntaxHighlighting = _roslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile, newCt); var razorSyntaxHighlighting = _roslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile, newCt); await Task.WhenAll(documentSyntaxHighlighting, razorSyntaxHighlighting).WaitAsync(newCt).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); if (newCt.IsCancellationRequested) return; var documentDiagnosticsTask = _roslynAnalysis.GetDocumentDiagnostics(_currentFile, newCt); await this.InvokeAsync(async () => SetSyntaxHighlightingModel(await documentSyntaxHighlighting, await razorSyntaxHighlighting)); - await ((Task)documentDiagnosticsTask).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); + await documentDiagnosticsTask.AsTask().ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); if (newCt.IsCancellationRequested) return; var documentDiagnostics = await documentDiagnosticsTask; await this.InvokeAsync(() => SetDiagnostics(documentDiagnostics)); + if (await hasFocus) + { + await _roslynAnalysis.UpdateProjectDiagnosticsForFile(_currentFile, newCt).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); + if (newCt.IsCancellationRequested) return; + } } public enum LineEditOrigin diff --git a/src/SharpIDE.Godot/NodeExtensions.cs b/src/SharpIDE.Godot/NodeExtensions.cs index ef5dce1..6482871 100644 --- a/src/SharpIDE.Godot/NodeExtensions.cs +++ b/src/SharpIDE.Godot/NodeExtensions.cs @@ -174,6 +174,11 @@ public static class NodeExtensions public static class GodotTask { + extension(Task task) + { + public Task AsTask() => task; + } + extension(Task task) { public static async Task GodotRun(Action action)