Skip to content

Commit

Permalink
Fixed issues with codelens, documentlink and completion item data (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
david-driscoll authored Aug 2, 2020
1 parent a0f0bcb commit c6cea42
Show file tree
Hide file tree
Showing 22 changed files with 437 additions and 318 deletions.
27 changes: 19 additions & 8 deletions src/Dap.Shared/DebugAdapterHandlerCollection.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reactive.Disposables;
using System.Reflection;
using System.Threading;
using MediatR;
using OmniSharp.Extensions.JsonRpc;

namespace OmniSharp.Extensions.DebugAdapter.Shared
{
class DebugAdapterHandlerCollection : IEnumerable<IHandlerDescriptor>, IHandlersManager
{
internal readonly HashSet<HandlerDescriptor> _handlers = new HashSet<HandlerDescriptor>();
private ImmutableHashSet<HandlerDescriptor> _descriptors = ImmutableHashSet<HandlerDescriptor>.Empty;

public IEnumerator<IHandlerDescriptor> GetEnumerator()
{
return _handlers.GetEnumerator();
return _descriptors.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
Expand All @@ -29,7 +31,7 @@ IEnumerator IEnumerable.GetEnumerator()

IDisposable IHandlersManager.AddLink(string sourceMethod, string destinationMethod)
{
var source = _handlers.First(z => z.Method == sourceMethod);
var source = _descriptors.First(z => z.Method == sourceMethod);
HandlerDescriptor descriptor = null;
descriptor = GetDescriptor(
destinationMethod,
Expand All @@ -38,15 +40,15 @@ IDisposable IHandlersManager.AddLink(string sourceMethod, string destinationMeth
source.RequestProcessType.HasValue ? new JsonRpcHandlerOptions() {RequestProcessType = source.RequestProcessType.Value} : null,
source.TypeDescriptor,
source.HandlerType);
_handlers.Add(descriptor);
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));

return descriptor;
}

public IDisposable Add(string method, IJsonRpcHandler handler, JsonRpcHandlerOptions options)
{
var descriptor = GetDescriptor(method, handler.GetType(), handler, options);
_handlers.Add(descriptor);
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
return new CompositeDisposable {descriptor};
}

Expand All @@ -66,7 +68,7 @@ public IDisposable Add(params IJsonRpcHandler[] handlers)
{
var descriptor = GetDescriptor(method, implementedInterface, handler, null);
cd.Add(descriptor);
_handlers.Add(descriptor);
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
}
}

Expand Down Expand Up @@ -100,7 +102,7 @@ private IDisposable Add(IJsonRpcHandler[] handlers, JsonRpcHandlerOptions option
{
var descriptor = GetDescriptor(method, implementedInterface, handler, options);
cd.Add(descriptor);
_handlers.Add(descriptor);
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
}
}

Expand Down Expand Up @@ -148,7 +150,16 @@ private HandlerDescriptor GetDescriptor(string method, Type handlerType, IJsonRp
@params,
response,
requestProcessType,
() => { _handlers.RemoveWhere(d => d.Handler == handler); });
() => {
var descriptors = _descriptors.ToBuilder();
foreach (var descriptor in _descriptors)
{
if (descriptor.Handler != handler) continue;
descriptors.Remove(descriptor);
}

Interlocked.Exchange(ref _descriptors, descriptors.ToImmutable());
});

return descriptor;
}
Expand Down
34 changes: 19 additions & 15 deletions src/JsonRpc/HandlerCollection.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Disposables;
using System.Reflection;
using System.Threading;
using MediatR;

namespace OmniSharp.Extensions.JsonRpc
Expand All @@ -13,7 +15,7 @@ namespace OmniSharp.Extensions.JsonRpc

