Skip to content

Commit 561a96d

Browse files
Merge pull request #26 from OmniSharp/latest-lsp
Reacting to latest changes for LSP
2 parents f76a391 + 6be75f3 commit 561a96d

22 files changed

+509
-40
lines changed

src/Lsp/HandlerCollection.cs

+1-19
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
3737
.ImplementedInterfaces
3838
.Where(x => !string.IsNullOrWhiteSpace(LspHelper.GetMethodName(x))))
3939
{
40-
var @interface = GetHandlerInterface(implementedInterface);
40+
var @interface = HandlerTypeHelpers.GetHandlerInterface(implementedInterface);
4141
var registration = UnwrapGenericType(typeof(IRegistration<>), implementedInterface);
4242
var capability = UnwrapGenericType(typeof(ICapability<>), implementedInterface);
4343

@@ -72,24 +72,6 @@ public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
7272
return new ImutableDisposable(descriptors);
7373
}
7474

75-
private static readonly Type[] HandlerTypes = { typeof(INotificationHandler), typeof(INotificationHandler<>), typeof(IRequestHandler<>), typeof(IRequestHandler<,>), };
76-
77-
private bool IsValidInterface(Type type)
78-
{
79-
if (type.GetTypeInfo().IsGenericType)
80-
{
81-
return HandlerTypes.Contains(type.GetGenericTypeDefinition());
82-
}
83-
return HandlerTypes.Contains(type);
84-
}
85-
86-
private Type GetHandlerInterface(Type type)
87-
{
88-
return type?.GetTypeInfo()
89-
.ImplementedInterfaces
90-
.First(IsValidInterface);
91-
}
92-
9375
private Type UnwrapGenericType(Type genericType, Type type)
9476
{
9577
return type?.GetTypeInfo()

src/Lsp/HandlerDescriptor.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public HandlerDescriptor(string method, string key, IJsonRpcHandler handler, Typ
3636

3737
public Registration Registration
3838
{
39-
get {
39+
get
40+
{
4041
if (!HasRegistration) return null;
4142
if (_registration != null) return _registration;
4243

@@ -47,7 +48,8 @@ public Registration Registration
4748
.MakeGenericMethod(RegistrationType)
4849
.Invoke(this, new object[] { Handler });
4950

50-
return _registration = new Registration() {
51+
return _registration = new Registration()
52+
{
5153
Id = Guid.NewGuid().ToString(),
5254
Method = Method,
5355
RegisterOptions = options

src/Lsp/HandlerTypeHelpers.cs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
using OmniSharp.Extensions.JsonRpc;
5+
6+
namespace OmniSharp.Extensions.LanguageServer
7+
{
8+
public static class HandlerTypeHelpers
9+
{
10+
private static readonly Type[] HandlerTypes = { typeof(INotificationHandler), typeof(INotificationHandler<>), typeof(IRequestHandler<>), typeof(IRequestHandler<,>), };
11+
12+
private static bool IsValidInterface(Type type)
13+
{
14+
if (type.GetTypeInfo().IsGenericType)
15+
{
16+
return HandlerTypes.Contains(type.GetGenericTypeDefinition());
17+
}
18+
return HandlerTypes.Contains(type);
19+
}
20+
21+
public static Type GetHandlerInterface(Type type)
22+
{
23+
return type?.GetTypeInfo()
24+
.ImplementedInterfaces
25+
.First(IsValidInterface);
26+
}
27+
}
28+
}

src/Lsp/LanguageServer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public Task Handle()
196196

197197
private bool HasHandler<T>()
198198
{
199-
return _collection.Any(z => z.HandlerType == typeof(T));
199+
return _collection.Any(z => z.Handler is T);
200200
}
201201

202202
private T GetOptions<O, T>(Func<O, T> action)

src/Lsp/Models/CompletionItem.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ public class CompletionItem
7272
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
7373
public TextEditContainer AdditionalTextEdits { get; set; }
7474
/// <summary>
75+
/// An optional set of characters that when pressed while this completion is active will accept it first and
76+
/// then type that character. *Note* that all commit characters should have `length=1` and that superfluous
77+
/// characters will be ignored.
78+
/// </summary>
79+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
80+
public Container<string> CommitCharacters { get; set; }
81+
/// <summary>
7582
/// An optional command that is executed/// after* inserting this completion./// Note* that
7683
/// additional modifications to the current document should be described with the
7784
/// additionalTextEdits-property.
@@ -85,4 +92,4 @@ public class CompletionItem
8592
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
8693
public object Data { get; set; }
8794
}
88-
}
95+
}

src/Lsp/Models/TextDocumentEdit.cs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Serialization;
3+
4+
namespace OmniSharp.Extensions.LanguageServer.Models
5+
{
6+
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
7+
public class TextDocumentEdit
8+
{
9+
/// <summary>
10+
/// The text document to change.
11+
/// </summary>
12+
public VersionedTextDocumentIdentifier TextDocument { get; set; }
13+
14+
/// <summary>
15+
/// The edits to be applied.
16+
/// </summary>
17+
public Container<TextEdit> Edits { get; set; }
18+
}
19+
}

src/Lsp/Models/WorkspaceEdit.cs

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ public class WorkspaceEdit
1111
/// <summary>
1212
/// Holds changes to existing resources.
1313
/// </summary>
14-
public IDictionary<Uri, IEnumerable<TextEdit>> Changes { get; set; } = new Dictionary<Uri, IEnumerable<TextEdit>>();
14+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
15+
public IDictionary<Uri, IEnumerable<TextEdit>> Changes { get; set; }
16+
/// <summary>
17+
/// An array of `TextDocumentEdit`s to express changes to n different text documents
18+
/// where each text document edit addresses a specific version of a text document.
19+
/// Whether a client supports versioned document edits is expressed via
20+
/// `WorkspaceClientCapabilities.workspaceEdit.documentChanges`.
21+
/// </summary>
22+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
23+
public Container<TextDocumentEdit> DocumentChanges { get; set; }
1524
}
16-
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using OmniSharp.Extensions.LanguageServer.Models;
2+
3+
// ReSharper disable CheckNamespace
4+
5+
namespace OmniSharp.Extensions.LanguageServer.Protocol
6+
{
7+
public static class CancelRequestExtensions
8+
{
9+
public static void CancelRequest(this ILanguageServer mediator, CancelParams @params)
10+
{
11+
mediator.SendNotification<CancelParams>("$/cancelRequest", @params);
12+
}
13+
14+
public static void CancelRequest(this ILanguageServer mediator, string id)
15+
{
16+
mediator.SendNotification<CancelParams>("$/cancelRequest", new CancelParams() { Id = id });
17+
}
18+
19+
public static void CancelRequest(this ILanguageServer mediator, long id)
20+
{
21+
mediator.SendNotification<CancelParams>("$/cancelRequest", new CancelParams() { Id = id });
22+
}
23+
}
24+
}

src/Lsp/Protocol/General/ICancelRequestHandler.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol
77
{
88
[Method("$/cancelRequest")]
99
public interface ICancelRequestHandler : INotificationHandler<CancelParams> { }
10-
}
10+
}

src/Lsp/Protocol/Window/LogMessageExtensions.cs

+26-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,30 @@ public static void LogMessage(this ILanguageServer mediator, LogMessageParams @p
1111
{
1212
mediator.SendNotification("window/logMessage", @params);
1313
}
14+
15+
public static void Log(this ILanguageServer mediator, LogMessageParams @params)
16+
{
17+
mediator.LogMessage(@params);
18+
}
19+
20+
public static void LogError(this ILanguageServer mediator, string message)
21+
{
22+
mediator.LogMessage(new LogMessageParams() { Type = MessageType.Error, Message = message });
23+
}
24+
25+
public static void Log(this ILanguageServer mediator, string message)
26+
{
27+
mediator.LogMessage(new LogMessageParams() { Type = MessageType.Log, Message = message });
28+
}
29+
30+
public static void LogWarning(this ILanguageServer mediator, string message)
31+
{
32+
mediator.LogMessage(new LogMessageParams() { Type = MessageType.Warning, Message = message });
33+
}
34+
35+
public static void LogInfo(this ILanguageServer mediator, string message)
36+
{
37+
mediator.LogMessage(new LogMessageParams() { Type = MessageType.Info, Message = message });
38+
}
1439
}
15-
}
40+
}

