Maintain document text when updating documents that have the same file path

This commit is contained in:
David Wengier 2024-05-09 16:29:25 +10:00
Родитель 2e6e65fd8a
Коммит f4d78d115c
2 изменённых файлов: 39 добавлений и 2 удалений

Просмотреть файл

@ -391,10 +391,15 @@ internal class RazorProjectService(
_logger.LogTrace($"Updating document '{newHostDocument.FilePath}''s file kind to '{newHostDocument.FileKind}' and target path to '{newHostDocument.TargetPath}'.");
var remoteTextLoader = _remoteTextLoaderFactory.Create(newFilePath);
// If the physical file name hasn't changed, we use the current document snapshot as the source of truth for text, in case
// it has received text change info from LSP. eg, if someone changes the TargetPath of the file while its open in the editor
// with unsaved changes, we don't want to reload it from disk.
var textLoader = FilePathComparer.Instance.Equals(currentHostDocument.FilePath, newHostDocument.FilePath)
? new DocumentSnapshotTextLoader(documentSnapshot)
: _remoteTextLoaderFactory.Create(newFilePath);
updater.DocumentRemoved(currentProjectKey, currentHostDocument);
updater.DocumentAdded(currentProjectKey, newHostDocument, remoteTextLoader);
updater.DocumentAdded(currentProjectKey, newHostDocument, textLoader);
}
project = _projectManager.GetLoadedProject(project.Key);

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the MIT license. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -1138,6 +1139,37 @@ public class RazorProjectServiceTest(ITestOutputHelper testOutput) : LanguageSer
}
private static TextLoader CreateEmptyTextLoader()
[Fact]
public async Task AddProject_MigratesMiscellaneousDocumentsToNewOwnerProject_FixesTargetPath()
{
// Arrange
const string ProjectFilePath = "C:/path/to/project.csproj";
const string IntermediateOutputPath = "C:/path/to/obj";
const string DocumentFilePath1 = "C:/path/to/document1.cshtml";
const string DocumentFilePath2 = "C:/path/to/document2.cshtml";
var miscProject = _snapshotResolver.GetMiscellaneousProject();
await _projectManager.UpdateAsync(updater =>
{
updater.DocumentAdded(miscProject.Key,
new HostDocument(DocumentFilePath1, "C:/path/to/document1.cshtml"), CreateEmptyTextLoader());
updater.DocumentAdded(miscProject.Key,
new HostDocument(DocumentFilePath2, "C:/path/to/document2.cshtml"), CreateEmptyTextLoader());
});
using var listener = _projectManager.ListenToNotifications();
// Act
var newProjectKey = await _projectService.AddProjectAsync(
ProjectFilePath, IntermediateOutputPath, RazorConfiguration.Default, rootNamespace: null, displayName: null, DisposalToken);
// Assert
var newProject = _projectManager.GetLoadedProject(newProjectKey);
Assert.Equal("document1.cshtml", newProject.GetDocument(DocumentFilePath1)!.TargetPath);
Assert.Equal("document2.cshtml", newProject.GetDocument(DocumentFilePath2)!.TargetPath);
}
{
var textLoaderMock = new StrictMock<TextLoader>();
textLoaderMock