add add file v1
This commit is contained in:
@@ -739,4 +739,25 @@ public class RoslynAnalysis
|
|||||||
|
|
||||||
_workspace.TryApplyChanges(newSolution);
|
_workspace.TryApplyChanges(newSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task AddDocument(SharpIdeFile fileModel, string content)
|
||||||
|
{
|
||||||
|
using var _ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(AddDocument)}");
|
||||||
|
await _solutionLoadedTcs.Task;
|
||||||
|
Guard.Against.Null(fileModel, nameof(fileModel));
|
||||||
|
Guard.Against.NullOrEmpty(content, nameof(content));
|
||||||
|
|
||||||
|
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath);
|
||||||
|
|
||||||
|
var sourceText = SourceText.From(content, Encoding.UTF8);
|
||||||
|
|
||||||
|
var newSolution = fileModel switch
|
||||||
|
{
|
||||||
|
{ IsRazorFile: true } => _workspace.CurrentSolution.AddAdditionalDocument(DocumentId.CreateNewId(project.Id), fileModel.Name, sourceText, filePath: fileModel.Path),
|
||||||
|
{ IsCsharpFile: true } => _workspace.CurrentSolution.AddDocument(DocumentId.CreateNewId(project.Id), fileModel.Name, sourceText, filePath: fileModel.Path),
|
||||||
|
_ => throw new InvalidOperationException("AddDocument failed: File is not in workspace")
|
||||||
|
};
|
||||||
|
|
||||||
|
_workspace.TryApplyChanges(newSolution);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ public class FileChangedService(RoslynAnalysis roslynAnalysis, IdeOpenTabsFileMa
|
|||||||
|
|
||||||
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
|
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
|
||||||
|
|
||||||
|
public async Task SharpIdeFileAdded(SharpIdeFile file, string content)
|
||||||
|
{
|
||||||
|
if (file.IsRoslynWorkspaceFile)
|
||||||
|
{
|
||||||
|
await HandleWorkspaceFileAdded(file, content);
|
||||||
|
}
|
||||||
|
// TODO: handle csproj added
|
||||||
|
}
|
||||||
|
|
||||||
// All file changes should go via this service
|
// All file changes should go via this service
|
||||||
public async Task SharpIdeFileChanged(SharpIdeFile file, string newContents, FileChangeType changeType)
|
public async Task SharpIdeFileChanged(SharpIdeFile file, string newContents, FileChangeType changeType)
|
||||||
{
|
{
|
||||||
@@ -86,4 +95,15 @@ public class FileChangedService(RoslynAnalysis roslynAnalysis, IdeOpenTabsFileMa
|
|||||||
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
|
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
|
||||||
await _roslynAnalysis.UpdateSolutionDiagnostics(newCts.Token);
|
await _roslynAnalysis.UpdateSolutionDiagnostics(newCts.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleWorkspaceFileAdded(SharpIdeFile file, string contents)
|
||||||
|
{
|
||||||
|
var newCts = new CancellationTokenSource();
|
||||||
|
var oldCts = Interlocked.Exchange(ref _updateSolutionDiagnosticsCts, newCts);
|
||||||
|
await oldCts.CancelAsync();
|
||||||
|
oldCts.Dispose();
|
||||||
|
await _roslynAnalysis.AddDocument(file, contents);
|
||||||
|
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
|
||||||
|
await _roslynAnalysis.UpdateSolutionDiagnostics(newCts.Token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using SharpIDE.Application.Features.Events;
|
using Ardalis.GuardClauses;
|
||||||
|
using SharpIDE.Application.Features.Events;
|
||||||
|
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||||
|
|
||||||
namespace SharpIDE.Application.Features.FileWatching;
|
namespace SharpIDE.Application.Features.FileWatching;
|
||||||
@@ -11,6 +13,20 @@ public class IdeFileExternalChangeHandler
|
|||||||
{
|
{
|
||||||
_fileChangedService = fileChangedService;
|
_fileChangedService = fileChangedService;
|
||||||
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.Subscribe(OnFileChanged);
|
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.Subscribe(OnFileChanged);
|
||||||
|
GlobalEvents.Instance.FileSystemWatcherInternal.FileCreated.Subscribe(OnFileCreated);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnFileCreated(string filePath)
|
||||||
|
{
|
||||||
|
// Create a new sharpIdeFile, update SolutionModel
|
||||||
|
var sharpIdeFile = SolutionModel.AllFiles.SingleOrDefault(f => f.Path == filePath);
|
||||||
|
if (sharpIdeFile == null)
|
||||||
|
{
|
||||||
|
// If sharpIdeFile is null, it means the file was created externally, and we need to create it and add it to the solution model
|
||||||
|
// sharpIdeFile = TODO;
|
||||||
|
}
|
||||||
|
Guard.Against.Null(sharpIdeFile, nameof(sharpIdeFile));
|
||||||
|
await _fileChangedService.SharpIdeFileAdded(sharpIdeFile, await File.ReadAllTextAsync(filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnFileChanged(string filePath)
|
private async Task OnFileChanged(string filePath)
|
||||||
|
|||||||
Reference in New Issue
Block a user