Skip to content

Commit fb7961b

Browse files
Merge pull request #85 from OmniSharp/builder
Adds a new LanguageServer Builder API
2 parents 0074159 + 2392283 commit fb7961b

File tree

441 files changed

+4459
-3100
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

441 files changed

+4459
-3100
lines changed

Common.Build.props

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project>
2+
<PropertyGroup>
3+
<Company>OmniSharp</Company>
4+
<Copyright>Copyright OmniSharp and contributors © 2018</Copyright>
5+
<Authors>David Driscoll</Authors>
6+
<LangVersion>latest</LangVersion>
7+
</PropertyGroup>
8+
<PropertyGroup>
9+
<Microsoft_Extensions_Logging_Version>2.0.0</Microsoft_Extensions_Logging_Version>
10+
<Microsoft_Extensions_DependencyInjection_Version>2.0.0</Microsoft_Extensions_DependencyInjection_Version>
11+
<Newtonsoft_Version>11.0.2</Newtonsoft_Version>
12+
<SourceLink_Version>2.8.1</SourceLink_Version>
13+
<System_Reactive_Version>3.1.1</System_Reactive_Version>
14+
<MediatR_Version>4.1.0</MediatR_Version>
15+
<Autofac_Version>4.8.0</Autofac_Version>
16+
<Autofac_Extensions_DependencyInjection_Version>4.2.2</Autofac_Extensions_DependencyInjection_Version>
17+
<Microsoft_NET_Test_Sdk_Version>15.7.0</Microsoft_NET_Test_Sdk_Version>
18+
<xunit_Version>2.3.1</xunit_Version>
19+
<FluentAssertions_Version>5.3.0</FluentAssertions_Version>
20+
<NSubstitute_Version>3.1.0</NSubstitute_Version>
21+
<Serilog_Extensions_Logging_Version>2.0.2</Serilog_Extensions_Logging_Version>
22+
<Serilog_Sinks_XUnit_Version>1.0.5</Serilog_Sinks_XUnit_Version>
23+
</PropertyGroup>
24+
</Project>

LSP.sln

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D764E024-3D3
88
EndProjectSection
99
EndProject
1010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}"
11+
ProjectSection(SolutionItems) = preProject
12+
test\Directory.Build.props = test\Directory.Build.props
13+
test\Directory.Build.targets = test\Directory.Build.targets
14+
EndProjectSection
1115
EndProject
1216
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{AE4D7807-6F78-428C-A0D9-914BA583A104}"
1317
ProjectSection(SolutionItems) = preProject
@@ -19,6 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{AE4D
1923
build.cake = build.cake
2024
build.ps1 = build.ps1
2125
build.sh = build.sh
26+
Common.Build.props = Common.Build.props
2227
nuget.config = nuget.config
2328
EndProjectSection
2429
EndProject

sample/SampleServer/Program.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@ static void Main(string[] args)
1616

1717
static async Task MainAsync(string[] args)
1818
{
19-
//while (!System.Diagnostics.Debugger.IsAttached)
20-
//{
19+
// while (!System.Diagnostics.Debugger.IsAttached)
20+
// {
2121
// await Task.Delay(100);
22-
//}
22+
// }
2323

24-
var server = new LanguageServer(Console.OpenStandardInput(), Console.OpenStandardOutput(), new LoggerFactory());
24+
var server = await LanguageServer.From(options =>
25+
options
26+
.WithInput(Console.OpenStandardInput())
27+
.WithOutput(Console.OpenStandardOutput())
28+
.WithLoggerFactory(new LoggerFactory())
29+
.AddDefaultLoggingProvider()
30+
.WithMinimumLogLevel(LogLevel.Trace)
31+
.WithHandler<TextDocumentHandler>()
32+
);
2533

26-
server.AddHandler(new TextDocumentHandler(server));
27-
28-
await server.Initialize();
2934
await server.WaitForExit;
3035
}
3136
}

sample/SampleServer/TextDocumentHandler.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,40 @@
11
using System;
2+
using System.Threading;
23
using System.Threading.Tasks;
34
using OmniSharp.Extensions.LanguageServer;
45
using OmniSharp.Extensions.LanguageServer.Protocol;
56
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
67
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
8+
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
79
using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities;
810
using OmniSharp.Extensions.LanguageServer.Server;
11+
using ILanguageServer = OmniSharp.Extensions.LanguageServer.Server.ILanguageServer;
912

