apply code fixes

This commit is contained in:
Matt Parker
2025-08-18 20:04:08 +10:00
parent 28a6e95d2b
commit d54e037cf9
2 changed files with 58 additions and 6 deletions

View File

@@ -19,7 +19,7 @@ namespace SharpIDE.Application.Features.Analysis;
public static class RoslynAnalysis public static class RoslynAnalysis
{ {
private static MSBuildWorkspace? _workspace; public static MSBuildWorkspace? _workspace;
private static HashSet<CodeFixProvider> _codeFixProviders = []; private static HashSet<CodeFixProvider> _codeFixProviders = [];
private static HashSet<CodeRefactoringProvider> _codeRefactoringProviders = []; private static HashSet<CodeRefactoringProvider> _codeRefactoringProviders = [];
private static TaskCompletionSource _solutionLoadedTcs = new(); private static TaskCompletionSource _solutionLoadedTcs = new();
@@ -269,4 +269,23 @@ public static class RoslynAnalysis
// } // }
return completions; return completions;
} }
public static async Task ApplyCodeActionAsync(CodeAction codeAction)
{
var cancellationToken = CancellationToken.None;
var operations = await codeAction.GetOperationsAsync(cancellationToken);
foreach (var operation in operations)
{
operation.Apply(_workspace!, cancellationToken);
// if (operation is ApplyChangesOperation applyChangesOperation)
// {
// var newSolution = applyChangesOperation.ChangedSolution;
// _workspace.TryApplyChanges(newSolution);
// }
// else
// {
// throw new NotSupportedException($"Unsupported operation type: {operation.GetType().Name}");
// }
}
}
} }

View File

@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using Godot; using Godot;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using SharpIDE.Application.Features.Analysis; using SharpIDE.Application.Features.Analysis;
using SharpIDE.Application.Features.SolutionDiscovery; using SharpIDE.Application.Features.SolutionDiscovery;
@@ -28,14 +30,12 @@ public partial class SharpIdeCodeEdit : CodeEdit
private PopupMenu _popupMenu = null!; private PopupMenu _popupMenu = null!;
private ImmutableArray<(FileLinePositionSpan fileSpan, Diagnostic diagnostic)> _diagnostics = []; private ImmutableArray<(FileLinePositionSpan fileSpan, Diagnostic diagnostic)> _diagnostics = [];
private ImmutableArray<CodeAction> _currentCodeActionsInPopup = [];
public override void _Ready() public override void _Ready()
{ {
_popupMenu = GetNode<PopupMenu>("CodeFixesMenu"); _popupMenu = GetNode<PopupMenu>("CodeFixesMenu");
_popupMenu.IdPressed += (id) => _popupMenu.IdPressed += OnCodeFixSelected;
{
GD.Print($"Code fix selected: {id}");
};
this.CodeCompletionRequested += OnCodeCompletionRequested; this.CodeCompletionRequested += OnCodeCompletionRequested;
this.CodeFixesRequested += OnCodeFixesRequested; this.CodeFixesRequested += OnCodeFixesRequested;
this.CaretChanged += () => this.CaretChanged += () =>
@@ -48,6 +48,38 @@ public partial class SharpIdeCodeEdit : CodeEdit
this.SyntaxHighlighter = _syntaxHighlighter; this.SyntaxHighlighter = _syntaxHighlighter;
} }
private void OnCodeFixSelected(long id)
{
GD.Print($"Code fix selected: {id}");
var codeAction = _currentCodeActionsInPopup[(int)id];
if (codeAction is null) return;
var currentCaretPosition = GetCaretPosition();
var vScroll = GetVScroll();
_ = Task.Run(async () =>
{
try
{
await RoslynAnalysis.ApplyCodeActionAsync(codeAction);
var fileContents = await File.ReadAllTextAsync(_currentFile.Path);
var syntaxHighlighting = await RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
var diagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
Callable.From(() =>
{
SetText(fileContents);
SetSyntaxHighlightingModel(syntaxHighlighting);
SetDiagnosticsModel(diagnostics);
SetCaretLine(currentCaretPosition.line);
SetCaretColumn(currentCaretPosition.col);
SetVScroll(vScroll);
}).CallDeferred();
}
catch (Exception ex)
{
GD.PrintErr($"Error applying code fix: {ex.Message}");
}
});
}
public async Task SetSharpIdeFile(SharpIdeFile file) public async Task SetSharpIdeFile(SharpIdeFile file)
{ {
_currentFile = file; _currentFile = file;
@@ -159,6 +191,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
_popupMenu.Clear(); _popupMenu.Clear();
foreach (var (index, codeAction) in codeActions.Index()) foreach (var (index, codeAction) in codeActions.Index())
{ {
_currentCodeActionsInPopup = codeActions;
_popupMenu.AddItem(codeAction.Title, index); _popupMenu.AddItem(codeAction.Title, index);
//_popupMenu.SetItemMetadata(menuItem, codeAction); //_popupMenu.SetItemMetadata(menuItem, codeAction);
} }
@@ -203,7 +236,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
}); });
} }
private (int, int) GetCaretPosition() private (int line, int col) GetCaretPosition()
{ {
var caretColumn = GetCaretColumn(); var caretColumn = GetCaretColumn();
var caretLine = GetCaretLine(); var caretLine = GetCaretLine();