Skip to content

Commit ae45bf7

Browse files
added preprocessing because what we had was not working 100%
1 parent 0b3c365 commit ae45bf7

File tree

7 files changed

+102
-4
lines changed

7 files changed

+102
-4
lines changed

src/Server/Abstractions/IHandlerMatcherCollection.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public interface IHandlerMatcherCollection : IEnumerable<object>
77
{
88
IDisposable Add(object handler);
99
IEnumerable<IHandlerMatcher> ForHandlerMatchers();
10+
IEnumerable<IHandlerPreProcessorMatcher> ForHandlerPreProcessorMatcher();
11+
IEnumerable<IHandlerPreProcessor> ForHandlerPreProcessor();
1012
IEnumerable<IHandlerPostProcessorMatcher> ForHandlerPostProcessorMatcher();
1113
IEnumerable<IHandlerPostProcessor> ForHandlerPostProcessor();
1214
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace OmniSharp.Extensions.LanguageServer.Server.Abstractions
2+
{
3+
public interface IHandlerPreProcessor
4+
{
5+
/// <summary>
6+
/// Does post processing for a request of descriptor type
7+
/// </summary>
8+
/// <param name="descriptor">The descriptor.</param>
9+
/// <param name="parameters">The parameters.</param>
10+
/// <returns></returns>
11+
object Process(ILspHandlerDescriptor descriptor, object parameters);
12+
}
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Server.Abstractions
4+
{
5+
public interface IHandlerPreProcessorMatcher
6+
{
7+
/// <summary>
8+
/// Finds any postproessor for a given descriptor and response
9+
/// </summary>
10+
/// <param name="descriptor">The descriptor.</param>
11+
/// <param name="parameters">The parameters.</param>
12+
/// <param name="response">The response.</param>
13+
/// <returns></returns>
14+
IEnumerable<IHandlerPreProcessor> FindPreProcessor(ILspHandlerDescriptor descriptor, object parameters);
15+
}
16+
}

src/Server/HandlerMatcherCollection.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public class HandlerMatcherCollection : IHandlerMatcherCollection
1313

1414
private static readonly Type[] ValidHandlers = {
1515
typeof(IHandlerMatcher),
16+
typeof(IHandlerPreProcessor),
17+
typeof(IHandlerPreProcessorMatcher),
1618
typeof(IHandlerPostProcessor),
1719
typeof(IHandlerPostProcessorMatcher)
1820
};
@@ -36,6 +38,16 @@ public IEnumerable<IHandlerMatcher> ForHandlerMatchers()
3638
return _handlers.OfType<IHandlerMatcher>();
3739
}
3840

41+
public IEnumerable<IHandlerPreProcessorMatcher> ForHandlerPreProcessorMatcher()
42+
{
43+
return _handlers.OfType<IHandlerPreProcessorMatcher>();
44+
}
45+
46+
public IEnumerable<IHandlerPreProcessor> ForHandlerPreProcessor()
47+
{
48+
return _handlers.OfType<IHandlerPreProcessor>();
49+
}
50+
3951
public IEnumerable<IHandlerPostProcessorMatcher> ForHandlerPostProcessorMatcher()
4052
{
4153
return _handlers.OfType<IHandlerPostProcessorMatcher>();

src/Server/LspRequestRouter.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ public async Task<ErrorResponse> RouteRequest(IHandlerDescriptor descriptor, Req
138138
_logger.LogError(new EventId(-32602), cannotDeserializeRequestParams, "Failed to deserialise request parameters.");
139139
return new InvalidParams(request.Id);
140140
}
141+
var lspDescriptor = descriptor as ILspHandlerDescriptor;
142+
143+
foreach (var preProcessor in _routeMatchers.ForHandlerPreProcessorMatcher()
144+
.SelectMany(strat => strat.FindPreProcessor(lspDescriptor, @params)))
145+
{
146+
@params = preProcessor.Process(lspDescriptor, @params);
147+
}
141148

142149
var result = ReflectionRequestHandlers.HandleRequest(descriptor, @params, cts.Token);
143150
await result;
@@ -154,8 +161,6 @@ public async Task<ErrorResponse> RouteRequest(IHandlerDescriptor descriptor, Req
154161
responseValue = property.GetValue(result);
155162
_logger.LogDebug("Response value was {Type}", responseValue?.GetType().FullName);
156163

157-
var lspDescriptor = descriptor as ILspHandlerDescriptor;
158-
159164
foreach (var postProcessor in _routeMatchers.ForHandlerPostProcessorMatcher()
160165
.SelectMany(strat => strat.FindPostProcessor(lspDescriptor, @params, responseValue)))
161166
{

src/Server/Matchers/ResolveCommandMatcher.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace OmniSharp.Extensions.LanguageServer.Server.Matchers
1111
{
12-
public class ResolveCommandMatcher : IHandlerMatcher, IHandlerPostProcessorMatcher, IHandlerPostProcessor
12+
public class ResolveCommandMatcher : IHandlerMatcher, IHandlerPostProcessorMatcher, IHandlerPreProcessor, IHandlerPostProcessor
1313
{
1414
private readonly ILogger _logger;
1515
internal static string PrivateHandlerTypeName = "$$___handlerType___$$";
@@ -67,7 +67,6 @@ public IEnumerable<ILspHandlerDescriptor> FindHandler(object parameters, IEnumer
6767
descriptor.Handler.GetType().FullName);
6868
if (descriptor.Handler.GetType().FullName == handlerType || descriptor.HandlerType.FullName == handlerType)
6969
{
70-
canBeResolved.Data = canBeResolved.Data["data"];
7170
yield return descriptor;
7271
}
7372
}
@@ -91,6 +90,23 @@ public IEnumerable<IHandlerPostProcessor> FindPostProcessor(ILspHandlerDescripto
9190
}
9291
}
9392

93+
public object Process(ILspHandlerDescriptor descriptor, object parameters)
94+
{
95+
if (parameters is ICanBeResolved canBeResolved)
96+
{
97+
string handlerType = null;
98+
if (canBeResolved.Data != null && canBeResolved.Data.Type == JTokenType.Object)
99+
handlerType = canBeResolved.Data?[PrivateHandlerTypeName]?.ToString();
100+
101+
if (!string.IsNullOrWhiteSpace(handlerType))
102+
{
103+
canBeResolved.Data = canBeResolved.Data["data"];
104+
}
105+
}
106+
107+
return parameters;
108+
}
109+
94110
public object Process(ILspHandlerDescriptor descriptor, object parameters, object response)
95111
{
96112
// Only pin the handler type, if we know the source handler (codelens) is also the resolver.

test/Lsp.Tests/Matchers/ResolveCommandMatcherTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,5 +414,39 @@ public void Should_Update_CodeLensContainer_With_HandlerType()
414414
responseItem.Data[ResolveCommandMatcher.PrivateHandlerTypeName].Value<string>().Should().NotBeNullOrEmpty();
415415
responseItem.Data["data"]["hello"].Value<string>().Should().Be("world");
416416
}
417+
418+
[Fact]
419+
public void Should_Update_CodeLens_Removing_HandlerType()
420+
{
421+
// Given
422+
var handlerMatcher = new ResolveCommandMatcher(_logger);
423+
var resolveHandler = Substitute.For(new Type[] {
424+
typeof(ICodeLensHandler),
425+
typeof(ICodeLensResolveHandler)
426+
}, new object[0]);
427+
(resolveHandler as ICodeLensResolveHandler).CanResolve(Arg.Any<CodeLens>()).Returns(true);
428+
var descriptor = new HandlerDescriptor(
429+
DocumentNames.CodeLensResolve,
430+
"Key",
431+
resolveHandler as IJsonRpcHandler,
432+
resolveHandler.GetType(),
433+
typeof(CodeLens),
434+
null,
435+
null,
436+
() => { });
437+
438+
var item = new CodeLens() {
439+
Data = JObject.FromObject(new { data = new { hello = "world" } })
440+
};
441+
item.Data[ResolveCommandMatcher.PrivateHandlerTypeName] = resolveHandler.GetType().FullName;
442+
443+
// When
444+
var response = handlerMatcher.Process(descriptor, item);
445+
446+
// Then
447+
response.Should().Be(item);
448+
item.Data?[ResolveCommandMatcher.PrivateHandlerTypeName].Should().BeNull();
449+
item.Data["hello"].Value<string>().Should().Be("world");
450+
}
417451
}
418452
}

0 commit comments

Comments
 (0)