diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/WrapWithTag/WrapWithTagParams.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/WrapWithTag/WrapWithTagParams.cs
index 65892849b52..41700e4a53e 100644
--- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/WrapWithTag/WrapWithTagParams.cs
+++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/WrapWithTag/WrapWithTagParams.cs
@@ -3,20 +3,19 @@
using System.Text.Json.Serialization;
using Microsoft.VisualStudio.LanguageServer.Protocol;
-using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Razor.LanguageServer.WrapWithTag;
///
/// Class representing the parameters sent for a textDocument/_vsweb_wrapWithTag request.
///
-internal class WrapWithTagParams
+internal class WrapWithTagParams(TextDocumentIdentifier textDocument)
{
///
/// Gets or sets the identifier for the text document to be operate on.
///
[JsonPropertyName("_vs_textDocument")]
- public TextDocumentIdentifier TextDocument { get; set; }
+ public TextDocumentIdentifier TextDocument { get; set; } = textDocument;
///
/// Gets or sets the selection range to be wrapped.
@@ -35,11 +34,6 @@ internal class WrapWithTagParams
///
[JsonPropertyName("_vs_options")]
public FormattingOptions? Options { get; set; }
-
- public WrapWithTagParams(TextDocumentIdentifier textDocument)
- {
- TextDocument = textDocument;
- }
}
internal class DelegatedWrapWithTagParams : WrapWithTagParams
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs
index a6c511d1911..9422f42ece7 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs
@@ -8,15 +8,14 @@
using System.Text.Json;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.VisualStudio.LanguageServer.Protocol;
-using Newtonsoft.Json.Linq;
namespace Microsoft.CodeAnalysis.Razor.Completion;
internal static class CompletionListMerger
{
- private static readonly string Data1Key = nameof(MergedCompletionListData.Data1);
- private static readonly string Data2Key = nameof(MergedCompletionListData.Data2);
- private static readonly object EmptyData = new object();
+ private static readonly string s_data1Key = nameof(MergedCompletionListData.Data1);
+ private static readonly string s_data2Key = nameof(MergedCompletionListData.Data2);
+ private static readonly object s_emptyData = new();
public static VSInternalCompletionList? Merge(VSInternalCompletionList? razorCompletionList, VSInternalCompletionList? delegatedCompletionList)
{
@@ -109,10 +108,7 @@ private static void Split(object data, ref PooledArrayBuilder colle
return;
}
- // We have to be agnostic to which serialization method the delegated servers use, including
- // the scenario where they use different ones, so we normalize the data to JObject.
TrySplitJsonElement(data, ref collector);
- TrySplitJObject(data, ref collector);
}
private static void TrySplitJsonElement(object data, ref PooledArrayBuilder collector)
@@ -122,8 +118,8 @@ private static void TrySplitJsonElement(object data, ref PooledArrayBuilder();
@@ -143,39 +139,10 @@ private static void TrySplitJsonElement(object data, ref PooledArrayBuilder collector)
- {
- if (data is not JObject jObject)
- {
- return;
- }
-
- if ((jObject.ContainsKey(Data1Key) || jObject.ContainsKey(Data1Key.ToLowerInvariant())) &&
- (jObject.ContainsKey(Data2Key) || jObject.ContainsKey(Data2Key.ToLowerInvariant())))
- {
- // Merged data
- var mergedCompletionListData = jObject.ToObject();
-
- if (mergedCompletionListData is null)
- {
- Debug.Fail("Merged completion list data is null, this should never happen.");
- return;
- }
-
- Split(mergedCompletionListData.Data1, ref collector);
- Split(mergedCompletionListData.Data2, ref collector);
- }
- else
- {
- // Normal, non-merged data
- collector.Add(JsonDocument.Parse(jObject.ToString()).RootElement);
- }
- }
-
private static void EnsureMergeableData(VSInternalCompletionList completionListA, VSInternalCompletionList completionListB)
{
if (completionListA.Data != completionListB.Data &&
- completionListA.Data is null || completionListB.Data is null)
+ (completionListA.Data is null || completionListB.Data is null))
{
// One of the completion lists have data while the other does not, we need to ensure that any non-data centric items don't get incorrect data associated
@@ -185,10 +152,7 @@ private static void EnsureMergeableData(VSInternalCompletionList completionListA
for (var i = 0; i < candidateCompletionList.Items.Length; i++)
{
var item = candidateCompletionList.Items[i];
- if (item.Data is null)
- {
- item.Data = EmptyData;
- }
+ item.Data ??= s_emptyData;
}
}
}
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/JsonHelpers.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/JsonHelpers.cs
index 628b46695ef..67fd12b5d1c 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/JsonHelpers.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/JsonHelpers.cs
@@ -5,44 +5,14 @@
using System.Text.Json;
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
using Microsoft.VisualStudio.LanguageServer.Protocol;
-using Newtonsoft.Json.Linq;
namespace Microsoft.CodeAnalysis.Razor.Protocol;
internal static class JsonHelpers
{
- private const string s_convertedFlag = "__convertedFromJObject";
private static readonly Lazy s_roslynLspJsonSerializerOptions = new(CreateRoslynLspJsonSerializerOptions);
private static readonly Lazy s_vsLspJsonSerializerOptions = new(CreateVsLspJsonSerializerOptions);
- ///
- /// Normalizes data from JObject to JsonElement as thats what we expect to process
- ///
- internal static object? TryConvertFromJObject(object? data)
- {
- if (data is JObject jObject)
- {
- jObject[s_convertedFlag] = true;
- return JsonDocument.Parse(jObject.ToString()).RootElement;
- }
-
- return data;
- }
-
- ///
- /// Converts from JObject back to JsonElement, but only if the original conversion was done with
- ///
- internal static object? TryConvertBackToJObject(object? data)
- {
- if (data is JsonElement jsonElement &&
- jsonElement.TryGetProperty(s_convertedFlag, out _))
- {
- data = JObject.Parse(jsonElement.ToString());
- }
-
- return data;
- }
-
///
/// Serializer options to use when serializing or deserializing a Roslyn LSP type
///
diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs
index 143084c6827..75ac8add9c0 100644
--- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs
+++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs
@@ -80,8 +80,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie
(service, solutionInfo, cancellationToken) => service.GetCodeActionRequestInfoAsync(solutionInfo, razorDocument.Id, request, cancellationToken),
cancellationToken).ConfigureAwait(false);
- if (requestInfo is null ||
- requestInfo.LanguageKind == RazorLanguageKind.CSharp && requestInfo.CSharpRequest is null)
+ if (requestInfo is null or { LanguageKind: RazorLanguageKind.CSharp, CSharpRequest: null })
{
return null;
}
@@ -137,18 +136,7 @@ private async Task GetHtmlCodeActionsAsync(TextDocu
request,
cancellationToken).ConfigureAwait(false);
- if (result?.Response is null)
- {
- return [];
- }
-
- // WebTools is still using Newtonsoft, so we have to convert to STJ
- foreach (var codeAction in result.Response)
- {
- codeAction.Data = JsonHelpers.TryConvertFromJObject(codeAction.Data);
- }
-
- return result.Response;
+ return result?.Response ?? [];
}
finally
{
diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs
index 49510c508eb..965a98be7a0 100644
--- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs
+++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs
@@ -74,11 +74,7 @@ internal partial class RazorCustomMessageTarget
if (response.Response != null)
{
- foreach (var codeAction in response.Response)
- {
- codeAction.Data = JsonHelpers.TryConvertFromJObject(codeAction.Data);
- codeActions.Add(codeAction);
- }
+ codeActions.AddRange(response.Response);
}
}
@@ -124,7 +120,6 @@ internal partial class RazorCustomMessageTarget
var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer;
var codeAction = resolveCodeActionParams.CodeAction;
- codeAction.Data = JsonHelpers.TryConvertBackToJObject(codeAction.Data);
var requests = _requestInvoker.ReinvokeRequestOnMultipleServersAsync(
textBuffer,
@@ -137,10 +132,7 @@ internal partial class RazorCustomMessageTarget
if (response.Response is not null)
{
// Only take the first response from a resolution
- var resolved = response.Response;
- resolved.Data = JsonHelpers.TryConvertFromJObject(resolved.Data);
-
- return resolved;
+ return response.Response;
}
}
diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs
index 2ab78534f45..bc3ebe07147 100644
--- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs
+++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs
@@ -157,9 +157,6 @@ internal partial class RazorCustomMessageTarget
completionList.Items = builder.ToArray();
- completionList.Data = JsonHelpers.TryConvertFromJObject(completionList.Data);
- ConvertJsonElementToJObject(completionList);
-
return completionList;
}
finally
@@ -173,14 +170,6 @@ internal partial class RazorCustomMessageTarget
}
}
- private void ConvertJsonElementToJObject(VSInternalCompletionList completionList)
- {
- foreach (var item in completionList.Items)
- {
- item.Data = JsonHelpers.TryConvertFromJObject(item.Data);
- }
- }
-
private static TextEdit BuildRevertedEdit(TextEdit provisionalTextEdit)
{
TextEdit? revertedProvisionalTextEdit;
@@ -222,7 +211,7 @@ private void UpdateVirtualDocument(
trackingDocumentManager.UpdateVirtualDocument(
documentSnapshotUri,
virtualDocumentUri,
- new[] { textChange },
+ [textChange],
hostDocumentVersion,
state: null);
}
@@ -231,7 +220,7 @@ private void UpdateVirtualDocument(
trackingDocumentManager.UpdateVirtualDocument(
documentSnapshotUri,
virtualDocumentUri,
- new[] { textChange },
+ [textChange],
hostDocumentVersion,
state: null);
}
@@ -291,25 +280,15 @@ private void UpdateVirtualDocument(
return null;
}
- var completionResolveParams = request.CompletionItem;
-
- completionResolveParams.Data = JsonHelpers.TryConvertBackToJObject(completionResolveParams.Data);
-
var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer;
var response = await _requestInvoker.ReinvokeRequestOnServerAsync(
textBuffer,
Methods.TextDocumentCompletionResolve.Name,
languageServerName,
- completionResolveParams,
+ request.CompletionItem,
cancellationToken).ConfigureAwait(false);
- var item = response?.Response;
- if (item is not null)
- {
- item.Data = JsonHelpers.TryConvertFromJObject(item.Data);
- }
-
- return item;
+ return response?.Response;
}
[JsonRpcMethod(LanguageServerConstants.RazorGetFormattingOptionsEndpointName, UseSingleObjectParameterDeserialization = true)]
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/CSharpTestLspServer.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/CSharpTestLspServer.cs
index f095947c978..cc3760b27c9 100644
--- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/CSharpTestLspServer.cs
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/CSharpTestLspServer.cs
@@ -11,6 +11,7 @@
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
+using Microsoft.CodeAnalysis.Razor.Protocol;
using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using Nerdbank.Streams;
@@ -77,8 +78,7 @@ static SystemTextJsonFormatter CreateSystemTextJsonMessageFormatter(AbstractRazo
// Roslyn has its own converters since it doesn't use MS.VS.LS.Protocol
languageServerFactory.AddJsonConverters(messageFormatter.JsonSerializerOptions);
- // In its infinite wisdom, the LSP client has a public method that takes Newtonsoft.Json types, but an internal method that takes System.Text.Json types.
- typeof(VSInternalExtensionUtilities).GetMethod("AddVSInternalExtensionConverters", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)!.Invoke(null, [messageFormatter.JsonSerializerOptions]);
+ JsonHelpers.AddVSInternalExtensionConverters(messageFormatter.JsonSerializerOptions);
return messageFormatter;
}