diff --git a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs index f5928559c4d59..887e53d8856d7 100644 --- a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs +++ b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs @@ -13,6 +13,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeRefactorings.MoveType; using Microsoft.CodeAnalysis.Contracts.EditAndContinue; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; @@ -4251,6 +4252,90 @@ static void F() EndDebuggingSession(debuggingSession); } + /// + /// Scenario: + /// - F5 + /// - edit source and apply code fix to move type to file XYZ.cs + /// - continue execution + /// + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72984")] + public async Task EditAndContinueAfterApplyingMoveTypeToFileCodeFix() + { + const string movedType = "AnotherClass"; + + const string source = $$""" + class {{movedType}} + { + public const bool True = true; + } + + class Test + { + static bool B() => {{movedType}}.True; + static void G() { while (B()); } + + static void F() + { + G(); + } + } + """; + + const string modifiedSource = $$""" + class Test + { + static bool A() => {{movedType}}.True; + static bool B() => A(); + static void G() { while (B()); } + + static void F() + { + H(); + } + + static void H() + { + G(); + } + } + """; + + var moduleId = EmitAndLoadLibraryToDebuggee(source); + + using var workspace = CreateWorkspace(out var solution, out var service); + (solution, var document) = AddDefaultTestProject(solution, source); + var documentId = document.Id; + var oldProject = document.Project; + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + // Apply code fix: Move type to AnotherClass.cs + + var moveTypeService = document.GetLanguageService(); + var root = await document.GetSyntaxRootAsync(); + var span = root.DescendantTokens() + .Where(s => s.Text is movedType) + .FirstOrDefault() + .Span; + var modifiedSolution = await moveTypeService.GetModifiedSolutionAsync(document, span, MoveTypeOperationKind.MoveType, cancellationToken: default); + + // Apply edit on remaining document: source after code fix -> modifiedSource + + modifiedSolution = modifiedSolution.WithDocumentText(document.Id, CreateText(modifiedSource)); + + var newProject = modifiedSolution.GetProject(oldProject.Id); + Assert.Equal(1, oldProject.DocumentIds.Count); + Assert.Equal(2, newProject.DocumentIds.Count); + + var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, modifiedSolution); + Assert.Empty(emitDiagnostics); + Assert.False(updates.Updates.IsEmpty); + Assert.Equal(ModuleUpdateStatus.Ready, updates.Status); + + CommitSolutionUpdate(debuggingSession); + EndDebuggingSession(debuggingSession); + } + [Fact] public async Task MultiSession() { diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpWinForms.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpWinForms.cs index 3675c407613eb..482daa543441f 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpWinForms.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpWinForms.cs @@ -94,7 +94,7 @@ public async Task AddClickHandler() Assert.Contains(@"this.SomeButton.Click += new System.EventHandler(this.ExecuteWhenButtonClicked);", designerActualText); await TestServices.SolutionExplorer.OpenFileAsync(project, "Form1.cs", HangMitigatingCancellationToken); var codeFileActualText = await TestServices.Editor.GetTextAsync(HangMitigatingCancellationToken); - Assert.Contains(@" public partial class Form1 : Form + Assert.Contains(@" public partial class Form1: Form { public Form1() { diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs index 8579fba2f1ba8..07baa5aaf65f9 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs @@ -495,23 +495,8 @@ internal DocumentState UpdateTree(SyntaxNode newRoot, PreservationMode mode) var newTextVersion = GetNewerVersion(); var newTreeVersion = GetNewTreeVersionForUpdatedTree(newRoot, newTextVersion, mode); - // determine encoding - Encoding? encoding; - - if (TryGetSyntaxTree(out var priorTree)) - { - // this is most likely available since UpdateTree is normally called after modifying the existing tree. - encoding = priorTree.Encoding; - } - else if (TryGetText(out var priorText)) - { - encoding = priorText.Encoding; - } - else - { - // the existing encoding was never observed so is unknown. - encoding = null; - } + // use the encoding that we get from the new root + var encoding = newRoot.SyntaxTree.Encoding; var syntaxTreeFactory = LanguageServices.GetRequiredService(); diff --git a/src/Workspaces/MSBuildTest/VisualStudioMSBuildWorkspaceTests.cs b/src/Workspaces/MSBuildTest/VisualStudioMSBuildWorkspaceTests.cs index 8ff00ac110e18..6d853aee9d3c3 100644 --- a/src/Workspaces/MSBuildTest/VisualStudioMSBuildWorkspaceTests.cs +++ b/src/Workspaces/MSBuildTest/VisualStudioMSBuildWorkspaceTests.cs @@ -2893,14 +2893,13 @@ class C { }"; Assert.Equal(encoding.EncodingName, text.Encoding.EncodingName); Assert.Equal(fileContent, text.ToString()); - // update root blindly again, after observing encoding, see that now encoding is known + // update root blindly again, after observing encoding, see that encoding is overridden to null var doc3 = document.WithSyntaxRoot(gen.CompilationUnit()); // empty CU var doc3text = await doc3.GetTextAsync(); - Assert.NotNull(doc3text.Encoding); - Assert.Equal(encoding.EncodingName, doc3text.Encoding.EncodingName); + Assert.Null(doc3text.Encoding); var doc3tree = await doc3.GetSyntaxTreeAsync(); - Assert.Equal(doc3text.Encoding, doc3tree.GetText().Encoding); - Assert.Equal(doc3text.Encoding, doc3tree.Encoding); + Assert.Null(doc3tree.Encoding); + Assert.Null(doc3tree.GetText().Encoding); // change doc to have no encoding, still succeeds at writing to disk with old encoding var root = await document.GetSyntaxRootAsync();