show project diagnostics in document

This commit is contained in:
Matt Parker
2025-10-18 00:20:38 +10:00
parent d5567cf32a
commit 11cb9c1deb
2 changed files with 44 additions and 7 deletions

View File

@@ -294,6 +294,25 @@ public static class RoslynAnalysis
return diagnostics;
}
public static async Task<ImmutableArray<SharpIdeDiagnostic>> GetProjectDiagnosticsForFile(SharpIdeFile sharpIdeFile)
{
using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetProjectDiagnosticsForFile)}");
await _solutionLoadedTcs.Task;
var cancellationToken = CancellationToken.None;
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)sharpIdeFile).GetNearestProjectNode()!.FilePath);
var compilation = await project.GetCompilationAsync(cancellationToken);
Guard.Against.Null(compilation, nameof(compilation));
var document = await GetDocumentForSharpIdeFile(sharpIdeFile);
var syntaxTree = compilation.SyntaxTrees.Single(s => s.FilePath == document.FilePath);
var diagnostics = compilation.GetDiagnostics(cancellationToken)
.Where(d => d.Severity is not DiagnosticSeverity.Hidden && d.Location.SourceTree == syntaxTree)
.Select(d => new SharpIdeDiagnostic(syntaxTree.GetMappedLineSpan(d.Location.SourceSpan).Span, d))
.ToImmutableArray();
return diagnostics;
}
public static async Task<ImmutableArray<SharpIdeDiagnostic>> GetDocumentDiagnostics(SharpIdeFile fileModel, CancellationToken cancellationToken = default)
{
if (fileModel.IsRoslynWorkspaceFile is false) return [];

View File

@@ -4,9 +4,11 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using SharpIDE.Application;
using SharpIDE.Application.Features.Analysis;
using SharpIDE.Application.Features.Debugging;
using SharpIDE.Application.Features.Events;
using SharpIDE.Application.Features.SolutionDiscovery;
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
using SharpIDE.RazorAccess;
@@ -32,7 +34,8 @@ public partial class SharpIdeCodeEdit : CodeEdit
private CustomHighlighter _syntaxHighlighter = new();
private PopupMenu _popupMenu = null!;
private ImmutableArray<SharpIdeDiagnostic> _diagnostics = [];
private ImmutableArray<SharpIdeDiagnostic> _fileDiagnostics = [];
private ImmutableArray<SharpIdeDiagnostic> _projectDiagnosticsForFile = [];
private ImmutableArray<CodeAction> _currentCodeActionsInPopup = [];
private bool _fileChangingSuppressBreakpointToggleEvent;
@@ -266,7 +269,12 @@ public partial class SharpIdeCodeEdit : CodeEdit
_ = Task.GodotRun(async () =>
{
var documentDiagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile, _textChangedCts.Token);
await this.InvokeAsync(() => SetDiagnosticsModel(documentDiagnostics));
await this.InvokeAsync(() => SetDiagnostics(documentDiagnostics));
});
_ = Task.GodotRun(async () =>
{
var projectDiagnosticsForFile = await RoslynAnalysis.GetProjectDiagnosticsForFile(_currentFile);
await this.InvokeAsync(() => SetProjectDiagnostics(projectDiagnosticsForFile));
});
});
}
@@ -305,7 +313,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
BeginComplexOperation();
SetText(fileContents);
SetSyntaxHighlightingModel(syntaxHighlighting.Result, razorSyntaxHighlighting.Result);
SetDiagnosticsModel(diagnostics.Result);
SetDiagnostics(diagnostics.Result);
SetCaretLine(currentCaretPosition.line);
SetCaretColumn(currentCaretPosition.col);
SetVScroll(vScroll);
@@ -336,6 +344,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
var syntaxHighlighting = RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
var razorSyntaxHighlighting = RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
var diagnostics = RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
var projectDiagnosticsForFile = RoslynAnalysis.GetProjectDiagnosticsForFile(_currentFile);
var setTextTask = this.InvokeAsync(async () =>
{
_fileChangingSuppressBreakpointToggleEvent = true;
@@ -345,7 +354,9 @@ public partial class SharpIdeCodeEdit : CodeEdit
await Task.WhenAll(syntaxHighlighting, razorSyntaxHighlighting, setTextTask); // Text must be set before setting syntax highlighting
await this.InvokeAsync(async () => SetSyntaxHighlightingModel(await syntaxHighlighting, await razorSyntaxHighlighting));
await diagnostics;
await this.InvokeAsync(async () => SetDiagnosticsModel(await diagnostics));
await this.InvokeAsync(async () => SetDiagnostics(await diagnostics));
await projectDiagnosticsForFile;
await this.InvokeAsync(async () => SetProjectDiagnostics(await projectDiagnosticsForFile));
}
private async Task OnFileChangedExternallyFromDisk()
@@ -391,7 +402,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
public override void _Draw()
{
//UnderlineRange(_currentLine, _selectionStartCol, _selectionEndCol, new Color(1, 0, 0));
foreach (var sharpIdeDiagnostic in _diagnostics)
foreach (var sharpIdeDiagnostic in _fileDiagnostics.ConcatFast(_projectDiagnosticsForFile))
{
var line = sharpIdeDiagnostic.Span.Start.Line;
var startCol = sharpIdeDiagnostic.Span.Start.Character;
@@ -447,9 +458,16 @@ public partial class SharpIdeCodeEdit : CodeEdit
}
[RequiresGodotUiThread]
private void SetDiagnosticsModel(ImmutableArray<SharpIdeDiagnostic> diagnostics)
private void SetDiagnostics(ImmutableArray<SharpIdeDiagnostic> diagnostics)
{
_diagnostics = diagnostics;
_fileDiagnostics = diagnostics;
QueueRedraw();
}
[RequiresGodotUiThread]
private void SetProjectDiagnostics(ImmutableArray<SharpIdeDiagnostic> diagnostics)
{
_fileDiagnostics = diagnostics;
QueueRedraw();
}