src/Lsp/Protocol/Window/ShowMessageExtensions.cs

+26-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,30 @@ public static void ShowMessage(this ILanguageServer mediator, ShowMessageParams
1111
{
1212
mediator.SendNotification("window/showMessage", @params);
1313
}
14+
15+
public static void Show(this ILanguageServer mediator, ShowMessageParams @params)
16+
{
17+
mediator.ShowMessage(@params);
18+
}
19+
20+
public static void ShowError(this ILanguageServer mediator, string message)
21+
{
22+
mediator.ShowMessage(new ShowMessageParams() { Type = MessageType.Error, Message = message });
23+
}
24+
25+
public static void Show(this ILanguageServer mediator, string message)
26+
{
27+
mediator.ShowMessage(new ShowMessageParams() { Type = MessageType.Log, Message = message });
28+
}
29+
30+
public static void ShowWarning(this ILanguageServer mediator, string message)
31+
{
32+
mediator.ShowMessage(new ShowMessageParams() { Type = MessageType.Warning, Message = message });
33+
}
34+
35+
public static void ShowInfo(this ILanguageServer mediator, string message)
36+
{
37+
mediator.ShowMessage(new ShowMessageParams() { Type = MessageType.Info, Message = message });
38+
}
1439
}
15-
}
40+
}

