Reload projects when analyzer dlls change

This commit is contained in:
Matt Parker
2025-11-28 22:26:39 +10:00
parent f4b1e9c1c0
commit e75d1319ef
7 changed files with 113 additions and 5 deletions

View File

@@ -0,0 +1,55 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
using FileWatcherEx;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Threading;
using SharpIDE.Application.Features.Events;
namespace SharpIDE.Application.Features.FileWatching;
public class AnalyzerFileWatcher
{
private readonly AsyncBatchingWorkQueue<string> _fileChangedQueue;
public AnalyzerFileWatcher()
{
_fileChangedQueue = new AsyncBatchingWorkQueue<string>(
TimeSpan.FromMilliseconds(500),
async (filePaths, ct) => await GlobalEvents.Instance.AnalyzerDllsChanged.InvokeParallelAsync(filePaths.ToImmutableArray()),
new AsynchronousOperationListenerProvider.NullOperationListener(),
CancellationToken.None);
}
private readonly ConcurrentDictionary<string, FileSystemWatcherEx> _fileWatchers = new();
// I wanted to avoid this, but unfortunately we have to watch individual files in different directories
public async Task StartWatchingFiles(ImmutableArray<string> filePaths)
{
// This can definitely be optimized to not recreate watchers unnecessarily
var existingFileWatchers = _fileWatchers.Values.ToList();
foreach (var watcher in existingFileWatchers)
{
watcher.OnChanged -= OnFileChanged;
watcher.Dispose();
}
_fileWatchers.Clear();
foreach (var filePath in filePaths)
{
var fileWatcher = new FileSystemWatcherEx(Path.GetDirectoryName(filePath)!)
{
Filter = Path.GetFileName(filePath),
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size
};
fileWatcher.OnChanged += OnFileChanged;
fileWatcher.Start();
_fileWatchers.TryAdd(filePath, fileWatcher);
}
}
private void OnFileChanged(object? sender, FileChangedEvent e)
{
_fileChangedQueue.AddWork(e.FullPath);
}
}