public class HandlerCollection : IEnumerable<IHandlerDescriptor>, IHandlersManager
{
internal readonly List<IHandlerDescriptor> _handlers = new List<IHandlerDescriptor>();
private ImmutableArray<IHandlerDescriptor> _descriptors = ImmutableArray<IHandlerDescriptor>.Empty;

public HandlerCollection() { }

Expand Down Expand Up @@ -109,7 +111,7 @@ public void Dispose()

public IEnumerator<IHandlerDescriptor> GetEnumerator()
{
return _handlers.GetEnumerator();
return _descriptors.AsEnumerable().GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
Expand All @@ -119,19 +121,21 @@ IEnumerator IEnumerable.GetEnumerator()

private void Remove(IJsonRpcHandler handler)
{
var handlers = _handlers.FindAll(instance => instance.Handler == handler);
foreach (var item in handlers)
var descriptors = _descriptors.ToBuilder();
foreach (var item in _descriptors.Where(instance => instance.Handler == handler))
{
_handlers.Remove(item);
descriptors.Remove(item);
}

ImmutableInterlocked.InterlockedExchange(ref _descriptors, descriptors.ToImmutableArray());
}

public IDisposable Add(params IJsonRpcHandler[] handlers)
{
var cd = new CompositeDisposable();
foreach (var handler in handlers)
{
if (_handlers.Any(z => z.Handler == handler)) continue;
if (_descriptors.Any(z => z.Handler == handler)) continue;
cd.Add(Add(GetMethodName(handler.GetType()), handler, null));
}
return cd;
Expand Down Expand Up @@ -167,27 +171,27 @@ public IDisposable Add(string method, IJsonRpcHandler handler, JsonRpcHandlerOpt
.OfType<ProcessAttribute>()
.FirstOrDefault()?.Type;

var h = new HandlerInstance(method, handler, @interface, @params, response, requestProcessType, () => Remove(handler));
_handlers.Add(h);
return h;
var descriptor = new HandlerInstance(method, handler, @interface, @params, response, requestProcessType, () => Remove(handler));
ImmutableInterlocked.InterlockedExchange(ref _descriptors, _descriptors.Add(descriptor));
return descriptor;
}

public IDisposable AddLink(string sourceMethod, string destinationMethod)
{
var source = _handlers.Find(z => z.Method == sourceMethod);
var h = new LinkedHandler(destinationMethod, source, () => _handlers.RemoveAll(z => z.Method == destinationMethod));
_handlers.Add(h);
return h;
var source = _descriptors.FirstOrDefault(z => z.Method == sourceMethod);
var descriptor = new LinkedHandler(destinationMethod, source, () => _descriptors.RemoveAll(z => z.Method == destinationMethod));
ImmutableInterlocked.InterlockedExchange(ref _descriptors, _descriptors.Add(descriptor));
return descriptor;
}

public bool ContainsHandler(Type type)
{
return _handlers.Any(z => type.IsAssignableFrom(z.HandlerType));
return _descriptors.Any(z => type.IsAssignableFrom(z.HandlerType));
}

public bool ContainsHandler(TypeInfo type)
{
return _handlers.Any(z => type.IsAssignableFrom(z.HandlerType));
return _descriptors.Any(z => type.IsAssignableFrom(z.HandlerType));
}

private static readonly Type[] HandlerTypes = {
Expand Down
8 changes: 5 additions & 3 deletions src/Protocol/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace OmniSharp.Extensions.LanguageServer.Protocol
namespace OmniSharp.Extensions.LanguageServer.Protocol
{
internal static class Constants
public static class Constants
{
public const string Proposal =
internal const string Proposal =
"Proposed for the next version of the language server. May not work with all clients. May be removed or changed in the future.";

public const string PrivateHandlerId = "$$__handler_id__$$";
}
}
32 changes: 16 additions & 16 deletions src/Protocol/Document/ICodeLensHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected PartialCodeLensHandlerBase(CodeLensRegistrationOptions registrationOpt
public virtual Guid Id { get; } = Guid.NewGuid();
}

public abstract class CodeLensHandlerBase<T> : CodeLensHandler where T : class
public abstract class CodeLensHandlerBase<T> : CodeLensHandler where T : HandlerIdentity, new()
{
private readonly ISerializer _serializer;

Expand All @@ -71,20 +71,20 @@ public CodeLensHandlerBase(CodeLensRegistrationOptions registrationOptions, ISer
public sealed override async Task<CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken)
{
var response = await HandleParams(request, cancellationToken);
return response.Convert(_serializer);
return response;
}

public sealed override async Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
{
var response = await HandleResolve(request.From<T>(_serializer), cancellationToken);
return response.To(_serializer);
var response = await HandleResolve(request, cancellationToken);
return response;
}

protected abstract Task<CodeLensContainer<T>> HandleParams(CodeLensParams request, CancellationToken cancellationToken);
protected abstract Task<CodeLens<T>> HandleResolve(CodeLens<T> request, CancellationToken cancellationToken);
}

public abstract class PartialCodeLensHandlerBase<T> : PartialCodeLensHandlerBase where T : class
public abstract class PartialCodeLensHandlerBase<T> : PartialCodeLensHandlerBase where T : HandlerIdentity, new()
{
private readonly ISerializer _serializer;

Expand All @@ -97,15 +97,15 @@ protected PartialCodeLensHandlerBase(CodeLensRegistrationOptions registrationOpt
protected sealed override void Handle(CodeLensParams request, IObserver<IEnumerable<CodeLens>> results, CancellationToken cancellationToken) => Handle(
request,
Observer.Create<IEnumerable<CodeLens<T>>>(
x => results.OnNext(x.Select(z => z.To(_serializer))),
x => results.OnNext(x.Select(z => (CodeLens)z)),
results.OnError,
results.OnCompleted
), cancellationToken);

public sealed override async Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
{
var response = await HandleResolve(request.From<T>(_serializer), cancellationToken);
return response.To(_serializer);
var response = await HandleResolve(request, cancellationToken);
return response;
}

protected abstract void Handle(CodeLensParams request, IObserver<IEnumerable<CodeLens<T>>> results, CancellationToken cancellationToken);
Expand Down Expand Up @@ -148,7 +148,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Func<CodeLensParams, CodeLensCapability, CancellationToken, Task<CodeLensContainer<T>>> handler,
Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand Down Expand Up @@ -196,7 +196,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Func<CodeLensParams, CancellationToken, Task<CodeLensContainer<T>>> handler,
Func<CodeLens<T>, CancellationToken, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand Down Expand Up @@ -244,7 +244,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Func<CodeLensParams, Task<CodeLensContainer<T>>> handler,
Func<CodeLens<T>, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand Down Expand Up @@ -295,7 +295,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CodeLensCapability, CancellationToken> handler,
Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand Down Expand Up @@ -346,7 +346,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CancellationToken> handler,
Func<CodeLens<T>, CancellationToken, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand Down Expand Up @@ -397,7 +397,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>> handler,
Func<CodeLens<T>, Task<CodeLens<T>>> resolveHandler,
CodeLensRegistrationOptions registrationOptions) where T : class
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
{
registrationOptions ??= new CodeLensRegistrationOptions();
registrationOptions.ResolveProvider = true;
Expand All @@ -412,7 +412,7 @@ public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry
);
}

class DelegatingCodeLensHandler<T> : CodeLensHandlerBase<T> where T : class
class DelegatingCodeLensHandler<T> : CodeLensHandlerBase<T> where T : HandlerIdentity, new()
{
private readonly Func<CodeLensParams, CodeLensCapability, CancellationToken, Task<CodeLensContainer<T>>> _handleParams;
private readonly Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> _handleResolve;
Expand All @@ -434,7 +434,7 @@ protected override Task<CodeLensContainer<T>> HandleParams(CodeLensParams reques
protected override Task<CodeLens<T>> HandleResolve(CodeLens<T> request, CancellationToken cancellationToken) => _handleResolve(request, Capability, cancellationToken);
}

class DelegatingPartialCodeLensHandler<T> : PartialCodeLensHandlerBase<T> where T : class
class DelegatingPartialCodeLensHandler<T> : PartialCodeLensHandlerBase<T> where T : HandlerIdentity, new()
{
private readonly Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CodeLensCapability, CancellationToken> _handleParams;
private readonly Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> _handleResolve;
Expand Down
Loading

0 comments on commit c6cea42

Please sign in to comment.