src/Lsp/Protocol/Window/ShowMessageRequestExtensions.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,15 @@ public static Task<MessageActionItem> ShowMessage(this ILanguageServer mediator,
1212
{
1313
return mediator.SendRequest<ShowMessageRequestParams, MessageActionItem>("window/showMessageRequest", @params);
1414
}
15+
16+
public static Task<MessageActionItem> Show(this ILanguageServer mediator, ShowMessageRequestParams @params)
17+
{
18+
return mediator.ShowMessage(@params);
19+
}
20+
21+
public static Task<MessageActionItem> Request(this ILanguageServer mediator, ShowMessageRequestParams @params)
22+
{
23+
return mediator.ShowMessage(@params);
24+
}
1525
}
16-
}
26+
}

test/Lsp.Tests/Fixture.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private static string SerializeObjectInternal(object value, Type type, JsonSeria
3232
jsonSerializer.Serialize(jsonWriter, value, type);
3333
}
3434

35-
return sw.ToString()?.Replace("\r\n", "\n");//?.Replace("\n", "\r\n");
35+
return sw.ToString()?.Replace("\r\n", "\n")?.TrimEnd();//?.Replace("\n", "\r\n");
3636
}
3737
}
38-
}
38+
}

test/Lsp.Tests/JsonFixtureAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
@@ -21,7 +21,7 @@ public override IEnumerable<object[]> GetData(MethodInfo testMethod)
2121

2222
using (var streamReader = new StreamReader(Resources.GetManifestResourceStream(fileName)))
2323
{
24-
yield return new object[] { streamReader.ReadToEnd()?.Replace("\r\n", "\n") };
24+
yield return new object[] { streamReader.ReadToEnd()?.Replace("\r\n", "\n")?.TrimEnd() };
2525
}
2626
}
2727
}

test/Lsp.Tests/Models/ApplyWorkspaceEditParamsTests.cs

+59-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ public class ApplyWorkspaceEditParamsTests
1212
[Theory, JsonFixture]
1313
public void SimpleTest(string expected)
1414
{
15-
var model = new ApplyWorkspaceEditParams() {
16-
Edit = new WorkspaceEdit() {
15+
var model = new ApplyWorkspaceEditParams()
16+
{
17+
Edit = new WorkspaceEdit()
18+
{
1719
Changes = new Dictionary<Uri, IEnumerable<TextEdit>>() {
1820
{
1921
new Uri("file:///abc/123/d.cs"), new [] {
@@ -37,5 +39,60 @@ public void SimpleTest(string expected)
3739
var deresult = JsonConvert.DeserializeObject<ApplyWorkspaceEditParams>(expected);
3840
deresult.ShouldBeEquivalentTo(model);
3941
}
42+
43+
[Theory, JsonFixture]
44+
public void DocumentChangesTest(string expected)
45+
{
46+
var model = new ApplyWorkspaceEditParams()
47+
{
48+
Edit = new WorkspaceEdit()
49+
{
50+
DocumentChanges = new Container<TextDocumentEdit>(
51+
new TextDocumentEdit()
52+
{
53+
TextDocument = new VersionedTextDocumentIdentifier()
54+
{
55+
Version = 1,
56+
Uri = new Uri("file:///abc/123/d.cs"),
57+
},
58+
Edits = new[] {
59+
new TextEdit() {
60+
NewText = "new text",
61+
Range = new Range(new Position(1, 1), new Position(2,2))
62+
},
63+
new TextEdit() {
64+
NewText = "new text2",
65+
Range = new Range(new Position(3, 3), new Position(4,4))
66+
}
67+
}
68+
},
69+
new TextDocumentEdit()
70+
{
71+
TextDocument = new VersionedTextDocumentIdentifier()
72+
{
73+
Version = 1,
74+
Uri = new Uri("file:///abc/123/b.cs"),
75+
},
76+
Edits = new[] {
77+
new TextEdit() {
78+
NewText = "new text2",
79+
Range = new Range(new Position(1, 1), new Position(2,2))
80+
},
81+
new TextEdit() {
82+
NewText = "new text3",
83+
Range = new Range(new Position(3, 3), new Position(4,4))
84+
}
85+
}
86+
}
87+
)
88+
}
89+
};
90+
var result = Fixture.SerializeObject(model);
91+
92+
result.Should().Be(expected);
93+
94+
var deresult = JsonConvert.DeserializeObject<ApplyWorkspaceEditParams>(expected);
95+
deresult.ShouldBeEquivalentTo(model);
96+
}
4097
}
4198
}

0 commit comments

Comments
 (0)