Skip to content

Commit 26f8f49

Browse files
authored
Remove some Newtonsoft.Json references and conversions (#11593)
2 parents b1848f5 + b315693 commit 26f8f49

File tree

7 files changed

+19
-132
lines changed

7 files changed

+19
-132
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/WrapWithTag/WrapWithTagParams.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33

44
using System.Text.Json.Serialization;
55
using Microsoft.VisualStudio.LanguageServer.Protocol;
6-
using Newtonsoft.Json;
76

87
namespace Microsoft.AspNetCore.Razor.LanguageServer.WrapWithTag;
98

109
/// <summary>
1110
/// Class representing the parameters sent for a textDocument/_vsweb_wrapWithTag request.
1211
/// </summary>
13-
internal class WrapWithTagParams
12+
internal class WrapWithTagParams(TextDocumentIdentifier textDocument)
1413
{
1514
/// <summary>
1615
/// Gets or sets the identifier for the text document to be operate on.
1716
/// </summary>
1817
[JsonPropertyName("_vs_textDocument")]
19-
public TextDocumentIdentifier TextDocument { get; set; }
18+
public TextDocumentIdentifier TextDocument { get; set; } = textDocument;
2019

2120
/// <summary>
2221
/// Gets or sets the selection range to be wrapped.
@@ -35,11 +34,6 @@ internal class WrapWithTagParams
3534
/// </summary>
3635
[JsonPropertyName("_vs_options")]
3736
public FormattingOptions? Options { get; set; }
38-
39-
public WrapWithTagParams(TextDocumentIdentifier textDocument)
40-
{
41-
TextDocument = textDocument;
42-
}
4337
}
4438

4539
internal class DelegatedWrapWithTagParams : WrapWithTagParams

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/CompletionListMerger.cs

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
using System.Text.Json;
99
using Microsoft.AspNetCore.Razor.PooledObjects;
1010
using Microsoft.VisualStudio.LanguageServer.Protocol;
11-
using Newtonsoft.Json.Linq;
1211

1312
namespace Microsoft.CodeAnalysis.Razor.Completion;
1413

1514
internal static class CompletionListMerger
1615
{
17-
private static readonly string Data1Key = nameof(MergedCompletionListData.Data1);
18-
private static readonly string Data2Key = nameof(MergedCompletionListData.Data2);
19-
private static readonly object EmptyData = new object();
16+
private static readonly string s_data1Key = nameof(MergedCompletionListData.Data1);
17+
private static readonly string s_data2Key = nameof(MergedCompletionListData.Data2);
18+
private static readonly object s_emptyData = new();
2019

2120
public static VSInternalCompletionList? Merge(VSInternalCompletionList? razorCompletionList, VSInternalCompletionList? delegatedCompletionList)
2221
{
@@ -109,10 +108,7 @@ private static void Split(object data, ref PooledArrayBuilder<JsonElement> colle
109108
return;
110109
}
111110

112-
// We have to be agnostic to which serialization method the delegated servers use, including
113-
// the scenario where they use different ones, so we normalize the data to JObject.
114111
TrySplitJsonElement(data, ref collector);
115-
TrySplitJObject(data, ref collector);
116112
}
117113

118114
private static void TrySplitJsonElement(object data, ref PooledArrayBuilder<JsonElement> collector)
@@ -122,8 +118,8 @@ private static void TrySplitJsonElement(object data, ref PooledArrayBuilder<Json
122118
return;
123119
}
124120

125-
if (jsonElement.TryGetProperty(Data1Key, out _) || jsonElement.TryGetProperty(Data1Key.ToLowerInvariant(), out _) &&
126-
jsonElement.TryGetProperty(Data2Key, out _) || jsonElement.TryGetProperty(Data2Key.ToLowerInvariant(), out _))
121+
if ((jsonElement.TryGetProperty(s_data1Key, out _) || jsonElement.TryGetProperty(s_data1Key.ToLowerInvariant(), out _)) &&
122+
(jsonElement.TryGetProperty(s_data2Key, out _) || jsonElement.TryGetProperty(s_data2Key.ToLowerInvariant(), out _)))
127123
{
128124
// Merged data
129125
var mergedCompletionListData = jsonElement.Deserialize<MergedCompletionListData>();
@@ -143,39 +139,10 @@ private static void TrySplitJsonElement(object data, ref PooledArrayBuilder<Json
143139
}
144140
}
145141

146-
private static void TrySplitJObject(object data, ref PooledArrayBuilder<JsonElement> collector)
147-
{
148-
if (data is not JObject jObject)
149-
{
150-
return;
151-
}
152-
153-
if ((jObject.ContainsKey(Data1Key) || jObject.ContainsKey(Data1Key.ToLowerInvariant())) &&
154-
(jObject.ContainsKey(Data2Key) || jObject.ContainsKey(Data2Key.ToLowerInvariant())))
155-
{
156-
// Merged data
157-
var mergedCompletionListData = jObject.ToObject<MergedCompletionListData>();
158-
159-
if (mergedCompletionListData is null)
160-
{
161-
Debug.Fail("Merged completion list data is null, this should never happen.");
162-
return;
163-
}
164-
165-
Split(mergedCompletionListData.Data1, ref collector);
166-
Split(mergedCompletionListData.Data2, ref collector);
167-
}
168-
else
169-
{
170-
// Normal, non-merged data
171-
collector.Add(JsonDocument.Parse(jObject.ToString()).RootElement);
172-
}
173-
}
174-
175142
private static void EnsureMergeableData(VSInternalCompletionList completionListA, VSInternalCompletionList completionListB)
176143
{
177144
if (completionListA.Data != completionListB.Data &&
178-
completionListA.Data is null || completionListB.Data is null)
145+
(completionListA.Data is null || completionListB.Data is null))
179146
{
180147
// 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
181148

@@ -185,10 +152,7 @@ private static void EnsureMergeableData(VSInternalCompletionList completionListA
185152
for (var i = 0; i < candidateCompletionList.Items.Length; i++)
186153
{
187154
var item = candidateCompletionList.Items[i];
188-
if (item.Data is null)
189-
{
190-
item.Data = EmptyData;
191-
}
155+
item.Data ??= s_emptyData;
192156
}
193157
}
194158
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/JsonHelpers.cs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,14 @@
55
using System.Text.Json;
66
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
77
using Microsoft.VisualStudio.LanguageServer.Protocol;
8-
using Newtonsoft.Json.Linq;
98

109
namespace Microsoft.CodeAnalysis.Razor.Protocol;
1110

1211
internal static class JsonHelpers
1312
{
14-
private const string s_convertedFlag = "__convertedFromJObject";
1513
private static readonly Lazy<JsonSerializerOptions> s_roslynLspJsonSerializerOptions = new(CreateRoslynLspJsonSerializerOptions);
1614
private static readonly Lazy<JsonSerializerOptions> s_vsLspJsonSerializerOptions = new(CreateVsLspJsonSerializerOptions);
1715

18-
/// <summary>
19-
/// Normalizes data from JObject to JsonElement as thats what we expect to process
20-
/// </summary>
21-
internal static object? TryConvertFromJObject(object? data)
22-
{
23-
if (data is JObject jObject)
24-
{
25-
jObject[s_convertedFlag] = true;
26-
return JsonDocument.Parse(jObject.ToString()).RootElement;
27-
}
28-
29-
return data;
30-
}
31-
32-
/// <summary>
33-
/// Converts from JObject back to JsonElement, but only if the original conversion was done with <see cref="TryConvertFromJObject(object?)"/>
34-
/// </summary>
35-
internal static object? TryConvertBackToJObject(object? data)
36-
{
37-
if (data is JsonElement jsonElement &&
38-
jsonElement.TryGetProperty(s_convertedFlag, out _))
39-
{
40-
data = JObject.Parse(jsonElement.ToString());
41-
}
42-
43-
return data;
44-
}
45-
4616
/// <summary>
4717
/// Serializer options to use when serializing or deserializing a Roslyn LSP type
4818
/// </summary>

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostCodeActionsEndpoint.cs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ public ImmutableArray<Registration> GetRegistrations(VSInternalClientCapabilitie
8080
(service, solutionInfo, cancellationToken) => service.GetCodeActionRequestInfoAsync(solutionInfo, razorDocument.Id, request, cancellationToken),
8181
cancellationToken).ConfigureAwait(false);
8282

83-
if (requestInfo is null ||
84-
requestInfo.LanguageKind == RazorLanguageKind.CSharp && requestInfo.CSharpRequest is null)
83+
if (requestInfo is null or { LanguageKind: RazorLanguageKind.CSharp, CSharpRequest: null })
8584
{
8685
return null;
8786
}
@@ -137,18 +136,7 @@ private async Task<RazorVSInternalCodeAction[]> GetHtmlCodeActionsAsync(TextDocu
137136
request,
138137
cancellationToken).ConfigureAwait(false);
139138

140-
if (result?.Response is null)
141-
{
142-
return [];
143-
}
144-
145-
// WebTools is still using Newtonsoft, so we have to convert to STJ
146-
foreach (var codeAction in result.Response)
147-
{
148-
codeAction.Data = JsonHelpers.TryConvertFromJObject(codeAction.Data);
149-
}
150-
151-
return result.Response;
139+
return result?.Response ?? [];
152140
}
153141
finally
154142
{

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,7 @@ internal partial class RazorCustomMessageTarget
7474

7575
if (response.Response != null)
7676
{
77-
foreach (var codeAction in response.Response)
78-
{
79-
codeAction.Data = JsonHelpers.TryConvertFromJObject(codeAction.Data);
80-
codeActions.Add(codeAction);
81-
}
77+
codeActions.AddRange(response.Response);
8278
}
8379
}
8480

@@ -124,7 +120,6 @@ internal partial class RazorCustomMessageTarget
124120

125121
var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer;
126122
var codeAction = resolveCodeActionParams.CodeAction;
127-
codeAction.Data = JsonHelpers.TryConvertBackToJObject(codeAction.Data);
128123

129124
var requests = _requestInvoker.ReinvokeRequestOnMultipleServersAsync<CodeAction, VSInternalCodeAction?>(
130125
textBuffer,
@@ -137,10 +132,7 @@ internal partial class RazorCustomMessageTarget
137132
if (response.Response is not null)
138133
{
139134
// Only take the first response from a resolution
140-
var resolved = response.Response;
141-
resolved.Data = JsonHelpers.TryConvertFromJObject(resolved.Data);
142-
143-
return resolved;
135+
return response.Response;
144136
}
145137
}
146138

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,6 @@ internal partial class RazorCustomMessageTarget
157157

158158
completionList.Items = builder.ToArray();
159159

160-
completionList.Data = JsonHelpers.TryConvertFromJObject(completionList.Data);
161-
ConvertJsonElementToJObject(completionList);
162-
163160
return completionList;
164161
}
165162
finally
@@ -173,14 +170,6 @@ internal partial class RazorCustomMessageTarget
173170
}
174171
}
175172

