update project diagnostics in file on sln alteration
This commit is contained in:
@@ -15,13 +15,10 @@ using Microsoft.CodeAnalysis.MSBuild;
|
|||||||
using Microsoft.CodeAnalysis.Razor.SemanticTokens;
|
using Microsoft.CodeAnalysis.Razor.SemanticTokens;
|
||||||
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||||
using Microsoft.CodeAnalysis.Remote.Razor.SemanticTokens;
|
using Microsoft.CodeAnalysis.Remote.Razor.SemanticTokens;
|
||||||
using Microsoft.CodeAnalysis.Shared.Extensions;
|
|
||||||
using Microsoft.CodeAnalysis.Shared.Utilities;
|
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using SharpIDE.Application.Features.Analysis.FixLoaders;
|
using SharpIDE.Application.Features.Analysis.FixLoaders;
|
||||||
using SharpIDE.Application.Features.Analysis.Razor;
|
using SharpIDE.Application.Features.Analysis.Razor;
|
||||||
using SharpIDE.Application.Features.Build;
|
using SharpIDE.Application.Features.Build;
|
||||||
using SharpIDE.Application.Features.Events;
|
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||||
using SharpIDE.RazorAccess;
|
using SharpIDE.RazorAccess;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ public class GlobalEvents
|
|||||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStoppedRunning { get; } = new(_ => Task.CompletedTask);
|
public EventWrapper<SharpIdeProjectModel, Task> ProjectStoppedRunning { get; } = new(_ => Task.CompletedTask);
|
||||||
public EventWrapper<ExecutionStopInfo, Task> DebuggerExecutionStopped { get; } = new(_ => Task.CompletedTask);
|
public EventWrapper<ExecutionStopInfo, Task> DebuggerExecutionStopped { get; } = new(_ => Task.CompletedTask);
|
||||||
public EventWrapper<SharpIdeFile, Task> IdeFileSavedToDisk { get; } = new(_ => Task.CompletedTask);
|
public EventWrapper<SharpIdeFile, Task> IdeFileSavedToDisk { get; } = new(_ => Task.CompletedTask);
|
||||||
|
/// A document changed, project was reloaded etc. Document changes include unsaved changes in the IDE.
|
||||||
|
public EventWrapper<Task> SolutionAltered { get; } = new(() => Task.CompletedTask);
|
||||||
|
|
||||||
public FileSystemWatcherInternal FileSystemWatcherInternal { get; } = new();
|
public FileSystemWatcherInternal FileSystemWatcherInternal { get; } = new();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace SharpIDE.Application.Features.FilePersistence;
|
|||||||
#pragma warning disable VSTHRD011
|
#pragma warning disable VSTHRD011
|
||||||
|
|
||||||
/// Holds the in memory copies of files, and manages saving/loading them to/from disk.
|
/// Holds the in memory copies of files, and manages saving/loading them to/from disk.
|
||||||
public class IdeFileManager
|
public class IdeOpenTabsFileManager
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<SharpIdeFile, Lazy<Task<string>>> _openFiles = new();
|
private ConcurrentDictionary<SharpIdeFile, Lazy<Task<string>>> _openFiles = new();
|
||||||
|
|
||||||
@@ -35,6 +35,7 @@ public class IdeFileManager
|
|||||||
if (file.IsRoslynWorkspaceFile)
|
if (file.IsRoslynWorkspaceFile)
|
||||||
{
|
{
|
||||||
await RoslynAnalysis.UpdateDocument(file, newText);
|
await RoslynAnalysis.UpdateDocument(file, newText);
|
||||||
|
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ public class IdeFileManager
|
|||||||
{
|
{
|
||||||
var text = await textTask;
|
var text = await textTask;
|
||||||
await RoslynAnalysis.UpdateDocument(file, text);
|
await RoslynAnalysis.UpdateDocument(file, text);
|
||||||
|
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +53,15 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
SymbolValidate += OnSymbolValidate;
|
SymbolValidate += OnSymbolValidate;
|
||||||
SymbolLookup += OnSymbolLookup;
|
SymbolLookup += OnSymbolLookup;
|
||||||
LinesEditedFrom += OnLinesEditedFrom;
|
LinesEditedFrom += OnLinesEditedFrom;
|
||||||
|
GlobalEvents.Instance.SolutionAltered.Subscribe(OnSolutionAltered);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnSolutionAltered()
|
||||||
|
{
|
||||||
|
if (_currentFile is null) return;
|
||||||
|
GD.Print("Solution altered, updating project diagnostics for current file");
|
||||||
|
var projectDiagnostics = await RoslynAnalysis.GetProjectDiagnosticsForFile(_currentFile);
|
||||||
|
await this.InvokeAsync(() => SetProjectDiagnostics(projectDiagnostics));
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LineEditOrigin
|
public enum LineEditOrigin
|
||||||
@@ -254,7 +263,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
_ = Task.GodotRun(async () =>
|
_ = Task.GodotRun(async () =>
|
||||||
{
|
{
|
||||||
_currentFile.IsDirty.Value = true;
|
_currentFile.IsDirty.Value = true;
|
||||||
await Singletons.FileManager.UpdateFileTextInMemory(_currentFile, Text);
|
await Singletons.OpenTabsFileManager.UpdateFileTextInMemory(_currentFile, Text);
|
||||||
await _textChangedCts.CancelAsync(); // Currently the below methods throw, TODO Fix with suppress throwing, and handle
|
await _textChangedCts.CancelAsync(); // Currently the below methods throw, TODO Fix with suppress throwing, and handle
|
||||||
_textChangedCts.Dispose();
|
_textChangedCts.Dispose();
|
||||||
_textChangedCts = new CancellationTokenSource();
|
_textChangedCts = new CancellationTokenSource();
|
||||||
@@ -271,11 +280,6 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
var documentDiagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile, _textChangedCts.Token);
|
var documentDiagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile, _textChangedCts.Token);
|
||||||
await this.InvokeAsync(() => SetDiagnostics(documentDiagnostics));
|
await this.InvokeAsync(() => SetDiagnostics(documentDiagnostics));
|
||||||
});
|
});
|
||||||
_ = Task.GodotRun(async () =>
|
|
||||||
{
|
|
||||||
var projectDiagnosticsForFile = await RoslynAnalysis.GetProjectDiagnosticsForFile(_currentFile);
|
|
||||||
await this.InvokeAsync(() => SetProjectDiagnostics(projectDiagnosticsForFile));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +296,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
// TODO: This can be more efficient - we can just update in memory and proceed with highlighting etc. Save to disk in background.
|
// TODO: This can be more efficient - we can just update in memory and proceed with highlighting etc. Save to disk in background.
|
||||||
foreach (var (affectedFile, updatedText) in affectedFiles)
|
foreach (var (affectedFile, updatedText) in affectedFiles)
|
||||||
{
|
{
|
||||||
await Singletons.FileManager.UpdateInMemoryIfOpenAndSaveAsync(affectedFile, updatedText);
|
await Singletons.OpenTabsFileManager.UpdateInMemoryIfOpenAndSaveAsync(affectedFile, updatedText);
|
||||||
affectedFile.FileContentsChangedExternally.InvokeParallelFireAndForget();
|
affectedFile.FileContentsChangedExternally.InvokeParallelFireAndForget();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -300,7 +304,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
|
|
||||||
private async Task OnFileChangedExternallyInMemory()
|
private async Task OnFileChangedExternallyInMemory()
|
||||||
{
|
{
|
||||||
var fileContents = await Singletons.FileManager.GetFileTextAsync(_currentFile);
|
var fileContents = await Singletons.OpenTabsFileManager.GetFileTextAsync(_currentFile);
|
||||||
var syntaxHighlighting = RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
|
var syntaxHighlighting = RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
|
||||||
var razorSyntaxHighlighting = RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
|
var razorSyntaxHighlighting = RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
|
||||||
var diagnostics = RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
|
var diagnostics = RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
|
||||||
@@ -337,7 +341,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
{
|
{
|
||||||
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); // get off the UI thread
|
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); // get off the UI thread
|
||||||
_currentFile = file;
|
_currentFile = file;
|
||||||
var readFileTask = Singletons.FileManager.GetFileTextAsync(file);
|
var readFileTask = Singletons.OpenTabsFileManager.GetFileTextAsync(file);
|
||||||
_currentFile.FileContentsChangedExternally.Subscribe(OnFileChangedExternallyInMemory);
|
_currentFile.FileContentsChangedExternally.Subscribe(OnFileChangedExternallyInMemory);
|
||||||
_currentFile.FileContentsChangedExternallyFromDisk.Subscribe(OnFileChangedExternallyFromDisk);
|
_currentFile.FileContentsChangedExternallyFromDisk.Subscribe(OnFileChangedExternallyFromDisk);
|
||||||
|
|
||||||
@@ -361,7 +365,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
|
|
||||||
private async Task OnFileChangedExternallyFromDisk()
|
private async Task OnFileChangedExternallyFromDisk()
|
||||||
{
|
{
|
||||||
await Singletons.FileManager.ReloadFileFromDisk(_currentFile);
|
await Singletons.OpenTabsFileManager.ReloadFileFromDisk(_currentFile);
|
||||||
await OnFileChangedExternallyInMemory();
|
await OnFileChangedExternallyInMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,14 +432,14 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
{
|
{
|
||||||
_ = Task.GodotRun(async () =>
|
_ = Task.GodotRun(async () =>
|
||||||
{
|
{
|
||||||
await Singletons.FileManager.SaveAllOpenFilesAsync();
|
await Singletons.OpenTabsFileManager.SaveAllOpenFilesAsync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (@event.IsActionPressed(InputStringNames.SaveFile))
|
else if (@event.IsActionPressed(InputStringNames.SaveFile))
|
||||||
{
|
{
|
||||||
_ = Task.GodotRun(async () =>
|
_ = Task.GodotRun(async () =>
|
||||||
{
|
{
|
||||||
await Singletons.FileManager.SaveFileAsync(_currentFile);
|
await Singletons.OpenTabsFileManager.SaveFileAsync(_currentFile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -467,7 +471,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
[RequiresGodotUiThread]
|
[RequiresGodotUiThread]
|
||||||
private void SetProjectDiagnostics(ImmutableArray<SharpIdeDiagnostic> diagnostics)
|
private void SetProjectDiagnostics(ImmutableArray<SharpIdeDiagnostic> diagnostics)
|
||||||
{
|
{
|
||||||
_fileDiagnostics = diagnostics;
|
_projectDiagnosticsForFile = diagnostics;
|
||||||
QueueRedraw();
|
QueueRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public partial class IdeRoot : Control
|
|||||||
Singletons.BuildService = BuildService.Instance;
|
Singletons.BuildService = BuildService.Instance;
|
||||||
Singletons.FileWatcher?.Dispose();
|
Singletons.FileWatcher?.Dispose();
|
||||||
Singletons.FileWatcher = new IdeFileWatcher();
|
Singletons.FileWatcher = new IdeFileWatcher();
|
||||||
Singletons.FileManager = new IdeFileManager();
|
Singletons.OpenTabsFileManager = new IdeOpenTabsFileManager();
|
||||||
Singletons.FileExternalChangeHandler = new IdeFileExternalChangeHandler();
|
Singletons.FileExternalChangeHandler = new IdeFileExternalChangeHandler();
|
||||||
Singletons.FileSavedToDiskHandler = new IdeFileSavedToDiskHandler();
|
Singletons.FileSavedToDiskHandler = new IdeFileSavedToDiskHandler();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public partial class IdeWindow : Control
|
|||||||
|
|
||||||
private void OnFocusExited()
|
private void OnFocusExited()
|
||||||
{
|
{
|
||||||
_ = Task.GodotRun(async () => await Singletons.FileManager.SaveAllOpenFilesAsync());
|
_ = Task.GodotRun(async () => await Singletons.OpenTabsFileManager.SaveAllOpenFilesAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PickSolution(bool fullscreen = false)
|
public void PickSolution(bool fullscreen = false)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public static class Singletons
|
|||||||
public static RunService RunService { get; set; } = null!;
|
public static RunService RunService { get; set; } = null!;
|
||||||
public static BuildService BuildService { get; set; } = null!;
|
public static BuildService BuildService { get; set; } = null!;
|
||||||
public static IdeFileWatcher FileWatcher { get; set; } = null!;
|
public static IdeFileWatcher FileWatcher { get; set; } = null!;
|
||||||
public static IdeFileManager FileManager { get; set; } = null!;
|
public static IdeOpenTabsFileManager OpenTabsFileManager { get; set; } = null!;
|
||||||
public static IdeFileExternalChangeHandler FileExternalChangeHandler { get; set; } = null!;
|
public static IdeFileExternalChangeHandler FileExternalChangeHandler { get; set; } = null!;
|
||||||
public static IdeFileSavedToDiskHandler FileSavedToDiskHandler { get; set; } = null!;
|
public static IdeFileSavedToDiskHandler FileSavedToDiskHandler { get; set; } = null!;
|
||||||
public static AppState AppState { get; set; } = null!;
|
public static AppState AppState { get; set; } = null!;
|
||||||
|
|||||||
Reference in New Issue
Block a user