From b171b0051f350cb86261213999ec91fb24cefc1c Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 10:39:01 +1000 Subject: [PATCH 01/34] Move document and edit mapping code up to Remote.Razor --- .../DocumentMapping/AbstractDocumentMappingService.cs | 3 ++- .../DocumentMapping/IRazorEditServiceExtensions.cs | 3 ++- .../DocumentMapping/RazorEditService.CSharpMember.cs | 2 +- .../DocumentMapping/RazorEditService.cs | 6 ++++-- .../DocumentMapping/RazorEditService_Members.cs | 4 ++-- .../DocumentMapping/RazorEditService_UsingDirectives.cs | 4 +++- .../DocumentMapping/RazorEditService_WorkspaceEdit.cs | 3 ++- .../DocumentMapping/RemoteSpanMappingService.cs | 1 + .../InlayHints/RemoteInlayHintService.cs | 5 +++-- .../Mapping/RazorEditServiceTest.cs | 9 ++++++--- .../RazorDocumentMappingServiceTest.cs | 3 ++- 11 files changed, 28 insertions(+), 15 deletions(-) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/AbstractDocumentMappingService.cs (99%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/IRazorEditServiceExtensions.cs (90%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/RazorEditService.CSharpMember.cs (99%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/RazorEditService.cs (98%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/RazorEditService_Members.cs (98%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/RazorEditService_UsingDirectives.cs (98%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/RazorEditService_WorkspaceEdit.cs (98%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs similarity index 99% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs index 45167af11a46..dd743006c91d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs @@ -8,11 +8,12 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal abstract class AbstractDocumentMappingService(ILogger logger) : IDocumentMappingService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditServiceExtensions.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs similarity index 90% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditServiceExtensions.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs index 72a60a8848bf..8008d03a73b3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditServiceExtensions.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs @@ -4,11 +4,12 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal static class IRazorEditServiceExtensions { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.CSharpMember.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.CSharpMember.cs similarity index 99% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.CSharpMember.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.CSharpMember.cs index de174404341d..faf4fe978ec1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.CSharpMember.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.CSharpMember.cs @@ -6,7 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal partial class RazorEditService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs similarity index 98% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs index 4dc79c4b6d5d..72cd5c9a93ee 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -11,6 +11,8 @@ using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.AspNetCore.Razor.Utilities; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Protocol; @@ -20,7 +22,7 @@ using Microsoft.CodeAnalysis.Text; using RoslynSyntaxNode = Microsoft.CodeAnalysis.SyntaxNode; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal abstract partial class RazorEditService( IDocumentMappingService documentMappingService, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_Members.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs similarity index 98% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_Members.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs index 6fd30b2d4e5f..58bb0517398c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_Members.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -16,7 +16,7 @@ using Microsoft.CodeAnalysis.Text; using RoslynSyntaxNode = Microsoft.CodeAnalysis.SyntaxNode; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal partial class RazorEditService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_UsingDirectives.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_UsingDirectives.cs similarity index 98% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_UsingDirectives.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_UsingDirectives.cs index 8303bea2f81c..88387002981c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_UsingDirectives.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_UsingDirectives.cs @@ -13,10 +13,12 @@ using Microsoft.AspNetCore.Razor.Language.Extensions; using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal partial class RazorEditService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_WorkspaceEdit.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs similarity index 98% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_WorkspaceEdit.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs index c59004b76ef3..6d4bb8bd3017 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RazorEditService_WorkspaceEdit.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs @@ -10,9 +10,10 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; +using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.ProjectSystem; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal partial class RazorEditService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs index 6a4ac727e11f..d620403ffa95 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Telemetry; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs index cb47af9622e9..1c1a61de6cf2 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; @@ -10,13 +10,14 @@ using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.InlineHints; +using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.LanguageServer.Handler.InlayHint; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol.InlayHints; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.LanguageServer; namespace Microsoft.CodeAnalysis.Remote.Razor; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs index 507f7c9406fb..2e28140a423c 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Settings; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; @@ -2030,13 +2031,15 @@ private async Task TestAsync( var snapshot = TestDocumentSnapshot.Create(razorPath, codeDocument); var responseTextChanges = await _razorEditService.AssumeNotNull().MapCSharpEditsAsync( - changes, + changes.SelectAsArray(static c => c.ToRazorTextChange()), snapshot, + includeCSharpLanguageFeatureEdits: true, + directlyMappedEditFilter: null, CancellationToken.None); Assert.NotEmpty(responseTextChanges); - var newRazorSourceText = razorSourceText.WithChanges(responseTextChanges); + var newRazorSourceText = razorSourceText.WithChanges(responseTextChanges.SelectAsArray(static c => c.ToTextChange())); AssertEx.EqualOrDiff(expectedRazorSource, newRazorSourceText.ToString()); } diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs index 4768363eb9b5..e6a2a6793a76 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #if DEBUG @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Logging; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; From 844035f11692808985a09b2cb402a7c5f02a0d8d Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 10:39:15 +1000 Subject: [PATCH 02/34] Move resource --- .../Resources/SR.resx | 5 +---- .../Resources/xlf/SR.cs.xlf | 5 ----- .../Resources/xlf/SR.de.xlf | 5 ----- .../Resources/xlf/SR.es.xlf | 5 ----- .../Resources/xlf/SR.fr.xlf | 5 ----- .../Resources/xlf/SR.it.xlf | 5 ----- .../Resources/xlf/SR.ja.xlf | 5 ----- .../Resources/xlf/SR.ko.xlf | 5 ----- .../Resources/xlf/SR.pl.xlf | 5 ----- .../Resources/xlf/SR.pt-BR.xlf | 5 ----- .../Resources/xlf/SR.ru.xlf | 5 ----- .../Resources/xlf/SR.tr.xlf | 5 ----- .../Resources/xlf/SR.zh-Hans.xlf | 5 ----- .../Resources/xlf/SR.zh-Hant.xlf | 5 ----- .../Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx | 3 +++ .../Resources/xlf/SR.cs.xlf | 5 +++++ .../Resources/xlf/SR.de.xlf | 5 +++++ .../Resources/xlf/SR.es.xlf | 5 +++++ .../Resources/xlf/SR.fr.xlf | 5 +++++ .../Resources/xlf/SR.it.xlf | 5 +++++ .../Resources/xlf/SR.ja.xlf | 5 +++++ .../Resources/xlf/SR.ko.xlf | 5 +++++ .../Resources/xlf/SR.pl.xlf | 5 +++++ .../Resources/xlf/SR.pt-BR.xlf | 5 +++++ .../Resources/xlf/SR.ru.xlf | 5 +++++ .../Resources/xlf/SR.tr.xlf | 5 +++++ .../Resources/xlf/SR.zh-Hans.xlf | 5 +++++ .../Resources/xlf/SR.zh-Hant.xlf | 5 +++++ 28 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx index 13cdc9285a28..638a1fe1f226 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx @@ -136,9 +136,6 @@ Line '{0}' outside of the {1} range of '{2}' was queried. The document may not be up to date. - - Unknown mapping behavior - A format operation is being abandoned because it would add or delete non-whitespace content. @@ -219,4 +216,4 @@ (Baseline since {0}) {0} is the year the feature reached baseline status (e.g., "2015") - + \ No newline at end of file diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf index c34f35f19b1c..feaeee861fc7 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf @@ -139,11 +139,6 @@ Aktivovat znovu dokončení… - - Unknown mapping behavior - Neznámé chování mapování - - Unsupported Razor extension: '{0}'. Nepodporované rozšíření Razor: {0}. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf index f1dc4b4f6f15..47150b14b26e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf @@ -139,11 +139,6 @@ "Abschlüsse erneut auslösen..." - - Unknown mapping behavior - Unbekanntes Zuordnungsverhalten - - Unsupported Razor extension: '{0}'. Nicht unterstützte Razor-Erweiterung: „{0}“. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf index bdfc0a685928..bea3924ab7be 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf @@ -139,11 +139,6 @@ "Volver a desencadenar las finalizaciones..." - - Unknown mapping behavior - Comportamiento de asignación desconocido - - Unsupported Razor extension: '{0}'. Extensión Razor no admitida: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf index 137a3d55c2f0..81eb2a1ed945 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf @@ -139,11 +139,6 @@ « Déclencher à nouveau les complétions... » - - Unknown mapping behavior - Comportement de mappage inconnu - - Unsupported Razor extension: '{0}'. Extension Razor non prise en charge : « {0} ». diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf index 353fe8e67e43..538d9cc2b63e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf @@ -139,11 +139,6 @@ "Riattiva i completamenti..." - - Unknown mapping behavior - Comportamento di mapping sconosciuto - - Unsupported Razor extension: '{0}'. Estensione Razor non supportata: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf index c76c81245a91..d7f0bc5dec09 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf @@ -139,11 +139,6 @@ "再トリガーの完了..." - - Unknown mapping behavior - 不明なマッピング動作 - - Unsupported Razor extension: '{0}'. サポートされていない Razor 拡張機能: '{0}'。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf index 4771a9f96357..1030ffd5f626 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf @@ -139,11 +139,6 @@ "완료된 항목 다시 트리거" - - Unknown mapping behavior - 알 수 없는 매핑 동작 - - Unsupported Razor extension: '{0}'. 지원되지 않는 Razor 확장: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf index db68b1a2e75d..f5a8f14ff79e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf @@ -139,11 +139,6 @@ klawisz [Tab], aby przechodzić pomiędzy elementami, klawisz [Enter], aby zako "Ponownie wyzwalaj uzupełniania..." - - Unknown mapping behavior - Nieznane zachowanie mapowania - - Unsupported Razor extension: '{0}'. Nieobsługiwane rozszerzenie Razor: „{0}”. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf index 62d53d069022..09269d15cf72 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf @@ -139,11 +139,6 @@ "Disparar conclusões novamente..." - - Unknown mapping behavior - Comportamento de mapeamento desconhecido - - Unsupported Razor extension: '{0}'. Extensão Razor sem suporte: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf index e2042ee217f3..d2a124fe1b5e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf @@ -139,11 +139,6 @@ "Повторный запуск завершений..." - - Unknown mapping behavior - Неизвестное поведение сопоставления - - Unsupported Razor extension: '{0}'. Неподдерживаемое расширение Razor: "{0}". diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf index 65cd3b8e0027..d37493b8e047 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf @@ -139,11 +139,6 @@ "Tamamlamaları yeniden tetikleyin..." - - Unknown mapping behavior - Bilinmeyen eşleme davranışı - - Unsupported Razor extension: '{0}'. Desteklenmeyen Razor uzantısı: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf index dcdfafb1d190..04452359a1e6 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf @@ -139,11 +139,6 @@ “重新触发完成…” - - Unknown mapping behavior - 未知映射行为 - - Unsupported Razor extension: '{0}'. 不支持的 Razor 扩展:“{0}”。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf index 9671b7b5dafd..3eab73cc139d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf @@ -139,11 +139,6 @@ "重新觸發完成..." - - Unknown mapping behavior - 未知的對應行為 - - Unsupported Razor extension: '{0}'. 不支援的 Razor 延伸模組: '{0}'。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx index d94bfe106870..3e94cca94ac1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx @@ -199,4 +199,7 @@ Attempted to visit a RazorMetaCode other than '{' or '}'. + + Unknown mapping behavior + \ No newline at end of file diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf index 1c405a51c364..e4a0baa95c75 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf @@ -127,6 +127,11 @@ Došlo k pokusu navštívit RazorMetaCode jiný než '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Nepodporovaný typ: {0} diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf index ac34e8cf0e4f..ccbf277a5934 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf @@ -127,6 +127,11 @@ Es wurde versucht, einen anderen RazorMetaCode als '{' or '}' zu besuchen. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Nicht unterstützter Typ: „{0}“. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf index 52f9b67c472d..88d39e2d3b26 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf @@ -127,6 +127,11 @@ Se intentó visitar un RazorMetaCode distinto de '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Tipo no compatible: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf index 5e841b281eb2..8af9f9aee5d2 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf @@ -127,6 +127,11 @@ Tentative de visite d’un RazorMetaCode autre que '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Type non pris en charge : '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf index 962d5caf2b8e..79f12683f630 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf @@ -127,6 +127,11 @@ È stato effettuato un tentativo di visitare un elemento RazorMetaCode diverso da '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Tipo non supportato: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf index f2ea23afe1ef..0a5478bfed90 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf @@ -127,6 +127,11 @@ '{' or '}' 以外の RazorMetaCode にアクセスしようとしました。 + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. サポートされていない型: '{0}'。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf index 45f20bb86c25..5a7b6d4c58a3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf @@ -127,6 +127,11 @@ ''{' or '}' 이외의 RazorMetaCode를 방문하려고 했습니다. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. 지원되지 않는 유형: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf index a8cc2b3947e7..782cb2d68dd3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf @@ -127,6 +127,11 @@ Podjęto próbę odwiedzenia elementu RazorMetaCode innego niż '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Nieobsługiwany typ: „{0}”. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf index 9cff8d4e7e16..6cc396831814 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf @@ -127,6 +127,11 @@ Tentativa de visitar um RazorMetaCode diferente de '{' or '}'. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Tipo sem suporte: "{0}". diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf index 14737c7e2fa9..148fea685881 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf @@ -127,6 +127,11 @@ Предпринята попытка посетить RazorMetaCode, отличный от "{' or '}". + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Неподдерживаемый тип: "{0}". diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf index f4510d9f480c..6296c5412974 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf @@ -127,6 +127,11 @@ '{' or '}' dışında bir RazorMetaCode ziyaret edilmeye çalışıldı. + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. Desteklenmeyen tür: '{0}'. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf index 091cb2ddf551..a5a9386853c2 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf @@ -127,6 +127,11 @@ 已尝试访问除 "{' or '}" 之外的 RazorMetaCode。 + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. 不支持的类型:“{0}”。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf index c3ca6642b8fe..d8bfd15074d5 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf @@ -127,6 +127,11 @@ 嘗試瀏覽 '{' or '}' 除外的 RazorMetaCode。 + + Unknown mapping behavior + Unknown mapping behavior + + Unsupported type: '{0}'. 不支援的類型: '{0}'。 From c9b000f2f1c4834662e7a21a2efbcf81e10087d3 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 10:39:20 +1000 Subject: [PATCH 03/34] Delete unused file --- .../DocumentMapping/RangeComparer.cs | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RangeComparer.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RangeComparer.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RangeComparer.cs deleted file mode 100644 index 9422822a99d8..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/RangeComparer.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; - -namespace Microsoft.CodeAnalysis.Razor.Workspaces.DocumentMapping; - -internal sealed class RangeComparer : IComparer -{ - public static readonly RangeComparer Instance = new(); - - public int Compare(LspRange? x, LspRange? y) - { - if (x is null) - { - return y is null ? 0 : 1; - } - - if (y is null) - { - return -1; - } - - return x.CompareTo(y); - } -} From db79a4d350ef7a23dfd046e4b1ac758d5a49fb12 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 11:15:59 +1000 Subject: [PATCH 04/34] Move MEF exports to the real classes, and remove indirection --- .../Formatting/DocumentFormattingBenchmark.cs | 4 +- .../AbstractDocumentMappingService.cs | 91 +++++++++++++++- .../IDocumentMappingServiceExtensions.cs | 2 +- .../DocumentMapping/RazorEditService.cs | 8 +- .../RazorEditService_WorkspaceEdit.cs | 42 ++++++- .../RemoteDocumentMappingService.cs | 103 ------------------ .../DocumentMapping/RemoteRazorEditService.cs | 67 ------------ .../RazorDocumentMappingServiceTest.cs | 12 +- 8 files changed, 145 insertions(+), 184 deletions(-) delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteDocumentMappingService.cs delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteRazorEditService.cs diff --git a/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs b/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs index 986e3406f903..137a326bd73c 100644 --- a/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs +++ b/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs @@ -81,8 +81,8 @@ public void Setup() hostServicesProvider.SetWorkspaceProvider(new WorkspaceProvider(_workspace)); var clientSettingsManager = new RemoteClientSettingsManager(); - var documentMappingService = new RemoteDocumentMappingService(filePathService, snapshotManager, EmptyLoggerFactory.Instance); - var razorEditService = new RemoteRazorEditService(documentMappingService, clientSettingsManager, filePathService, snapshotManager, NoOpTelemetryReporter.Instance); + var documentMappingService = new DocumentMappingService(filePathService, snapshotManager, EmptyLoggerFactory.Instance); + var razorEditService = new RazorEditService(documentMappingService, clientSettingsManager, filePathService, snapshotManager, NoOpTelemetryReporter.Instance); _formattingService = new RemoteRazorFormattingService( documentMappingService, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs index dd743006c91d..cca8b7803f98 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs @@ -3,21 +3,32 @@ using System; using System.Collections.Immutable; +using System.Composition; using System.Diagnostics; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; -internal abstract class AbstractDocumentMappingService(ILogger logger) : IDocumentMappingService +[Export(typeof(IDocumentMappingService)), Shared] +[method: ImportingConstructor] +internal sealed class DocumentMappingService( + IFilePathService filePathService, + RemoteSnapshotManager snapshotManager, + ILoggerFactory loggerFactory) : IDocumentMappingService { - protected readonly ILogger Logger = logger; + private readonly IFilePathService _filePathService = filePathService; + private readonly RemoteSnapshotManager _snapshotManager = snapshotManager; + private readonly ILogger Logger = loggerFactory.GetOrCreateLogger(); public bool TryMapToRazorDocumentRange(RazorCSharpDocument csharpDocument, LinePositionSpan csharpRange, MappingBehavior mappingBehavior, out LinePositionSpan razorRange) { @@ -423,4 +434,80 @@ static bool IsPositionWithinDocument(LinePosition linePosition, SourceText sourc return sourceText.TryGetAbsoluteIndex(linePosition, out _); } } + + public async Task<(Uri MappedDocumentUri, LinePositionSpan MappedRange)> MapToHostDocumentUriAndRangeAsync( + RemoteDocumentSnapshot originSnapshot, + Uri generatedDocumentUri, + LinePositionSpan generatedDocumentRange, + CancellationToken cancellationToken) + { + // For Html we just map the Uri, the range will be the same + if (_filePathService.IsVirtualHtmlFile(generatedDocumentUri)) + { + return (_filePathService.GetRazorDocumentUri(generatedDocumentUri), generatedDocumentRange); + } + + // We only map from C# files + if (!_filePathService.IsVirtualCSharpFile(generatedDocumentUri)) + { + return (generatedDocumentUri, generatedDocumentRange); + } + + var solution = originSnapshot.TextDocument.Project.Solution; + if (!solution.TryGetSourceGeneratedDocumentIdentity(generatedDocumentUri, out var identity) || + !solution.TryGetProject(identity.DocumentId.ProjectId, out var project)) + { + return (generatedDocumentUri, generatedDocumentRange); + } + + var razorCodeDocument = await _snapshotManager.GetSnapshot(project).TryGetCodeDocumentForGeneratedDocumentAsync(identity, cancellationToken).ConfigureAwait(false); + if (razorCodeDocument is null) + { + return (generatedDocumentUri, generatedDocumentRange); + } + + var razorDocumentUri = project.Solution.GetRazorDocumentUri(razorCodeDocument); + if (TryMapToRazorDocumentRange(razorCodeDocument.GetCSharpDocumentForHintName(identity.HintName), generatedDocumentRange, MappingBehavior.Strict, out var mappedRange)) + { + return (razorDocumentUri, mappedRange); + } + + // If the position is unmappable, but was in a generated Razor, we have one last check to see if Roslyn wants to navigate + // to the class declaration, in which case we'll map to (0,0) in the Razor document itself. + if (await TryGetCSharpClassDeclarationSpanAsync(identity, project, cancellationToken).ConfigureAwait(false) is { } classDeclSpan && + generatedDocumentRange.Start == classDeclSpan.Start && + (generatedDocumentRange.End == generatedDocumentRange.Start || + generatedDocumentRange.End == classDeclSpan.End)) + { + return (razorDocumentUri, new(LinePosition.Zero, LinePosition.Zero)); + } + + return (generatedDocumentUri, generatedDocumentRange); + } + + private static async Task TryGetCSharpClassDeclarationSpanAsync(SourceGeneratedDocumentIdentity identity, Project project, CancellationToken cancellationToken) + { + var generatedDocument = await project.TryGetCSharpDocumentForGeneratedDocumentAsync(identity, cancellationToken).ConfigureAwait(false); + if (generatedDocument is null) + { + return null; + } + + var csharpSyntaxTree = await generatedDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + if (csharpSyntaxTree is null) + { + return null; + } + + var csharpSyntaxRoot = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + if (!csharpSyntaxRoot.TryGetClassDeclaration(out var classDecl)) + { + return null; + } + + var sourceText = await generatedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); + var classDeclSpan = sourceText.GetLinePositionSpan(classDecl.Identifier.Span); + + return classDeclSpan; + } } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentMappingServiceExtensions.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentMappingServiceExtensions.cs index 4da656e85326..9744c7207365 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentMappingServiceExtensions.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentMappingServiceExtensions.cs @@ -25,7 +25,7 @@ internal static class IDocumentMappingServiceExtensions LinePositionSpan generatedDocumentRange, CancellationToken cancellationToken) { - if (service is RemoteDocumentMappingService remoteService) + if (service is DocumentMappingService remoteService) { return remoteService.MapToHostDocumentUriAndRangeAsync(originSnapshot, generatedDocumentUri, generatedDocumentRange, cancellationToken); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs index 72cd5c9a93ee..cd6c5b4688c7 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; +using System.Composition; using System.Diagnostics; using System.Linq; using System.Threading; @@ -19,20 +20,25 @@ using Microsoft.CodeAnalysis.Razor.Telemetry; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Razor.Workspaces.Settings; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using RoslynSyntaxNode = Microsoft.CodeAnalysis.SyntaxNode; namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; -internal abstract partial class RazorEditService( +[Export(typeof(IRazorEditService)), Shared] +[method: ImportingConstructor] +internal sealed partial class RazorEditService( IDocumentMappingService documentMappingService, IClientSettingsManager clientSettingsManager, IFilePathService filePathService, + RemoteSnapshotManager snapshotManager, ITelemetryReporter telemetryReporter) : IRazorEditService { private readonly IDocumentMappingService _documentMappingService = documentMappingService; private readonly IClientSettingsManager _clientSettingsManager = clientSettingsManager; private readonly IFilePathService _filePathService = filePathService; + private readonly RemoteSnapshotManager _snapshotManager = snapshotManager; private readonly ITelemetryReporter _telemetryReporter = telemetryReporter; public async Task> MapCSharpEditsAsync( diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs index 6d4bb8bd3017..92e55773c51a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; @@ -73,7 +74,7 @@ private async Task MapTextDocumentEditAsync(IDocumentSnapshot contextDocumentSna return; } - if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, entry.TextDocument.GetProjectContext(), out var documentContext)) + if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, out var documentContext)) { return; } @@ -123,7 +124,7 @@ private async Task> MapDocumentEditsAsync(IDocume continue; } - if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, projectContext: null, out var documentContext)) + if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, out var documentContext)) { continue; } @@ -153,7 +154,40 @@ private async Task> GetMappedTextEditsAsync(DocumentCon return mappedEdits.SelectAsArray(razorSourceText.GetTextEdit); } - protected abstract bool TryGetDocumentContext(IDocumentSnapshot contextDocumentSnapshot, Uri razorDocumentUri, VSProjectContext? projectContext, [NotNullWhen(true)] out DocumentContext? documentContext); + private bool TryGetDocumentContext(IDocumentSnapshot contextDocumentSnapshot, Uri razorDocumentUri, [NotNullWhen(true)] out DocumentContext? documentContext) + { + if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) + { + throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); + } + + var solution = originSnapshot.TextDocument.Project.Solution; + if (!solution.TryGetRazorDocument(razorDocumentUri, out var razorDocument)) + { + documentContext = null; + return false; + } + + var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); + + documentContext = new RemoteDocumentContext(razorDocumentUri.CreateDocumentUriFromSystemUri(), razorDocumentSnapshot); + return true; + } - protected abstract Task GetRazorDocumentUriAsync(IDocumentSnapshot contextDocumentSnapshot, Uri uri, CancellationToken cancellationToken); + private async Task GetRazorDocumentUriAsync(IDocumentSnapshot contextDocumentSnapshot, Uri generatedDocumentUri, CancellationToken cancellationToken) + { + if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) + { + throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); + } + + var solution = originSnapshot.TextDocument.Project.Solution; + var razorCodeDocument = await _snapshotManager.TryGetRazorCodeDocumentAsync(solution, generatedDocumentUri, cancellationToken).ConfigureAwait(false); + if (razorCodeDocument is null) + { + return null; + } + + return solution.GetRazorDocumentUri(razorCodeDocument); + } } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteDocumentMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteDocumentMappingService.cs deleted file mode 100644 index 8ad2030a0e78..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteDocumentMappingService.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Composition; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor.Language; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; - -[Export(typeof(IDocumentMappingService)), Shared] -[method: ImportingConstructor] -internal sealed class RemoteDocumentMappingService( - IFilePathService filePathService, - RemoteSnapshotManager snapshotManager, - ILoggerFactory loggerFactory) - : AbstractDocumentMappingService(loggerFactory.GetOrCreateLogger()) -{ - private readonly IFilePathService _filePathService = filePathService; - private readonly RemoteSnapshotManager _snapshotManager = snapshotManager; - - public async Task<(Uri MappedDocumentUri, LinePositionSpan MappedRange)> MapToHostDocumentUriAndRangeAsync( - RemoteDocumentSnapshot originSnapshot, - Uri generatedDocumentUri, - LinePositionSpan generatedDocumentRange, - CancellationToken cancellationToken) - { - // For Html we just map the Uri, the range will be the same - if (_filePathService.IsVirtualHtmlFile(generatedDocumentUri)) - { - return (_filePathService.GetRazorDocumentUri(generatedDocumentUri), generatedDocumentRange); - } - - // We only map from C# files - if (!_filePathService.IsVirtualCSharpFile(generatedDocumentUri)) - { - return (generatedDocumentUri, generatedDocumentRange); - } - - var solution = originSnapshot.TextDocument.Project.Solution; - if (!solution.TryGetSourceGeneratedDocumentIdentity(generatedDocumentUri, out var identity) || - !solution.TryGetProject(identity.DocumentId.ProjectId, out var project)) - { - return (generatedDocumentUri, generatedDocumentRange); - } - - var razorCodeDocument = await _snapshotManager.GetSnapshot(project).TryGetCodeDocumentForGeneratedDocumentAsync(identity, cancellationToken).ConfigureAwait(false); - if (razorCodeDocument is null) - { - return (generatedDocumentUri, generatedDocumentRange); - } - - var razorDocumentUri = project.Solution.GetRazorDocumentUri(razorCodeDocument); - if (TryMapToRazorDocumentRange(razorCodeDocument.GetCSharpDocumentForHintName(identity.HintName), generatedDocumentRange, MappingBehavior.Strict, out var mappedRange)) - { - return (razorDocumentUri, mappedRange); - } - - // If the position is unmappable, but was in a generated Razor, we have one last check to see if Roslyn wants to navigate - // to the class declaration, in which case we'll map to (0,0) in the Razor document itself. - if (await TryGetCSharpClassDeclarationSpanAsync(identity, project, cancellationToken).ConfigureAwait(false) is { } classDeclSpan && - generatedDocumentRange.Start == classDeclSpan.Start && - (generatedDocumentRange.End == generatedDocumentRange.Start || - generatedDocumentRange.End == classDeclSpan.End)) - { - return (razorDocumentUri, new(LinePosition.Zero, LinePosition.Zero)); - } - - return (generatedDocumentUri, generatedDocumentRange); - } - - private static async Task TryGetCSharpClassDeclarationSpanAsync(SourceGeneratedDocumentIdentity identity, Project project, CancellationToken cancellationToken) - { - var generatedDocument = await project.TryGetCSharpDocumentForGeneratedDocumentAsync(identity, cancellationToken).ConfigureAwait(false); - if (generatedDocument is null) - { - return null; - } - - var csharpSyntaxTree = await generatedDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - if (csharpSyntaxTree is null) - { - return null; - } - - var csharpSyntaxRoot = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); - if (!csharpSyntaxRoot.TryGetClassDeclaration(out var classDecl)) - { - return null; - } - - var sourceText = await generatedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); - var classDeclSpan = sourceText.GetLinePositionSpan(classDecl.Identifier.Span); - - return classDeclSpan; - } -} diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteRazorEditService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteRazorEditService.cs deleted file mode 100644 index 711639f2d6cd..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteRazorEditService.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Composition; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.Razor.Telemetry; -using Microsoft.CodeAnalysis.Razor.Workspaces; -using Microsoft.CodeAnalysis.Razor.Workspaces.Settings; -using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; - -namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; - -[Export(typeof(IRazorEditService)), Shared] -[method: ImportingConstructor] -internal sealed class RemoteRazorEditService( - IDocumentMappingService documentMappingService, - IClientSettingsManager clientSettingsManager, - IFilePathService filePathService, - RemoteSnapshotManager snapshotManager, - ITelemetryReporter telemetryReporter) - : RazorEditService(documentMappingService, clientSettingsManager, filePathService, telemetryReporter) -{ - private readonly RemoteSnapshotManager _snapshotManager = snapshotManager; - - protected override bool TryGetDocumentContext(IDocumentSnapshot contextDocumentSnapshot, Uri razorDocumentUri, VSProjectContext? projectContext, [NotNullWhen(true)] out DocumentContext? documentContext) - { - if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) - { - throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); - } - - var solution = originSnapshot.TextDocument.Project.Solution; - if (!solution.TryGetRazorDocument(razorDocumentUri, out var razorDocument)) - { - documentContext = null; - return false; - } - - var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); - - documentContext = new RemoteDocumentContext(razorDocumentUri.CreateDocumentUriFromSystemUri(), razorDocumentSnapshot); - return true; - } - - protected override async Task GetRazorDocumentUriAsync(IDocumentSnapshot contextDocumentSnapshot, Uri generatedDocumentUri, CancellationToken cancellationToken) - { - if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) - { - throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); - } - - var solution = originSnapshot.TextDocument.Project.Solution; - var razorCodeDocument = await _snapshotManager.TryGetRazorCodeDocumentAsync(solution, generatedDocumentUri, cancellationToken).ConfigureAwait(false); - if (razorCodeDocument is null) - { - return null; - } - - return solution.GetRazorDocumentUri(razorCodeDocument); - } -} diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs index e6a2a6793a76..1d752ee30b29 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/RazorDocumentMappingServiceTest.cs @@ -8,8 +8,10 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Logging; +using Microsoft.CodeAnalysis.Razor.Telemetry; +using Microsoft.CodeAnalysis.Remote.Razor; using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; @@ -19,7 +21,11 @@ namespace Microsoft.CodeAnalysis.Razor; public class RazorDocumentMappingServiceTest(ITestOutputHelper testOutput) : ToolingTestBase(testOutput) { private IDocumentMappingService CreateMappingService() - => new TestDocumentMappingService(LoggerFactory.GetOrCreateLogger(nameof(TestDocumentMappingService))); + { + var filePathService = new RemoteFilePathService(); + var snapshotManager = new RemoteSnapshotManager(filePathService, NoOpTelemetryReporter.Instance); + return new DocumentMappingService(filePathService, snapshotManager, LoggerFactory); + } [Fact] public void TryMapToHostDocumentRange_Strict_StartOnlyMaps_ReturnsFalse() @@ -828,6 +834,4 @@ private static RazorCodeDocument CreateCodeDocumentWithCSharpProjection(string r return codeDocument; } - - private sealed class TestDocumentMappingService(ILogger logger) : AbstractDocumentMappingService(logger); } From 43d93ebf59d58cb6d6ac820d8d1b65734dfd8a12 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 11:16:21 +1000 Subject: [PATCH 05/34] Rename file --- ...bstractDocumentMappingService.cs => DocumentMappingService.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/{AbstractDocumentMappingService.cs => DocumentMappingService.cs} (100%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/DocumentMappingService.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/AbstractDocumentMappingService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/DocumentMappingService.cs From 1e8434afb0aa938f37fdd9f9fa96775c3cfa37d7 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 11:39:37 +1000 Subject: [PATCH 06/34] Strongly type and simplify logic, now that there is no abstraction to maintain --- .../RazorEditService_WorkspaceEdit.cs | 86 ++++++------------- 1 file changed, 25 insertions(+), 61 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs index 92e55773c51a..2a6a2324fc2a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs @@ -4,12 +4,12 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; +using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; @@ -20,6 +20,11 @@ internal partial class RazorEditService { public async Task MapWorkspaceEditAsync(IDocumentSnapshot contextDocumentSnapshot, WorkspaceEdit workspaceEdit, CancellationToken cancellationToken) { + if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) + { + throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); + } + if (workspaceEdit.DocumentChanges is not null) { using var builder = new PooledArrayBuilder>(); @@ -27,7 +32,7 @@ public async Task MapWorkspaceEditAsync(IDocumentSnapshot contextDocumentSnapsho { if (edit.TryGetFirst(out var textDocumentEdit)) { - await MapTextDocumentEditAsync(contextDocumentSnapshot, textDocumentEdit, cancellationToken).ConfigureAwait(false); + await MapTextDocumentEditAsync(originSnapshot, textDocumentEdit, cancellationToken).ConfigureAwait(false); if (textDocumentEdit.Edits.Length == 0) { continue; @@ -42,11 +47,11 @@ public async Task MapWorkspaceEditAsync(IDocumentSnapshot contextDocumentSnapsho if (workspaceEdit.Changes is { } changeMap) { - workspaceEdit.Changes = await MapDocumentEditsAsync(contextDocumentSnapshot, changeMap, cancellationToken).ConfigureAwait(false); + workspaceEdit.Changes = await MapDocumentEditsAsync(originSnapshot, changeMap, cancellationToken).ConfigureAwait(false); } } - private async Task MapTextDocumentEditAsync(IDocumentSnapshot contextDocumentSnapshot, TextDocumentEdit entry, CancellationToken cancellationToken) + private async Task MapTextDocumentEditAsync(RemoteDocumentSnapshot contextDocumentSnapshot, TextDocumentEdit entry, CancellationToken cancellationToken) { var generatedDocumentUri = entry.TextDocument.DocumentUri.GetRequiredSystemUri(); @@ -68,16 +73,14 @@ private async Task MapTextDocumentEditAsync(IDocumentSnapshot contextDocumentSna return; } - var razorDocumentUri = await GetRazorDocumentUriAsync(contextDocumentSnapshot, generatedDocumentUri, cancellationToken).ConfigureAwait(false); - if (razorDocumentUri is null) + var solution = contextDocumentSnapshot.TextDocument.Project.Solution; + var razorDocument = await _snapshotManager.TryGetRazorDocumentAsync(solution, generatedDocumentUri, cancellationToken).ConfigureAwait(false); + if (razorDocument is null) { return; } - if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, out var documentContext)) - { - return; - } + var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); var edits = new TextEdit[entry.Edits.Length]; for (var i = 0; i < entry.Edits.Length; i++) @@ -86,17 +89,17 @@ private async Task MapTextDocumentEditAsync(IDocumentSnapshot contextDocumentSna edits[i] = (TextEdit)entry.Edits[i]; } - var mappedEdits = await GetMappedTextEditsAsync(documentContext, edits, cancellationToken).ConfigureAwait(false); + var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, edits, cancellationToken).ConfigureAwait(false); // Update the entry in-place entry.TextDocument = new OptionalVersionedTextDocumentIdentifier() { - DocumentUri = razorDocumentUri.CreateDocumentUriFromSystemUri(), + DocumentUri = razorDocument.GetURI(), }; entry.Edits = mappedEdits.SelectAsPlainArray(static e => new SumType(e)); } - private async Task> MapDocumentEditsAsync(IDocumentSnapshot contextDocumentSnapshot, Dictionary changes, CancellationToken cancellationToken) + private async Task> MapDocumentEditsAsync(RemoteDocumentSnapshot contextDocumentSnapshot, Dictionary changes, CancellationToken cancellationToken) { var mappedChanges = new Dictionary(capacity: changes.Count); @@ -118,76 +121,37 @@ private async Task> MapDocumentEditsAsync(IDocume continue; } - var razorDocumentUri = await GetRazorDocumentUriAsync(contextDocumentSnapshot, generatedDocumentUri, cancellationToken).ConfigureAwait(false); - if (razorDocumentUri is null) + var solution = contextDocumentSnapshot.TextDocument.Project.Solution; + var razorDocument = await _snapshotManager.TryGetRazorDocumentAsync(solution, generatedDocumentUri, cancellationToken).ConfigureAwait(false); + if (razorDocument is null) { continue; } - if (!TryGetDocumentContext(contextDocumentSnapshot, razorDocumentUri, out var documentContext)) - { - continue; - } + var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); - var mappedEdits = await GetMappedTextEditsAsync(documentContext, edits, cancellationToken).ConfigureAwait(false); + var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, edits, cancellationToken).ConfigureAwait(false); if (mappedEdits.Length == 0) { // Nothing to do. continue; } - mappedChanges[razorDocumentUri.AbsoluteUri] = ImmutableCollectionsMarshal.AsArray(mappedEdits)!; + mappedChanges[razorDocument.CreateSystemUri().AbsoluteUri] = ImmutableCollectionsMarshal.AsArray(mappedEdits)!; } return mappedChanges; } - private async Task> GetMappedTextEditsAsync(DocumentContext documentContext, TextEdit[] edits, CancellationToken cancellationToken) + private async Task> GetMappedTextEditsAsync(RemoteDocumentSnapshot snapshot, TextEdit[] edits, CancellationToken cancellationToken) { - var codeDocument = await documentContext.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); + var codeDocument = await snapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); var razorSourceText = codeDocument.Source.Text; var csharpSourceText = codeDocument.GetCSharpSourceText(); var textChanges = edits.SelectAsArray(csharpSourceText.GetRazorTextChange); - var mappedEdits = await MapCSharpEditsAsync(textChanges, documentContext.Snapshot, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, cancellationToken).ConfigureAwait(false); + var mappedEdits = await MapCSharpEditsAsync(textChanges, snapshot, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, cancellationToken).ConfigureAwait(false); return mappedEdits.SelectAsArray(razorSourceText.GetTextEdit); } - - private bool TryGetDocumentContext(IDocumentSnapshot contextDocumentSnapshot, Uri razorDocumentUri, [NotNullWhen(true)] out DocumentContext? documentContext) - { - if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) - { - throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); - } - - var solution = originSnapshot.TextDocument.Project.Solution; - if (!solution.TryGetRazorDocument(razorDocumentUri, out var razorDocument)) - { - documentContext = null; - return false; - } - - var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); - - documentContext = new RemoteDocumentContext(razorDocumentUri.CreateDocumentUriFromSystemUri(), razorDocumentSnapshot); - return true; - } - - private async Task GetRazorDocumentUriAsync(IDocumentSnapshot contextDocumentSnapshot, Uri generatedDocumentUri, CancellationToken cancellationToken) - { - if (contextDocumentSnapshot is not RemoteDocumentSnapshot originSnapshot) - { - throw new InvalidOperationException("RemoteRazorEditService can only be used with RemoteDocumentSnapshot instances."); - } - - var solution = originSnapshot.TextDocument.Project.Solution; - var razorCodeDocument = await _snapshotManager.TryGetRazorCodeDocumentAsync(solution, generatedDocumentUri, cancellationToken).ConfigureAwait(false); - if (razorCodeDocument is null) - { - return null; - } - - return solution.GetRazorDocumentUri(razorCodeDocument); - } } From 9fa00753d3a68e00eefeffc83a965fb42aec3918 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 12:10:12 +1000 Subject: [PATCH 07/34] Make edit service and mapping service handle multiple C# documents --- .../DocumentMapping/IRazorEditService.cs | 1 + .../Extensions/RazorCodeDocumentExtensions.cs | 14 ++++++++ .../Passes/CSharpOnTypeFormattingPass.cs | 3 +- .../IRazorEditServiceExtensions.cs | 22 ++++++++++++ .../DocumentMapping/RazorEditService.cs | 8 +++-- .../RazorEditService_WorkspaceEdit.cs | 24 ++++++++----- .../RemoteSpanMappingService.cs | 35 ++++++++++--------- .../Mapping/RazorEditServiceTest.cs | 1 + 8 files changed, 79 insertions(+), 29 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditService.cs index 5dcb22686dfa..cb8361846da5 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IRazorEditService.cs @@ -28,6 +28,7 @@ internal interface IRazorEditService Task> MapCSharpEditsAsync( ImmutableArray textChanges, IDocumentSnapshot snapshot, + bool declarationDocument, bool includeCSharpLanguageFeatureEdits, Func? directlyMappedEditFilter, CancellationToken cancellationToken); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.cs index 61dd411b06f7..63f24eed6405 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using Microsoft.AspNetCore.Razor.Language.Intermediate; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; @@ -58,6 +60,18 @@ public static RazorCSharpDocument GetCSharpDocumentForHintName(this RazorCodeDoc return document.GetRequiredCSharpDocument(declarationDocument: false); } + public static bool TryGetCSharpDocumentForGeneratedUri(this RazorCodeDocument codeDocument, Solution solution, Uri generatedDocumentUri, [NotNullWhen(true)] out RazorCSharpDocument? csharpDocument) + { + if (solution.TryGetSourceGeneratedDocumentIdentity(generatedDocumentUri, out var identity)) + { + csharpDocument = GetCSharpDocumentForHintName(codeDocument, identity.HintName); + return true; + } + + csharpDocument = null; + return false; + } + public static SourceText GetHtmlSourceText(this RazorCodeDocument document, CancellationToken cancellationToken) => GetCachedData(document).GetOrComputeHtmlDocument(cancellationToken).Text; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs index cd70641abd9e..115635498dd9 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -117,6 +117,7 @@ public async Task> ExecuteAsync(FormattingContext con var mappedChanges = await _razorEditService.MapCSharpEditsAsync( normalizedChanges.SelectAsArray(static c => c.ToRazorTextChange()), context.CurrentSnapshot, + declarationDocument: false, // PROTOTYPE: Still to fix context.IncludeCSharpLanguageFeatureEdits, directlyMappedEditFilter: change => ShouldKeepDirectlyMappedEdit(context, indent, change), cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs index 8008d03a73b3..79f73d2d0bab 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IRazorEditServiceExtensions.cs @@ -13,6 +13,9 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal static class IRazorEditServiceExtensions { +#if SONICDEV + [System.Obsolete("PROTOTYPE(sonic): Call the overload that takes a bool to prove that you thought about which document to get")] +#endif public static async Task> MapCSharpEditsAsync( this IRazorEditService service, ImmutableArray textChanges, @@ -22,6 +25,25 @@ public static async Task> MapCSharpEditsAsync( var mappedChanges = await service.MapCSharpEditsAsync( textChanges.SelectAsArray(static c => c.ToRazorTextChange()), snapshot, + declarationDocument: false, + includeCSharpLanguageFeatureEdits: true, + directlyMappedEditFilter: null, + cancellationToken).ConfigureAwait(false); + + return mappedChanges.SelectAsArray(static c => c.ToTextChange()); + } + + public static async Task> MapCSharpEditsAsync( + this IRazorEditService service, + ImmutableArray textChanges, + bool declarationDocument, + IDocumentSnapshot snapshot, + CancellationToken cancellationToken) + { + var mappedChanges = await service.MapCSharpEditsAsync( + textChanges.SelectAsArray(static c => c.ToRazorTextChange()), + snapshot, + declarationDocument, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs index cd6c5b4688c7..a09ffda21abe 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService.cs @@ -44,6 +44,7 @@ internal sealed partial class RazorEditService( public async Task> MapCSharpEditsAsync( ImmutableArray textChanges, IDocumentSnapshot snapshot, + bool declarationDocument, bool includeCSharpLanguageFeatureEdits, Func? directlyMappedEditFilter, CancellationToken cancellationToken) @@ -51,13 +52,13 @@ public async Task> MapCSharpEditsAsync( var codeDocument = await snapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); using var edits = new PooledArrayBuilder(); - AddDirectlyMappedEdits(ref edits.AsRef(), textChanges, codeDocument, directlyMappedEditFilter, cancellationToken, out var skippedEdits); + AddDirectlyMappedEdits(ref edits.AsRef(), declarationDocument, textChanges, codeDocument, directlyMappedEditFilter, cancellationToken, out var skippedEdits); if (includeCSharpLanguageFeatureEdits && skippedEdits.Length != 0) { // If there was something that didn't map, and the caller wants us to, we need to process the generated C# document // that Roslyn wanted to produce, and look for changes that we can translate into their Razor equivalents. - var originalCSharpSyntaxTree = await snapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var originalCSharpSyntaxTree = await snapshot.GetCSharpSyntaxTreeAsync(declarationDocument, cancellationToken).ConfigureAwait(false); var originalCSharpSourceText = await originalCSharpSyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var originalCSharpSyntaxRoot = await originalCSharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); @@ -296,6 +297,7 @@ private static bool StrictlyContains(TextSpan outer, TextSpan inner) /// private void AddDirectlyMappedEdits( ref PooledArrayBuilder edits, + bool declarationDocument, ImmutableArray csharpEdits, RazorCodeDocument codeDocument, Func? directlyMappedEditFilter, @@ -303,7 +305,7 @@ private void AddDirectlyMappedEdits( out ImmutableArray skippedEdits) { var root = codeDocument.GetRequiredSyntaxRoot(); - var csharpDocument = codeDocument.GetRequiredImplCSharpDocument(); + var csharpDocument = codeDocument.GetRequiredCSharpDocument(declarationDocument); using var skipped = new PooledArrayBuilder(); foreach (var csharpEdit in csharpEdits) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs index 2a6a2324fc2a..ef0a4a88df86 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_WorkspaceEdit.cs @@ -81,6 +81,11 @@ private async Task MapTextDocumentEditAsync(RemoteDocumentSnapshot contextDocume } var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); + var codeDocument = await razorDocumentSnapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + if (!codeDocument.TryGetCSharpDocumentForGeneratedUri(solution, generatedDocumentUri, out var csharpDocument)) + { + return; + } var edits = new TextEdit[entry.Edits.Length]; for (var i = 0; i < entry.Edits.Length; i++) @@ -89,7 +94,7 @@ private async Task MapTextDocumentEditAsync(RemoteDocumentSnapshot contextDocume edits[i] = (TextEdit)entry.Edits[i]; } - var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, edits, cancellationToken).ConfigureAwait(false); + var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, csharpDocument, edits, cancellationToken).ConfigureAwait(false); // Update the entry in-place entry.TextDocument = new OptionalVersionedTextDocumentIdentifier() @@ -129,8 +134,13 @@ private async Task> MapDocumentEditsAsync(RemoteD } var razorDocumentSnapshot = _snapshotManager.GetSnapshot(razorDocument); + var codeDocument = await razorDocumentSnapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + if (!codeDocument.TryGetCSharpDocumentForGeneratedUri(solution, generatedDocumentUri, out var csharpDocument)) + { + continue; + } - var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, edits, cancellationToken).ConfigureAwait(false); + var mappedEdits = await GetMappedTextEditsAsync(razorDocumentSnapshot, csharpDocument, edits, cancellationToken).ConfigureAwait(false); if (mappedEdits.Length == 0) { // Nothing to do. @@ -143,14 +153,12 @@ private async Task> MapDocumentEditsAsync(RemoteD return mappedChanges; } - private async Task> GetMappedTextEditsAsync(RemoteDocumentSnapshot snapshot, TextEdit[] edits, CancellationToken cancellationToken) + private async Task> GetMappedTextEditsAsync(RemoteDocumentSnapshot snapshot, RazorCSharpDocument csharpDocument, TextEdit[] edits, CancellationToken cancellationToken) { - var codeDocument = await snapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); - - var razorSourceText = codeDocument.Source.Text; - var csharpSourceText = codeDocument.GetCSharpSourceText(); + var razorSourceText = csharpDocument.CodeDocument.Source.Text; + var csharpSourceText = csharpDocument.Text; var textChanges = edits.SelectAsArray(csharpSourceText.GetRazorTextChange); - var mappedEdits = await MapCSharpEditsAsync(textChanges, snapshot, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, cancellationToken).ConfigureAwait(false); + var mappedEdits = await MapCSharpEditsAsync(textChanges, snapshot, csharpDocument.IsDeclarationDocument, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, cancellationToken).ConfigureAwait(false); return mappedEdits.SelectAsArray(razorSourceText.GetTextEdit); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs index d620403ffa95..ca82011e75a7 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RemoteSpanMappingService.cs @@ -57,8 +57,9 @@ protected override IRemoteSpanMappingService CreateService(in ServiceArgs args) var documentSnapshot = _snapshotManager.GetSnapshot(razorDocument); var codeDocument = await documentSnapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + var csharpDocument = codeDocument.GetCSharpDocumentForHintName(generatedDocument.Identity.HintName); - var mappedSpans = await MapSpansAsync(documentSnapshot, codeDocument, generatedDocument.HintName, [span], cancellationToken).ConfigureAwait(false); + var mappedSpans = await MapSpansAsync(documentSnapshot, csharpDocument, [span], cancellationToken).ConfigureAwait(false); if (mappedSpans is not [{ IsDefault: false } mappedSpan]) { return null; @@ -106,22 +107,23 @@ private async ValueTask> MapSpansAsync(So var documentSnapshot = _snapshotManager.GetSnapshot(razorDocument); var codeDocument = await documentSnapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + var csharpDocument = codeDocument.GetCSharpDocumentForHintName(generatedDocument.Identity.HintName); - return await MapSpansAsync(documentSnapshot, codeDocument, generatedDocument.HintName, spans, cancellationToken).ConfigureAwait(false); + return await MapSpansAsync(documentSnapshot, csharpDocument, spans, cancellationToken).ConfigureAwait(false); } - private static async Task> MapSpansAsync(RemoteDocumentSnapshot documentSnapshot, RazorCodeDocument codeDocument, string generatedDocumentHintName, ImmutableArray spans, CancellationToken cancellationToken) + private static async Task> MapSpansAsync(RemoteDocumentSnapshot documentSnapshot, RazorCSharpDocument csharpDocument, ImmutableArray spans, CancellationToken cancellationToken) { - var csharpSyntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var csharpSyntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(csharpDocument.IsDeclarationDocument, cancellationToken).ConfigureAwait(false); var csharpSyntaxNode = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + var codeDocument = csharpDocument.CodeDocument; var source = codeDocument.Source.Text; // Pick the half of the generated source that the requested span actually lives in. // Roslyn calls us back with positions in either the impl (.razor.g.cs) or decl // (.razor.g.cs.decl.g.cs) generated document, and the source mappings live on the // matching half. - var csharpDocument = codeDocument.GetCSharpDocumentForHintName(generatedDocumentHintName); var filePath = codeDocument.Source.FilePath.AssumeNotNull(); var classDeclSpan = csharpSyntaxNode.TryGetClassDeclaration(out var classDecl) @@ -199,15 +201,25 @@ private async ValueTask> MapTextChangesAs { try { - var razorDocument = await TryGetRazorDocumentForGeneratedDocumentIdAsync(generatedDocumentId, solution, cancellationToken).ConfigureAwait(false); + var generatedDocument = await solution.GetSourceGeneratedDocumentAsync(generatedDocumentId, cancellationToken).ConfigureAwait(false); + if (generatedDocument is null) + { + return []; + } + + var razorDocument = await TryGetRazorDocumentForGeneratedDocumentAsync(generatedDocument, cancellationToken).ConfigureAwait(false); if (razorDocument is null) { return []; } + var codeDocument = await _snapshotManager.GetSnapshot(razorDocument).GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + var csharpDocument = codeDocument.GetCSharpDocumentForHintName(generatedDocument.Identity.HintName); + var documentSnapshot = _snapshotManager.GetSnapshot(razorDocument); var textChanges = await _razorEditService.MapCSharpEditsAsync( changes, + csharpDocument.IsDeclarationDocument, documentSnapshot, cancellationToken).ConfigureAwait(false); @@ -225,17 +237,6 @@ private async ValueTask> MapTextChangesAs } } - private async Task TryGetRazorDocumentForGeneratedDocumentIdAsync(DocumentId generatedDocumentId, Solution solution, CancellationToken cancellationToken) - { - var generatedDocument = await solution.GetSourceGeneratedDocumentAsync(generatedDocumentId, cancellationToken).ConfigureAwait(false); - if (generatedDocument is null) - { - return null; - } - - return await TryGetRazorDocumentForGeneratedDocumentAsync(generatedDocument, cancellationToken).ConfigureAwait(false); - } - private async Task TryGetRazorDocumentForGeneratedDocumentAsync(SourceGeneratedDocument generatedDocument, CancellationToken cancellationToken) { var identity = generatedDocument.Identity; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs index 2e28140a423c..d051d37ff9c9 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Mapping/RazorEditServiceTest.cs @@ -2033,6 +2033,7 @@ private async Task TestAsync( var responseTextChanges = await _razorEditService.AssumeNotNull().MapCSharpEditsAsync( changes.SelectAsArray(static c => c.ToRazorTextChange()), snapshot, + declarationDocument: false, includeCSharpLanguageFeatureEdits: true, directlyMappedEditFilter: null, CancellationToken.None); From db803ac9fe7a516a0463ee208d1f4982943b499e Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 12:42:49 +1000 Subject: [PATCH 08/34] Move document position info code May as well move this now. Can't move the rest until we do formatting --- .../AutoInsert/RemoteAutoInsertService.cs | 2 +- .../DocumentMapping/DefaultDocumentPositionInfoStrategy.cs | 3 ++- .../DocumentMapping/IDocumentPositionInfoStrategy.cs | 3 ++- .../PreferAttributeNameDocumentPositionInfoStrategy.cs | 4 +++- .../PreferHtmlInAttributeValuesDocumentPositionStrategy.cs | 3 ++- .../FindAllReferences/RemoteFindAllReferencesService.cs | 1 - .../GoToDefinition/RemoteGoToDefinitionService.cs | 1 - .../GoToImplementation/RemoteGoToImplementationService.cs | 1 - .../Hover/RemoteHoverService.cs | 1 + .../RazorDocumentServiceBase.cs | 5 +++-- .../Rename/RemoteRenameService.cs | 3 ++- .../TypeHierarchy/RemoteTypeHierarchyService.cs | 1 - ...rHtmlInAttributeValuesDocumentPositionInfoStrategyTest.cs | 1 + 13 files changed, 17 insertions(+), 12 deletions(-) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs (85%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/IDocumentPositionInfoStrategy.cs (76%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs (92%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs (95%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs index 629129167f17..b2678b8f2e9a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs @@ -8,7 +8,6 @@ using Microsoft.CodeAnalysis.LanguageServer.Handler; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Razor.AutoInsert; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Protocol; @@ -16,6 +15,7 @@ using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Razor.Workspaces.Settings; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs similarity index 85% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs index 5f231ff61c7b..92dd794661d7 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/DefaultDocumentPositionInfoStrategy.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal sealed class DefaultDocumentPositionInfoStrategy : IDocumentPositionInfoStrategy { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IDocumentPositionInfoStrategy.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentPositionInfoStrategy.cs similarity index 76% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IDocumentPositionInfoStrategy.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentPositionInfoStrategy.cs index 9e208690f94a..ddd23c74698b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/IDocumentPositionInfoStrategy.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/IDocumentPositionInfoStrategy.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; internal interface IDocumentPositionInfoStrategy { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs similarity index 92% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs index 30c7a3f8e160..09458db3c953 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferAttributeNameDocumentPositionInfoStrategy.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; /// /// A projection strategy that, when given a position that occurs anywhere in an attribute name, will return the projection diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs similarity index 95% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs index 550c0c2ef2b5..5fd5ce06a55a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/PreferHtmlInAttributeValuesDocumentPositionStrategy.cs @@ -3,9 +3,10 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Syntax; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; -namespace Microsoft.CodeAnalysis.Razor.DocumentMapping; +namespace Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; // The main reason for this service is auto-insert of empty double quotes when a user types // equals "=" after Blazor component attribute. We think this is C# (correctly I guess) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FindAllReferences/RemoteFindAllReferencesService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FindAllReferences/RemoteFindAllReferencesService.cs index 15b24a856ab7..227e2160acdb 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FindAllReferences/RemoteFindAllReferencesService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FindAllReferences/RemoteFindAllReferencesService.cs @@ -12,7 +12,6 @@ using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs index e2114701263e..9e1a7a8de1c1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.GoToDefinition; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToImplementation/RemoteGoToImplementationService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToImplementation/RemoteGoToImplementationService.cs index ae9a933fb6da..baf698b47a4a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToImplementation/RemoteGoToImplementationService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToImplementation/RemoteGoToImplementationService.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.LanguageServer.Handler; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Hover/RemoteHoverService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Hover/RemoteHoverService.cs index faec82fa616e..f6b6caa85a72 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Hover/RemoteHoverService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Hover/RemoteHoverService.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.Hover; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using static Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RazorDocumentServiceBase.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RazorDocumentServiceBase.cs index a875d1f35a71..7cb2ccdd6e8e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RazorDocumentServiceBase.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RazorDocumentServiceBase.cs @@ -5,11 +5,12 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; -using Microsoft.CodeAnalysis.LanguageServer; namespace Microsoft.CodeAnalysis.Remote.Razor; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Rename/RemoteRenameService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Rename/RemoteRenameService.cs index c1ea76ea8fec..e6caa8975a3a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Rename/RemoteRenameService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Rename/RemoteRenameService.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; @@ -18,6 +18,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Remote.Razor.Rename; using Microsoft.CodeAnalysis.Text; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/TypeHierarchy/RemoteTypeHierarchyService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/TypeHierarchy/RemoteTypeHierarchyService.cs index a741ca881019..a2e7ad4e076d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/TypeHierarchy/RemoteTypeHierarchyService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/TypeHierarchy/RemoteTypeHierarchyService.cs @@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.LanguageServer.Handler.TypeHierarchy; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/AutoInsert/PreferHtmlInAttributeValuesDocumentPositionInfoStrategyTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/AutoInsert/PreferHtmlInAttributeValuesDocumentPositionInfoStrategyTest.cs index 7b4b4d18f8aa..f5bb5e082ccb 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/AutoInsert/PreferHtmlInAttributeValuesDocumentPositionInfoStrategyTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/AutoInsert/PreferHtmlInAttributeValuesDocumentPositionInfoStrategyTest.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Text; From b41ce6beed9fd0df3f92acf9624a3f317beca2ad Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 15:42:58 +1000 Subject: [PATCH 09/34] Remove unused Razor using directive Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../CallHierarchy/RemoteCallHierarchyService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CallHierarchy/RemoteCallHierarchyService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CallHierarchy/RemoteCallHierarchyService.cs index 038a422015d1..431b2eca369d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CallHierarchy/RemoteCallHierarchyService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CallHierarchy/RemoteCallHierarchyService.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.LanguageServer.Handler.CallHierarchy; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; From 6b65bbb2fd7921b0bf3f60c092a888c13793be3c Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 12:59:33 +1000 Subject: [PATCH 10/34] Move formatting files up to Remote.Razor --- .../Formatting/CSharpFormatter.cs | 0 .../Formatting/FormattedDocument.cs | 0 .../Formatting/FormattingBlockKind.cs | 0 .../Formatting/FormattingContext.cs | 0 .../Formatting/FormattingLogger.cs | 0 .../Formatting/FormattingLoggerFactory.cs | 0 .../Formatting/FormattingSpan.cs | 0 .../Formatting/FormattingSpanKind.cs | 0 .../Formatting/FormattingVisitor.cs | 0 .../Formatting/IFormattingLogger.cs | 0 .../Formatting/IFormattingLoggerFactory.cs | 0 .../Formatting/IFormattingPass.cs | 0 .../Formatting/IFormattingValidationPass.cs | 0 .../Formatting/IndentCache.cs | 0 .../Formatting/IndentationContext.cs | 0 .../Formatting/LineInfo.cs | 0 .../Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs | 0 .../Formatting/Passes/CSharpFormattingPass.cs | 0 .../Formatting/Passes/CSharpOnTypeFormattingPass.cs | 0 .../Formatting/Passes/FormattingContentValidationPass.cs | 0 .../Formatting/Passes/FormattingDiagnosticValidationPass.cs | 0 .../Formatting/Passes/HtmlFormattingPass.cs | 0 .../Formatting/Passes/HtmlOnTypeFormattingPass.cs | 0 .../Formatting/Passes/RazorFormattingPass.cs | 0 .../Formatting/Passes/RoslynWorkspaceHelper.cs | 0 .../Formatting/RazorFormattingService.cs | 0 .../Formatting/SnippetFormatter.cs | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/CSharpFormatter.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattedDocument.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingBlockKind.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingContext.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingLogger.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingLoggerFactory.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingSpan.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingSpanKind.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingVisitor.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IFormattingLogger.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IFormattingLoggerFactory.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IFormattingValidationPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IndentCache.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/IndentationContext.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/LineInfo.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/CSharpFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/CSharpOnTypeFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/FormattingContentValidationPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/FormattingDiagnosticValidationPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/HtmlFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/HtmlOnTypeFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/RazorFormattingPass.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/Passes/RoslynWorkspaceHelper.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/RazorFormattingService.cs (100%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/SnippetFormatter.cs (100%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormatter.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormatter.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattedDocument.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattedDocument.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingBlockKind.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingBlockKind.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingContext.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingContext.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingLogger.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingLogger.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingLoggerFactory.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingSpan.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingSpan.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingSpanKind.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingSpanKind.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingLogger.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingLogger.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingLoggerFactory.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IFormattingValidationPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IndentCache.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IndentCache.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IndentationContext.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IndentationContext.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/LineInfo.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/LineInfo.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpOnTypeFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/FormattingContentValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/FormattingContentValidationPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/FormattingDiagnosticValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/FormattingDiagnosticValidationPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlOnTypeFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/RazorFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/RazorFormattingPass.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/RoslynWorkspaceHelper.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/RoslynWorkspaceHelper.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/RazorFormattingService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/SnippetFormatter.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/SnippetFormatter.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs From 3796b77e205f3e2c341e8dfa530bb0190779d32d Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:11:21 +1000 Subject: [PATCH 11/34] Move almost all of FormattingUtilities There was one simple method that was called from the Workspaces layer, but that can just be an extension method --- .../Extensions/SourceTextExtensions.cs | 29 +++++++++++++++++ .../CodeActions/Html/HtmlCodeActionHelpers.cs | 4 +-- .../Formatting/FormattingUtilities.cs | 31 +------------------ .../Cohost/CohostWrapWithTagEndpoint.cs | 2 +- 4 files changed, 33 insertions(+), 33 deletions(-) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/Formatting/FormattingUtilities.cs (95%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/SourceTextExtensions.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/SourceTextExtensions.cs index f8e9ae9cd3a8..309f3d5772f3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/SourceTextExtensions.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/SourceTextExtensions.cs @@ -370,4 +370,33 @@ public static ImmutableArray GetTextChangesArray(this SourceText new return list.ToImmutableArray(); } + + /// + /// Sometimes the Html language server will send back an edit that contains a tilde, because the generated + /// document we send them has lots of tildes. In those cases, we need to do some extra work to compute the + /// minimal text edits + /// + public static TextEdit[] FixHtmlTextEdits(this SourceText htmlSourceText, TextEdit[] edits) + { + // Avoid computing a minimal diff if we don't need to + if (!edits.Any(static e => e.NewText.Contains('~'))) + return edits; + + var changes = edits.SelectAsArray(htmlSourceText.GetTextChange); + + var fixedChanges = htmlSourceText.MinimizeTextChanges(changes); + return fixedChanges.SelectAsPlainArray(htmlSourceText.GetTextEdit); + } + + public static SumType[] FixHtmlTextEdits(this SourceText htmlSourceText, SumType[] edits) + { + // Avoid computing a minimal diff if we don't need to + if (!edits.Any(static e => ((TextEdit)e).NewText.Contains('~'))) + return edits; + + var changes = edits.SelectAsArray(e => htmlSourceText.GetTextChange((TextEdit)e)); + + var fixedChanges = htmlSourceText.MinimizeTextChanges(changes); + return fixedChanges.SelectAsPlainArray>(c => htmlSourceText.GetTextEdit(c)); + } } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Html/HtmlCodeActionHelpers.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Html/HtmlCodeActionHelpers.cs index 31a79e3ec43e..e8595aee8e6e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Html/HtmlCodeActionHelpers.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Html/HtmlCodeActionHelpers.cs @@ -4,8 +4,8 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; namespace Microsoft.CodeAnalysis.Razor.CodeActions; @@ -23,7 +23,7 @@ internal static async Task MapAndFixHtmlCodeActionEditAsync(IRazorEditService ra foreach (var edit in codeAction.Edit.EnumerateTextDocumentEdits()) { - edit.Edits = FormattingUtilities.FixHtmlTextEdits(htmlSourceText, edit.Edits); + edit.Edits = htmlSourceText.FixHtmlTextEdits(edit.Edits); } } } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingUtilities.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs similarity index 95% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingUtilities.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs index ed1abfce3f1b..7c2df36dbf8c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingUtilities.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal static class FormattingUtilities { @@ -208,35 +208,6 @@ static ImmutableArray GetLineRanges(string text) } } - /// - /// Sometimes the Html language server will send back an edit that contains a tilde, because the generated - /// document we send them has lots of tildes. In those cases, we need to do some extra work to compute the - /// minimal text edits - /// - public static TextEdit[] FixHtmlTextEdits(SourceText htmlSourceText, TextEdit[] edits) - { - // Avoid computing a minimal diff if we don't need to - if (!edits.Any(static e => e.NewText.Contains('~'))) - return edits; - - var changes = edits.SelectAsArray(htmlSourceText.GetTextChange); - - var fixedChanges = htmlSourceText.MinimizeTextChanges(changes); - return fixedChanges.SelectAsPlainArray(htmlSourceText.GetTextEdit); - } - - internal static SumType[] FixHtmlTextEdits(SourceText htmlSourceText, SumType[] edits) - { - // Avoid computing a minimal diff if we don't need to - if (!edits.Any(static e => ((TextEdit)e).NewText.Contains('~'))) - return edits; - - var changes = edits.SelectAsArray(e => htmlSourceText.GetTextChange((TextEdit)e)); - - var fixedChanges = htmlSourceText.MinimizeTextChanges(changes); - return fixedChanges.SelectAsPlainArray>(c => htmlSourceText.GetTextEdit(c)); - } - public static void GetOriginalDocumentChangesFromLineInfo(FormattingContext context, SourceText originalText, ImmutableArray formattedLineInfo, SourceText formattedText, ILogger logger, Func? shouldKeepInsertedNewlineAtPosition, ref PooledArrayBuilder formattingChanges, out int lastFormattedTextLine) { var iFormatted = 0; diff --git a/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs index 93a787cfbf46..cecbcb3b312e 100644 --- a/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs @@ -92,7 +92,7 @@ internal sealed class CohostWrapWithTagEndpoint( } var htmlSourceText = htmlDocument.Snapshot.AsText(); - htmlResponse.TextEdits = FormattingUtilities.FixHtmlTextEdits(htmlSourceText, edits); + htmlResponse.TextEdits = htmlSourceText.FixHtmlTextEdits(edits); } return htmlResponse; From d60bd03b9246632dd92a995e3fceaf2a160a768f Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:24:07 +1000 Subject: [PATCH 12/34] Move C# formatting options helper back a to shared location --- .../CohostDocumentFormattingEndpoint.cs | 2 +- .../CohostOnTypeFormattingEndpoint.cs | 2 +- .../CohostRangeFormattingEndpoint.cs | 2 +- .../CSharpFormattingOptionsHelper.cs | 43 +++++++++++++++++++ .../Formatting/CSharpFormatter.cs | 40 ++--------------- .../Formatting/Passes/CSharpFormattingPass.cs | 2 +- 6 files changed, 51 insertions(+), 40 deletions(-) create mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormattingOptionsHelper.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostDocumentFormattingEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostDocumentFormattingEndpoint.cs index dbfb7d7b2b2d..85bf85a96f07 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostDocumentFormattingEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostDocumentFormattingEndpoint.cs @@ -62,7 +62,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie protected override Task HandleRequestAsync(DocumentFormattingParams request, TextDocument razorDocument, CancellationToken cancellationToken) { - var csharpSyntaxFormattingOptions = CSharpFormatter.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); + var csharpSyntaxFormattingOptions = CSharpFormattingOptionsHelper.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); return HandleRequestAsync(request, razorDocument, csharpSyntaxFormattingOptions, cancellationToken); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs index f77fde5d2494..9cb6b383aa75 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs @@ -112,7 +112,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie htmlChanges = htmlEdits.SelectAsArray(sourceText.GetTextChange); } - var csharpSyntaxFormattingOptions = CSharpFormatter.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); + var csharpSyntaxFormattingOptions = CSharpFormattingOptionsHelper.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); var options = RazorFormattingOptions.From(request.Options, clientSettings.AdvancedSettings.CodeBlockBraceOnNextLine, clientSettings.AdvancedSettings.AttributeIndentStyle, csharpSyntaxFormattingOptions); _logger.LogDebug($"Calling OOP with the {htmlChanges.Length} html edits, so it can fill in the rest"); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostRangeFormattingEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostRangeFormattingEndpoint.cs index fe704f082ccf..42621fbc8fc4 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostRangeFormattingEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostRangeFormattingEndpoint.cs @@ -83,7 +83,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie var sourceText = await razorDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var htmlChanges = htmlEdits.SelectAsArray(sourceText.GetTextChange); - var csharpSyntaxFormattingOptions = CSharpFormatter.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); + var csharpSyntaxFormattingOptions = CSharpFormattingOptionsHelper.GetCSharpSyntaxFormattingOptions(razorDocument.Project.Solution.Services, csharpSyntaxFormattingOptions: null); var options = RazorFormattingOptions.From( request.Options, _clientSettingsManager.GetClientSettings().AdvancedSettings.CodeBlockBraceOnNextLine, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormattingOptionsHelper.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormattingOptionsHelper.cs new file mode 100644 index 000000000000..ab41b3b2f906 --- /dev/null +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/CSharpFormattingOptionsHelper.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Razor.Formatting; + +internal static class CSharpFormattingOptionsHelper +{ + internal static CSharpSyntaxFormattingOptions GetCSharpSyntaxFormattingOptions( + SolutionServices services, + CSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions) + { + csharpSyntaxFormattingOptions + ??= (CSharpSyntaxFormattingOptions)(services.GetService()?.GetSyntaxFormattingOptions(services.GetLanguageServices(LanguageNames.CSharp)) + ?? CSharpSyntaxFormattingOptions.Default); + + return csharpSyntaxFormattingOptions; + } + + internal static CSharpSyntaxFormattingOptions GetResolvedCSharpSyntaxFormattingOptions( + SolutionServices services, + RazorFormattingOptions options, + CSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions = null) + { + csharpSyntaxFormattingOptions = GetCSharpSyntaxFormattingOptions( + services, + csharpSyntaxFormattingOptions ?? options.CSharpSyntaxFormattingOptions); + + return csharpSyntaxFormattingOptions with + { + LineFormatting = csharpSyntaxFormattingOptions.LineFormatting with + { + UseTabs = !options.InsertSpaces, + TabSize = options.TabSize, + IndentationSize = options.TabSize, + NewLine = CSharpSyntaxFormattingOptions.Default.NewLine + } + }; + } +} diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs index cae41d2912c3..492ddd2750c3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs @@ -13,47 +13,15 @@ using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Indentation; -using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class CSharpFormatter { private const string MarkerId = "RazorMarker"; - internal static CSharpSyntaxFormattingOptions GetCSharpSyntaxFormattingOptions( - SolutionServices services, - CSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions) - { - csharpSyntaxFormattingOptions - ??= (CSharpSyntaxFormattingOptions)(services.GetService()?.GetSyntaxFormattingOptions(services.GetLanguageServices(LanguageNames.CSharp)) - ?? CSharpSyntaxFormattingOptions.Default); - - return csharpSyntaxFormattingOptions; - } - - internal static CSharpSyntaxFormattingOptions GetResolvedCSharpSyntaxFormattingOptions( - SolutionServices services, - RazorFormattingOptions options, - CSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions = null) - { - csharpSyntaxFormattingOptions = GetCSharpSyntaxFormattingOptions( - services, - csharpSyntaxFormattingOptions ?? options.CSharpSyntaxFormattingOptions); - - return csharpSyntaxFormattingOptions with - { - LineFormatting = csharpSyntaxFormattingOptions.LineFormatting with - { - UseTabs = !options.InsertSpaces, - TabSize = options.TabSize, - IndentationSize = options.TabSize, - NewLine = CSharpSyntaxFormattingOptions.Default.NewLine - } - }; - } - internal static IndentationOptions GetIndentationOptions( SolutionServices services, RazorFormattingOptions options, @@ -61,7 +29,7 @@ internal static IndentationOptions GetIndentationOptions( FormattingOptions2.IndentStyle indentStyle, CSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions = null) { - var resolvedCSharpSyntaxFormattingOptions = GetResolvedCSharpSyntaxFormattingOptions( + var resolvedCSharpSyntaxFormattingOptions = CSharpFormattingOptionsHelper.GetResolvedCSharpSyntaxFormattingOptions( services, options, csharpSyntaxFormattingOptions); @@ -107,7 +75,7 @@ private static async Task> GetCSharpIndentationCoreAsync( // At this point, we have added all the necessary markers and attached annotations. // Let's invoke the C# formatter and hope for the best. - var formattingOptions = GetResolvedCSharpSyntaxFormattingOptions( + var formattingOptions = CSharpFormattingOptionsHelper.GetResolvedCSharpSyntaxFormattingOptions( hostWorkspaceServices.SolutionServices, context.Options); var formattedRoot = Formatter.Format( diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs index 0ee3e2624086..7471fd109d6b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs @@ -143,7 +143,7 @@ private async Task FormatCSharpAsync(SourceText generatedCSharpText, }; } - var formattingOptions = CSharpFormatter.GetResolvedCSharpSyntaxFormattingOptions( + var formattingOptions = CSharpFormattingOptionsHelper.GetResolvedCSharpSyntaxFormattingOptions( helper.HostWorkspaceServices.SolutionServices, options, csharpSyntaxFormattingOptions); From e4059b1b13b70a9662818740c1938b3b2cd736c0 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:27:09 +1000 Subject: [PATCH 13/34] Move trigger characters to where they're actually used --- .../Formatting/CohostOnTypeFormattingEndpoint.cs | 12 +++++++++--- .../Formatting/RazorFormattingService.cs | 4 ---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs index 9cb6b383aa75..d22a54ff1553 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs @@ -15,6 +15,8 @@ using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces.Settings; using Microsoft.CodeAnalysis.Text; +using System.Collections.Frozen; +using System; namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; @@ -33,6 +35,10 @@ internal sealed class CohostOnTypeFormattingEndpoint( ILoggerFactory loggerFactory) : AbstractCohostDocumentEndpoint(incompatibleProjectService), IDynamicRegistrationProvider { + private const string FirstTriggerCharacter = "}"; + private static readonly string[] MoreTriggerCharacters = [";", "\n", "{"]; + private static readonly FrozenSet AllTriggerCharacterSet = FrozenSet.ToFrozenSet([FirstTriggerCharacter, .. MoreTriggerCharacters], StringComparer.Ordinal); + private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker; private readonly IHtmlRequestInvoker _requestInvoker = requestInvoker; private readonly IClientSettingsManager _clientSettingsManager = clientSettingsManager; @@ -51,8 +57,8 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie Method = Methods.TextDocumentOnTypeFormattingName, RegisterOptions = new DocumentOnTypeFormattingRegistrationOptions() { - FirstTriggerCharacter = RazorFormattingService.FirstTriggerCharacter, - MoreTriggerCharacter = RazorFormattingService.MoreTriggerCharacters + FirstTriggerCharacter = FirstTriggerCharacter, + MoreTriggerCharacter = MoreTriggerCharacters } }]; } @@ -72,7 +78,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie return null; } - if (!RazorFormattingService.AllTriggerCharacterSet.Contains(request.Character)) + if (!AllTriggerCharacterSet.Contains(request.Character)) { _logger.LogWarning($"Unexpected trigger character '{request.Character}'."); return null; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs index d90b3576893e..59d10d654753 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs @@ -23,10 +23,6 @@ namespace Microsoft.CodeAnalysis.Razor.Formatting; internal class RazorFormattingService : IRazorFormattingService { - public const string FirstTriggerCharacter = "}"; - public static readonly string[] MoreTriggerCharacters = [";", "\n", "{"]; - public static readonly FrozenSet AllTriggerCharacterSet = FrozenSet.ToFrozenSet([FirstTriggerCharacter, .. MoreTriggerCharacters], StringComparer.Ordinal); - private static readonly FrozenSet s_csharpTriggerCharacterSet = FrozenSet.ToFrozenSet(["}", ";"], StringComparer.Ordinal); private static readonly FrozenSet s_htmlTriggerCharacterSet = FrozenSet.ToFrozenSet(["\n", "{", "}", ";"], StringComparer.Ordinal); From b63641bc8c592beb5e50cb918b2f968345f763eb Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:28:46 +1000 Subject: [PATCH 14/34] Fix namespaces and usings --- .../Razor/ExtractToComponentCodeActionResolver.cs | 1 + .../Razor/GenerateEventHandlerCodeActionResolver.cs | 1 + .../CodeActions/Razor/WrapAttributesCodeActionResolver.cs | 1 + .../DevTools/RemoteDevToolsService.cs | 2 +- .../DocumentMapping/RazorEditService_Members.cs | 1 + .../Formatting/FormattedDocument.cs | 2 +- .../Formatting/FormattingBlockKind.cs | 2 +- .../Formatting/FormattingContext.cs | 3 ++- .../Formatting/FormattingLogger.cs | 2 +- .../Formatting/FormattingLoggerFactory.cs | 2 +- .../Formatting/FormattingSpan.cs | 2 +- .../Formatting/FormattingSpanKind.cs | 2 +- .../Formatting/FormattingUtilities.cs | 2 -- .../Formatting/FormattingVisitor.cs | 2 +- .../Formatting/IFormattingLogger.cs | 2 +- .../Formatting/IFormattingLoggerFactory.cs | 2 +- .../Formatting/IFormattingPass.cs | 2 +- .../Formatting/IFormattingValidationPass.cs | 2 +- .../Formatting/IndentCache.cs | 2 +- .../Formatting/IndentationContext.cs | 2 +- .../Formatting/LineInfo.cs | 2 +- .../Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs | 6 ++++-- .../Formatting/Passes/CSharpFormattingPass.cs | 5 +++-- .../Formatting/Passes/CSharpOnTypeFormattingPass.cs | 2 +- .../Formatting/Passes/FormattingContentValidationPass.cs | 2 +- .../Formatting/Passes/FormattingDiagnosticValidationPass.cs | 2 +- .../Formatting/Passes/HtmlFormattingPass.cs | 5 +++-- .../Formatting/Passes/HtmlOnTypeFormattingPass.cs | 2 +- .../Formatting/Passes/RazorFormattingPass.cs | 2 +- .../Formatting/Passes/RoslynWorkspaceHelper.cs | 2 +- .../Formatting/RazorFormattingService.cs | 5 +++-- .../Formatting/SnippetFormatter.cs | 2 +- .../InlineCompletion/RemoteInlineCompletionService.cs | 1 + .../LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs | 3 +-- 34 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/ExtractToComponentCodeActionResolver.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/ExtractToComponentCodeActionResolver.cs index 05ff09101264..a57379fb2eac 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/ExtractToComponentCodeActionResolver.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/ExtractToComponentCodeActionResolver.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Razor; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; namespace Microsoft.CodeAnalysis.Remote.Razor.CodeActions; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs index 7cec116f595e..5f1fc72cf538 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/WrapAttributesCodeActionResolver.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/WrapAttributesCodeActionResolver.cs index ab61078be3e9..c9653e73c30d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/WrapAttributesCodeActionResolver.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/WrapAttributesCodeActionResolver.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.Razor.CodeActions.Models; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs index 3eb9d5045a3c..4d56e5463151 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs @@ -6,9 +6,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol.DevTools; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; namespace Microsoft.CodeAnalysis.Remote.Razor; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs index 58bb0517398c..1f8f9c9274f1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DocumentMapping/RazorEditService_Members.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using RoslynSyntaxNode = Microsoft.CodeAnalysis.SyntaxNode; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs index 1b9872152d30..3d1b0302ad5a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattedDocument.cs @@ -4,6 +4,6 @@ using System.Collections.Immutable; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal readonly record struct FormattedDocument(SourceText SourceText, ImmutableArray LineInfo); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs index 2ecdeba3b0b3..c927565efd29 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingBlockKind.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal enum FormattingBlockKind { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs index ead39bbbfa74..1be2c121c25f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs @@ -12,10 +12,11 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class FormattingContext { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs index 2c467a144993..83317ccb7a6c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLogger.cs @@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class FormattingLogger(string logFolder) : IFormattingLogger { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs index 25d166e452bc..abdad0dce7b8 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs @@ -4,7 +4,7 @@ using System; using System.IO; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal class FormattingLoggerFactory : IFormattingLoggerFactory { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs index cae8539161eb..c59b194bf82b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpan.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed record class FormattingSpan( TextSpan Span, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs index 42dfecfdb37d..d002a9b20be1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingSpanKind.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal enum FormattingSpanKind { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs index 7c2df36dbf8c..0b3e6ea737ba 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingUtilities.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using System.Linq; using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.Razor.Logging; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs index 5a392347cbb0..4932ae51ea71 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingVisitor.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Razor.Language.Components; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.AspNetCore.Razor.Language.Syntax; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs index 2d5c32380b05..2bea42b48b54 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLogger.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal interface IFormattingLogger { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs index 1ef008ea4552..3e5ce9082ca0 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingLoggerFactory.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal interface IFormattingLoggerFactory { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs index 96e185871a23..bb4a88004d47 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingPass.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal interface IFormattingPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs index 8dbdb39d0f4a..6935d3f4428d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IFormattingValidationPass.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal interface IFormattingValidationPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs index 55833c35cab6..279dfcfe9168 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentCache.cs @@ -6,7 +6,7 @@ #endif using Microsoft.AspNetCore.Razor; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal static class IndentCache { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs index 0ef3a2dae0a4..44895f428c38 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/IndentationContext.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed record class IndentationContext( FormattingSpan FirstSpan, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs index 0d0bf2221948..4a2ab71a06e0 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/LineInfo.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; /// /// Represents the state of a line in the generated C# document. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs index 486e445066fc..91172b45c9e4 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -12,14 +12,16 @@ using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Settings; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; using RazorSyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode; using RazorSyntaxToken = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxToken; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal partial class CSharpFormattingPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs index 7471fd109d6b..79462f3e2aae 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs @@ -1,4 +1,4 @@ - + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -12,12 +12,13 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.TextDifferencing; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed partial class CSharpFormattingPass( IHostServicesProvider hostServicesProvider, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs index 115635498dd9..42df390ca55c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs @@ -27,7 +27,7 @@ using Microsoft.VisualStudio.Threading; using RazorSyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; /// /// Gets edits in C# files, and returns edits to Razor files, with nicely formatted Html diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs index cc9377744f72..ccd61a0c3a7e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingContentValidationPass.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class FormattingContentValidationPass(ILoggerFactory loggerFactory) : IFormattingValidationPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs index 6b17d2425fd6..671af1a21dae 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/FormattingDiagnosticValidationPass.cs @@ -13,7 +13,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class FormattingDiagnosticValidationPass(ILoggerFactory loggerFactory) : IFormattingValidationPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs index 3516e2214d79..d4c75b976b20 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; @@ -11,13 +11,14 @@ using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.TextDifferencing; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed partial class HtmlFormattingPass( IDocumentMappingService documentMappingService, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs index c257aa95c393..e37dd6d52c6f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlOnTypeFormattingPass.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.Razor.TextDifferencing; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; /// /// Gets edits in Html files, and returns edits to Razor files, with nicely formatted Html diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs index 307efdf11477..5b790e5b0d66 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RazorFormattingPass.cs @@ -20,7 +20,7 @@ using RazorSyntaxNodeList = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxList; using RazorSyntaxNodeOrToken = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNodeOrToken; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class RazorFormattingPass : IFormattingPass { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs index 93c5a739ae10..19f961c0cf48 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/RoslynWorkspaceHelper.cs @@ -6,7 +6,7 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Razor.Workspaces; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal sealed class RoslynWorkspaceHelper(IHostServicesProvider hostServicesProvider) : IDisposable { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs index 59d10d654753..bae8a78c736a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -13,13 +13,14 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal class RazorFormattingService : IRazorFormattingService { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs index 46bbe91ba97c..a7bfd152a5ed 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/SnippetFormatter.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal static class SnippetFormatter { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlineCompletion/RemoteInlineCompletionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlineCompletion/RemoteInlineCompletionService.cs index 191b91abb46b..0e38f6f9fd8e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlineCompletion/RemoteInlineCompletionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlineCompletion/RemoteInlineCompletionService.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; diff --git a/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs index cecbcb3b312e..51df3c32acbe 100644 --- a/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostWrapWithTagEndpoint.cs @@ -8,10 +8,9 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor.CohostingShared; using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.Cohost; -using Microsoft.CodeAnalysis.Razor.Formatting; +using Microsoft.CodeAnalysis.Razor.CohostingShared; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; From 8f4a32d943d75d5571db93693a687055f9cda8aa Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:28:57 +1000 Subject: [PATCH 15/34] Add IVT --- .../Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Workspaces/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj b/src/Workspaces/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj index 416a6786cb74..a56728be8a9b 100644 --- a/src/Workspaces/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj +++ b/src/Workspaces/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj @@ -46,6 +46,7 @@ + From e46ed3272d4cee8f4577530ae95b93209303beae Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 14:29:09 +1000 Subject: [PATCH 16/34] Move resources --- .../Resources/SR.resx | 21 ----------- .../Resources/xlf/SR.cs.xlf | 35 ------------------- .../Resources/xlf/SR.de.xlf | 35 ------------------- .../Resources/xlf/SR.es.xlf | 35 ------------------- .../Resources/xlf/SR.fr.xlf | 35 ------------------- .../Resources/xlf/SR.it.xlf | 35 ------------------- .../Resources/xlf/SR.ja.xlf | 35 ------------------- .../Resources/xlf/SR.ko.xlf | 35 ------------------- .../Resources/xlf/SR.pl.xlf | 35 ------------------- .../Resources/xlf/SR.pt-BR.xlf | 35 ------------------- .../Resources/xlf/SR.ru.xlf | 35 ------------------- .../Resources/xlf/SR.tr.xlf | 35 ------------------- .../Resources/xlf/SR.zh-Hans.xlf | 35 ------------------- .../Resources/xlf/SR.zh-Hant.xlf | 35 ------------------- .../Resources/SR.resx | 21 +++++++++++ .../Resources/xlf/SR.cs.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.de.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.es.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.fr.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.it.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.ja.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.ko.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.pl.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.pt-BR.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.ru.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.tr.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.zh-Hans.xlf | 35 +++++++++++++++++++ .../Resources/xlf/SR.zh-Hant.xlf | 35 +++++++++++++++++++ 28 files changed, 476 insertions(+), 476 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx index 638a1fe1f226..e2e91b97e33c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/SR.resx @@ -136,24 +136,6 @@ Line '{0}' outside of the {1} range of '{2}' was queried. The document may not be up to date. - - A format operation is being abandoned because it would add or delete non-whitespace content. - - - Edit at {0} adds the non-whitespace content '{1}'. - - - Edit at {0} deletes the non-whitespace content '{1}'. - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - - - Diagnostics before: - - - Diagnostics after: - Razor language services not configured properly, missing language service '{0}'. @@ -197,9 +179,6 @@ {0} Keyword - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - ✅ Widely available across major browsers{0} {0} is " (Baseline since YYYY)" or empty diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf index feaeee861fc7..a414ab8ea2bb 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.cs.xlf @@ -32,16 +32,6 @@ Atributy direktivy Blazor - - Diagnostics after: - Diagnostika po: - - - - Diagnostics before: - Diagnostika před: - - directive direktiva @@ -54,31 +44,6 @@ [Tab] pro navigaci mezi elementy, [Enter] pro dokončení - - Edit at {0} adds the non-whitespace content '{1}'. - Úprava na {0} přidá neprázdný obsah {1}. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Úprava na {0} odstraní neprázdný obsah {1}. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Operace formátování je ukončována, protože by zavedla nebo odebrala jednu z více diagnostik. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Operace formátování je ukončována, protože by přidala nebo odstranila neprázdný obsah. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Chyba formátování Práce se přerušuje, aby nedošlo k poškození souboru, prosím nahlaste tento problém. Více informací zde: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Editor Razor využívá Generátor zdroje Razor, který vyžaduje, aby soubory *.razor a *.cshtml v projektu byly AdditionalFiles. {0} nejspíš pochází z: {1} a neobsahuje žádné dokumenty Razor, které jsou AdditionalFiles, takže možnosti úprav budou omezené. Používá sadu Razor SDK? Pro tento projekt se nebudou protokolovat žádné další zprávy. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf index 47150b14b26e..9204ba99a7c3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.de.xlf @@ -32,16 +32,6 @@ Attribute für Blazor-Direktiven - - Diagnostics after: - Diagnose nach: - - - - Diagnostics before: - Diagnose vor: - - directive Direktive @@ -54,31 +44,6 @@ [Registerkarte] ein, um zwischen Elementen zu navigieren, [EINGABETASTE], um den Vorgang abzuschließen - - Edit at {0} adds the non-whitespace content '{1}'. - Das Bearbeiten bei {0} fügt den Nicht-Leerraum-Inhalt "{1}" hinzu. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Das Bearbeiten bei {0} löscht den Nicht-Leerraum-Inhalt "{1}". - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Ein Formatierungsvorgang wird abgebrochen, weil er eine oder mehrere Diagnosen einführen oder entfernen würde. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Ein Formatierungsvorgang wird abgebrochen, da er Nicht-Leerraum-Inhalte hinzufügen oder löschen würde. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Formatierungsfehler Die weitere Bearbeitung wird abgebrochen, um die Datei nicht zu beschädigen. Melden Sie dieses Problem. Weitere Informationen unter https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Der Razor-Editor verwendet den Razor-Quellgenerator, der *.razor- und *.cshtml-Dateien als AdditionalFiles im Projekt erfordert. {0} scheint von „{1}“ zu stammen, das keine Razor-Dokumente enthält, die "AdditionalFiles" sind, sodass die Bearbeitungserfahrung eingeschränkt ist. Wird das Razor SDK verwendet? Für dieses Projekt werden keine weiteren Nachrichten protokolliert. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf index bea3924ab7be..7ea6af6811b4 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.es.xlf @@ -32,16 +32,6 @@ Atributos de directiva de Blazor - - Diagnostics after: - Diagnósticos después de: - - - - Diagnostics before: - Diagnósticos antes de: - - directive directiva @@ -54,31 +44,6 @@ [Tab] para navegar entre elementos, [Entrar] para completar - - Edit at {0} adds the non-whitespace content '{1}'. - Editar en {0}agregar el contenido que no es un espacio en blanco "{1}" . - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Editar en {0} eliminar el contenido que no es un espacio en blanco "{1}" . - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Se está abandonando una operación de formato porque introduciría o quitaría uno de más diagnósticos. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Se está abandonando una operación de formato porque agregaría o eliminaría contenido que no es un espacio en blanco. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Error de formato. Si abandona el trabajo adicional para no dañar el archivo, notifique este problema. Consulte: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. El editor de Razor usa Razor Source Generator, que requiere que los archivos *.razor y *.cshtml sean AdditionalFiles en el proyecto. {0} parece venir de "{1}", que no tiene documentos de Razor que sean AdditionalFiles, por lo que la experiencia de edición será limitada. ¿Usa el SDK de Razor? No se registrarán más mensajes para este proyecto. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf index 81eb2a1ed945..4c9437eb0e78 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.fr.xlf @@ -32,16 +32,6 @@ Attributs de directive Blazor - - Diagnostics after: - Diagnostics après : - - - - Diagnostics before: - Diagnostics avant : - - directive directif @@ -54,31 +44,6 @@ [Tab] pour naviguer entre les éléments, [Entrée] pour terminer - - Edit at {0} adds the non-whitespace content '{1}'. - Modifier à {0} ajoute le contenu autre qu’un espace « {1} ». - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Modifier à {0} supprime le contenu autre qu’un espace « {1} ». - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Une opération de formatage est en cours d’abandon, car elle introduit ou supprime un ou plusieurs diagnostics. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Une opération de formatage est en cours d’abandon, car elle ajouterait ou supprimerait du contenu qui n’est pas un espace blanc. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Erreur de mise en forme. Abandon du travail pour éviter de corrompre le fichier, veuillez signaler ce problème. Voir : https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. L’éditeur Razor utilise le générateur de source Razor, qui requiert que les fichiers *.razor et *.cshtml soient AdditionalFiles dans le projet. {0} semble provenir de '{1}', qui ne contient aucun document Razor qui sont des AdditionalFiles. L’expérience d’édition sera donc limitée. Utilise-t-il le kit de développement logiciel (SDK) Razor ? Aucun autre message ne sera enregistré pour ce projet. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf index 538d9cc2b63e..bb7e88e16e0a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.it.xlf @@ -32,16 +32,6 @@ Attributo per la direttiva Blazor - - Diagnostics after: - Diagnostica dopo: - - - - Diagnostics before: - Diagnostica prima di: - - directive direttiva @@ -54,31 +44,6 @@ [TAB] per spostarsi tra gli elementi, [INVIO] per completare - - Edit at {0} adds the non-whitespace content '{1}'. - La modifica in {0} aggiunge contenuti diversi da spazi vuoti '{1}'. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - La modifica in {0} elimina contenuti diversi da spazi vuoti '{1}'. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - È in corso l'abbandono di un'operazione di formato perché comporterebbe l'introduzione o la rimozione di una o più operazioni di diagnostica. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - È in corso l'abbandono di un'operazione di formattazione perché aggiungerebbe o eliminerebbe contenuto diverso da spazi vuoti. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Errore di formattazione. Per evitare di danneggiare il file, interrompere l'operazione e segnalare il problema. Vedere: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. L'editor Razor usa il generatore di origine Razor, che richiede che i file *.razor e *.cshtml siano AdditionalFiles nel progetto. {0} sembra provenire da '{1}', che non contiene documenti Razor classificati come AdditionalFiles, quindi l'esperienza di modifica sarà limitata. Si sta utilizzando Razor SDK? Non verranno registrati altri messaggi per questo progetto. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf index d7f0bc5dec09..0804a9b2f62f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ja.xlf @@ -32,16 +32,6 @@ Blazor ディレクティブ属性 - - Diagnostics after: - 次の時間が経過した後の診断: - - - - Diagnostics before: - 次の時間以前の診断: - - directive ディレクティブ @@ -54,31 +44,6 @@ [Tab] を挿入して要素間を移動し、[Enter] を押して完了します - - Edit at {0} adds the non-whitespace content '{1}'. - {0} で編集すると空白以外のスペース '{1}' が追加されます。 - - - - Edit at {0} deletes the non-whitespace content '{1}'. - {0} で削除すると空白以外のスペース '{1}' が追加されます。 - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - 書式設定操作は、さらに診断の 1 つを導入または削除するため、破棄されています。 - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - 書式設定操作は、空白以外のコンテンツを追加または削除するため、破棄されています。 - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - 書式設定エラーです。ファイルを破損しないようにこれ以上の作業を中止してください。この問題を報告してください。参照: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Razor エディターは Razor ソース ジェネレーターを利用します。これには、*.razor および *.cshtml ファイルがプロジェクトの AddedFiles である必要があります。{0} は、'{1}' から取得されたようですが、これには AddedFiles である Razor ドキュメントがないため、編集エクスペリエンスが制限されます。Razor SDK を使用していますか?このプロジェクトのメッセージはこれ以上ログに記録されません。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf index 1030ffd5f626..5b34a4d8d87b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ko.xlf @@ -32,16 +32,6 @@ Blazor 지시문 특성 - - Diagnostics after: - 다음 이후 진단: - - - - Diagnostics before: - 다음 이전 진단: - - directive 지시문 @@ -54,31 +44,6 @@ 요소 간에 탐색하려면 [Tab], 완료하려면 [Enter] - - Edit at {0} adds the non-whitespace content '{1}'. - {0}에서 편집은 공백이 아닌 콘텐츠 '{1}'을(를) 추가합니다. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - {0}에서 편집은 공백이 아닌 콘텐츠 '{1}'을(를) 삭제합니다. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - 서식 작업이 중단되는 이유는 진단 중 하나를 더 도입하거나 제거할 수 있기 때문입니다. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - 공백이 아닌 콘텐츠를 추가하거나 삭제하기 때문에 형식 작업이 중단됩니다. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - 서식 오류입니다. 파일이 손상되지 않도록 추가 작업을 중단합니다. 이 문제를 보고하세요. 참조: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Razor 편집기는 프로젝트의 AdditionalFiles이 *.razor 및 *.cshtml 파일이어야 하는 Razor 원본 생성기를 사용합니다. {0}은(는) AdditionalFiles인 Razor 문서가 포함되지 않은 '{1}'에서 가져왔으므로 편집 환경이 제한됩니다. Razor SDK를 사용하고 계십니까? 이 프로젝트에 대해 더 이상 메시지가 기록되지 않습니다. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf index f5a8f14ff79e..7d46d4f050d9 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pl.xlf @@ -32,16 +32,6 @@ Atrybut dyrektywy Blazor - - Diagnostics after: - Diagnostyka po: - - - - Diagnostics before: - Diagnostyka przed: - - directive dyrektywa @@ -54,31 +44,6 @@ klawisz [Tab], aby przechodzić pomiędzy elementami, klawisz [Enter], aby zakończyć - - Edit at {0} adds the non-whitespace content '{1}'. - Edycja na stronie {0} dodaje zawartość bez białych znaków „{1}”. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Edycja na stronie {0} usuwa zawartość bez białych znaków „{1}”. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Operacja formatowania jest porzucana, ponieważ spowodowałaby wprowadzenie lub usunięcie jednej z większej liczby diagnostyki. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Operacja formatowania jest porzucana, ponieważ doda lub usunie zawartość bez białych znaków. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Błąd formatowania. Porzucanie dalszej pracy, aby nie uszkodzić pliku, zgłoś ten problem. Zobacz: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Edytor Razor korzysta z generatora źródła Razor, który wymaga, aby pliki *.razor i *.cshtml były plikami AdditionalFiles w projekcie. Wygląda na to, że {0} pochodzi z folderu „{1}”, który nie zawiera dokumentów usługi Razor będących plikami AdditionalFiles, więc środowisko edycji będzie ograniczone. Czy używa zestawu Razor SDK? Dla tego projektu nie będą rejestrowane żadne inne wiadomości. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf index 09269d15cf72..298addf270b3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.pt-BR.xlf @@ -32,16 +32,6 @@ Atributos da diretiva Blazor - - Diagnostics after: - Diagnóstico após: - - - - Diagnostics before: - Diagnóstico antes: - - directive diretiva @@ -54,31 +44,6 @@ [Tab] para navegar entre elementos, [Enter] para concluir - - Edit at {0} adds the non-whitespace content '{1}'. - Editar em {0} adiciona o conteúdo que não é espaço em branco ''{1}''. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Editar em {0} exclui o conteúdo que não é espaço em branco ''{1}''. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Uma operação de formato está sendo abandonada porque introduziria ou removeria um ou mais diagnósticos. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Uma operação de formato está sendo abandonada porque adicionaria ou excluiria conteúdo que não é espaço em branco. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Erro de formatação. Interrompendo o trabalho para não corromper o arquivo. Reporte esse problema. Consulte: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. O editor Razor utiliza o Razor Source Generator, que exige que arquivos \*.razor e \*.cshtml sejam especificados como AdditionalFiles no projeto. {0} parece vir de '{1}', que não contém documentos Razor como AdditionalFiles, portanto, a experiência de edição será limitada. Está usando o SDK do Razor? Nenhuma outra mensagem será registrada para este projeto. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf index d2a124fe1b5e..52f862a5cfcc 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.ru.xlf @@ -32,16 +32,6 @@ Атрибуты директивы Blazor - - Diagnostics after: - Диагностика после: - - - - Diagnostics before: - Диагностика до: - - directive директива @@ -54,31 +44,6 @@ [TAB] для перемещения между элементами, нажмите [ВВОД] для завершения - - Edit at {0} adds the non-whitespace content '{1}'. - Редактирование {0} добавляет содержимое, не являющееся пробелами "{1}". - - - - Edit at {0} deletes the non-whitespace content '{1}'. - Редактирование {0} удаляет содержимое, не являющееся пробелами "{1}". - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Операция форматирования отменяется, поскольку она вводит или удаляет одну или несколько диагностик. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Операция форматирования отменяется, поскольку она может добавить или удалить содержимое, отличное от пробелов. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Ошибка форматирования. Дальнейшая работа прекращается, чтобы не повредить файл. Сообщите об этой проблеме. См.: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Редактор Razor использует генератор источника Razor, который требует, чтобы файлы *.razor и *.cshtml были файлами AdditionalFile в проекте. {0} поступает из "{1}", где нет документов Razor, которые являются файлами AdditionalFile, поэтому возможности редактирования будут ограничены. Используется ли пакет SDK Razor? Для этого проекта больше не будут регистрироваться сообщения в журнале. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf index d37493b8e047..2f01db9460ec 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.tr.xlf @@ -32,16 +32,6 @@ Blazor yönergesi öznitelikleri - - Diagnostics after: - Şundan sonraki tanılama: - - - - Diagnostics before: - Şundan önceki tanılama: - - directive yönerge @@ -54,31 +44,6 @@ Öğeler arasında gezinmek için [Tab], tamamlamak için [Enter] - - Edit at {0} adds the non-whitespace content '{1}'. - {0} konumunda düzenleme, '{1}' boşluk dışı içeriğini ekler. - - - - Edit at {0} deletes the non-whitespace content '{1}'. - {0} konumunda düzenleme, '{1}' boşluk dışı içeriğini siler. - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - Bir veya daha fazla tanılamayı ortaya çıkarabileceği veya kaldırabileceği için biçimlendirme işlemi bırakılıyor. - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - Boşluk dışı içeriği ekleyebileceği veya silebileceği için biçimlendirme işlemi bırakıl. - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - Biçimlendirme hatası. Dosyanın bozulmaması için çalışmaya devam etmeyin ve lütfen bu sorunu bildirin. Bkz.: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Razor düzenleyici, *.razor ve *.cshtml dosyalarının projede AdditionalFiles olmasını gerektiren Razor Kaynak Oluşturucuyu kullanır. {0}, AdditionalFile olan herhangi bir Razor belgesine sahip olmayan '{1}' dosyasından geliyor gibi görünüyor, bu nedenle düzenleme deneyimi sınırlı olacaktır. Razor SDK'sını kullanıyor mu? Bu proje için başka mesajlar günlüğe kaydedilmeyecektir. diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf index 04452359a1e6..99cc4412e3cc 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hans.xlf @@ -32,16 +32,6 @@ Blazor 指令特性 - - Diagnostics after: - 诊断后: - - - - Diagnostics before: - 诊断前: - - directive 指令 @@ -54,31 +44,6 @@ 按 [Tab] 在元素之间导航,按 [Enter] 以完成 - - Edit at {0} adds the non-whitespace content '{1}'. - 于 {0} 编辑,添加非空格内容“{1}”。 - - - - Edit at {0} deletes the non-whitespace content '{1}'. - 于 {0} 编辑,删除非空格内容“{1}”。 - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - 正在放弃格式操作,因为它会引入或删除其他诊断之一。 - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - 正在放弃格式操作,因为它会添加或删除非空格内容。 - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - 格式错误。为避免文件损坏,已停止后续操作,请报告此问题。详情请见:https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Razor 编辑器使用 Razor 源生成器,这要求 *.razor 和 *.cshtml 文件是项目中的 AdditionalFile。{0} 似乎来自“{1}”,其中不包含任何为 AdditionalFile 的 Razor 文档,因此编辑体验将受到限制。它使用的是 Razor SDK 吗?对于此项目,将不会记录更多消息。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf index 3eab73cc139d..5e638c6f5b55 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources/xlf/SR.zh-Hant.xlf @@ -32,16 +32,6 @@ Blazor 指示詞屬性 - - Diagnostics after: - 在以下事項之後的診斷: - - - - Diagnostics before: - 在以下事項之前的診斷: - - directive 指示詞 @@ -54,31 +44,6 @@ [Tab] 在元素之間瀏覽,[Enter] 完成 - - Edit at {0} adds the non-whitespace content '{1}'. - 在 {0} 處編輯將新增非空白內容 '{1}'。 - - - - Edit at {0} deletes the non-whitespace content '{1}'. - 在 {0} 處編輯將刪除非空白內容 '{1}'。 - - - - A format operation is being abandoned because it would introduce or remove one of more diagnostics. - 將放棄格式化作業,因為它將引入或移除一個或多個診斷。 - - - - A format operation is being abandoned because it would add or delete non-whitespace content. - 將放棄格式化作業,因為它將新增或删除非空白內容。 - - - - Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue - 格式錯誤。為避免檔案損壞,已停止後續作業,請回報此問題。詳情請參閱: https://aka.ms/razor-formatting-issue - - The Razor editor utilizes the Razor Source Generator, which requires *.razor and *.cshtml files to be AdditionalFiles in the project. {0} appears to come from '{1}', which has no Razor documents that are AdditionalFiles, so the editing experience will be limited. Is it using the Razor SDK? No more messages will be logged for this project. Razor 編輯器會使用 Razor 原始碼產生器,其需要在專案中將 *.razor 和 *.cshtml 檔案設為 AdditionalFiles。{0} 似乎來自 '{1}',其沒有設為 AdditionalFiles 的 Razor 文件,因此編輯體驗將會受到限制。是否使用 Razor SDK?系統將不會再記錄此專案的任何訊息。 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx index 3e94cca94ac1..c72fb5e4cac0 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/SR.resx @@ -202,4 +202,25 @@ Unknown mapping behavior + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + A format operation is being abandoned because it would add or delete non-whitespace content. + + + Diagnostics after: + + + Diagnostics before: + + + Edit at {0} adds the non-whitespace content '{1}'. + + + Edit at {0} deletes the non-whitespace content '{1}'. + \ No newline at end of file diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf index e4a0baa95c75..062fd81addef 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.cs.xlf @@ -27,6 +27,16 @@ Vytvořit komponentu ze značky + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Dokument nepatří do tohoto projektu. @@ -37,6 +47,16 @@ Dokument není dokument Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Extrahovat blok do kódu na pozadí @@ -52,6 +72,21 @@ Extrahovat do {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Generovat asynchronní obslužnou rutinu události {0} diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf index ccbf277a5934..a47dd114967d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.de.xlf @@ -27,6 +27,16 @@ Komponente aus Tag erstellen + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Das Dokument gehört nicht zu diesem Projekt. @@ -37,6 +47,16 @@ Das Dokument ist kein Razor-Dokument. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Block auf CodeBehind extrahieren @@ -52,6 +72,21 @@ In {0}.css extrahieren + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Asynchronen Ereignishandler "{0}" generieren diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf index 88d39e2d3b26..8d9ecedca16a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.es.xlf @@ -27,6 +27,16 @@ Crear un componente a partir de la etiqueta + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. El documento no pertenece a este proyecto. @@ -37,6 +47,16 @@ El documento no es un documento de Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Extraer el bloque al código subyacente @@ -52,6 +72,21 @@ Extraer a {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Generar controlador de eventos asincrónicos ''{0}'' diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf index 8af9f9aee5d2..ebc92064761f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.fr.xlf @@ -27,6 +27,16 @@ Créer un composant à partir de la balise + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Le document n’appartient pas à ce projet. @@ -37,6 +47,16 @@ Le document n’est pas un document Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Extraire le bloc vers le code-behind @@ -52,6 +72,21 @@ Extraire vers {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Générer le gestionnaire d’événements asynchrone « {0} » diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf index 79f12683f630..53b3b393c4d7 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.it.xlf @@ -27,6 +27,16 @@ Crea componente da tag + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Il documento non appartiene a questo progetto. @@ -37,6 +47,16 @@ Il documento non è un documento Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Estrai il blocco in code-behind @@ -52,6 +72,21 @@ Estrarre in {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Genera gestore dell'evento '{0}' asincrono diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf index 0a5478bfed90..e8cfabcef68b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ja.xlf @@ -27,6 +27,16 @@ タグからコンポーネントを作成する + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. ドキュメントはこのプロジェクトに属していません。 @@ -37,6 +47,16 @@ ドキュメントは Razor ドキュメントではありません。 + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind ブロック抽出から分離コード @@ -52,6 +72,21 @@ {0}.css に抽出する + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' 非同期イベント ハンドラー '{0}' の生成 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf index 5a7b6d4c58a3..21d4bd3c0747 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ko.xlf @@ -27,6 +27,16 @@ 태그에서 구성 요소 만들기 + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. 문서가 이 프로젝트에 속하지 않습니다. @@ -37,6 +47,16 @@ 문서가 Razor 문서가 아닙니다. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind 코드 숨김에 블록 추출 @@ -52,6 +72,21 @@ {0}.css로 추출 + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' 비동기 이벤트 처리기 '{0}' 생성 diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf index 782cb2d68dd3..72f50e7138c8 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pl.xlf @@ -27,6 +27,16 @@ Utwórz składnik z tagu + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Dokument nie należy do tego projektu. @@ -37,6 +47,16 @@ Dokument nie jest dokumentem Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Wyodrębnij blok do kodu znajdującego się poza @@ -52,6 +72,21 @@ Wyodrębnij do {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Generuj asynchroniczny program obsługi zdarzeń „{0}” diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf index 6cc396831814..c9005be1999f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.pt-BR.xlf @@ -27,6 +27,16 @@ Criar componente a partir da marca + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. O documento não pertence a esse projeto. @@ -37,6 +47,16 @@ O documento não é um documento Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Extrair o bloco para codificar atrás @@ -52,6 +72,21 @@ Extrair para {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Gerar Manipulador de Eventos Assíncronos '{0}' diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf index 148fea685881..25298be41cff 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.ru.xlf @@ -27,6 +27,16 @@ Создание компонента из тега + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Документ не принадлежит этому проекту. @@ -37,6 +47,16 @@ Документ не является документом Razor. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Извлечь блок в код программной части @@ -52,6 +72,21 @@ Извлечь в {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' Создать обработчик асинхронных событий "{0}" diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf index 6296c5412974..7880792f1f11 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.tr.xlf @@ -27,6 +27,16 @@ Etiketten bileşen oluştur + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. Belge bu projeye ait değil. @@ -37,6 +47,16 @@ Belge Razor belgesi değil. + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind Bloğu arkadaki koda ayıkla @@ -52,6 +72,21 @@ {0}.css'a ayıkla + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' '{0}' Asenkron Olay İşleyicisini Oluştur diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf index a5a9386853c2..e619eaa24453 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hans.xlf @@ -27,6 +27,16 @@ 从标记创建组件 + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. 文档不属于此项目。 @@ -37,6 +47,16 @@ 文档不是 Razor 文档。 + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind 将块提取到代码隐藏中 @@ -52,6 +72,21 @@ 提取到 {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' 生成异步事件处理程序“{0}” diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf index d8bfd15074d5..4a67a8ef7fe9 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Resources/xlf/SR.zh-Hant.xlf @@ -27,6 +27,16 @@ 從標籤建立元件 + + Diagnostics after: + Diagnostics after: + + + + Diagnostics before: + Diagnostics before: + + Document does not belong to this project. 文件不屬於此專案。 @@ -37,6 +47,16 @@ 文件並非 Razor 文件。 + + Edit at {0} adds the non-whitespace content '{1}'. + Edit at {0} adds the non-whitespace content '{1}'. + + + + Edit at {0} deletes the non-whitespace content '{1}'. + Edit at {0} deletes the non-whitespace content '{1}'. + + Extract block to code behind 擷取區塊以在後方編碼 @@ -52,6 +72,21 @@ 擷取為 {0}.css + + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + A format operation is being abandoned because it would introduce or remove one of more diagnostics. + + + + A format operation is being abandoned because it would add or delete non-whitespace content. + A format operation is being abandoned because it would add or delete non-whitespace content. + + + + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + Formatting error. Abandoning further work to not corrupt the file, please report this issue. See: https://aka.ms/razor-formatting-issue + + Generate Async Event Handler '{0}' 產生非同步事件處理常式 '{0}' From 51db2163b9b538b163bff4ce506f20b6727d5f9e Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 16:13:17 +1000 Subject: [PATCH 17/34] Update tests --- .../Formatting/CohostOnTypeFormattingEndpoint.cs | 6 +++--- .../Formatting/TestFormattingLoggerFactory.cs | 2 +- .../Formatting/DocumentFormattingTest.cs | 1 + .../Formatting/DocumentFormattingTestBase.cs | 3 ++- .../Formatting/FormattingContentValidationPassTest.cs | 1 + .../Formatting/FormattingDiagnosticValidationPassTest.cs | 1 + .../Formatting/HtmlFormattingPassTest.cs | 1 + .../Formatting/HtmlFormattingTest.cs | 1 + .../Formatting/RazorFormattingServiceTest.cs | 5 +++-- .../Formatting/FormattingUtilitiesTest.cs | 1 + .../Cohost/CohostRangeFormattingEndpointTest.cs | 3 ++- .../Cohost/Formatting/FormattingLogTest.cs | 1 + .../Cohost/Formatting/FormattingTestBase.cs | 1 + 13 files changed, 19 insertions(+), 8 deletions(-) rename src/Razor/src/Razor/test/{Microsoft.AspNetCore.Razor.Test.Common.Tooling => Microsoft.AspNetCore.Razor.Test.Common.Cohosting}/Formatting/TestFormattingLoggerFactory.cs (97%) rename src/Razor/src/Razor/test/{Microsoft.CodeAnalysis.Razor.Workspaces.UnitTests => Microsoft.CodeAnalysis.Remote.Razor.UnitTests}/Formatting/FormattingUtilitiesTest.cs (98%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs index d22a54ff1553..a678f2443818 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Formatting/CohostOnTypeFormattingEndpoint.cs @@ -35,9 +35,9 @@ internal sealed class CohostOnTypeFormattingEndpoint( ILoggerFactory loggerFactory) : AbstractCohostDocumentEndpoint(incompatibleProjectService), IDynamicRegistrationProvider { - private const string FirstTriggerCharacter = "}"; - private static readonly string[] MoreTriggerCharacters = [";", "\n", "{"]; - private static readonly FrozenSet AllTriggerCharacterSet = FrozenSet.ToFrozenSet([FirstTriggerCharacter, .. MoreTriggerCharacters], StringComparer.Ordinal); + internal const string FirstTriggerCharacter = "}"; + internal static readonly string[] MoreTriggerCharacters = [";", "\n", "{"]; + internal static readonly FrozenSet AllTriggerCharacterSet = FrozenSet.ToFrozenSet([FirstTriggerCharacter, .. MoreTriggerCharacters], StringComparer.Ordinal); private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker; private readonly IHtmlRequestInvoker _requestInvoker = requestInvoker; diff --git a/src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Formatting/TestFormattingLoggerFactory.cs b/src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/Formatting/TestFormattingLoggerFactory.cs similarity index 97% rename from src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Formatting/TestFormattingLoggerFactory.cs rename to src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/Formatting/TestFormattingLoggerFactory.cs index c7aca59f8cdd..16ee538b1179 100644 --- a/src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/Formatting/TestFormattingLoggerFactory.cs +++ b/src/Razor/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/Formatting/TestFormattingLoggerFactory.cs @@ -8,7 +8,7 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Razor.Formatting; +namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; internal class TestFormattingLoggerFactory(ITestOutputHelper testOutputHelper) : IFormattingLoggerFactory { diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs index 665dfe31b5bc..6513d6a23e71 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Settings; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Xunit; using Xunit.Abstractions; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTestBase.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTestBase.cs index 986dd436da88..6a51540431bd 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTestBase.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTestBase.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -21,6 +21,7 @@ using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost.Formatting; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingContentValidationPassTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingContentValidationPassTest.cs index 30e88b223188..7fa5eb4a35e0 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingContentValidationPassTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingContentValidationPassTest.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Moq; using Xunit; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingDiagnosticValidationPassTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingDiagnosticValidationPassTest.cs index 96d27275aeb6..00b8fe454a9a 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingDiagnosticValidationPassTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/FormattingDiagnosticValidationPassTest.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.ProjectSystem; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingPassTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingPassTest.cs index aa5b45a9acb0..422b98107880 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingPassTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingPassTest.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Formatting; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingTest.cs index afd3c092a621..c20607efef72 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/HtmlFormattingTest.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Settings; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Xunit; using Xunit.Abstractions; using AssertEx = Roslyn.Test.Utilities.AssertEx; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs index 48e41442a078..99a71ee60771 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.Formatting; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; @@ -44,7 +45,7 @@ public void AllTriggerCharacters_IncludesCSharpTriggerCharacters() { foreach (var character in RazorFormattingService.TestAccessor.GetCSharpTriggerCharacterSet()) { - Assert.Contains(character, RazorFormattingService.AllTriggerCharacterSet.ToList()); + Assert.Contains(character, CohostOnTypeFormattingEndpoint.AllTriggerCharacterSet.ToList()); } } @@ -53,7 +54,7 @@ public void AllTriggerCharacters_IncludesHtmlTriggerCharacters() { foreach (var character in RazorFormattingService.TestAccessor.GetHtmlTriggerCharacterSet()) { - Assert.Contains(character, RazorFormattingService.AllTriggerCharacterSet.ToList()); + Assert.Contains(character, CohostOnTypeFormattingEndpoint.AllTriggerCharacterSet.ToList()); } } } diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.UnitTests/Formatting/FormattingUtilitiesTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Remote.Razor.UnitTests/Formatting/FormattingUtilitiesTest.cs similarity index 98% rename from src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.UnitTests/Formatting/FormattingUtilitiesTest.cs rename to src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Remote.Razor.UnitTests/Formatting/FormattingUtilitiesTest.cs index 9446ef5c0af7..32185b5ab789 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.UnitTests/Formatting/FormattingUtilitiesTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Remote.Razor.UnitTests/Formatting/FormattingUtilitiesTest.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNetCore.Razor.Test.Common; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRangeFormattingEndpointTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRangeFormattingEndpointTest.cs index 7683e1bda120..5bbb682d6673 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRangeFormattingEndpointTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRangeFormattingEndpointTest.cs @@ -7,11 +7,12 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.LanguageServer; +using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingLogTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingLogTest.cs index 5e7948b46c98..454d73eab4f3 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingLogTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingLogTest.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingTestBase.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingTestBase.cs index c4acd399d180..ff241c702092 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingTestBase.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/FormattingTestBase.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; +using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Razor.Settings; using Roslyn.Test.Utilities; From 24d5d268e1364c284ee990c2bbb7c3db76307953 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 10 Jun 2026 17:10:07 +1000 Subject: [PATCH 18/34] Move MEF attributes and remote unnecessary indirection --- .../Formatting/FormattingLoggerFactory.cs | 4 +++- .../Formatting/RazorFormattingService.cs | 5 ++++- .../Formatting/RemoteFormattingLoggerFactory.cs | 12 ------------ .../Formatting/RemoteRazorFormattingService.cs | 17 ----------------- 4 files changed, 7 insertions(+), 31 deletions(-) delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingLoggerFactory.cs delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteRazorFormattingService.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs index abdad0dce7b8..59032e21248a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingLoggerFactory.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Composition; using System.IO; namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; -internal class FormattingLoggerFactory : IFormattingLoggerFactory +[Export(typeof(IFormattingLoggerFactory)), Shared] +internal sealed class FormattingLoggerFactory : IFormattingLoggerFactory { private const string LogDirEnvVar = "RazorFormattingLogPath"; private static string? BaseLogDir { get; } = Environment.GetEnvironmentVariable(LogDirEnvVar); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs index bae8a78c736a..e6e426252fd9 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs @@ -5,6 +5,7 @@ using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; +using System.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -22,7 +23,8 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; -internal class RazorFormattingService : IRazorFormattingService +[Export(typeof(IRazorFormattingService)), Shared] +internal sealed class RazorFormattingService : IRazorFormattingService { private static readonly FrozenSet s_csharpTriggerCharacterSet = FrozenSet.ToFrozenSet(["}", ";"], StringComparer.Ordinal); private static readonly FrozenSet s_htmlTriggerCharacterSet = FrozenSet.ToFrozenSet(["\n", "{", "}", ";"], StringComparer.Ordinal); @@ -34,6 +36,7 @@ internal class RazorFormattingService : IRazorFormattingService private IFormattingLoggerFactory _formattingLoggerFactory; + [ImportingConstructor] public RazorFormattingService( IDocumentMappingService documentMappingService, IRazorEditService razorEditService, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingLoggerFactory.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingLoggerFactory.cs deleted file mode 100644 index 4f7412481ee8..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingLoggerFactory.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using Microsoft.CodeAnalysis.Razor.Formatting; - -namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; - -[Export(typeof(IFormattingLoggerFactory)), Shared] -internal sealed class RemoteFormattingLoggerFactory : FormattingLoggerFactory -{ -} diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteRazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteRazorFormattingService.cs deleted file mode 100644 index 77652b2a563d..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteRazorFormattingService.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Formatting; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.CodeAnalysis.Razor.Workspaces; - -namespace Microsoft.CodeAnalysis.Remote.Razor.Formatting; - -[Export(typeof(IRazorFormattingService)), Shared] -[method: ImportingConstructor] -internal sealed class RemoteRazorFormattingService(IDocumentMappingService documentMappingService, IRazorEditService razorEditService, IHostServicesProvider hostServicesProvider, IFormattingLoggerFactory formattingLoggerFactory, ILoggerFactory loggerFactory) - : RazorFormattingService(documentMappingService, razorEditService, hostServicesProvider, formattingLoggerFactory, loggerFactory) -{ -} From 74d67606832ebdbeff18fdf2f0cdc9277d790c17 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:16:49 +1000 Subject: [PATCH 19/34] Unskip tests Just happened to notice that these two were skipped, the issue they link to is closed, and they pass, so figured I'd unskip them --- .../Cohost/Formatting/OnTypeFormattingTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs index c6b763a7d1d7..4abc6e9e440f 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs @@ -624,7 +624,7 @@ await RunOnTypeFormattingTestAsync( triggerCharacter: ';'); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/36390")] + [FormattingTestFact] [WorkItem("https://github.com/dotnet/aspnetcore/issues/34319")] public async Task NestedHtml_NestedCodeBlock_EndingBrace() { @@ -660,7 +660,7 @@ await RunOnTypeFormattingTestAsync( triggerCharacter: '}'); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/36390")] + [FormattingTestFact] [WorkItem("https://github.com/dotnet/aspnetcore/issues/34319")] public async Task NestedHtml_NestedCodeBlock_EndingBrace_WithCode() { From 62c0956254b2cea8eeafcc973ab2abf786556fc7 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:34:08 +1000 Subject: [PATCH 20/34] Make formatting sonic compatible --- .../Formatting/IRazorFormattingService.cs | 4 ++ .../Formatting/CSharpFormatter.cs | 4 +- .../Formatting/FormattingContext.cs | 15 +++++- ...pFormattingPass.CSharpDocumentGenerator.cs | 50 +++++++++++++++---- .../Formatting/Passes/CSharpFormattingPass.cs | 19 ++++--- .../Passes/CSharpOnTypeFormattingPass.cs | 21 ++++---- .../Formatting/Passes/HtmlFormattingPass.cs | 23 ++++++--- .../Passes/RoslynWorkspaceHelper.cs | 5 +- .../Formatting/RazorFormattingService.cs | 19 ++++--- .../Formatting/RemoteFormattingService.cs | 8 ++- 10 files changed, 123 insertions(+), 45 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IRazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IRazorFormattingService.cs index 8a210bc63b3a..20433a681b8b 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IRazorFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/IRazorFormattingService.cs @@ -33,23 +33,27 @@ Task> GetCSharpOnTypeFormattingChangesAsync( RazorFormattingOptions options, int hostDocumentIndex, char triggerCharacter, + bool declarationDocument, CancellationToken cancellationToken); Task TryGetSingleCSharpEditAsync( DocumentContext documentContext, TextChange csharpEdit, + bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken); Task TryGetCSharpCodeActionEditAsync( DocumentContext documentContext, ImmutableArray csharpEdits, + bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken); Task TryGetCSharpSnippetFormattingEditAsync( DocumentContext documentContext, ImmutableArray csharpEdits, + bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs index 492ddd2750c3..591b5afc22a1 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/CSharpFormatter.cs @@ -286,7 +286,7 @@ static bool IgnoreInitializerExpression(InitializerExpressionSyntax initializer, using var changes = new PooledArrayBuilder(); - var syntaxTree = await context.CurrentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var syntaxTree = await context.CurrentSnapshot.GetCSharpSyntaxTreeAsync(context.CSharpDocument.IsDeclarationDocument, cancellationToken).ConfigureAwait(false); var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var previousMarkerOffset = 0; @@ -328,7 +328,7 @@ static bool IgnoreInitializerExpression(InitializerExpressionSyntax initializer, } } - var changedText = context.CSharpSourceText.WithChanges(changes.ToImmutable()); + var changedText = context.CSharpDocument.Text.WithChanges(changes.ToImmutable()); return (indentationMap, syntaxTree.WithChangedText(changedText)); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs index 1be2c121c25f..32a344073c5f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/FormattingContext.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Syntax; using Microsoft.AspNetCore.Razor.PooledObjects; @@ -23,9 +24,12 @@ internal sealed class FormattingContext private ImmutableArray? _formattingSpans; private IReadOnlyDictionary? _indentations; + private readonly RazorCSharpDocument? _csharpDocument; + private FormattingContext( IDocumentSnapshot originalSnapshot, RazorCodeDocument codeDocument, + bool? declarationDocument, IDocumentSnapshot currentSnapshot, RazorFormattingOptions options, IFormattingLogger? logger, @@ -41,6 +45,11 @@ private FormattingContext( IncludeCSharpLanguageFeatureEdits = includeCSharpLanguageFeatureEdits; HostDocumentIndex = hostDocumentIndex; TriggerCharacter = triggerCharacter; + + if (declarationDocument is { } declDoc) + { + _csharpDocument = codeDocument.GetRequiredCSharpDocument(declDoc); + } } public static bool SkipValidateComponents { get; set; } @@ -56,7 +65,7 @@ private FormattingContext( public SourceText SourceText => CodeDocument.Source.Text; - public SourceText CSharpSourceText => CodeDocument.GetCSharpSourceText(); + public RazorCSharpDocument CSharpDocument => _csharpDocument.AssumeNotNull("Cannot get C# source text when declaration document is not specified."); public string NewLineString => Environment.NewLine; @@ -241,6 +250,7 @@ public async Task WithTextAsync(SourceText changedText, Cance var newContext = new FormattingContext( OriginalSnapshot, codeDocument, + _csharpDocument?.IsDeclarationDocument, currentSnapshot: changedSnapshot, Options, Logger, @@ -272,6 +282,7 @@ private static void DEBUG_ValidateComponents(RazorCodeDocument oldCodeDocument, public static FormattingContext CreateForOnTypeFormatting( IDocumentSnapshot originalSnapshot, RazorCodeDocument codeDocument, + bool? declarationDocument, RazorFormattingOptions options, IFormattingLogger? logger, bool includeCSharpLanguageFeatureEdits, @@ -281,6 +292,7 @@ public static FormattingContext CreateForOnTypeFormatting( return new FormattingContext( originalSnapshot, codeDocument, + declarationDocument, currentSnapshot: originalSnapshot, options, logger, @@ -298,6 +310,7 @@ public static FormattingContext Create( return new FormattingContext( originalSnapshot, codeDocument, + declarationDocument: null, currentSnapshot: originalSnapshot, options, logger, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs index 91172b45c9e4..5374f0280dd5 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; @@ -85,13 +86,13 @@ internal partial class CSharpFormattingPass /// private sealed class CSharpDocumentGenerator { - public static FormattedDocument Generate(RazorCodeDocument codeDocument, SyntaxNode csharpSyntaxRoot, RazorFormattingOptions options, IDocumentMappingService documentMappingService) + public static FormattedDocument Generate(RazorCodeDocument codeDocument, SyntaxNode csharpSyntaxRoot, SyntaxNode? declSyntaxRoot, RazorFormattingOptions options, IDocumentMappingService documentMappingService) { using var _1 = StringBuilderPool.GetPooledObject(out var builder); using var _2 = ArrayBuilderPool.GetPooledObject(out var lineInfoBuilder); lineInfoBuilder.SetCapacityIfLarger(codeDocument.Source.Text.Lines.Count); - var generator = new Generator(codeDocument, csharpSyntaxRoot, options, builder, lineInfoBuilder, documentMappingService); + var generator = new Generator(codeDocument, csharpSyntaxRoot, declSyntaxRoot, options, builder, lineInfoBuilder, documentMappingService); generator.Generate(); @@ -149,6 +150,7 @@ public static bool TryParseAdditionalLineComment(TextLine line, out int start, o private sealed class Generator( RazorCodeDocument codeDocument, SyntaxNode csharpSyntaxRoot, + SyntaxNode? declSyntaxRoot, RazorFormattingOptions options, StringBuilder builder, ImmutableArray.Builder lineInfoBuilder, @@ -160,6 +162,7 @@ private sealed class Generator( private readonly SourceText _sourceText = codeDocument.Source.Text; private readonly RazorCodeDocument _codeDocument = codeDocument; private readonly SyntaxNode _csharpSyntaxRoot = csharpSyntaxRoot; + private readonly SyntaxNode? _declSyntaxRoot = declSyntaxRoot; private readonly bool _insertSpaces = options.InsertSpaces; private readonly int _tabSize = options.TabSize; private readonly AttributeIndentStyle _attributeIndentStyle = options.AttributeIndentStyle; @@ -167,7 +170,6 @@ private sealed class Generator( private readonly StringBuilder _builder = builder; private readonly ImmutableArray.Builder _lineInfoBuilder = lineInfoBuilder; private readonly IDocumentMappingService _documentMappingService = documentMappingService; - private readonly RazorCSharpDocument _csharpDocument = codeDocument.GetImplCSharpDocument().AssumeNotNull(); private TextLine _currentLine; private int _currentFirstNonWhitespacePosition; @@ -200,7 +202,7 @@ public void Generate() using var _ = StringBuilderPool.GetPooledObject(out var additionalLinesBuilder); var root = _codeDocument.GetRequiredSyntaxRoot(); - var sourceMappings = _codeDocument.GetRequiredImplCSharpDocument().SourceMappingsSortedByOriginal; + var sourceMappings = GetAllSourceMappingOriginalSpans(); var iMapping = 0; foreach (var line in _sourceText.Lines) { @@ -218,7 +220,7 @@ public void Generate() // If there are C# mappings on this line, we want to output additional lines that represent the C# blocks. while (iMapping < sourceMappings.Length) { - var originalSpan = sourceMappings[iMapping].OriginalSpan; + var originalSpan = sourceMappings[iMapping]; if (originalSpan.AbsoluteIndex < _currentFirstNonWhitespacePosition) { iMapping++; @@ -266,6 +268,29 @@ public void Generate() _builder.AppendLine(additionalLinesBuilder.ToString()); } + /// + /// Source mappings are stored separately for each C# document, but for the purposes of finding C# code in the middle of a line + /// of Razor code, we want to treat them as one combined list sorted by their position in the original Razor document. As long + /// as we know which C# document they came from, we can still find the relevant syntax nodes in the C# syntax tree. + /// + private ImmutableArray GetAllSourceMappingOriginalSpans() + { + var csharpDoc = _codeDocument.GetRequiredCSharpDocument(declarationDocument: false); + + using var _ = HashSetPool.GetPooledObject(out var mappings); + mappings.AddRange(csharpDoc.SourceMappingsSortedByOriginal.Select(static m => m.OriginalSpan)); + + if (_declSyntaxRoot is not null) + { + var declDoc = _codeDocument.GetRequiredCSharpDocument(declarationDocument: true); + mappings.AddRange(declDoc.SourceMappingsSortedByOriginal.Select(static m => m.OriginalSpan)); + } + + // We assume that if there is a location in a Razor document that maps to both C# documents, it's because it maps to the + // same construct (ie, a using directive that appears in both C# documents) and so we can just include one. + return mappings.OrderAsArray(static (lhs, rhs) => lhs.AbsoluteIndex.CompareTo(rhs.AbsoluteIndex)); + } + private void AddAdditionalLineFormattingContent(StringBuilder additionalLinesBuilder, RazorSyntaxNode node, SourceSpan originalSpan) { // Rather than bother to store more data about the formatted file, since we don't actually know where @@ -563,12 +588,17 @@ private LineInfo VisitCSharpLiteral(RazorSyntaxNode node, RazorSyntaxToken lastT // If we're here, it means this is a "normal" line of C#, so we can just emit it as is. The exception to this is // when we're inside a string literal. We still want to emit it as is, but we need to make sure we tell the formatter // to ignore any existing indentation too. - if (_documentMappingService.TryMapToCSharpDocumentPosition(_csharpDocument, _currentToken.SpanStart, out _, out var csharpIndex) && - _csharpSyntaxRoot.FindNode(new TextSpan(csharpIndex, 0), getInnermostNodeForTie: true) is { } csharpNode && - csharpNode.IsStringLiteral(multilineOnly: true)) + if (_documentMappingService.TryMapToCSharpDocumentLinePosition(_codeDocument, _currentToken.SpanStart, out _, out var csharpIndex, out var inDeclDocument)) { - _builder.AppendLine(_currentLine.ToString()); - return CreateLineInfo(processIndentation: false, processFormatting: true, checkForNewLines: true); + var csharpSyntaxRoot = inDeclDocument + ? _declSyntaxRoot.AssumeNotNull() + : _csharpSyntaxRoot; + if (csharpSyntaxRoot.FindNode(new TextSpan(csharpIndex, 0), getInnermostNodeForTie: true) is { } csharpNode && + csharpNode.IsStringLiteral(multilineOnly: true)) + { + _builder.AppendLine(_currentLine.ToString()); + return CreateLineInfo(processIndentation: false, processFormatting: true, checkForNewLines: true); + } } return EmitCurrentLineAsCSharp(); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs index 79462f3e2aae..bea8a602b3d3 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpFormattingPass.cs @@ -34,14 +34,21 @@ public async Task> ExecuteAsync(FormattingContext con // Process changes from previous passes var changedText = context.SourceText.WithChanges(changes); var changedContext = await context.WithTextAsync(changedText, cancellationToken).ConfigureAwait(false); - context.Logger?.LogObject("SourceMappings", changedContext.CodeDocument.GetRequiredImplCSharpDocument().SourceMappingsSortedByGenerated); + context.Logger?.LogObject("ImplSourceMappings", changedContext.CodeDocument.GetRequiredCSharpDocument(declarationDocument: false).SourceMappingsSortedByGenerated); - var csharpSyntaxTrue = await changedContext.CurrentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - var csharpSyntaxRoot = await csharpSyntaxTrue.GetRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? declSyntaxRoot = null; + if (changedContext.CodeDocument.GetCSharpDocument(declarationDocument: true) is { } declarationDocument) + { + var declSyntaxTree = await changedContext.CurrentSnapshot.GetCSharpSyntaxTreeAsync(declarationDocument: true, cancellationToken).ConfigureAwait(false); + declSyntaxRoot = await declSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + } + + var csharpSyntaxTree = await changedContext.CurrentSnapshot.GetCSharpSyntaxTreeAsync(declarationDocument: false, cancellationToken).ConfigureAwait(false); + var csharpSyntaxRoot = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); // To format C# code we generate a C# document that represents the indentation semantics the user would be // expecting in their Razor file. See the doc comments on CSharpDocumentGenerator for more info - var generatedDocument = CSharpDocumentGenerator.Generate(changedContext.CodeDocument, csharpSyntaxRoot, context.Options, _documentMappingService); + var generatedDocument = CSharpDocumentGenerator.Generate(changedContext.CodeDocument, csharpSyntaxRoot, declSyntaxRoot, context.Options, _documentMappingService); var generatedCSharpText = generatedDocument.SourceText; context.Logger?.LogSourceText("FormattingDocument", generatedCSharpText); @@ -159,6 +166,6 @@ private async Task FormatCSharpAsync(SourceText generatedCSharpText, } [Obsolete("Only for the syntax visualizer, do not call")] - internal static string GetFormattingDocumentContentsForSyntaxVisualizer(RazorCodeDocument codeDocument, SyntaxNode csharpSyntaxRoot, IDocumentMappingService documentMappingService) - => CSharpDocumentGenerator.Generate(codeDocument, csharpSyntaxRoot, new(), documentMappingService).SourceText.ToString(); + internal static string GetFormattingDocumentContentsForSyntaxVisualizer(RazorCodeDocument codeDocument, SyntaxNode csharpSyntaxRoot, SyntaxNode? declSyntaxRoot, IDocumentMappingService documentMappingService) + => CSharpDocumentGenerator.Generate(codeDocument, csharpSyntaxRoot, declSyntaxRoot, new(), documentMappingService).SourceText.ToString(); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs index 42df390ca55c..24ea7943225f 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/CSharpOnTypeFormattingPass.cs @@ -49,18 +49,19 @@ public async Task> ExecuteAsync(FormattingContext con // Normalize and re-map the C# edits. var codeDocument = context.CodeDocument; - var csharpText = codeDocument.GetCSharpSourceText(); + var csharpDocument = context.CSharpDocument; + var csharpText = csharpDocument.Text; if (changes.Length == 0) { - if (!_documentMappingSerivce.TryMapToCSharpDocumentPosition(codeDocument.GetRequiredImplCSharpDocument(), context.HostDocumentIndex, out _, out var projectedIndex)) + if (!_documentMappingSerivce.TryMapToCSharpDocumentPosition(csharpDocument, context.HostDocumentIndex, out _, out var projectedIndex)) { _logger.LogWarning($"Failed to map to projected position for document {context.OriginalSnapshot.FilePath}."); return []; } // Ask C# for formatting changes. - var document = roslynWorkspaceHelper.CreateCSharpDocument(context.CodeDocument); + var document = roslynWorkspaceHelper.CreateCSharpDocument(context.CSharpDocument); var formattingService = document.Project.Services.GetRequiredService(); var documentSyntax = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); @@ -117,7 +118,7 @@ public async Task> ExecuteAsync(FormattingContext con var mappedChanges = await _razorEditService.MapCSharpEditsAsync( normalizedChanges.SelectAsArray(static c => c.ToRazorTextChange()), context.CurrentSnapshot, - declarationDocument: false, // PROTOTYPE: Still to fix + declarationDocument: csharpDocument.IsDeclarationDocument, context.IncludeCSharpLanguageFeatureEdits, directlyMappedEditFilter: change => ShouldKeepDirectlyMappedEdit(context, indent, change), cancellationToken).ConfigureAwait(false); @@ -133,7 +134,7 @@ public async Task> ExecuteAsync(FormattingContext con var originalText = codeDocument.Source.Text; context.Logger?.LogSourceText("OriginalRazor", originalText); - context.Logger?.LogMessage($"Source Mappings:\r\n{RenderSourceMappings(context.CodeDocument)}"); + context.Logger?.LogMessage($"Source Mappings:\r\n{RenderSourceMappings(context.CSharpDocument)}"); // Apply the format on type edits sent over by the client. var formattedText = ApplyChangesAndTrackChange(originalText, filteredChanges, out _, out var spanAfterFormatting); @@ -282,7 +283,7 @@ private static int LineDelta(SourceText text, IEnumerable changes, o private static ImmutableArray CleanupDocument(FormattingContext context, LinePositionSpan spanAfterFormatting) { var text = context.SourceText; - var csharpDocument = context.CodeDocument.GetRequiredImplCSharpDocument(); + var csharpDocument = context.CSharpDocument; using var changes = new PooledArrayBuilder(); foreach (var mapping in csharpDocument.SourceMappingsSortedByOriginal) @@ -561,7 +562,7 @@ private async Task> AdjustIndentationAsync(Formatting // 2. The indentation due to Razor and HTML constructs var text = context.SourceText; - var csharpDocument = context.CodeDocument.GetRequiredImplCSharpDocument(); + var csharpDocument = context.CSharpDocument; // To help with figuring out the correct indentation, first we will need the indentation // that the C# formatter wants to apply in the following locations, @@ -1148,14 +1149,14 @@ owner.Parent is CSharpCodeBlockSyntax codeBlock && } } - private static string RenderSourceMappings(RazorCodeDocument codeDocument) + private static string RenderSourceMappings(RazorCSharpDocument csharpDocument) { using var pooledBuilder = AspNetCore.Razor.PooledObjects.StringBuilderPool.GetPooledObject(); var builder = pooledBuilder.Object; - var documentText = codeDocument.Source.Text.ToString(); + var documentText = csharpDocument.CodeDocument.Source.Text.ToString(); var lastIndex = 0; - foreach (var mapping in codeDocument.GetRequiredImplCSharpDocument().SourceMappingsSortedByOriginal) + foreach (var mapping in csharpDocument.SourceMappingsSortedByOriginal) { var originalStart = mapping.OriginalSpan.AbsoluteIndex; var originalEnd = originalStart + mapping.OriginalSpan.Length; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs index d4c75b976b20..2a83b896117e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/Passes/HtmlFormattingPass.cs @@ -88,11 +88,16 @@ public async Task> ExecuteAsync(FormattingContext con private async Task> FilterIncomingChangesAsync(FormattingContext context, ImmutableArray changes, CancellationToken cancellationToken) { var codeDocument = context.CodeDocument; - var csharpDocument = codeDocument.GetRequiredImplCSharpDocument(); var originalText = codeDocument.Source.Text; - var csharpSyntaxTree = await context.OriginalSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var csharpSyntaxTree = await context.OriginalSnapshot.GetCSharpSyntaxTreeAsync(declarationDocument: false, cancellationToken).ConfigureAwait(false); var csharpSyntaxRoot = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? declSyntaxRoot = null; + if (context.CodeDocument.GetCSharpDocument(declarationDocument: true) is { } declarationDocument) + { + var declSyntaxTree = await context.OriginalSnapshot.GetCSharpSyntaxTreeAsync(declarationDocument: true, cancellationToken).ConfigureAwait(false); + declSyntaxRoot = await declSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + } // Apply all changes to create the formatted document var formattedText = originalText.WithChanges(changes); @@ -194,11 +199,17 @@ ImmutableArray FilterChangesInStringLiterals(ImmutableArray _lazyWorkspace.Value.Services; - public Document CreateCSharpDocument(RazorCodeDocument codeDocument) + public Document CreateCSharpDocument(RazorCSharpDocument csharpDocument) { var project = _lazyWorkspace.Value.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp); - var csharpSourceText = codeDocument.GetCSharpSourceText(); - return project.AddDocument("TestDocument", csharpSourceText); + return project.AddDocument("TestDocument", csharpDocument.Text); } private static AdhocWorkspace CreateWorkspace(IHostServicesProvider hostServicesProvider) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs index e6e426252fd9..988ffafb674a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RazorFormattingService.cs @@ -86,7 +86,7 @@ public async Task> GetDocumentFormattingChangesAsync( var sourceText = codeDocument.Source.Text; if (range is { } span) { - if (codeDocument.GetRequiredImplCSharpDocument().Diagnostics.Any(d => d.Span != SourceSpan.Undefined && span.OverlapsWith(sourceText.GetLinePositionSpan(d.Span)))) + if (codeDocument.GetRequiredCSharpDocument(declarationDocument: false).Diagnostics.Any(d => d.Span != SourceSpan.Undefined && span.OverlapsWith(sourceText.GetLinePositionSpan(d.Span)))) { return []; } @@ -135,7 +135,7 @@ public async Task> GetDocumentFormattingChangesAsync( return originalText.MinimizeTextChanges(normalizedChanges); } - public async Task> GetCSharpOnTypeFormattingChangesAsync(DocumentContext documentContext, RazorFormattingOptions options, int hostDocumentIndex, char triggerCharacter, CancellationToken cancellationToken) + public async Task> GetCSharpOnTypeFormattingChangesAsync(DocumentContext documentContext, RazorFormattingOptions options, int hostDocumentIndex, char triggerCharacter, bool declarationDocument, CancellationToken cancellationToken) { var documentSnapshot = documentContext.Snapshot; @@ -144,6 +144,7 @@ public async Task> GetCSharpOnTypeFormattingChangesAs return await ApplyFormattedChangesAsync( documentSnapshot, codeDocument, + declarationDocument, generatedDocumentChanges: [], options, hostDocumentIndex, @@ -166,6 +167,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn return await ApplyFormattedChangesAsync( documentSnapshot, codeDocument, + declarationDocument: null, htmlChanges, options, hostDocumentIndex, @@ -178,7 +180,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn cancellationToken: cancellationToken).ConfigureAwait(false); } - public async Task TryGetSingleCSharpEditAsync(DocumentContext documentContext, TextChange csharpEdit, RazorFormattingOptions options, CancellationToken cancellationToken) + public async Task TryGetSingleCSharpEditAsync(DocumentContext documentContext, TextChange csharpEdit, bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken) { var documentSnapshot = documentContext.Snapshot; // Since we've been provided with an edit from the C# generated doc, forcing design time would make things not line up @@ -187,6 +189,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn var razorChanges = await ApplyFormattedChangesAsync( documentSnapshot, codeDocument, + declarationDocument, [csharpEdit], options, hostDocumentIndex: 0, @@ -203,7 +206,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn : null; } - public async Task TryGetCSharpCodeActionEditAsync(DocumentContext documentContext, ImmutableArray csharpChanges, RazorFormattingOptions options, CancellationToken cancellationToken) + public async Task TryGetCSharpCodeActionEditAsync(DocumentContext documentContext, ImmutableArray csharpChanges, bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken) { var documentSnapshot = documentContext.Snapshot; // Since we've been provided with edits from the C# generated doc, forcing design time would make things not line up @@ -212,6 +215,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn var razorChanges = await ApplyFormattedChangesAsync( documentSnapshot, codeDocument, + declarationDocument, csharpChanges, options, hostDocumentIndex: 0, @@ -228,7 +232,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn : null; } - public async Task TryGetCSharpSnippetFormattingEditAsync(DocumentContext documentContext, ImmutableArray csharpChanges, RazorFormattingOptions options, CancellationToken cancellationToken) + public async Task TryGetCSharpSnippetFormattingEditAsync(DocumentContext documentContext, ImmutableArray csharpChanges, bool declarationDocument, RazorFormattingOptions options, CancellationToken cancellationToken) { csharpChanges = WrapCSharpSnippets(csharpChanges); @@ -239,6 +243,7 @@ public async Task> GetHtmlOnTypeFormattingChangesAsyn var razorChanges = await ApplyFormattedChangesAsync( documentSnapshot, codeDocument, + declarationDocument, csharpChanges, options, hostDocumentIndex: 0, @@ -272,6 +277,7 @@ public bool TryGetOnTypeFormattingTriggerKind(RazorCodeDocument codeDocument, in private async Task> ApplyFormattedChangesAsync( IDocumentSnapshot documentSnapshot, RazorCodeDocument codeDocument, + bool? declarationDocument, ImmutableArray generatedDocumentChanges, RazorFormattingOptions options, int hostDocumentIndex, @@ -290,7 +296,7 @@ private async Task> ApplyFormattedChangesAsync( var logger = _formattingLoggerFactory.CreateLogger(documentSnapshot.FilePath, formattingType); logger?.LogObject("FileKind", documentSnapshot.FileKind); logger?.LogObject("Options", options); - logger?.LogObject("Parameters", new { hostDocumentIndex, triggerCharacter, collapseChanges, includeCSharpLanguageFeatureEdits, validate }); + logger?.LogObject("Parameters", new { hostDocumentIndex, triggerCharacter, collapseChanges, includeCSharpLanguageFeatureEdits, validate, declarationDocument }); logger?.LogObject("GeneratedDocumentChanges", generatedDocumentChanges); logger?.LogSourceText("InitialDocument", codeDocument.Source.Text); LogSyntaxTree(logger, codeDocument); @@ -298,6 +304,7 @@ private async Task> ApplyFormattedChangesAsync( var context = FormattingContext.CreateForOnTypeFormatting( documentSnapshot, codeDocument, + declarationDocument, options, logger, includeCSharpLanguageFeatureEdits: includeCSharpLanguageFeatureEdits, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingService.cs index 67c5db13e78b..e4613e66d5ee 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Formatting/RemoteFormattingService.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; @@ -94,8 +95,13 @@ private async ValueTask> GetOnTypeFormattingEditsAsyn return await _formattingService.GetHtmlOnTypeFormattingChangesAsync(context, htmlChanges, options, hostDocumentIndex, triggerCharacter[0], cancellationToken).ConfigureAwait(false); } + if (!DocumentMappingService.TryMapToCSharpDocumentLinePosition(codeDocument, hostDocumentIndex, out _, out _, out var inDeclDocument)) + { + return []; + } + Debug.Assert(triggerCharacterKind is RazorLanguageKind.CSharp); - return await _formattingService.GetCSharpOnTypeFormattingChangesAsync(context, options, hostDocumentIndex, triggerCharacter[0], cancellationToken).ConfigureAwait(false); + return await _formattingService.GetCSharpOnTypeFormattingChangesAsync(context, options, hostDocumentIndex, triggerCharacter[0], inDeclDocument, cancellationToken).ConfigureAwait(false); } public ValueTask GetOnTypeFormattingTriggerKindAsync( From df1109473608674b642215957fc46554c87e7476 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:34:44 +1000 Subject: [PATCH 21/34] Update dependent services so they at least compile --- .../Completion/Delegation/DelegatedCompletionHelper.cs | 1 + .../AutoInsert/RemoteAutoInsertService.cs | 2 ++ .../CodeActions/CSharp/CSharpCodeActionResolver.cs | 1 + .../Razor/GenerateEventHandlerCodeActionResolver.cs | 4 +++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs index f48ba6054bb8..1a124dbc0fc0 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs @@ -447,6 +447,7 @@ static string GetArgumentTypesLogString(VSInternalCompletionItem resolvedComplet var formattedTextChange = await formattingService.TryGetCSharpSnippetFormattingEditAsync( documentContext, changes, + declarationDocument: false, // PROTOTYPE(sonic): Pass in the right value to this options, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs index b2678b8f2e9a..7aafff2f406a 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/AutoInsert/RemoteAutoInsertService.cs @@ -173,12 +173,14 @@ private async ValueTask TryResolveInsertionInCSharpAsync( ? await _razorFormattingService.TryGetCSharpSnippetFormattingEditAsync( remoteDocumentContext, [csharpTextChange], + declarationDocument: false, // PROTOTYPE(sonic): Pass in the right value to this options, cancellationToken) .ConfigureAwait(false) : await _razorFormattingService.TryGetSingleCSharpEditAsync( remoteDocumentContext, csharpTextChange, + declarationDocument: false, // PROTOTYPE(sonic): Pass in the right value to this options, cancellationToken) .ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/CSharp/CSharpCodeActionResolver.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/CSharp/CSharpCodeActionResolver.cs index 35c2ecc5fe32..46802453cc77 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/CSharp/CSharpCodeActionResolver.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/CSharp/CSharpCodeActionResolver.cs @@ -76,6 +76,7 @@ public async Task ResolveAsync( var formattedChange = await _razorFormattingService.TryGetCSharpCodeActionEditAsync( editDocumentContext, csharpTextChanges, + declarationDocument: false, // PROTOTYPE(sonic): Pass in the right value to this formattingOptions, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs index 5f1fc72cf538..4778ab0504de 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/CodeActions/Razor/GenerateEventHandlerCodeActionResolver.cs @@ -126,7 +126,9 @@ await GetCodeBehindSyntaxTreeAsync(documentContext, codeBehindPath, cancellation // to create a code block if one doesn't exist, or put the method in an existing one, and it will also ensure the method gets properly formatted. var csharpSourceText = code.GetCSharpSourceText(); var csharpTextChanges = edits.SelectAsArray(csharpSourceText.GetTextChange); - var formattedChange = await _razorFormattingService.TryGetCSharpCodeActionEditAsync(documentContext, csharpTextChanges, options, cancellationToken).ConfigureAwait(false); + var formattedChange = await _razorFormattingService.TryGetCSharpCodeActionEditAsync(documentContext, csharpTextChanges, + declarationDocument: false, // PROTOTYPE(sonic): Pass in the right value to this + options, cancellationToken).ConfigureAwait(false); if (formattedChange is not { } razorChange) { return null; From a4948b719379eedaa8294503f0c0d869e9c6c7d6 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:35:03 +1000 Subject: [PATCH 22/34] Fix "Show Formatting Document" feature --- .../DevTools/RemoteDevToolsService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs index 4d56e5463151..723c5145438c 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/DevTools/RemoteDevToolsService.cs @@ -66,10 +66,16 @@ public ValueTask GetFormattingDocumentTextAsync( async context => { var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); - var csharpSyntaxTree = await context.Snapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var csharpSyntaxTree = await context.Snapshot.GetCSharpSyntaxTreeAsync(declarationDocument: false, cancellationToken).ConfigureAwait(false); + var declSyntaxTree = codeDocument.GetCSharpDocument(declarationDocument: true) is not null + ? await context.Snapshot.GetCSharpSyntaxTreeAsync(declarationDocument: true, cancellationToken).ConfigureAwait(false) + : null; var csharpSyntaxRoot = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + var declSyntaxRoot = declSyntaxTree is not null + ? await declSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false) + : null; #pragma warning disable CS0618 // Type or member is obsolete - return CSharpFormattingPass.GetFormattingDocumentContentsForSyntaxVisualizer(codeDocument, csharpSyntaxRoot, DocumentMappingService); + return CSharpFormattingPass.GetFormattingDocumentContentsForSyntaxVisualizer(codeDocument, csharpSyntaxRoot, declSyntaxRoot, DocumentMappingService); #pragma warning restore CS0618 // Type or member is obsolete }, cancellationToken); From 4ec51a37b4881833cc4ef9a7d45f1169e2f6f3a5 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:35:15 +1000 Subject: [PATCH 23/34] Unskip tests (and add one) --- .../Formatting/DocumentFormattingTest.cs | 75 ++++++++++++++++++- .../Formatting/RazorFormattingServiceTest.cs | 1 - .../Cohost/Formatting/OnTypeFormattingTest.cs | 38 +++++----- 3 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs index 6513d6a23e71..07defa0396f9 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/DocumentFormattingTest.cs @@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.CSharp.Formatting; -using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Razor.Settings; using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Xunit; @@ -124,6 +123,76 @@ await RunFormattingTestAsync( """"); } + [Fact] + public async Task MultilineRawStringLiteral_CodeBlock() + { + await RunFormattingTestAsync( + input: """" +
+ @code + { + private string _x = """ + Nieuw + + + Aanmaak scherm + + + + +
+ Opslaan + Annuleren +
+
+ """; + } + """", + htmlFormatted: """" +
+ @code + { + private string _x = """ + Nieuw + + + Aanmaak scherm + + + + +
+ Opslaan + Annuleren +
+
+ """; + } + """", + expected: """" +
+ @code + { + private string _x = """ + Nieuw + + + Aanmaak scherm + + + + +
+ Opslaan + Annuleren +
+
+ """; + } + """", + validateHtmlFormattedMatchesWebTools: false); + } + [Fact] [WorkItem("https://developercommunity.visualstudio.com/t/Razor-Formatting-Feature-internal-error/11041869")] public async Task TextAndTagOnSameLine() @@ -11666,7 +11735,7 @@ await RunFormattingTestAsync( fileKind: RazorFileKind.Legacy); } - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public async Task MultilineExplicitExpression() { await RunFormattingTestAsync( @@ -11756,7 +11825,7 @@ await RunFormattingTestAsync( """); } - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public async Task MultilineExplicitExpression_IsStable() { // This test explicitly validates that the expected output from the above test results in stable formatting. diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs index 99a71ee60771..03bbfef33e9a 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Formatting/RazorFormattingServiceTest.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.AspNetCore.Razor.Test.Common; -using Microsoft.CodeAnalysis.Razor.Formatting; using Microsoft.CodeAnalysis.Remote.Razor.Formatting; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs index 4abc6e9e440f..101bd843dc90 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/Formatting/OnTypeFormattingTest.cs @@ -105,7 +105,7 @@ @using Microsoft.AspNetCore.Components.Forms triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Class_SingleLineAsync() { await RunOnTypeFormattingTestAsync( @@ -123,7 +123,7 @@ public class Foo { } expectedChangedLines: 1); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Class_SingleLine_UseTabsAsync() { await RunOnTypeFormattingTestAsync( @@ -142,7 +142,7 @@ public class Foo { } expectedChangedLines: 1); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Class_SingleLine_AdjustTabSizeAsync() { await RunOnTypeFormattingTestAsync( @@ -161,7 +161,7 @@ public class Foo { } expectedChangedLines: 1); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Class_MultiLineAsync() { await RunOnTypeFormattingTestAsync( @@ -181,7 +181,7 @@ public class Foo triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Method_SingleLineAsync() { await RunOnTypeFormattingTestAsync( @@ -199,7 +199,7 @@ public void Foo { } expectedChangedLines: 1); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Method_MultiLineAsync() { await RunOnTypeFormattingTestAsync( @@ -219,7 +219,7 @@ public void Foo triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Property_SingleLineAsync() { await RunOnTypeFormattingTestAsync( @@ -236,7 +236,7 @@ await RunOnTypeFormattingTestAsync( triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Property_MultiLineAsync() { await RunOnTypeFormattingTestAsync( @@ -257,7 +257,7 @@ public string Foo triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task CloseCurly_Property_StartOfBlockAsync() { await RunOnTypeFormattingTestAsync( @@ -273,7 +273,7 @@ await RunOnTypeFormattingTestAsync( triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task Semicolon_ClassField_SingleLineAsync() { await RunOnTypeFormattingTestAsync( @@ -290,7 +290,7 @@ public class Foo { private int _hello = 0; } triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task Semicolon_ClassField_MultiLineAsync() { await RunOnTypeFormattingTestAsync( @@ -309,7 +309,7 @@ public class Foo{ triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task Semicolon_MethodVariableAsync() { await RunOnTypeFormattingTestAsync( @@ -366,7 +366,7 @@ protected override async Task OnInitializedAsync() triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task ClosingBrace_MatchesCSharpIndentationAsync() { await RunOnTypeFormattingTestAsync( @@ -414,7 +414,7 @@ private void IncrementCount() triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task ClosingBrace_DoesntMatchCSharpIndentationAsync() { await RunOnTypeFormattingTestAsync( @@ -716,7 +716,7 @@ void Foo() await RunOnTypeFormattingTestAsync(input, input.Replace("$$", ""), triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] [WorkItem("https://github.com/dotnet/razor-tooling/issues/5698")] public async Task Semicolon_NoDocumentChanges2() { @@ -870,7 +870,7 @@ public void M() triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] [WorkItem("https://github.com/dotnet/razor-tooling/issues/6158")] public async Task Format_NestedLambdas() { @@ -1071,7 +1071,7 @@ await RunOnTypeFormattingTestAsync( triggerCharacter: ';'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task Semicolon_PropertyGet() { await RunOnTypeFormattingTestAsync( @@ -1135,7 +1135,7 @@ await RunOnTypeFormattingTestAsync( fileKind: RazorFileKind.Legacy); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] public async Task OnTypeFormatting_Enabled() { await RunOnTypeFormattingTestAsync( @@ -1161,7 +1161,7 @@ private void IncrementCount() triggerCharacter: '}'); } - [FormattingTestFact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [FormattingTestFact] [WorkItem("https://github.com/dotnet/razor/issues/11117")] public async Task SemiColon_DoesntBreakHtmlAttributes() { From f1cbb12f076e3344df793a98c62ed47422c3601b Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:35:22 +1000 Subject: [PATCH 24/34] Remove stale comment --- .../ProjectSystem/IDocumentSnapshot.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentSnapshot.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentSnapshot.cs index d9ca99c85c7f..8593c32cbeec 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentSnapshot.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentSnapshot.cs @@ -30,9 +30,6 @@ internal interface IDocumentSnapshot /// /// Gets the Roslyn syntax tree for the generated C# for this Razor document /// - /// - /// ⚠️ Should be used sparingly in language server scenarios. - /// ValueTask GetCSharpSyntaxTreeAsync(bool declarationDocument, CancellationToken cancellationToken); bool TryGetText([NotNullWhen(true)] out SourceText? result); From e384ef0adc1585bc21a1d4c6591123425a49f676 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 10:50:44 +1000 Subject: [PATCH 25/34] Fix benchmark --- .../Formatting/DocumentFormattingBenchmark.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs b/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs index 137a326bd73c..8a78dd472923 100644 --- a/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs +++ b/src/Razor/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Formatting/DocumentFormattingBenchmark.cs @@ -84,7 +84,7 @@ public void Setup() var documentMappingService = new DocumentMappingService(filePathService, snapshotManager, EmptyLoggerFactory.Instance); var razorEditService = new RazorEditService(documentMappingService, clientSettingsManager, filePathService, snapshotManager, NoOpTelemetryReporter.Instance); - _formattingService = new RemoteRazorFormattingService( + _formattingService = new RazorFormattingService( documentMappingService, razorEditService, hostServicesProvider, From cffd735f960aa8c69b1929acd80d28e303db6b5e Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 13:37:39 +1000 Subject: [PATCH 26/34] Make Razor inlay hints SONIC-aware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../CohostInlayHintResolveEndpoint.cs | 2 +- .../InlayHints/InlayHintDataWrapper.cs | 2 +- .../Remote/IRemoteInlayHintService.cs | 2 +- .../InlayHints/RemoteInlayHintService.cs | 134 ++++++++++-------- 4 files changed, 81 insertions(+), 59 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/InlayHints/CohostInlayHintResolveEndpoint.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/InlayHints/CohostInlayHintResolveEndpoint.cs index 28ddd5602024..48b49695ba25 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/InlayHints/CohostInlayHintResolveEndpoint.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/InlayHints/CohostInlayHintResolveEndpoint.cs @@ -59,7 +59,7 @@ internal class CohostInlayHintResolveEndpoint( var hint = await _remoteServiceInvoker.TryInvokeAsync( razorDocument.Project.Solution, - (service, solutionInfo, cancellationToken) => service.ResolveHintAsync(solutionInfo, razorDocument.Id, request, cancellationToken), + (service, solutionInfo, cancellationToken) => service.ResolveHintAsync(solutionInfo, razorDocument.Id, request, razorData.InDeclDocument, cancellationToken), cancellationToken).ConfigureAwait(false); if (hint is null) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/InlayHints/InlayHintDataWrapper.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/InlayHints/InlayHintDataWrapper.cs index 98351bd8a42f..41f2f57d91fb 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/InlayHints/InlayHintDataWrapper.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/InlayHints/InlayHintDataWrapper.cs @@ -3,4 +3,4 @@ namespace Microsoft.CodeAnalysis.Razor.Protocol.InlayHints; -internal record class InlayHintDataWrapper(TextDocumentIdentifier TextDocument, object? OriginalData, Position OriginalPosition); +internal record class InlayHintDataWrapper(TextDocumentIdentifier TextDocument, object? OriginalData, Position OriginalPosition, bool InDeclDocument); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteInlayHintService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteInlayHintService.cs index 52135f95cfc1..fe30d136c22d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteInlayHintService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteInlayHintService.cs @@ -10,5 +10,5 @@ internal interface IRemoteInlayHintService : IRemoteJsonService { ValueTask GetInlayHintsAsync(JsonSerializableRazorSolutionWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHintParams inlayHintParams, bool displayAllOverride, CancellationToken cancellationToken); - ValueTask ResolveHintAsync(JsonSerializableRazorSolutionWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, CancellationToken cancellationToken); + ValueTask ResolveHintAsync(JsonSerializableRazorSolutionWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, bool inDeclDocument, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs index 1c1a61de6cf2..ee58a72fa506 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs @@ -42,94 +42,116 @@ protected override IRemoteInlayHintService CreateService(in ServiceArgs args) private async ValueTask GetInlayHintsAsync(RemoteDocumentContext context, InlayHintParams inlayHintParams, bool displayAllOverride, CancellationToken cancellationToken) { var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); - var csharpDocument = codeDocument.GetRequiredImplCSharpDocument(); var span = inlayHintParams.Range.ToLinePositionSpan(); cancellationToken.ThrowIfCancellationRequested(); - var overlappingSpans = DocumentMappingService.GetCSharpSpansOverlappingRazorSpan(csharpDocument, span); + using var inlayHintsBuilder = new PooledArrayBuilder(); + var sawCSharpSpan = false; + var seenHints = new HashSet<(LinePosition Position, string? Label)>(); + + await AddInlayHintsAsync(codeDocument.GetRequiredCSharpDocument(declarationDocument: false), cancellationToken).ConfigureAwait(false); - if (overlappingSpans.IsEmpty) + if (codeDocument.GetCSharpDocument(declarationDocument: true) is { } declCSharpDocument) { - // There's no C# in the range. - return null; + await AddInlayHintsAsync(declCSharpDocument, cancellationToken).ConfigureAwait(false); } - var generatedDocument = await context.Snapshot - .GetGeneratedDocumentAsync(cancellationToken) - .ConfigureAwait(false); - - var textDocument = inlayHintParams.TextDocument.WithUri(generatedDocument.GetURI()); - - using var inlayHintsBuilder = new PooledArrayBuilder(); - var razorSourceText = codeDocument.Source.Text; - var csharpSourceText = codeDocument.GetCSharpSourceText(); - var root = codeDocument.GetRequiredSyntaxRoot(); + return !sawCSharpSpan + ? null + : inlayHintsBuilder.ToArray(); - foreach (var csharpSpan in overlappingSpans) + async ValueTask AddInlayHintsAsync(RazorCSharpDocument csharpDocument, CancellationToken cancellationToken) { - var range = csharpSpan.ToRange(); - var hints = await GetInlayHintsAsync(generatedDocument, textDocument, range, displayAllOverride, _cacheProvider.GetCache(), cancellationToken).ConfigureAwait(false); - if (hints is null) + var overlappingSpans = DocumentMappingService.GetCSharpSpansOverlappingRazorSpan(csharpDocument, span); + + if (overlappingSpans.IsEmpty) { - continue; + // There's no C# in the range for this generated document. + return; } - foreach (var hint in hints) - { - if (csharpSourceText.TryGetAbsoluteIndex(hint.Position.ToLinePosition(), out var absoluteIndex) && - DocumentMappingService.TryMapToRazorDocumentPosition(csharpDocument, absoluteIndex, out var hostDocumentPosition, out var hostDocumentIndex)) - { - // We know this C# maps to Razor, but does it map to Razor that we like? + sawCSharpSpan = true; - // We don't want inlay hints in tag helper attributes - var node = root.FindInnermostNode(hostDocumentIndex); - if (node?.FirstAncestorOrSelf() is not null) - { - continue; - } + var inDeclDocument = csharpDocument.IsDeclarationDocument; + var generatedDocument = await context.Snapshot + .GetGeneratedDocumentAsync(inDeclDocument, cancellationToken) + .ConfigureAwait(false); - // Inlay hints in directives are okay, eg '@attribute [Description(description: "Desc")]', but if the hint is going to be - // at the very start of the directive, we want to strip any TextEdit as it would make for an invalid document. eg: '// @page template: "/"' - if (node?.SpanStart == hostDocumentIndex && - node.FirstAncestorOrSelf(static n => n.IsDirectiveKind(DirectiveKind.SingleLine)) is not null) - { - hint.TextEdits = null; - } + var textDocument = inlayHintParams.TextDocument.WithUri(generatedDocument.GetURI()); - if (hint.TextEdits is not null) - { - var changes = hint.TextEdits.SelectAsArray(csharpSourceText.GetTextChange); - var textChanges = await _razorEditService.MapCSharpEditsAsync(changes, context.Snapshot, cancellationToken).ConfigureAwait(false); + var razorSourceText = codeDocument.Source.Text; + var csharpSourceText = csharpDocument.Text; + var root = codeDocument.GetRequiredSyntaxRoot(); - var textEdits = textChanges.SelectAsArray(razorSourceText.GetTextEdit); + foreach (var csharpSpan in overlappingSpans) + { + var range = csharpSpan.ToRange(); + var hints = await GetInlayHintsAsync(generatedDocument, textDocument, range, displayAllOverride, _cacheProvider.GetCache(), cancellationToken).ConfigureAwait(false); + if (hints is null) + { + continue; + } - hint.TextEdits = ImmutableCollectionsMarshal.AsArray(textEdits); + foreach (var hint in hints) + { + if (csharpSourceText.TryGetAbsoluteIndex(hint.Position.ToLinePosition(), out var absoluteIndex) && + DocumentMappingService.TryMapToRazorDocumentPosition(csharpDocument, absoluteIndex, out var hostDocumentPosition, out var hostDocumentIndex)) + { + // We know this C# maps to Razor, but does it map to Razor that we like? + + // We don't want inlay hints in tag helper attributes + var node = root.FindInnermostNode(hostDocumentIndex); + if (node?.FirstAncestorOrSelf() is not null) + { + continue; + } + + // Inlay hints in directives are okay, eg '@attribute [Description(description: "Desc")]', but if the hint is going to be + // at the very start of the directive, we want to strip any TextEdit as it would make for an invalid document. eg: '// @page template: "/"' + if (node?.SpanStart == hostDocumentIndex && + node.FirstAncestorOrSelf(static n => n.IsDirectiveKind(DirectiveKind.SingleLine)) is not null) + { + hint.TextEdits = null; + } + + if (hint.TextEdits is not null) + { + var changes = hint.TextEdits.SelectAsArray(csharpSourceText.GetTextChange); + var textChanges = await _razorEditService.MapCSharpEditsAsync(changes, inDeclDocument, context.Snapshot, cancellationToken).ConfigureAwait(false); + + var textEdits = textChanges.SelectAsArray(razorSourceText.GetTextEdit); + + hint.TextEdits = ImmutableCollectionsMarshal.AsArray(textEdits); + } + + if (!seenHints.Add((hostDocumentPosition, hint.Label.First))) + { + continue; + } + + hint.Data = new InlayHintDataWrapper(inlayHintParams.TextDocument, hint.Data, hint.Position, inDeclDocument); + hint.Position = hostDocumentPosition.ToPosition(); + + inlayHintsBuilder.Add(hint); } - - hint.Data = new InlayHintDataWrapper(inlayHintParams.TextDocument, hint.Data, hint.Position); - hint.Position = hostDocumentPosition.ToPosition(); - - inlayHintsBuilder.Add(hint); } } } - - return inlayHintsBuilder.ToArray(); } - public ValueTask ResolveHintAsync(JsonSerializableRazorSolutionWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, CancellationToken cancellationToken) + public ValueTask ResolveHintAsync(JsonSerializableRazorSolutionWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, bool inDeclDocument, CancellationToken cancellationToken) => RunServiceAsync( solutionInfo, razorDocumentId, - context => ResolveInlayHintAsync(context, inlayHint, cancellationToken), + context => ResolveInlayHintAsync(context, inlayHint, inDeclDocument, cancellationToken), cancellationToken); - private async ValueTask ResolveInlayHintAsync(RemoteDocumentContext context, InlayHint inlayHint, CancellationToken cancellationToken) + private async ValueTask ResolveInlayHintAsync(RemoteDocumentContext context, InlayHint inlayHint, bool inDeclDocument, CancellationToken cancellationToken) { var generatedDocument = await context.Snapshot - .GetGeneratedDocumentAsync(cancellationToken) + .GetGeneratedDocumentAsync(inDeclDocument, cancellationToken) .ConfigureAwait(false); return await ResolveInlayHintAsync(generatedDocument, inlayHint, _cacheProvider.GetCache(), cancellationToken).ConfigureAwait(false); From e5affc8c56e28ac597a5cb21d8343fc6647ace80 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 13:37:41 +1000 Subject: [PATCH 27/34] Add SONIC inlay hint tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Endpoints/CohostInlayHintEndpointTest.cs | 192 +++++++++++++++++- 1 file changed, 186 insertions(+), 6 deletions(-) diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostInlayHintEndpointTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostInlayHintEndpointTest.cs index 131ac2b39e84..88f9c1a36a36 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostInlayHintEndpointTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostInlayHintEndpointTest.cs @@ -7,6 +7,7 @@ using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor; +using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Testing; @@ -20,7 +21,7 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; public class CohostInlayHintEndpointTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper) { - [RoslynConditionalFact(typeof(IsEnglishLocal), AlwaysSkip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [RoslynConditionalFact(typeof(IsEnglishLocal))] public Task InlayHints() => VerifyInlayHintsAsync( input: """ @@ -62,7 +63,50 @@ private void M(string thisIsMyString) """); - [RoslynConditionalFact(typeof(IsEnglishLocal), AlwaysSkip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [RoslynConditionalFact(typeof(IsEnglishLocal))] + public Task InlayHints_Legacy() + => VerifyInlayHintsAsync( + input: """ + +
+ + @functions { + private void M(string thisIsMyString) + { + var {|int:x|} = 5; + + var {|string:y|} = "Hello"; + + M({|thisIsMyString:"Hello"|}); + } + } + + """, + toolTipMap: new Dictionary + { + { "int", "struct System.Int32" }, + { "string", "class System.String" }, + { "thisIsMyString", "(parameter) string thisIsMyStr" } + }, + output: """ + +
+ + @functions { + private void M(string thisIsMyString) + { + int x = 5; + + string y = "Hello"; + + M(thisIsMyString: "Hello"); + } + } + + """, + fileKind: RazorFileKind.Legacy); + + [RoslynConditionalFact(typeof(IsEnglishLocal))] public Task InlayHints_DisplayAllOverride() => VerifyInlayHintsAsync( input: """ @@ -105,6 +149,121 @@ private void M(string thisIsMyString) """, displayAllOverride: true); + [RoslynConditionalFact(typeof(IsEnglishLocal))] + public Task InlayHints_DisplayAllOverride_Legacy() + => VerifyInlayHintsAsync( + input: """ + +
+ + @functions { + private void M(string thisIsMyString) + { + {|int:var|} x = 5; + + {|string:var|} y = "Hello"; + + M({|thisIsMyString:"Hello"|}); + } + } + + """, + toolTipMap: new Dictionary + { + { "int", "struct System.Int32" }, + { "string", "class System.String" }, + { "thisIsMyString", "(parameter) string thisIsMyStr" } + }, + output: """ + +
+ + @functions { + private void M(string thisIsMyString) + { + int x = 5; + + string y = "Hello"; + + M(thisIsMyString: "Hello"); + } + } + + """, + displayAllOverride: true, + fileKind: RazorFileKind.Legacy); + + [RoslynConditionalFact(typeof(IsEnglishLocal))] + public Task InlayHints_ExplicitStatementAndCodeBlock() + => VerifyInlayHintsAsync( + input: """ +
+ @{ + var {|string:x|} = "asdf"; + } + + @code { + private void M() + { + var {|int:y|} = 1; + } + } + """, + toolTipMap: new Dictionary + { + { "int", "struct System.Int32" }, + { "string", "class System.String" } + }, + output: """ +
+ @{ + string x = "asdf"; + } + + @code { + private void M() + { + int y = 1; + } + } + """); + + [RoslynConditionalFact(typeof(IsEnglishLocal))] + public Task InlayHints_ExplicitStatementAndCodeBlock_Legacy() + => VerifyInlayHintsAsync( + input: """ +
+ @{ + var {|string:x|} = "asdf"; + } + + @functions { + private void M() + { + var {|int:y|} = 1; + } + } + """, + toolTipMap: new Dictionary + { + { "int", "struct System.Int32" }, + { "string", "class System.String" } + }, + output: """ +
+ @{ + string x = "asdf"; + } + + @functions { + private void M() + { + int y = 1; + } + } + """, + fileKind: RazorFileKind.Legacy); + [Fact] public Task InlayHints_ComponentAttributes() => VerifyInlayHintsAsync( @@ -154,7 +313,7 @@ public async Task InlayHints_InvalidRange(int startLine, int starChar, int endLi Assert.Null(hints); } - [RoslynConditionalFact(typeof(IsEnglishLocal), AlwaysSkip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [RoslynConditionalFact(typeof(IsEnglishLocal))] public Task PageDirective() => VerifyInlayHintsAsync( input: """ @@ -174,7 +333,7 @@ public Task PageDirective() """); - [RoslynConditionalFact(typeof(IsEnglishLocal), AlwaysSkip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [RoslynConditionalFact(typeof(IsEnglishLocal))] public Task AttributeDirective() => VerifyInlayHintsAsync( input: """ @@ -194,10 +353,31 @@ @attribute [System.ComponentModel.Description(description: "Desc")] """); - private async Task VerifyInlayHintsAsync(string input, Dictionary toolTipMap, string output, bool displayAllOverride = false) + [RoslynConditionalFact(typeof(IsEnglishLocal))] + public Task AttributeDirective_Legacy() + => VerifyInlayHintsAsync( + input: """ + @attribute [System.ComponentModel.Description({|description:"Desc"|})] + +
+ + """, + toolTipMap: new Dictionary + { + { "description", "(parameter) string description" }, + }, + output: """ + @attribute [System.ComponentModel.Description(description: "Desc")] + +
+ + """, + fileKind: RazorFileKind.Legacy); + + private async Task VerifyInlayHintsAsync(string input, Dictionary toolTipMap, string output, bool displayAllOverride = false, RazorFileKind? fileKind = null) { TestFileMarkupParser.GetSpans(input, out input, out ImmutableDictionary> spansDict); - var document = CreateProjectAndRazorDocument(input); + var document = CreateProjectAndRazorDocument(input, fileKind); var inputText = await document.GetTextAsync(DisposalToken); var endpoint = new CohostInlayHintEndpoint(IncompatibleProjectService, RemoteServiceInvoker); From d758621149d768731f293be91f3bb3bd00897f3c Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 14:14:48 +1000 Subject: [PATCH 28/34] Make Razor folding ranges SONIC-aware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../FoldingRanges/FoldingRangeService.cs | 30 ++++++++++++------- .../FoldingRanges/IFoldingRangeService.cs | 2 +- .../RemoteFoldingRangeService.cs | 16 ++++++---- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/FoldingRangeService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/FoldingRangeService.cs index 197372e0d255..98c9740cd411 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/FoldingRangeService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/FoldingRangeService.cs @@ -27,7 +27,7 @@ internal sealed class FoldingRangeService( private readonly IEnumerable _foldingRangeProviders = foldingRangeProviders; private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); - public ImmutableArray GetFoldingRanges(RazorCodeDocument codeDocument, FoldingRange[] csharpRanges, ImmutableArray htmlRanges, CancellationToken cancellationToken) + public ImmutableArray GetFoldingRanges(RazorCodeDocument codeDocument, FoldingRange[] csharpRanges, FoldingRange[]? declCSharpRanges, ImmutableArray htmlRanges, CancellationToken cancellationToken) { using var _ = ArrayBuilderPool.GetPooledObject(out var mappedRanges); @@ -35,20 +35,30 @@ public ImmutableArray GetFoldingRanges(RazorCodeDocument codeDocum // but we will at least have one per html range so can avoid some initial resizing of the backing data store. mappedRanges.SetCapacityIfLarger(htmlRanges.Length); - var csharpDocument = codeDocument.GetRequiredImplCSharpDocument(); + AddMappedCSharpRanges(csharpRanges, declarationDocument: false); + AddMappedCSharpRanges(declCSharpRanges, declarationDocument: true); - foreach (var foldingRange in csharpRanges) + void AddMappedCSharpRanges(FoldingRange[]? ranges, bool declarationDocument) { - var span = GetLinePositionSpan(foldingRange); + if (ranges is null) + { + return; + } - if (_documentMappingService.TryMapToRazorDocumentRange(csharpDocument, span, out var mappedSpan)) + var csharpDocument = codeDocument.GetRequiredCSharpDocument(declarationDocument); + foreach (var foldingRange in ranges) { - foldingRange.StartLine = mappedSpan.Start.Line; - foldingRange.StartCharacter = mappedSpan.Start.Character; - foldingRange.EndLine = mappedSpan.End.Line; - foldingRange.EndCharacter = mappedSpan.End.Character; + var span = GetLinePositionSpan(foldingRange); + + if (_documentMappingService.TryMapToRazorDocumentRange(csharpDocument, span, out var mappedSpan)) + { + foldingRange.StartLine = mappedSpan.Start.Line; + foldingRange.StartCharacter = mappedSpan.Start.Character; + foldingRange.EndLine = mappedSpan.End.Line; + foldingRange.EndCharacter = mappedSpan.End.Character; - mappedRanges.Add(foldingRange); + mappedRanges.Add(foldingRange); + } } } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/IFoldingRangeService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/IFoldingRangeService.cs index a3b55f57ba73..96d36fac0f12 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/IFoldingRangeService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/IFoldingRangeService.cs @@ -9,5 +9,5 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.FoldingRanges; internal interface IFoldingRangeService { - ImmutableArray GetFoldingRanges(RazorCodeDocument codeDocument, FoldingRange[] csharpRanges, ImmutableArray htmlRanges, CancellationToken cancellationToken); + ImmutableArray GetFoldingRanges(RazorCodeDocument codeDocument, FoldingRange[] csharpRanges, FoldingRange[]? declCSharpRanges, ImmutableArray htmlRanges, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/RemoteFoldingRangeService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/RemoteFoldingRangeService.cs index 4391a65a3057..fd50ce8f4c3e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/RemoteFoldingRangeService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/FoldingRanges/RemoteFoldingRangeService.cs @@ -41,18 +41,22 @@ private async ValueTask> GetFoldingRangesAsyn ImmutableArray htmlRanges, CancellationToken cancellationToken) { - var generatedDocument = await context.Snapshot - .GetGeneratedDocumentAsync(cancellationToken) - .ConfigureAwait(false); - var lineFoldingOnly = _clientCapabilitiesService.ClientCapabilities.TextDocument?.FoldingRange?.LineFoldingOnly ?? false; - var globalOptions = generatedDocument.Project.Solution.Services.ExportProvider.GetService(); + var globalOptions = context.TextDocument.Project.Solution.Services.ExportProvider.GetService(); + + var generatedDocument = await context.Snapshot.GetGeneratedDocumentAsync(declarationDocument: false, cancellationToken).ConfigureAwait(false); var csharpRanges = await FoldingRangesHandler.GetFoldingRangesAsync(globalOptions, generatedDocument, lineFoldingOnly, cancellationToken).ConfigureAwait(false); + FoldingRange[]? declCSharpRanges = null; + if (await context.Snapshot.TryGetGeneratedDocumentAsync(declarationDocument: true, cancellationToken).ConfigureAwait(false) is SourceGeneratedDocument declGeneratedDocument) + { + declCSharpRanges = await FoldingRangesHandler.GetFoldingRangesAsync(globalOptions, declGeneratedDocument, lineFoldingOnly, cancellationToken).ConfigureAwait(false); + } + var convertedHtml = htmlRanges.SelectAsArray(RemoteFoldingRange.ToLspFoldingRange); var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); - return _foldingRangeService.GetFoldingRanges(codeDocument, csharpRanges, convertedHtml, cancellationToken) + return _foldingRangeService.GetFoldingRanges(codeDocument, csharpRanges, declCSharpRanges, convertedHtml, cancellationToken) .SelectAsArray(RemoteFoldingRange.FromLspFoldingRange); } } From 2057517cb457c1365962ed4acb26fab09d425fed Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 14:14:49 +1000 Subject: [PATCH 29/34] Add SONIC folding range tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../CohostFoldingRangeEndpointTest.cs | 119 ++++++++++++++++-- 1 file changed, 110 insertions(+), 9 deletions(-) diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostFoldingRangeEndpointTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostFoldingRangeEndpointTest.cs index 4a3472f144d2..6aa2650633d3 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostFoldingRangeEndpointTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostFoldingRangeEndpointTest.cs @@ -207,7 +207,7 @@ public Task Section_Invalid() """, fileKind: RazorFileKind.Legacy); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public Task CSharpCodeInCodeBlocks() => VerifyFoldingRangesAsync("""
@@ -222,7 +222,23 @@ public void M() {{|implementation: }|] """); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] + public Task CSharpCodeInCodeBlocks_Legacy() + => VerifyFoldingRangesAsync(""" +
+ Hello @_name +
+ + @functions {[| + private string _name = "Dave"; + + public void M() {{|implementation: + }|} + }|] + """, + fileKind: RazorFileKind.Legacy); + + [Fact] public Task HtmlAndCSharp() => VerifyFoldingRangesAsync("""
{|html: @@ -241,7 +257,27 @@ public void M() {{|implementation: }|] """); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] + public Task HtmlAndCSharp_Legacy() + => VerifyFoldingRangesAsync(""" +
{|html: + Hello @_name + +
{|html: + Nests aren't just for birds! +
|} +
|} + + @functions {[| + private string _name = "Dave"; + + public void M() {{|implementation: + }|} + }|] + """, + fileKind: RazorFileKind.Legacy); + + [Fact] public Task CSharp_LineFoldingOnly() => VerifyFoldingRangesAsync("""
{|html: @@ -257,9 +293,26 @@ class C { public void M1() {{|implementation: """, lineFoldingOnly: true); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] + public Task CSharp_LineFoldingOnly_Legacy() + => VerifyFoldingRangesAsync(""" +
{|html: + Hello @_name +
|} + + @functions {[| + class C { public void M1() {{|implementation: + var x = 1; + |} } + } + }|] + """, + fileKind: RazorFileKind.Legacy, + lineFoldingOnly: true); + + [Fact] public Task CSharp_NotLineFoldingOnly() - => VerifyFoldingRangesAsync(""" + => VerifyFoldingRangesAsync("""
{|html: Hello @_name
|} @@ -271,9 +324,26 @@ class C { public void M1() {[| }|] }|] """, - lineFoldingOnly: false); + lineFoldingOnly: false); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] + public Task CSharp_NotLineFoldingOnly_Legacy() + => VerifyFoldingRangesAsync(""" +
{|html: + Hello @_name +
|} + + @functions {[| + class C { public void M1() {[| + var x = 1; + } + }|] + }|] + """, + fileKind: RazorFileKind.Legacy, + lineFoldingOnly: false); + + [Fact] public Task IfElseStatements_LineFoldingOnly() => VerifyFoldingRangesAsync("""
@@ -303,9 +373,40 @@ void M(){|implementation: """, lineFoldingOnly: true); - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] + public Task IfElseStatements_LineFoldingOnly_Legacy() + => VerifyFoldingRangesAsync(""" +
+ @if (true) {[| +
+ Hello World +
+ } else {[| +
+ Goodbye World +
+ |] } + |] } +
+ + @functions[| + { + void M(){|implementation: + { + if (true) {[| + |] var x = 1; + } else {[| + var y = 2; + |] } + |} } + }|] + """, + fileKind: RazorFileKind.Legacy, + lineFoldingOnly: true); + + [Fact] public Task CSharpExpressionBodiedMethods() - => VerifyFoldingRangesAsync(""" + => VerifyFoldingRangesAsync("""

hello!

@code {[| From 3eb3b12e60197075ffbd7d69d2f13bd8f3c1402f Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 14:34:35 +1000 Subject: [PATCH 30/34] Move files from Workspaces to Remote and unify namespaces --- .../ITagHelperSearchEngine.cs | 4 +++- .../GoToDefinition/AbstractDefinitionService.cs | 3 ++- .../GoToDefinition/DefinitionService.cs | 1 - .../GoToDefinition/IDefinitionService.cs | 2 +- .../GoToDefinition/RazorComponentDefinitionHelpers.cs | 6 ++---- .../GoToDefinition/RemoteGoToDefinitionService.cs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/GoToDefinition/AbstractDefinitionService.cs (98%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/GoToDefinition/IDefinitionService.cs (93%) rename src/Razor/src/Razor/src/{Microsoft.CodeAnalysis.Razor.Workspaces => Microsoft.CodeAnalysis.Remote.Razor}/GoToDefinition/RazorComponentDefinitionHelpers.cs (97%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ITagHelperSearchEngine.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ITagHelperSearchEngine.cs index 97a28c65c363..3a658dc978b4 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ITagHelperSearchEngine.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ITagHelperSearchEngine.cs @@ -4,7 +4,7 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Razor.GoToDefinition; +using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis.Razor.ProjectSystem; namespace Microsoft.CodeAnalysis.Razor.Workspaces; @@ -13,3 +13,5 @@ internal interface ITagHelperSearchEngine { Task TryLocateTagHelperDefinitionsAsync(ImmutableArray boundTagHelpers, IDocumentSnapshot documentSnapshot, ISolutionQueryOperations solutionQueryOperations, CancellationToken cancellationToken); } + +internal sealed record BoundTagHelperResult(TagHelperDescriptor ElementDescriptor, BoundAttributeDescriptor? AttributeDescriptor); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/AbstractDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs similarity index 98% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/AbstractDefinitionService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs index 9b149909b224..a4d9426c241e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/AbstractDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -13,7 +14,7 @@ using Microsoft.CodeAnalysis.Text; using CSharpSyntaxKind = Microsoft.CodeAnalysis.CSharp.SyntaxKind; -namespace Microsoft.CodeAnalysis.Razor.GoToDefinition; +namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; internal abstract class AbstractDefinitionService( IRazorComponentSearchEngine componentSearchEngine, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs index 5087e7764274..d624d5181158 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs @@ -3,7 +3,6 @@ using System.Composition; using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.GoToDefinition; using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Workspaces; diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/IDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs similarity index 93% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/IDefinitionService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs index 3fcd2ed6fbf8..57d81f239786 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/IDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs @@ -6,7 +6,7 @@ using Microsoft.CodeAnalysis.Razor.DocumentMapping; using Microsoft.CodeAnalysis.Razor.ProjectSystem; -namespace Microsoft.CodeAnalysis.Razor.GoToDefinition; +namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; /// /// Go to Definition support for Razor tag helpers (Mvc tag helpers and components). diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/RazorComponentDefinitionHelpers.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs similarity index 97% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/RazorComponentDefinitionHelpers.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs index d7d55e00c24a..8ad1bc734aa8 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/RazorComponentDefinitionHelpers.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -19,9 +19,7 @@ using RazorSyntaxNode = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxNode; using RazorSyntaxToken = Microsoft.AspNetCore.Razor.Language.Syntax.SyntaxToken; -namespace Microsoft.CodeAnalysis.Razor.GoToDefinition; - -internal sealed record BoundTagHelperResult(TagHelperDescriptor ElementDescriptor, BoundAttributeDescriptor? AttributeDescriptor); +namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; internal static class RazorComponentDefinitionHelpers { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs index 9e1a7a8de1c1..84c7a885615d 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs @@ -9,11 +9,11 @@ using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Razor; -using Microsoft.CodeAnalysis.Razor.GoToDefinition; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping; +using Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; using static Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse; From c9d98ae5a2d5c12cdf319ca124e9cc4822dc61d9 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 14:35:45 +1000 Subject: [PATCH 31/34] Move MEF export --- .../AbstractDefinitionService.cs | 9 ++++++--- .../GoToDefinition/DefinitionService.cs | 20 ------------------- 2 files changed, 6 insertions(+), 23 deletions(-) delete mode 100644 src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs index a4d9426c241e..2c29c8579dbc 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Composition; using System.Diagnostics; using System.IO; using System.Threading; @@ -16,16 +17,18 @@ namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; -internal abstract class AbstractDefinitionService( +[Export(typeof(IDefinitionService)), Shared] +[method: ImportingConstructor] +internal sealed class DefinitionService( IRazorComponentSearchEngine componentSearchEngine, ITagHelperSearchEngine? tagHelperSearchEngine, IDocumentMappingService documentMappingService, - ILogger logger) : IDefinitionService + ILoggerFactory loggerFactory) : IDefinitionService { private readonly IRazorComponentSearchEngine _componentSearchEngine = componentSearchEngine; private readonly ITagHelperSearchEngine? _tagHelperSearchEngine = tagHelperSearchEngine; private readonly IDocumentMappingService _documentMappingService = documentMappingService; - private readonly ILogger _logger = logger; + private readonly ILogger _logger = loggerFactory.GetOrCreateLogger(); public async Task GetDefinitionAsync( IDocumentSnapshot documentSnapshot, diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs deleted file mode 100644 index d624d5181158..000000000000 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Composition; -using Microsoft.CodeAnalysis.Razor.DocumentMapping; -using Microsoft.CodeAnalysis.Razor.Logging; -using Microsoft.CodeAnalysis.Razor.Workspaces; - -namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition; - -[Export(typeof(IDefinitionService)), Shared] -[method: ImportingConstructor] -internal sealed class DefinitionService( - IRazorComponentSearchEngine componentSearchEngine, - IDocumentMappingService documentMappingService, - ITagHelperSearchEngine tagHelperSearchEngine, - ILoggerFactory loggerFactory) - : AbstractDefinitionService(componentSearchEngine, tagHelperSearchEngine, documentMappingService, loggerFactory.GetOrCreateLogger()) -{ -} From bff73ca985103656aa8baaab42ab4dd790305e62 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 14:35:56 +1000 Subject: [PATCH 32/34] Rename file --- .../{AbstractDefinitionService.cs => DefinitionService.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/{AbstractDefinitionService.cs => DefinitionService.cs} (100%) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs similarity index 100% rename from src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/AbstractDefinitionService.cs rename to src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs From 577e795ef0a5392ab1bc85b21d08ab79e7593266 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 17:37:43 +1000 Subject: [PATCH 33/34] Make Razor go to definition SONIC-aware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../GoToDefinition/DefinitionService.cs | 3 ++- .../GoToDefinition/IDefinitionService.cs | 1 + .../RazorComponentDefinitionHelpers.cs | 14 +++++++++----- .../RemoteGoToDefinitionService.cs | 11 ++++++++++- .../RemoteTagHelperSearchEngine.cs | 1 - .../CohostGoToDefinitionEndpointTest.cs | 6 +++--- .../Cohost/CohostRoslynGoToDefTest.cs | 17 ++++++++++++++--- 7 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs index 2c29c8579dbc..877eaa9a6cb0 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/DefinitionService.cs @@ -110,12 +110,13 @@ private async Task GetNavigateRangeAsync(IDocumentSnapshot documentSna public async Task TryGetDefinitionFromStringLiteralAsync( IDocumentSnapshot documentSnapshot, Position position, + bool inDeclDocument, CancellationToken cancellationToken) { _logger.LogDebug($"Attempting to get definition from string literal at position {position}."); // Get the C# syntax tree to analyze the string literal - var syntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var syntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(inDeclDocument, cancellationToken).ConfigureAwait(false); var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var sourceText = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs index 57d81f239786..25c993f15115 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/IDefinitionService.cs @@ -23,5 +23,6 @@ internal interface IDefinitionService Task TryGetDefinitionFromStringLiteralAsync( IDocumentSnapshot documentSnapshot, Position position, + bool inDeclDocument, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs index 8ad1bc734aa8..acb3b7227512 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionHelpers.cs @@ -169,17 +169,22 @@ static bool TryGetTagName(RazorSyntaxNode node, out RazorSyntaxToken tagName) // will error, but allowing them to Go To Def on that property regardless, actually helps // them fix the error. - var csharpSyntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - var root = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var codeDocument = await documentSnapshot.GetGeneratedOutputAsync(cancellationToken).ConfigureAwait(false); + // By definition, properties will be part of the declaration document when it exists. + // Legacy documents don't have a declaration document, so they fall back to the implementation document. + var csharpDocument = codeDocument.GetCSharpDocument(declarationDocument: true) + ?? codeDocument.GetRequiredCSharpDocument(declarationDocument: false); + + var csharpSyntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(csharpDocument.IsDeclarationDocument, cancellationToken).ConfigureAwait(false); + var root = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + if (root.TryGetClassDeclaration(out var classDeclaration)) { var property = classDeclaration .Members .OfType() - .Where(p => p.Identifier.ValueText.Equals(propertyName, StringComparison.Ordinal)) - .FirstOrDefault(); + .FirstOrDefault(p => p.Identifier.ValueText.Equals(propertyName, StringComparison.Ordinal)); if (property is null) { @@ -188,7 +193,6 @@ static bool TryGetTagName(RazorSyntaxNode node, out RazorSyntaxToken tagName) return null; } - var csharpDocument = codeDocument.GetRequiredImplCSharpDocument(); var range = csharpDocument.Text.GetRange(property.Identifier.Span); if (documentMappingService.TryMapToRazorDocumentRange(csharpDocument, range, out var originalRange)) { diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs index 84c7a885615d..739581f87eb4 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RemoteGoToDefinitionService.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; @@ -100,6 +101,7 @@ protected override IRemoteGoToDefinitionService CreateService(in ServiceArgs arg var stringLiteralLocations = await _definitionService.TryGetDefinitionFromStringLiteralAsync( context.Snapshot, positionInfo.Position, + positionInfo.InDeclDocument, cancellationToken) .ConfigureAwait(false); @@ -117,7 +119,7 @@ protected override IRemoteGoToDefinitionService CreateService(in ServiceArgs arg // Finally, call into C#. var generatedDocument = await context.Snapshot - .GetGeneratedDocumentAsync(cancellationToken) + .GetGeneratedDocumentAsync(positionInfo.InDeclDocument, cancellationToken) .ConfigureAwait(false); var locations = await GetDefinitionsAsync( @@ -135,6 +137,7 @@ protected override IRemoteGoToDefinitionService CreateService(in ServiceArgs arg // Map the C# locations back to the Razor file. using var mappedLocations = new PooledArrayBuilder(locations.Length); + using var _ = HashSetPool<(Uri DocumentUri, LinePositionSpan Range)>.GetPooledObject(out var seenLocations); foreach (var location in locations) { @@ -144,6 +147,12 @@ protected override IRemoteGoToDefinitionService CreateService(in ServiceArgs arg .MapToHostDocumentUriAndRangeAsync(context.Snapshot, uri, range.ToLinePositionSpan(), cancellationToken) .ConfigureAwait(false); + // Impl and decl generated documents can both contain a generated class declaration that maps to the same Razor location. + if (!seenLocations.Add((mappedDocumentUri, mappedRange))) + { + continue; + } + var mappedLocation = LspFactory.CreateLocation(mappedDocumentUri.CreateDocumentUriFromSystemUri(), mappedRange); mappedLocations.Add(mappedLocation); diff --git a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RemoteTagHelperSearchEngine.cs b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RemoteTagHelperSearchEngine.cs index 46e541fa388c..80f6df393f3e 100644 --- a/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RemoteTagHelperSearchEngine.cs +++ b/src/Razor/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/RemoteTagHelperSearchEngine.cs @@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.LanguageServer; -using Microsoft.CodeAnalysis.Razor.GoToDefinition; using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Workspaces; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; diff --git a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostGoToDefinitionEndpointTest.cs b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostGoToDefinitionEndpointTest.cs index bff56cf7afc3..f67ac1f86d42 100644 --- a/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostGoToDefinitionEndpointTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests/Endpoints/CohostGoToDefinitionEndpointTest.cs @@ -39,7 +39,7 @@ public async Task CSharp_Method() await VerifyGoToDefinitionAsync(input); } - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public async Task CSharp_Local() { var input = """ @@ -60,7 +60,7 @@ string GetX() await VerifyGoToDefinitionAsync(input); } - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public async Task CSharp_MetadataReference() { var input = """ @@ -159,7 +159,7 @@ public async Task Component() Assert.Equal(range, location.Range); } - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public async Task Component_FromCSharp() { TestCode input = """ diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs index 421af086fb38..c96734560d69 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Remote.Razor; using Microsoft.CodeAnalysis.Razor.CohostingShared; +using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions; @@ -17,7 +18,7 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; public class CohostRoslynGoToDefTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper) { - [Fact(Skip = "PROTOTYPE(sonic): cohosting feature not yet decl/impl split aware; see PR #83887")] + [Fact] public Task Component() => VerifyGoToDefinitionAsync( csharpFile: """ @@ -69,7 +70,17 @@ private async Task VerifyGoToDefinitionAsync( var definition = await RemoteGoToDefinitionService.TestAccessor.GetDefinitionsAsync(LocalWorkspace, csharpDocument, typeOnly: false, csharpPosition, DisposalToken); Assert.NotNull(definition); - var def = Assert.Single(definition); - Assert.Equal(razorDocument.GetURI(), def.DocumentUri); + // This calls Roslyn's Go To Definition handler directly to verify that Roslyn can call Razor's span mapping service. + // A real Go To Definition request from a C# file doesn't go through Razor's remote service. Since both the impl and + // decl generated documents contain the component symbol, Roslyn maps both results back to the same Razor location here. + // TODO: Check if we need to de-dupe on the Roslyn side, after span mapping, or if Roslyn/VS/VS Code takes care of it already. + Assert.Equal(2, definition.Length); + var expectedUri = razorDocument.GetURI(); + var expectedRange = definition[0].Range.ToLinePositionSpan(); + Assert.All(definition, def => + { + Assert.Equal(expectedUri, def.DocumentUri); + Assert.Equal(expectedRange, def.Range.ToLinePositionSpan()); + }); } } From 4c73cf3dc53535896966f317a92e753d9c5f6755 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 11 Jun 2026 20:51:14 +1000 Subject: [PATCH 34/34] Correctness --- .../Cohost/CohostRoslynGoToDefTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs index c96734560d69..d4fec2a8ef0e 100644 --- a/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs +++ b/src/Razor/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.UnitTests/Cohost/CohostRoslynGoToDefTest.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Remote.Razor; using Microsoft.CodeAnalysis.Razor.CohostingShared; -using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Text; using Xunit; using Xunit.Abstractions;