176-
private void ConvertJsonElementToJObject(VSInternalCompletionList completionList)
177-
{
178-
foreach (var item in completionList.Items)
179-
{
180-
item.Data = JsonHelpers.TryConvertFromJObject(item.Data);
181-
}
182-
}
183-
184173
private static TextEdit BuildRevertedEdit(TextEdit provisionalTextEdit)
185174
{
186175
TextEdit? revertedProvisionalTextEdit;
@@ -222,7 +211,7 @@ private void UpdateVirtualDocument(
222211
trackingDocumentManager.UpdateVirtualDocument<CSharpVirtualDocument>(
223212
documentSnapshotUri,
224213
virtualDocumentUri,
225-
new[] { textChange },
214+
[textChange],
226215
hostDocumentVersion,
227216
state: null);
228217
}
@@ -231,7 +220,7 @@ private void UpdateVirtualDocument(
231220
trackingDocumentManager.UpdateVirtualDocument<HtmlVirtualDocument>(
232221
documentSnapshotUri,
233222
virtualDocumentUri,
234-
new[] { textChange },
223+
[textChange],
235224
hostDocumentVersion,
236225
state: null);
237226
}
@@ -291,25 +280,15 @@ private void UpdateVirtualDocument(
291280
return null;
292281
}
293282

294-
var completionResolveParams = request.CompletionItem;
295-
296-
completionResolveParams.Data = JsonHelpers.TryConvertBackToJObject(completionResolveParams.Data);
297-
298283
var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer;
299284
var response = await _requestInvoker.ReinvokeRequestOnServerAsync<VSInternalCompletionItem, CompletionItem?>(
300285
textBuffer,
301286
Methods.TextDocumentCompletionResolve.Name,
302287
languageServerName,
303-
completionResolveParams,
288+
request.CompletionItem,
304289
cancellationToken).ConfigureAwait(false);
305290

306-
var item = response?.Response;
307-
if (item is not null)
308-
{
309-
item.Data = JsonHelpers.TryConvertFromJObject(item.Data);
310-
}
311-
312-
return item;
291+
return response?.Response;
313292
}
314293

