Skip to content

Porting over the minor breaking changes from the nullablity branch to be included in 0.18 #335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Client/LanguageClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
Expand Down Expand Up @@ -381,7 +382,7 @@ private Supports<T> UseOrTryAndFindCapability<T>(Supports<T> supports) where T :

public IObservable<InitializeResult> Start => _initializeComplete.AsObservable();

(string method, TaskCompletionSource<JToken> pendingTask) IResponseRouter.GetRequest(long id) => _responseRouter.GetRequest(id);
bool IResponseRouter.TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask) => _responseRouter.TryGetRequest(id, out method, out pendingTask);

public Task<InitializeResult> WasStarted => _initializeComplete.ToTask();

Expand Down
9 changes: 6 additions & 3 deletions src/Dap.Shared/DapResponseRouter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
Expand Down Expand Up @@ -51,10 +52,12 @@ public Task<TResponse> SendRequest<TResponse>(IRequest<TResponse> @params, Cance

public IResponseRouterReturns SendRequest<T>(string method, T @params) => new ResponseRouterReturnsImpl(this, method, @params);

public (string method, TaskCompletionSource<JToken> pendingTask) GetRequest(long id)
public bool TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask)
{
Requests.TryGetValue(id, out var source);
return source;
var result = Requests.TryGetValue(id, out var source);
method = source.method;
pendingTask = source.pendingTask;
return result;
}

private string GetMethodName(Type type)
Expand Down
10 changes: 4 additions & 6 deletions src/Dap.Shared/HandlerDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ public HandlerDescriptor(
typeof(DelegatingNotification<>).IsAssignableFrom(@params.GetGenericTypeDefinition())
);

IsNotification = typeof(IJsonRpcNotificationHandler).IsAssignableFrom(handlerInterface) || handlerInterface
.GetInterfaces().Any(
z =>
z.IsGenericType && typeof(IJsonRpcNotificationHandler<>)
.IsAssignableFrom(z.GetGenericTypeDefinition())
);
IsNotification = handlerInterface.GetInterfaces().Any(
z => z.IsGenericType &&
typeof(IJsonRpcNotificationHandler<>).IsAssignableFrom(z.GetGenericTypeDefinition())
);
IsRequest = !IsNotification;
RequestProcessType = requestProcessType;
}
Expand Down
13 changes: 0 additions & 13 deletions src/JsonRpc/EmptyRequest.cs

This file was deleted.

10 changes: 4 additions & 6 deletions src/JsonRpc/HandlerInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ public HandlerInstance(
typeof(DelegatingNotification<>).IsAssignableFrom(@params.GetGenericTypeDefinition())
);

IsNotification = typeof(IJsonRpcNotificationHandler).IsAssignableFrom(handlerInterface) || handlerInterface
.GetInterfaces().Any(
z =>
z.IsGenericType && typeof(IJsonRpcNotificationHandler<>)
.IsAssignableFrom(z.GetGenericTypeDefinition())
);
IsNotification = handlerInterface.GetInterfaces().Any(
z => z.IsGenericType &&
typeof(IJsonRpcNotificationHandler<>).IsAssignableFrom(z.GetGenericTypeDefinition())
);
IsRequest = !IsNotification;
RequestProcessType = requestProcessType;
}
Expand Down
14 changes: 2 additions & 12 deletions src/JsonRpc/HandlerTypeDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,9 @@ public HandlerTypeDescriptor(Type handlerType)
{
ParamsType = InterfaceType.GetGenericArguments()[0];
}
else
{
ParamsType = typeof(EmptyRequest);
}

HasParamsType = ParamsType != null && ParamsType != typeof(EmptyRequest);
IsNotification = typeof(IJsonRpcNotificationHandler).IsAssignableFrom(handlerType) || handlerType
.GetInterfaces().Any(
z =>
z.IsGenericType && typeof(IJsonRpcNotificationHandler<>).IsAssignableFrom(
z.GetGenericTypeDefinition()
)
);
HasParamsType = ParamsType != null;
IsNotification = handlerType.GetInterfaces().Any(z => z.IsGenericType && typeof(IJsonRpcNotificationHandler<>).IsAssignableFrom(z.GetGenericTypeDefinition()));
IsRequest = !IsNotification;

var requestInterface = ParamsType?
Expand Down
1 change: 0 additions & 1 deletion src/JsonRpc/HandlerTypeDescriptorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ internal static Type GetMethodType(Type type)
}

private static readonly Type[] HandlerTypes = {
typeof(IJsonRpcNotificationHandler),
typeof(IJsonRpcNotificationHandler<>),
typeof(IJsonRpcRequestHandler<>),
typeof(IJsonRpcRequestHandler<,>),
Expand Down
4 changes: 0 additions & 4 deletions src/JsonRpc/IJsonRpcNotificationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

namespace OmniSharp.Extensions.JsonRpc
{
public interface IJsonRpcNotificationHandler : IRequestHandler<EmptyRequest>, IJsonRpcHandler
{
}

public interface IJsonRpcNotificationHandler<in TNotification> : IRequestHandler<TNotification>, IJsonRpcHandler
where TNotification : IRequest
{
Expand Down
3 changes: 2 additions & 1 deletion src/JsonRpc/IResponseRouter.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
Expand All @@ -13,6 +14,6 @@ public interface IResponseRouter
IResponseRouterReturns SendRequest<T>(string method, T @params);
IResponseRouterReturns SendRequest(string method);
Task<TResponse> SendRequest<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken);
(string method, TaskCompletionSource<JToken> pendingTask) GetRequest(long id);
bool TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask);
}
}
3 changes: 1 addition & 2 deletions src/JsonRpc/InputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,7 @@ private void HandleRequest(in ReadOnlySequence<byte> request)
continue;
}

