Skip to content

Commit 43a1eb8

Browse files
authored
Merge pull request #75153 from matteo-prosperi/dev/jorobich/gladstone-spike
Updating to match Gladstone and Editor side changes
2 parents c199622 + df4d5a8 commit 43a1eb8

File tree

5 files changed

+117
-15
lines changed

5 files changed

+117
-15
lines changed

src/VisualStudio/Core/Def/LanguageServer/Handler/CustomMessage/CustomMessage.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
1010

11-
internal class CustomMessage(JsonNode message, TextDocumentPositionParams[] textDocumentPositions)
11+
internal class CustomMessage(JsonNode message, TextDocumentIdentifier? textDocument, Position[] positions)
1212
{
1313
[JsonPropertyName("message")]
1414
public JsonNode Message { get; } = Requires.NotNull(message);
1515

16-
[JsonPropertyName("textDocumentPositions")]
17-
public TextDocumentPositionParams[] TextDocumentPositions { get; } = Requires.NotNull(textDocumentPositions);
16+
[JsonPropertyName("textDocument")]
17+
public TextDocumentIdentifier? TextDocument { get; } = textDocument;
18+
19+
[JsonPropertyName("positions")]
20+
public Position[] Positions { get; } = Requires.NotNull(positions);
1821
}

src/VisualStudio/Core/Def/LanguageServer/Handler/CustomMessage/CustomMessageHandler.cs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Threading;
1313
using System.Threading.Tasks;
1414
using Microsoft.CodeAnalysis.Host.Mef;
15+
using Microsoft.CodeAnalysis.Text;
1516
using Roslyn.LanguageServer.Protocol;
1617