315294
[JsonRpcMethod(LanguageServerConstants.RazorGetFormattingOptionsEndpointName, UseSingleObjectParameterDeserialization = true)]

src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Tooling/LanguageServer/CSharpTestLspServer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.AspNetCore.Razor.PooledObjects;
1212
using Microsoft.CodeAnalysis;
1313
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
14+
using Microsoft.CodeAnalysis.Razor.Protocol;
1415
using Microsoft.VisualStudio.Composition;
1516
using Microsoft.VisualStudio.LanguageServer.Protocol;
1617
using Nerdbank.Streams;
@@ -77,8 +78,7 @@ static SystemTextJsonFormatter CreateSystemTextJsonMessageFormatter(AbstractRazo
7778
// Roslyn has its own converters since it doesn't use MS.VS.LS.Protocol
7879
languageServerFactory.AddJsonConverters(messageFormatter.JsonSerializerOptions);
7980

80-
// 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.
81-
typeof(VSInternalExtensionUtilities).GetMethod("AddVSInternalExtensionConverters", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)!.Invoke(null, [messageFormatter.JsonSerializerOptions]);
81+
JsonHelpers.AddVSInternalExtensionConverters(messageFormatter.JsonSerializerOptions);
8282

8383
return messageFormatter;
8484
}

0 commit comments

Comments
 (0)