var (method, tcs) = _responseRouter.GetRequest(id);
if (tcs is null)
if (!_responseRouter.TryGetRequest(id, out var method, out var tcs))
{
// _logger.LogDebug("Request {ResponseId} was not found in the response router, unable to complete", response.Id);
continue;
Expand Down
6 changes: 4 additions & 2 deletions src/JsonRpc/JsonRpcServerBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -28,6 +29,7 @@ protected JsonRpcServerBase(IHandlersManager handlersManager, IResponseRouter re

public IResponseRouterReturns SendRequest(string method) => ResponseRouter.SendRequest(method);

(string method, TaskCompletionSource<JToken> pendingTask) IResponseRouter.GetRequest(long id) => ResponseRouter.GetRequest(id);
bool IResponseRouter.TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask)
=> ResponseRouter.TryGetRequest(id, out method, out pendingTask);
}
}
10 changes: 8 additions & 2 deletions src/JsonRpc/NoopResponseRouter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -34,7 +35,12 @@ public void SendNotification(IRequest request)

public Task<TResponse> SendRequest<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken) => Task.FromResult<TResponse>(default);

(string method, TaskCompletionSource<JToken> pendingTask) IResponseRouter.GetRequest(long id) => ( "UNKNOWN", new TaskCompletionSource<JToken>() );
bool IResponseRouter.TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask)
{
method = default;
pendingTask = default;
return false;
}

private class Impl : IResponseRouterReturns
{
Expand Down
141 changes: 141 additions & 0 deletions src/JsonRpc/Nullable/Attributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#pragma warning disable MA0048 // File name must match type name
#define INTERNAL_NULLABLE_ATTRIBUTES
#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48

// https://github.com/dotnet/corefx/blob/48363ac826ccf66fbe31a5dcb1dc2aab9a7dd768/src/Common/src/CoreLib/System/Diagnostics/CodeAnalysis/NullableAttributes.cs

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

// ReSharper disable once CheckNamespace
namespace System.Diagnostics.CodeAnalysis
{
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class AllowNullAttribute : Attribute
{ }

/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class DisallowNullAttribute : Attribute
{ }

/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class MaybeNullAttribute : Attribute
{ }

/// <summary>Specifies that an output will not be null even if the corresponding type allows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class NotNullAttribute : Attribute
{ }

/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class MaybeNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter may be null.
/// </param>
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;

/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
}

/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class NotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;

/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
}

/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class NotNullIfNotNullAttribute : Attribute
{
/// <summary>Initializes the attribute with the associated parameter name.</summary>
/// <param name="parameterName">
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
/// </param>
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;

/// <summary>Gets the associated parameter name.</summary>
public string ParameterName { get; }
}

/// <summary>Applied to a method that will never return under any circumstance.</summary>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class DoesNotReturnAttribute : Attribute
{ }

/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class DoesNotReturnIfAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified parameter value.</summary>
/// <param name="parameterValue">
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
/// the associated parameter matches this value.
/// </param>
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;

/// <summary>Gets the condition parameter value.</summary>
public bool ParameterValue { get; }
}
}
#endif
11 changes: 2 additions & 9 deletions src/JsonRpc/RequestRouterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,7 @@ static async Task InnerRoute(IServiceScopeFactory serviceScopeFactory, TDescript
context.Descriptor = descriptor;
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();

if (descriptor.Params is null)
{
await HandleNotification(mediator, descriptor, EmptyRequest.Instance, token);
}
else
{
await HandleNotification(mediator, descriptor, @params ?? Activator.CreateInstance(descriptor.Params), token);
}
await HandleNotification(mediator, descriptor, @params ?? Activator.CreateInstance(descriptor.Params), token);
}
}

Expand Down Expand Up @@ -183,7 +176,7 @@ ILogger logger

public static Task HandleNotification(IMediator mediator, IHandlerDescriptor handler, object @params, CancellationToken token) =>
(Task) SendRequestUnit
.MakeGenericMethod(handler.Params ?? typeof(EmptyRequest))
.MakeGenericMethod(handler.Params)
.Invoke(null, new[] { mediator, @params, token });

public static Task HandleRequest(IMediator mediator, IHandlerDescriptor descriptor, object @params, CancellationToken token)
Expand Down
9 changes: 6 additions & 3 deletions src/JsonRpc/ResponseRouter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
Expand Down Expand Up @@ -48,10 +49,12 @@ public Task<TResponse> SendRequest<TResponse>(IRequest<TResponse> @params, Cance

public IResponseRouterReturns SendRequest<T>(string method, T @params) => new ResponseRouterReturnsImpl(this, method, @params);

public (string method, TaskCompletionSource<JToken> pendingTask) GetRequest(long id)
public bool TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask)
{
Requests.TryGetValue(id, out var source);
return source;
var result = Requests.TryGetValue(id, out var source);
method = source.method;
pendingTask = source.pendingTask;
return result;
}

private string GetMethodName(Type type) =>
Expand Down
3 changes: 2 additions & 1 deletion src/Protocol/LanguageProtocolProxy.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
Expand Down Expand Up @@ -42,7 +43,7 @@ public LanguageProtocolProxy(

public Task<TResponse> SendRequest<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken) => _responseRouter.SendRequest(request, cancellationToken);

(string method, TaskCompletionSource<JToken> pendingTask) IResponseRouter.GetRequest(long id) => _responseRouter.GetRequest(id);
bool IResponseRouter.TryGetRequest(long id, [NotNullWhen(true)] out string method, [NotNullWhen(true)] out TaskCompletionSource<JToken> pendingTask) => _responseRouter.TryGetRequest(id, out method, out pendingTask);
object IServiceProvider.GetService(Type serviceType) => _serviceProvider.GetService(serviceType);
}
}
Loading