1718
namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
@@ -21,7 +22,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
2122
[method: ImportingConstructor]
2223
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
2324
internal class CustomMessageHandler()
24-
: ILspServiceDocumentRequestHandler<CustomMessageParams, CustomMessage>
25+
: ILspServiceDocumentRequestHandler<CustomMessageParams, CustomResponse>
2526
{
2627
private const string MethodName = "roslyn/customMessage";
2728

@@ -31,12 +32,12 @@ internal class CustomMessageHandler()
3132

3233
public TextDocumentIdentifier GetTextDocumentIdentifier(CustomMessageParams request)
3334
{
34-
return request.Message.TextDocumentPositions.First().TextDocument;
35+
return request.Message.TextDocument!;
3536
}
3637

37-
public async Task<CustomMessage> HandleRequestAsync(CustomMessageParams request, RequestContext context, CancellationToken cancellationToken)
38+
public async Task<CustomResponse> HandleRequestAsync(CustomMessageParams request, RequestContext context, CancellationToken cancellationToken)
3839
{
39-
return request.Message;
40+
return new CustomResponse(request.Message.Message, request.Message.Positions);
4041

4142
#pragma warning disable CS0162 // Unreachable code detected
4243
AppDomain? appDomain = null;
@@ -74,24 +75,36 @@ public async Task<CustomMessage> HandleRequestAsync(CustomMessageParams request,
7475
var assembly = appDomain.Load(assemblyName);
7576

7677
var handlerType = assembly.GetType(request.TypeFullName);
77-
var handlerMethod = handlerType.GetMethod("ExecuteAsync", BindingFlags.Static);
78+
var handlerMethod = handlerType.GetMethod("ExecuteAsync", BindingFlags.Instance);
7879

79-
var messageType = handlerMethod.GetParameters()[0].ParameterType;
80-
var deserializedMessage = JsonSerializer.Deserialize(request.Message.Message, messageType);
80+
JsonSerializerOptions readOptions = new();
81+
LinePositionReadConverter linePositionReadConverter = new(request.Message.Positions.Select(tdp => ProtocolConversions.PositionToLinePosition(tdp)).ToArray());
82+
readOptions.Converters.Add(linePositionReadConverter);
8183

82-
var linePositions = request.Message.TextDocumentPositions.Select(tdp => ProtocolConversions.PositionToLinePosition(tdp.Position)).ToArray();
84+
var messageType = handlerMethod.GetParameters()[0].ParameterType;
85+
var deserializedMessage = JsonSerializer.Deserialize(request.Message.Message, messageType, readOptions);
8386

84-
var parameters = new object?[] { deserializedMessage, context.Document, linePositions, cancellationToken };
85-
var resultTask = (Task)handlerMethod.Invoke(null, parameters);
87+
var handler = Activator.CreateInstance(handlerType);
88+
var parameters = new object?[] { deserializedMessage, context.Document, cancellationToken };
89+
var resultTask = (Task)handlerMethod.Invoke(handler, parameters);
8690

8791
await resultTask.ConfigureAwait(false);
8892

8993
var resultProperty = resultTask.GetType().GetProperty("Result");
9094
var result = resultProperty.GetValue(resultTask);
9195

92-
var resultJson = JsonSerializer.Serialize(result, resultProperty.PropertyType);
96+
JsonSerializerOptions writeOptions = new();
97+
LinePositionWriteConverter linePositionWriteConverter = new();
98+
writeOptions.Converters.Add(linePositionWriteConverter);
99+
100+
var resultJson = JsonSerializer.Serialize(result, resultProperty.PropertyType, writeOptions);
93101

94-
return new CustomMessage(JsonNode.Parse(resultJson)!, []);
102+
return new CustomResponse(
103+
JsonNode.Parse(resultJson)!,
104+
linePositionWriteConverter.LinePositions
105+
.OrderBy(p => p.Value)
106+
.Select(p => new Position(p.Key.Line, p.Key.Character))
107+
.ToArray());
95108
}
96109
finally
97110
{
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Text.Json.Nodes;
6+
using System.Text.Json.Serialization;
7+
using Roslyn.LanguageServer.Protocol;
8+
9+
namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
10+
11+
internal class CustomResponse(JsonNode message, Position[] positions)
12+
{
13+
[JsonPropertyName("message")]
14+
public JsonNode Message { get; } = Requires.NotNull(message);
15+
16+
[JsonPropertyName("positions")]
17+
public Position[] Positions { get; } = Requires.NotNull(positions);
18+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Text.Json;
8+
using System.Text.Json.Serialization;
9+
using Microsoft.CodeAnalysis.Text;
10+
11+
namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
12+
13+
internal class LinePositionReadConverter : JsonConverter<LinePosition>
14+
{
15+
private readonly IReadOnlyList<LinePosition> linePositions;
16+
17+
public LinePositionReadConverter(IReadOnlyList<LinePosition> linePositions)
18+
{
19+
this.linePositions = linePositions;
20+
}
21+
22+
public override LinePosition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
23+
{
24+
if (reader.TokenType != JsonTokenType.Number)
25+
{
26+
throw new JsonException();
27+
}
28+
29+
return this.linePositions[reader.GetInt32()];
30+
}
31+
32+
public override void Write(Utf8JsonWriter writer, LinePosition value, JsonSerializerOptions options)
33+
{
34+
throw new NotSupportedException();
35+
}
36+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Text.Json;
8+
using System.Text.Json.Serialization;
9+
using Microsoft.CodeAnalysis.Text;
10+
11+
namespace Microsoft.CodeAnalysis.LanguageServer.Handler.CustomMessage;
12+
13+
internal class LinePositionWriteConverter : JsonConverter<LinePosition>
14+
{
15+
public Dictionary<LinePosition, int> LinePositions { get; } = new();
16+
17+
public override LinePosition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
18+
{
19+
throw new NotSupportedException();
20+
}
21+
22+
public override void Write(Utf8JsonWriter writer, LinePosition value, JsonSerializerOptions options)
23+
{
24+
if (!this.LinePositions.TryGetValue(value, out var index))
25+
{
26+
index = this.LinePositions.Count;
27+
this.LinePositions.Add(value, index);
28+
}
29+
30+
writer.WriteNumberValue(index);
31+
}
32+
}

0 commit comments

Comments
 (0)