From 014ddf253430939ab9f8fe952555a16eaf088522 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 04:14:40 +0000 Subject: [PATCH 01/10] Initial plan From 8b34a3ec79ba860e0f229f54e11f72741a67ac6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 04:40:33 +0000 Subject: [PATCH 02/10] Add RemoveUnusedMembers to supported C# code actions for unused variables and parameters Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../CSharp/CSharpCodeActionProvider.cs | 1 + .../CodeActions/CSharpCodeActionTests.cs | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs index 3d14d8d3502..de2162aad5b 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs @@ -40,6 +40,7 @@ internal class CSharpCodeActionProvider(LanguageServerFeatureOptions languageSer RazorPredefinedCodeFixProviderNames.ImplementAbstractClass, RazorPredefinedCodeFixProviderNames.ImplementInterface, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable, + RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers, ]; // We don't support any code actions in implicit expressions at the moment, but rather than simply returning early diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs index c8b120513dd..b8a3655d521 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs @@ -372,4 +372,107 @@ private string GetDebuggerDisplay() await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeRefactoringProviderNames.AddDebuggerDisplay); } + + [Fact] + public async Task RemoveUnusedVariable_Local() + { + var input = """ + @code + { + void M() + { + int {|IDE0059:[||]x|} = 5; + } + } + """; + + var expected = """ + @code + { + void M() + { + } + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); + } + + [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] + public async Task RemoveUnusedVariable_Parameter() + { + var input = """ + @code + { + void M(int {|IDE0060:[||]unusedParameter|}) + { + } + } + """; + + var expected = """ + @code + { + void M() + { + } + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); + } + + [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] + public async Task RemoveUnusedVariable_PrivateField() + { + var input = """ + @code + { + private int {|IDE0051:[||]_field|}; + + void M() + { + } + } + """; + + var expected = """ + @code + { + void M() + { + } + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); + } + + [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] + public async Task RemoveUnusedVariable_PrivateMethod() + { + var input = """ + @code + { + private void {|IDE0051:[||]UnusedMethod|}() + { + } + + void M() + { + } + } + """; + + var expected = """ + @code + { + void M() + { + } + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); + } } From e24701638d9bf66dbbb170a1ecd26b4442fba66d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 05:38:20 +0000 Subject: [PATCH 03/10] Add tests for RemoveUnusedVariable in explicit statement blocks Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../CodeActions/CSharpCodeActionTests.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs index b8a3655d521..f4407d00bc1 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs @@ -398,6 +398,41 @@ void M() await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); } + [Fact] + public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine() + { + var input = """ + @{ var {|IDE0059:[||]x|} = 1; var y = 2; } + """; + + var expected = """ + @{ + var y = 2; + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); + } + + [Fact] + public async Task RemoveUnusedVariable_ExplicitStatement_MultiLine() + { + var input = """ + @{ + var {|IDE0059:[||]x|} = 1; + var y = 2; + } + """; + + var expected = """ + @{ + var y = 2; + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); + } + [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] public async Task RemoveUnusedVariable_Parameter() { From 57c674da08c46c56c73d7811b0e6d0dccc740f2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 05:47:23 +0000 Subject: [PATCH 04/10] Add test for single unused variable in single-line explicit statement Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../Shared/CodeActions/CSharpCodeActionTests.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs index f4407d00bc1..bcde7576f48 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs @@ -414,6 +414,21 @@ public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine() await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); } + [Fact(Skip = "RemoveUnusedVariable code action is not triggered when the only statement in a single-line explicit block is unused")] + public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine_OnlyVariable() + { + var input = """ + @{ var {|IDE0059:[||]message|} = "Hello World"; } + """; + + var expected = """ + @{ + } + """; + + await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); + } + [Fact] public async Task RemoveUnusedVariable_ExplicitStatement_MultiLine() { From a58c2922b04fcda4d1870dd5a95c2e3fe7a6175a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 07:05:46 +0000 Subject: [PATCH 05/10] Fix edit mapping for single-line explicit statements with only one unused variable Added handling in GetRazorDocumentEdits for the case where the start position maps successfully but the end position doesn't when an edit spans multiple lines. This is the opposite of the existing logic that handles when the end maps but not the start. The fix enables the RemoveUnusedVariable code action to work for single-line explicit statements like @{ var message = "Hello World"; }. Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../AbstractDocumentMappingService.cs | 32 +++++++++++++++++++ .../CodeActions/CSharpCodeActionTests.cs | 5 ++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs index 9db05857c2d..44d28e51c1c 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs @@ -94,6 +94,38 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD } } + // The opposite case of the above: for the last line of a code block, the C# formatter might + // return an edit that starts within our mapping, but ends after. In those cases, when the edit + // spans multiple lines we just take the first line and try to use that. + // + // This can happen with code actions that remove content, where the edit starts inside the mapped + // region but extends beyond it. For example, when removing an unused variable in a single-line + // explicit statement block like `@{ var x = 1; }`, Roslyn may generate edits that span beyond + // the mapped C# region. + if (mappedStart && !mappedEnd && startLine != endLine) + { + // Construct a theoretical edit that is just for the first line of the edit that the C# formatter + // gave us, and see if we can map that. + var firstNewLine = change.NewText.AssumeNotNull().IndexOfAny(['\n', '\r']); + + // Get the end of the start line + var endSync = csharpSourceText.TryGetAbsoluteIndex((startLine, csharpSourceText.Lines[startLine].Span.Length), out var endIndex); + if (endSync is false) + { + break; + } + + mappedEnd = this.TryMapToRazorDocumentPosition(csharpDocument, endIndex, out _, out hostEndIndex); + + if (mappedStart && mappedEnd) + { + // If there's a newline in the new text, only take the part before it + var newText = firstNewLine >= 0 ? change.NewText[..firstNewLine] : change.NewText; + yield return new TextChange(TextSpan.FromBounds(hostStartIndex, hostEndIndex), newText); + continue; + } + } + // If we couldn't map either the start or the end then we still might want to do something tricky. // When we have a block like this: // diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs index bcde7576f48..9d8f61e94e7 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs @@ -414,7 +414,7 @@ public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine() await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); } - [Fact(Skip = "RemoveUnusedVariable code action is not triggered when the only statement in a single-line explicit block is unused")] + [Fact] public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine_OnlyVariable() { var input = """ @@ -422,8 +422,7 @@ public async Task RemoveUnusedVariable_ExplicitStatement_SingleLine_OnlyVariable """; var expected = """ - @{ - } + @{} """; await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); From a18d029a1a4ee8301ce7032472a95221dbbe383b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 11:09:56 +0000 Subject: [PATCH 06/10] Remove RemoveUnusedMembers and skipped tests, focus on RemoveUnusedVariable Removed RemoveUnusedMembers from the allow list since it's not actually offered by Roslyn. Removed the three skipped tests that were testing RemoveUnusedMembers (Parameter, PrivateField, PrivateMethod). The PR now focuses on adding test coverage and a bug fix for RemoveUnusedVariable which was already in the list. Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../CSharp/CSharpCodeActionProvider.cs | 1 - .../CodeActions/CSharpCodeActionTests.cs | 78 ------------------- 2 files changed, 79 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs index de2162aad5b..3d14d8d3502 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/CSharp/CSharpCodeActionProvider.cs @@ -40,7 +40,6 @@ internal class CSharpCodeActionProvider(LanguageServerFeatureOptions languageSer RazorPredefinedCodeFixProviderNames.ImplementAbstractClass, RazorPredefinedCodeFixProviderNames.ImplementInterface, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable, - RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers, ]; // We don't support any code actions in implicit expressions at the moment, but rather than simply returning early diff --git a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs index 9d8f61e94e7..6638595248c 100644 --- a/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs +++ b/src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/CSharpCodeActionTests.cs @@ -446,82 +446,4 @@ public async Task RemoveUnusedVariable_ExplicitStatement_MultiLine() await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedVariable); } - - [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] - public async Task RemoveUnusedVariable_Parameter() - { - var input = """ - @code - { - void M(int {|IDE0060:[||]unusedParameter|}) - { - } - } - """; - - var expected = """ - @code - { - void M() - { - } - } - """; - - await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); - } - - [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] - public async Task RemoveUnusedVariable_PrivateField() - { - var input = """ - @code - { - private int {|IDE0051:[||]_field|}; - - void M() - { - } - } - """; - - var expected = """ - @code - { - void M() - { - } - } - """; - - await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); - } - - [Fact(Skip = "RemoveUnusedMembers code action is not triggered in test scenarios - requires full analyzer support")] - public async Task RemoveUnusedVariable_PrivateMethod() - { - var input = """ - @code - { - private void {|IDE0051:[||]UnusedMethod|}() - { - } - - void M() - { - } - } - """; - - var expected = """ - @code - { - void M() - { - } - } - """; - - await VerifyCodeActionAsync(input, expected, RazorPredefinedCodeFixProviderNames.RemoveUnusedMembers); - } } From a3637b255e65894ae082791faf7c304e129e56d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:31:04 +0000 Subject: [PATCH 07/10] Move firstNewLine assignment into the condition where it's used Optimization: moved the firstNewLine variable assignment from line 109 into the if (mappedStart && mappedEnd) condition at line 120 where it's actually used. This avoids computing the variable unnecessarily when mappedEnd is false. Co-authored-by: ToddGrun <6785178+ToddGrun@users.noreply.github.com> --- .../DocumentMapping/AbstractDocumentMappingService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs index 44d28e51c1c..3c9b22ae078 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs @@ -106,7 +106,6 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD { // Construct a theoretical edit that is just for the first line of the edit that the C# formatter // gave us, and see if we can map that. - var firstNewLine = change.NewText.AssumeNotNull().IndexOfAny(['\n', '\r']); // Get the end of the start line var endSync = csharpSourceText.TryGetAbsoluteIndex((startLine, csharpSourceText.Lines[startLine].Span.Length), out var endIndex); @@ -120,6 +119,7 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD if (mappedStart && mappedEnd) { // If there's a newline in the new text, only take the part before it + var firstNewLine = change.NewText.AssumeNotNull().IndexOfAny(['\n', '\r']); var newText = firstNewLine >= 0 ? change.NewText[..firstNewLine] : change.NewText; yield return new TextChange(TextSpan.FromBounds(hostStartIndex, hostEndIndex), newText); continue; From abe253351337d6f1d0b838b47e816c0e19a59930 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:39:17 +0000 Subject: [PATCH 08/10] Use TryGetAbsoluteIndex overload and remove redundant check - Changed TryGetAbsoluteIndex call to use the overload with separate line and character parameters instead of a tuple - Removed redundant mappedStart check in inner condition since it's already guaranteed by the outer if condition Co-authored-by: ToddGrun <6785178+ToddGrun@users.noreply.github.com> --- .../DocumentMapping/AbstractDocumentMappingService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs index 3c9b22ae078..5098dad9156 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs @@ -108,7 +108,7 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD // gave us, and see if we can map that. // Get the end of the start line - var endSync = csharpSourceText.TryGetAbsoluteIndex((startLine, csharpSourceText.Lines[startLine].Span.Length), out var endIndex); + var endSync = csharpSourceText.TryGetAbsoluteIndex(startLine, csharpSourceText.Lines[startLine].Span.Length, out var endIndex); if (endSync is false) { break; @@ -116,7 +116,7 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD mappedEnd = this.TryMapToRazorDocumentPosition(csharpDocument, endIndex, out _, out hostEndIndex); - if (mappedStart && mappedEnd) + if (mappedEnd) { // If there's a newline in the new text, only take the part before it var firstNewLine = change.NewText.AssumeNotNull().IndexOfAny(['\n', '\r']); From 413cc1d6149c376d660e9b1216b72078ffe40bab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:47:33 +0000 Subject: [PATCH 09/10] Simplify TryGetAbsoluteIndex check by using result directly in if condition Changed from storing the result in endSync variable and checking it separately to directly using the TryGetAbsoluteIndex result in the if condition with negation. This makes the code more concise and easier to read. Co-authored-by: ToddGrun <6785178+ToddGrun@users.noreply.github.com> --- .../DocumentMapping/AbstractDocumentMappingService.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs index 5098dad9156..de91651a123 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs @@ -108,8 +108,7 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD // gave us, and see if we can map that. // Get the end of the start line - var endSync = csharpSourceText.TryGetAbsoluteIndex(startLine, csharpSourceText.Lines[startLine].Span.Length, out var endIndex); - if (endSync is false) + if (!csharpSourceText.TryGetAbsoluteIndex(startLine, csharpSourceText.Lines[startLine].Span.Length, out var endIndex)) { break; } From 87ca65ac440be1157884dcc4a729b040f91f2a6f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:57:23 +0000 Subject: [PATCH 10/10] Inline TryMapToRazorDocumentPosition call instead of storing result Removed the intermediate mappedEnd assignment and directly used the TryMapToRazorDocumentPosition result in the if condition. This makes the code cleaner by avoiding the unnecessary variable assignment. Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../DocumentMapping/AbstractDocumentMappingService.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs index de91651a123..4d3ad34a23b 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs @@ -113,9 +113,7 @@ public IEnumerable GetRazorDocumentEdits(RazorCSharpDocument csharpD break; } - mappedEnd = this.TryMapToRazorDocumentPosition(csharpDocument, endIndex, out _, out hostEndIndex); - - if (mappedEnd) + if (this.TryMapToRazorDocumentPosition(csharpDocument, endIndex, out _, out hostEndIndex)) { // If there's a newline in the new text, only take the part before it var firstNewLine = change.NewText.AssumeNotNull().IndexOfAny(['\n', '\r']);