refactor diagnostic v2

This commit is contained in:
Matt Parker
2025-10-17 22:17:14 +10:00
parent 96d21f75f6
commit b6060e34f5
4 changed files with 19 additions and 12 deletions

View File

@@ -294,7 +294,7 @@ public static class RoslynAnalysis
return diagnostics; return diagnostics;
} }
public static async Task<ImmutableArray<(FileLinePositionSpan fileSpan, Diagnostic diagnostic)>> GetDocumentDiagnostics(SharpIdeFile fileModel, CancellationToken cancellationToken = default) public static async Task<ImmutableArray<SharpIdeDiagnostic>> GetDocumentDiagnostics(SharpIdeFile fileModel, CancellationToken cancellationToken = default)
{ {
if (fileModel.IsRoslynWorkspaceFile is false) return []; if (fileModel.IsRoslynWorkspaceFile is false) return [];
using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetDocumentDiagnostics)}"); using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetDocumentDiagnostics)}");
@@ -308,7 +308,7 @@ public static class RoslynAnalysis
var diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); var diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken);
diagnostics = diagnostics.Where(d => d.Severity is not DiagnosticSeverity.Hidden).ToImmutableArray(); diagnostics = diagnostics.Where(d => d.Severity is not DiagnosticSeverity.Hidden).ToImmutableArray();
var result = diagnostics.Select(d => (semanticModel.SyntaxTree.GetMappedLineSpan(d.Location.SourceSpan), d)).ToImmutableArray(); var result = diagnostics.Select(d => new SharpIdeDiagnostic(semanticModel.SyntaxTree.GetMappedLineSpan(d.Location.SourceSpan).Span, d)).ToImmutableArray();
return result; return result;
} }
@@ -441,7 +441,7 @@ public static class RoslynAnalysis
} }
// This is expensive for files that have just been updated, making it suboptimal for real-time highlighting // This is expensive for files that have just been updated, making it suboptimal for real-time highlighting
public static async Task<IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)>> GetDocumentSyntaxHighlighting(SharpIdeFile fileModel, CancellationToken cancellationToken = default) public static async Task<IEnumerable<SharpIdeClassifiedSpan>> GetDocumentSyntaxHighlighting(SharpIdeFile fileModel, CancellationToken cancellationToken = default)
{ {
using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetDocumentSyntaxHighlighting)}"); using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(GetDocumentSyntaxHighlighting)}");
await _solutionLoadedTcs.Task; await _solutionLoadedTcs.Task;
@@ -459,7 +459,7 @@ public static class RoslynAnalysis
var root = await syntaxTree!.GetRootAsync(cancellationToken); var root = await syntaxTree!.GetRootAsync(cancellationToken);
var classifiedSpans = await Classifier.GetClassifiedSpansAsync(document, root.FullSpan, cancellationToken); var classifiedSpans = await Classifier.GetClassifiedSpansAsync(document, root.FullSpan, cancellationToken);
var result = classifiedSpans.Select(s => (syntaxTree.GetMappedLineSpan(s.TextSpan), s)).ToList(); var result = classifiedSpans.Select(s => new SharpIdeClassifiedSpan(syntaxTree.GetMappedLineSpan(s.TextSpan).Span, s)).ToList();
return result; return result;
} }

View File

@@ -0,0 +1,6 @@
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Text;
namespace SharpIDE.Application.Features.Analysis;
public readonly record struct SharpIdeClassifiedSpan(LinePositionSpan FileSpan, ClassifiedSpan ClassifiedSpan);

View File

