Skip to content

Commit 9b6043e

Browse files
Added OnStarted delegate handler that is called after the server has successfully started
1 parent d26c4dd commit 9b6043e

15 files changed

+144
-111
lines changed

Common.Build.props renamed to Directory.Build.props

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
<PackageProjectUrl>https://github.com/OmniSharp/csharp-language-server-protocol</PackageProjectUrl>
1212
<PackageTags>lsp;language server;language server protocol;language client;language server client</PackageTags>
1313
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)\lsp.snk</AssemblyOriginatorKeyFile>
14-
<Logging_Extensions_Version>2.0.0</Logging_Extensions_Version>
15-
<MediatR_Version>7.0.0</MediatR_Version>
1614
</PropertyGroup>
1715
<PropertyGroup>
1816
<EmbedUntrackedSources>true</EmbedUntrackedSources>

Common.Build.targets renamed to Directory.Build.targets

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<Project>
22
<ItemGroup>
3-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="All" />
3+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
44
</ItemGroup>
55

66
<ItemGroup>
7-
<PackageReference Update="Microsoft.Extensions.Logging" Version="$(Logging_Extensions_Version)" />
8-
<PackageReference Update="Microsoft.Extensions.Logging.Abstractions" Version="$(Logging_Extensions_Version)" />
9-
<PackageReference Update="Microsoft.Extensions.Logging.Debug" Version="$(Logging_Extensions_Version)" />
7+
<PackageReference Update="Microsoft.Extensions.Logging" Version="2.0.0" />
8+
<PackageReference Update="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
9+
<PackageReference Update="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
1010
<PackageReference Update="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
1111
<PackageReference Update="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.0.0" />
1212
<PackageReference Update="Newtonsoft.Json" Version="11.0.2" />
@@ -22,7 +22,7 @@
2222
<PackageReference Update="XunitXml.TestLogger" Version="2.1.26" />
2323
<PackageReference Update="coverlet.msbuild" Version="2.5.1" />
2424
<PackageReference Update="System.Reactive" Version="4.1.2" />
25-
<PackageReference Update="MediatR" Version="$(MediatR_Version)" />
26-
<PackageReference Update="MediatR.Extensions.Microsoft.DependencyInjection" Version="$(MediatR_Version)" />
25+
<PackageReference Update="MediatR" Version="7.0.0" />
26+
<PackageReference Update="MediatR.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
2727
</ItemGroup>
2828
</Project>

LSP.sln

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{AE4D
2323
build.cake = build.cake
2424
build.ps1 = build.ps1
2525
build.sh = build.sh
26-
Common.Build.props = Common.Build.props
26+
Directory.Build.props = Directory.Build.props
2727
nuget.config = nuget.config
2828
EndProjectSection
2929
EndProject

src/Client/Protocol/LspConnection.cs

+38-42
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,14 @@ public void Disconnect(bool flushOutgoing = false)
291291
);
292292
}
293293

294-
_cancellationSource?.Cancel();
294+
try
295+
{
296+
_cancellationSource?.Cancel();
297+
}
298+
catch (AggregateException e) when (e.InnerException is ObjectDisposedException)
299+
{
300+
// Swallow object disposed exception
301+
}
295302
_sendLoop = null;
296303
_receiveLoop = null;
297304
_dispatchLoop = null;
@@ -312,8 +319,7 @@ public void SendEmptyNotification(string method)
312319
if (!IsOpen)
313320
throw new LspException("Not connected to the language server.");
314321