1013
namespace SampleServer
1114
{
1215
class TextDocumentHandler : ITextDocumentSyncHandler
1316
{
14-
private readonly ILanguageServer _router;
17+
private readonly OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServer _router;
1518

1619
private readonly DocumentSelector _documentSelector = new DocumentSelector(
1720
new DocumentFilter()
1821
{
19-
Pattern = "**/*.csproj",
20-
Language = "xml"
22+
Pattern = "**/*.cs"
2123
}
2224
);
2325

2426
private SynchronizationCapability _capability;
2527

26-
public TextDocumentHandler(ILanguageServer router)
28+
public TextDocumentHandler(OmniSharp.Extensions.LanguageServer.Protocol.Server.ILanguageServer router)
2729
{
2830
_router = router;
2931
}
3032

31-
public TextDocumentSyncOptions Options { get; } = new TextDocumentSyncOptions()
32-
{
33-
WillSaveWaitUntil = false,
34-
WillSave = true,
35-
Change = TextDocumentSyncKind.Full,
36-
Save = new SaveOptions()
37-
{
38-
IncludeText = true
39-
},
40-
OpenClose = true
41-
};
33+
public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Full;
4234

43-
public Task Handle(DidChangeTextDocumentParams notification)
35+
public Task Handle(DidChangeTextDocumentParams notification, CancellationToken token)
4436
{
45-
_router.LogMessage(new LogMessageParams()
37+
_router.Window.LogMessage(new LogMessageParams()
4638
{
4739
Type = MessageType.Log,
4840
Message = "Hello World!!!!"
@@ -55,7 +47,7 @@ TextDocumentChangeRegistrationOptions IRegistration<TextDocumentChangeRegistrati
5547
return new TextDocumentChangeRegistrationOptions()
5648
{
5749
DocumentSelector = _documentSelector,
58-
SyncKind = Options.Change
50+
SyncKind = Change
5951
};
6052
}
6153

@@ -64,10 +56,10 @@ public void SetCapability(SynchronizationCapability capability)
6456
_capability = capability;
6557
}
6658

67-
public async Task Handle(DidOpenTextDocumentParams notification)
59+
public async Task Handle(DidOpenTextDocumentParams notification, CancellationToken token)
6860
{
6961
await Task.Yield();
70-
_router.LogMessage(new LogMessageParams()
62+
_router.Window.LogMessage(new LogMessageParams()
7163
{
7264
Type = MessageType.Log,
7365
Message = "Hello World!!!!"
@@ -82,12 +74,12 @@ TextDocumentRegistrationOptions IRegistration<TextDocumentRegistrationOptions>.G
8274
};
8375
}
8476

85-
public Task Handle(DidCloseTextDocumentParams notification)
77+
public Task Handle(DidCloseTextDocumentParams notification, CancellationToken token)
8678
{
8779
return Task.CompletedTask;
8880
}
8981

90-
public Task Handle(DidSaveTextDocumentParams notification)
82+
public Task Handle(DidSaveTextDocumentParams notification, CancellationToken token)
9183
{
9284
return Task.CompletedTask;
9385
}
@@ -97,7 +89,7 @@ TextDocumentSaveRegistrationOptions IRegistration<TextDocumentSaveRegistrationOp
9789
return new TextDocumentSaveRegistrationOptions()
9890
{
9991
DocumentSelector = _documentSelector,
100-
IncludeText = Options.Save.IncludeText
92+
IncludeText = true
10193
};
10294
}
10395
public TextDocumentAttributes GetTextDocumentAttributes(Uri uri)

src/Client/Client.csproj

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
3+
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0</TargetFrameworks>
55
<PlatformTarget>AnyCPU</PlatformTarget>
66
<AssemblyName>OmniSharp.Extensions.LanguageClient</AssemblyName>
77
<RootNamespace>OmniSharp.Extensions.LanguageServer.Client</RootNamespace>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
12-
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
13-
<PackageReference Include="System.Reactive" Version="3.1.1" />
14-
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
11+
<PackageReference Include="System.Reactive" Version="$(System_Reactive_Version)" />
1512
</ItemGroup>
1613

1714
<ItemGroup>

src/Client/Handlers/JsonRpcEmptyNotificationHandler.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
using System;
1+
using System;
2+
using System.Threading;
23
using System.Threading.Tasks;
34
using OmniSharp.Extensions.JsonRpc;
45

56
namespace OmniSharp.Extensions.LanguageServer.Client.Handlers
67
{
78
/// <summary>
8-
/// An empty notification handler that invokes a JSON-RPC <see cref="INotificationHandler"/>.
9+
/// An empty notification handler that invokes a JSON-RPC <see cref="IJsonRpcNotificationHandler"/>.
910
/// </summary>
1011
public class JsonRpcEmptyNotificationHandler
1112
: JsonRpcHandler, IInvokeEmptyNotificationHandler
@@ -17,9 +18,9 @@ public class JsonRpcEmptyNotificationHandler
1718
/// The name of the method handled by the handler.
1819
/// </param>
1920
/// <param name="handler">
20-
/// The underlying JSON-RPC <see cref="INotificationHandler"/>.
21+
/// The underlying JSON-RPC <see cref="IJsonRpcNotificationHandler"/>.
2122
/// </param>
22-
public JsonRpcEmptyNotificationHandler(string method, INotificationHandler handler)
23+
public JsonRpcEmptyNotificationHandler(string method, IJsonRpcNotificationHandler handler)
2324
: base(method)
2425
{
2526
if (handler == null)
@@ -29,9 +30,9 @@ public JsonRpcEmptyNotificationHandler(string method, INotificationHandler handl
2930
}
3031

3132
/// <summary>
32-
/// The underlying JSON-RPC <see cref="INotificationHandler"/>.
33+
/// The underlying JSON-RPC <see cref="IJsonRpcNotificationHandler"/>.
3334
/// </summary>
34-
public INotificationHandler Handler { get; }
35+
public IJsonRpcNotificationHandler Handler { get; }
3536

3637
/// <summary>
3738
/// The expected CLR type of the notification payload (<c>null</c>, since the handler does not use the request payload).
@@ -44,6 +45,6 @@ public JsonRpcEmptyNotificationHandler(string method, INotificationHandler handl
4445
/// <returns>
4546
/// A <see cref="Task"/> representing the operation.
4647
/// </returns>
47-
public Task Invoke() => Handler.Handle();
48+
public Task Invoke() => Handler.Handle(null, CancellationToken.None);
4849
}
4950
}

src/Client/Handlers/JsonRpcNotificationHandler.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
using System;
2+
using System.Threading;
23
using System.Threading.Tasks;
4+
using MediatR;
5+
using Newtonsoft.Json.Linq;
36
using OmniSharp.Extensions.JsonRpc;
47
using OmniSharp.Extensions.LanguageServer.Protocol;
58
using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
69

710
namespace OmniSharp.Extensions.LanguageServer.Client.Handlers
811
{
912
/// <summary>
10-
/// A notification handler that invokes a JSON-RPC <see cref="INotificationHandler{TNotification}"/>.
13+
/// A notification handler that invokes a JSON-RPC <see cref="IJsonRpcNotificationHandler{TNotification}"/>.
1114
/// </summary>
1215
/// <typeparam name="TNotification">
1316
/// The notification message handler.
1417
/// </typeparam>
15-
public class JsonRpcNotificationHandler<TNotification>
16-
: JsonRpcHandler, IInvokeNotificationHandler
18+
public class JsonRpcNotificationHandler<TNotification> : JsonRpcHandler, IInvokeNotificationHandler
19+
where TNotification : IRequest
1720
{
1821
/// <summary>
1922
/// Create a new <see cref="JsonRpcNotificationHandler{TNotification}"/>.
@@ -22,9 +25,9 @@ public class JsonRpcNotificationHandler<TNotification>
2225
/// The name of the method handled by the handler.
2326
/// </param>
2427
/// <param name="handler">
25-
/// The underlying JSON-RPC <see cref="INotificationHandler{TNotification}"/>.
28+
/// The underlying JSON-RPC <see cref="IJsonRpcNotificationHandler{TNotification}"/>.
2629
/// </param>
27-
public JsonRpcNotificationHandler(string method, INotificationHandler<TNotification> handler)
30+
public JsonRpcNotificationHandler(string method, IJsonRpcNotificationHandler<TNotification> handler)
2831
: base(method)
2932
{
3033
if (handler == null)
@@ -34,9 +37,9 @@ public JsonRpcNotificationHandler(string method, INotificationHandler<TNotificat
3437
}
3538

3639
/// <summary>
37-
/// The underlying JSON-RPC <see cref="INotificationHandler{TNotification}"/>.
40+
/// The underlying JSON-RPC <see cref="IJsonRpcNotificationHandler{TNotification}"/>.
3841
/// </summary>
39-
public INotificationHandler<TNotification> Handler { get; }
42+
public IJsonRpcNotificationHandler<TNotification> Handler { get; }
4043

4144
/// <summary>
4245
/// The expected CLR type of the notification payload.
@@ -53,7 +56,8 @@ public JsonRpcNotificationHandler(string method, INotificationHandler<TNotificat
5356
/// A <see cref="Task"/> representing the operation.
5457
/// </returns>
5558
public Task Invoke(object notification) => Handler.Handle(
56-
(TNotification)notification
59+
(TNotification)notification,
60+
CancellationToken.None
5761
);
5862
}
5963
}

src/Client/LanguageClient.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
1414
using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
1515
using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities;
16+
using ISerializer = OmniSharp.Extensions.LanguageServer.Protocol.Serialization.ISerializer;
1617

1718
namespace OmniSharp.Extensions.LanguageServer.Client
1819
{
@@ -91,7 +92,7 @@ public LanguageClient(ILoggerFactory loggerFactory, ServerProcess process)
9192
throw new ArgumentNullException(nameof(process));
9293

9394
_process = process;
94-
_process.Exited += ServerProcess_Exit;
95+
_process.Exited.Subscribe(x => ServerProcess_Exit());
9596
}
9697

9798
/// <summary>
@@ -451,7 +452,7 @@ async Task Start()
451452
/// <param name="args">
452453
/// The event arguments.
453454
/// </param>
454-
async void ServerProcess_Exit(object sender, EventArgs args)
455+
async void ServerProcess_Exit()
455456
{
456457
Log.LogDebug("Server process has exited; language client is shutting down...");
457458

src/Client/LanguageRegistration.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using System;
2+
using MediatR;
23
using OmniSharp.Extensions.JsonRpc;
34
using OmniSharp.Extensions.LanguageServer.Client.Handlers;
45

@@ -50,12 +51,12 @@ public static IDisposable HandleNotification(this LanguageClient languageClient,
5051
/// The name of the notification method to handle.
5152
/// </param>
5253
/// <param name="handler">
53-
/// A JSON-RPC <see cref="INotificationHandler"/> that implements the handler.
54+
/// A JSON-RPC <see cref="IJsonRpcNotificationHandler"/> that implements the handler.
5455
/// </param>
5556
/// <returns>
5657
/// An <see cref="IDisposable"/> representing the registration.
5758
/// </returns>
58-
public static IDisposable HandleNotification(this LanguageClient languageClient, string method, INotificationHandler handler)
59+
public static IDisposable HandleNotification(this LanguageClient languageClient, string method, IJsonRpcNotificationHandler handler)
5960
{
6061
if (languageClient == null)
6162
throw new ArgumentNullException(nameof(languageClient));
@@ -119,12 +120,13 @@ public static IDisposable HandleNotification<TNotification>(this LanguageClient
119120
/// The name of the notification method to handle.
120121
/// </param>
121122
/// <param name="handler">
122-
/// A JSON-RPC <see cref="INotificationHandler{TNotification}"/> that implements the handler.
123+
/// A JSON-RPC <see cref="IJsonRpcNotificationHandler{TNotification}"/> that implements the handler.
123124
/// </param>
124125
/// <returns>
125126
/// An <see cref="IDisposable"/> representing the registration.
126127
/// </returns>
127-
public static IDisposable HandleNotification<TNotification>(this LanguageClient languageClient, string method, INotificationHandler<TNotification> handler)
128+
public static IDisposable HandleNotification<TNotification>(this LanguageClient languageClient, string method, IJsonRpcNotificationHandler<TNotification> handler)
129+
where TNotification : IRequest
128130
{
129131
if (languageClient == null)
130132
throw new ArgumentNullException(nameof(languageClient));

0 commit comments

Comments
 (0)