@@ -3,6 +3,7 @@ using Godot;
using Godot.Collections; using Godot.Collections;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Classification;
using SharpIDE.Application.Features.Analysis;
using SharpIDE.Godot.Features.CodeEditor; using SharpIDE.Godot.Features.CodeEditor;
using SharpIDE.RazorAccess; using SharpIDE.RazorAccess;
@@ -13,10 +14,10 @@ public partial class CustomHighlighter : SyntaxHighlighter
private readonly Dictionary _emptyDict = new(); private readonly Dictionary _emptyDict = new();
private System.Collections.Generic.Dictionary<int, ImmutableArray<SharpIdeRazorClassifiedSpan>> _razorClassifiedSpansByLine = []; private System.Collections.Generic.Dictionary<int, ImmutableArray<SharpIdeRazorClassifiedSpan>> _razorClassifiedSpansByLine = [];
private System.Collections.Generic.Dictionary<int, ImmutableArray<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)>> _classifiedSpansByLine = []; private System.Collections.Generic.Dictionary<int, ImmutableArray<SharpIdeClassifiedSpan>> _classifiedSpansByLine = [];
public void SetHighlightingData(IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> classifiedSpans, IEnumerable<SharpIdeRazorClassifiedSpan> razorClassifiedSpans) public void SetHighlightingData(IEnumerable<SharpIdeClassifiedSpan> classifiedSpans, IEnumerable<SharpIdeRazorClassifiedSpan> razorClassifiedSpans)
{ {
// separate each line here // separate each line here
var razorSpansForLine = razorClassifiedSpans var razorSpansForLine = razorClassifiedSpans
@@ -26,8 +27,8 @@ public partial class CustomHighlighter : SyntaxHighlighter
_razorClassifiedSpansByLine = razorSpansForLine.ToDictionary(g => g.Key, g => g.ToImmutableArray()); _razorClassifiedSpansByLine = razorSpansForLine.ToDictionary(g => g.Key, g => g.ToImmutableArray());
var spansGroupedByFileSpan = classifiedSpans var spansGroupedByFileSpan = classifiedSpans
.Where(s => s.classifiedSpan.TextSpan.Length is not 0) .Where(s => s.ClassifiedSpan.TextSpan.Length is not 0)
.GroupBy(span => span.fileSpan.StartLinePosition.Line) .GroupBy(span => span.FileSpan.Start.Line)
.ToList(); .ToList();
_classifiedSpansByLine = spansGroupedByFileSpan.ToDictionary(g => g.Key, g => g.ToImmutableArray()); _classifiedSpansByLine = spansGroupedByFileSpan.ToDictionary(g => g.Key, g => g.ToImmutableArray());
} }
@@ -195,8 +196,8 @@ public partial class CustomHighlighter : SyntaxHighlighter
// consider no linq or ZLinq // consider no linq or ZLinq
// group by span (start, length matches) // group by span (start, length matches)
var spansGroupedByFileSpan = spansForLine var spansGroupedByFileSpan = spansForLine
.GroupBy(span => span.fileSpan) .GroupBy(span => span.FileSpan)
.Select(group => (fileSpan: group.Key, classifiedSpans: group.Select(s => s.classifiedSpan).ToList())); .Select(group => (fileSpan: group.Key, classifiedSpans: group.Select(s => s.ClassifiedSpan).ToList()));
foreach (var (fileSpan, classifiedSpans) in spansGroupedByFileSpan) foreach (var (fileSpan, classifiedSpans) in spansGroupedByFileSpan)
{ {
@@ -207,7 +208,7 @@ public partial class CustomHighlighter : SyntaxHighlighter
if (staticClassifiedSpan is not null) classifiedSpans.Remove(staticClassifiedSpan.Value); if (staticClassifiedSpan is not null) classifiedSpans.Remove(staticClassifiedSpan.Value);
} }
// Column index of the first character in this span // Column index of the first character in this span
int columnIndex = fileSpan.StartLinePosition.Character; int columnIndex = fileSpan.Start.Character;
// Build the highlight entry // Build the highlight entry
var highlightInfo = new Dictionary var highlightInfo = new Dictionary

View File

@@ -454,7 +454,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
} }
[RequiresGodotUiThread] [RequiresGodotUiThread]
private void SetSyntaxHighlightingModel(IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> classifiedSpans, IEnumerable<SharpIdeRazorClassifiedSpan> razorClassifiedSpans) private void SetSyntaxHighlightingModel(IEnumerable<SharpIdeClassifiedSpan> classifiedSpans, IEnumerable<SharpIdeRazorClassifiedSpan> razorClassifiedSpans)
{ {
_syntaxHighlighter.SetHighlightingData(classifiedSpans, razorClassifiedSpans); _syntaxHighlighter.SetHighlightingData(classifiedSpans, razorClassifiedSpans);
//_syntaxHighlighter.ClearHighlightingCache(); //_syntaxHighlighter.ClearHighlightingCache();