315-
_outgoing.TryAdd(new ClientMessage
316-
{
322+
_outgoing.TryAdd(new ClientMessage {
317323
// No Id means it's a notification.
318324
Method = method
319325
});
@@ -339,8 +345,7 @@ public void SendNotification(string method, object notification)
339345
if (!IsOpen)
340346
throw new LspException("Not connected to the language server.");
341347

342-
_outgoing.TryAdd(new ClientMessage
343-
{
348+
_outgoing.TryAdd(new ClientMessage {
344349
// No Id means it's a notification.
345350
Method = method,
346351
Params = JToken.FromObject(notification, Serializer.JsonSerializer)
@@ -376,17 +381,15 @@ public void SendNotification(string method, object notification)
376381
string requestId = Interlocked.Increment(ref _nextRequestId).ToString();
377382

378383
var responseCompletion = new TaskCompletionSource<ServerMessage>(state: requestId);
379-
cancellationToken.Register(() =>
380-
{
384+
cancellationToken.Register(() => {
381385
responseCompletion.TrySetException(
382386
new OperationCanceledException("The request was canceled via the supplied cancellation token.", cancellationToken)
383387
);
384388

385389
// Send notification telling server to cancel the request, if possible.
386390
if (!_outgoing.IsAddingCompleted)
387391
{
388-
_outgoing.TryAdd(new ClientMessage
389-
{
392+
_outgoing.TryAdd(new ClientMessage {
390393
Method = JsonRpcNames.CancelRequest,
391394
Params = new JObject(
392395
new JProperty("id", requestId)
@@ -397,8 +400,7 @@ public void SendNotification(string method, object notification)
397400

398401
_responseCompletions.TryAdd(requestId, responseCompletion);
399402

400-
_outgoing.TryAdd(new ClientMessage
401-
{
403+
_outgoing.TryAdd(new ClientMessage {
402404
Id = requestId,
403405
Method = method,
404406
Params = request != null ? JToken.FromObject(request, Serializer.JsonSerializer) : null
@@ -439,17 +441,15 @@ public void SendNotification(string method, object notification)
439441
string requestId = Interlocked.Increment(ref _nextRequestId).ToString();
440442

441443
var responseCompletion = new TaskCompletionSource<ServerMessage>(state: requestId);
442-
cancellationToken.Register(() =>
443-
{
444+
cancellationToken.Register(() => {
444445
responseCompletion.TrySetException(
445446
new OperationCanceledException("The request was canceled via the supplied cancellation token.", cancellationToken)
446447
);
447448

448449
// Send notification telling server to cancel the request, if possible.
449450
if (!_outgoing.IsAddingCompleted)
450451
{
451-
_outgoing.TryAdd(new ClientMessage
452-
{
452+
_outgoing.TryAdd(new ClientMessage {
453453
Method = JsonRpcNames.CancelRequest,
454454
Params = new JObject(
455455
new JProperty("id", requestId)
@@ -460,8 +460,7 @@ public void SendNotification(string method, object notification)
460460

461461
_responseCompletions.TryAdd(requestId, responseCompletion);
462462

463-
_outgoing.TryAdd(new ClientMessage
464-
{
463+
_outgoing.TryAdd(new ClientMessage {
465464
Id = requestId,
466465
Method = method,
467466
Params = request != null ? JToken.FromObject(request, Serializer.JsonSerializer) : null
@@ -871,8 +870,7 @@ private void DispatchRequest(ServerMessage requestMessage)
871870
}
872871

873872
#pragma warning disable CS4014 // Continuation does the work we need; no need to await it as this would tie up the dispatch loop.
874-
handlerTask.ContinueWith(_ =>
875-
{
873+
handlerTask.ContinueWith(_ => {
876874
if (handlerTask.IsCanceled)
877875
Log.LogDebug("{RequestMethod} request {RequestId} canceled.", requestMessage.Method, requestId);
878876
else if (handlerTask.IsFaulted)
@@ -893,8 +891,7 @@ private void DispatchRequest(ServerMessage requestMessage)
893891
{
894892
Log.LogDebug("{RequestMethod} request {RequestId} complete (Result = {@Result}).", requestMessage.Method, requestId, handlerTask.Result);
895893

896-
_outgoing.TryAdd(new ClientMessage
897-
{
894+
_outgoing.TryAdd(new ClientMessage {
898895
Id = requestMessage.Id,
899896
Method = requestMessage.Method,
900897
Result = handlerTask.Result != null ? JToken.FromObject(handlerTask.Result, Serializer.JsonSerializer) : null
@@ -962,8 +959,7 @@ void DispatchNotification(ServerMessage notificationMessage)
962959
handlerTask = _dispatcher.TryHandleEmptyNotification(notificationMessage.Method);
963960

964961
#pragma warning disable CS4014 // Continuation does the work we need; no need to await it as this would tie up the dispatch loop.
965-
handlerTask.ContinueWith(completedHandler =>
966-
{
962+
handlerTask.ContinueWith(completedHandler => {
967963
if (handlerTask.IsCanceled)
968964
Log.LogDebug("{NotificationMethod} notification canceled.", notificationMessage.Method);
969965
else if (handlerTask.IsFaulted)
@@ -1006,31 +1002,31 @@ static LspException CreateLspException(ServerMessage message)
10061002
switch (message.Error.Code)
10071003
{
10081004
case LspErrorCodes.InvalidRequest:
1009-
{
1010-
return new LspInvalidRequestException(requestId);
1011-
}
1005+
{
1006+
return new LspInvalidRequestException(requestId);
1007+
}
10121008
case LspErrorCodes.InvalidParameters:
1013-
{
1014-
return new LspInvalidParametersException(requestId);
1015-
}
1009+
{
1010+
return new LspInvalidParametersException(requestId);
1011+
}
10161012
case LspErrorCodes.InternalError:
1017-
{
1018-
return new LspInternalErrorException(requestId);
1019-
}
1013+
{
1014+
return new LspInternalErrorException(requestId);
1015+
}
10201016
case LspErrorCodes.MethodNotSupported:
1021-
{
1022-
return new LspMethodNotSupportedException(requestId, message.Method);
1023-
}
1017+
{
1018+
return new LspMethodNotSupportedException(requestId, message.Method);
1019+
}
10241020
case LspErrorCodes.RequestCancelled:
1025-
{
1026-
return new LspRequestCancelledException(requestId);
1027-
}
1021+
{
1022+
return new LspRequestCancelledException(requestId);
1023+
}
10281024
default:
1029-
{
1030-
string exceptionMessage = $"Error processing request '{message.Id}' ({message.Error.Code}): {message.Error.Message}";
1025+
{
1026+
string exceptionMessage = $"Error processing request '{message.Id}' ({message.Error.Code}): {message.Error.Message}";
10311027

1032-
return new LspRequestException(exceptionMessage, requestId, message.Error.Code);
1033-
}
1028+
return new LspRequestException(exceptionMessage, requestId, message.Error.Code);
1029+
}
10341030
}
10351031
}
10361032
}

src/Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
2-
<Import Project="$([MSBuild]::GetPathOfFileAbove('Common.Build.props', '$(MSBuildThisFileDirectory)../'))" />
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
33
<PropertyGroup>
44
<PackageVersion Condition="'$(GitVersion_NuGetVersion)' != ''">$(GitVersion_NuGetVersion)</PackageVersion>
55
<AssemblyVersion>0.0.9.9</AssemblyVersion>

src/Directory.Build.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<Project>
2-
<Import Project="$([MSBuild]::GetPathOfFileAbove('Common.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
33
</Project>

src/Server/ILanguageServer.cs

+2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ public interface ILanguageServer : OmniSharp.Extensions.LanguageServer.Protocol.
1515
InitializeResult ServerSettings { get; }
1616
IServiceProvider Services { get; }
1717

18+
IObservable<InitializeResult> Start { get; }
1819
IObservable<bool> Shutdown { get; }
1920
IObservable<int> Exit { get; }
21+
Task<InitializeResult> WasStarted { get; }
2022
Task WasShutDown { get; }
2123
Task WaitForExit { get; }
2224
}

src/Server/InitializeDelegate.cs

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
namespace OmniSharp.Extensions.LanguageServer.Server
55
{
66
public delegate Task InitializeDelegate(ILanguageServer server, InitializeParams request);
7+
public delegate Task StartedDelegate(InitializeResult result);
78
}

0 commit comments

Comments
 (0)