Skip to content

Commit c6cea42

Browse files
Fixed issues with codelens, documentlink and completion item data (#272)
1 parent a0f0bcb commit c6cea42

22 files changed

+437
-318
lines changed

src/Dap.Shared/DebugAdapterHandlerCollection.cs

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.Immutable;
45
using System.Linq;
56
using System.Reactive.Disposables;
67
using System.Reflection;
8+
using System.Threading;
79
using MediatR;
810
using OmniSharp.Extensions.JsonRpc;
911

1012
namespace OmniSharp.Extensions.DebugAdapter.Shared
1113
{
1214
class DebugAdapterHandlerCollection : IEnumerable<IHandlerDescriptor>, IHandlersManager
1315
{
14-
internal readonly HashSet<HandlerDescriptor> _handlers = new HashSet<HandlerDescriptor>();
16+
private ImmutableHashSet<HandlerDescriptor> _descriptors = ImmutableHashSet<HandlerDescriptor>.Empty;
1517

1618
public IEnumerator<IHandlerDescriptor> GetEnumerator()
1719
{
18-
return _handlers.GetEnumerator();
20+
return _descriptors.GetEnumerator();
1921
}
2022

2123
IEnumerator IEnumerable.GetEnumerator()
@@ -29,7 +31,7 @@ IEnumerator IEnumerable.GetEnumerator()
2931

3032
IDisposable IHandlersManager.AddLink(string sourceMethod, string destinationMethod)
3133
{
32-
var source = _handlers.First(z => z.Method == sourceMethod);
34+
var source = _descriptors.First(z => z.Method == sourceMethod);
3335
HandlerDescriptor descriptor = null;
3436
descriptor = GetDescriptor(
3537
destinationMethod,
@@ -38,15 +40,15 @@ IDisposable IHandlersManager.AddLink(string sourceMethod, string destinationMeth
3840
source.RequestProcessType.HasValue ? new JsonRpcHandlerOptions() {RequestProcessType = source.RequestProcessType.Value} : null,
3941
source.TypeDescriptor,
4042
source.HandlerType);
41-
_handlers.Add(descriptor);
43+
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
4244

4345
return descriptor;
4446
}
4547

4648
public IDisposable Add(string method, IJsonRpcHandler handler, JsonRpcHandlerOptions options)
4749
{
4850
var descriptor = GetDescriptor(method, handler.GetType(), handler, options);
49-
_handlers.Add(descriptor);
51+
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
5052
return new CompositeDisposable {descriptor};
5153
}
5254

@@ -66,7 +68,7 @@ public IDisposable Add(params IJsonRpcHandler[] handlers)
6668
{
6769
var descriptor = GetDescriptor(method, implementedInterface, handler, null);
6870
cd.Add(descriptor);
69-
_handlers.Add(descriptor);
71+
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
7072
}
7173
}
7274

@@ -100,7 +102,7 @@ private IDisposable Add(IJsonRpcHandler[] handlers, JsonRpcHandlerOptions option
100102
{
101103
var descriptor = GetDescriptor(method, implementedInterface, handler, options);
102104
cd.Add(descriptor);
103-
_handlers.Add(descriptor);
105+
Interlocked.Exchange(ref _descriptors, _descriptors.Add(descriptor));
104106
}
105107
}
106108

@@ -148,7 +150,16 @@ private HandlerDescriptor GetDescriptor(string method, Type handlerType, IJsonRp
148150
@params,
149151
response,
150152
requestProcessType,
151-
() => { _handlers.RemoveWhere(d => d.Handler == handler); });
153+
() => {
154+
var descriptors = _descriptors.ToBuilder();
155+
foreach (var descriptor in _descriptors)
156+
{
157+
if (descriptor.Handler != handler) continue;
158+
descriptors.Remove(descriptor);
159+
}
160+
161+
Interlocked.Exchange(ref _descriptors, descriptors.ToImmutable());
162+
});
152163

153164
return descriptor;
154165
}

src/JsonRpc/HandlerCollection.cs

+19-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.Immutable;
45
using System.Diagnostics;
56
using System.Linq;
67
using System.Reactive.Disposables;
78
using System.Reflection;
9+
using System.Threading;
810
using MediatR;
911

1012
namespace OmniSharp.Extensions.JsonRpc
@@ -13,7 +15,7 @@ namespace OmniSharp.Extensions.JsonRpc
1315

1416
public class HandlerCollection : IEnumerable<IHandlerDescriptor>, IHandlersManager
1517
{
16-
internal readonly List<IHandlerDescriptor> _handlers = new List<IHandlerDescriptor>();
18+
private ImmutableArray<IHandlerDescriptor> _descriptors = ImmutableArray<IHandlerDescriptor>.Empty;
1719

1820
public HandlerCollection() { }
1921

@@ -109,7 +111,7 @@ public void Dispose()
109111

110112
public IEnumerator<IHandlerDescriptor> GetEnumerator()
111113
{
112-
return _handlers.GetEnumerator();
114+
return _descriptors.AsEnumerable().GetEnumerator();
113115
}
114116

115117
IEnumerator IEnumerable.GetEnumerator()
@@ -119,19 +121,21 @@ IEnumerator IEnumerable.GetEnumerator()
119121

120122
private void Remove(IJsonRpcHandler handler)
121123
{
122-
var handlers = _handlers.FindAll(instance => instance.Handler == handler);
123-
foreach (var item in handlers)
124+
var descriptors = _descriptors.ToBuilder();
125+
foreach (var item in _descriptors.Where(instance => instance.Handler == handler))
124126
{
125-
_handlers.Remove(item);
127+
descriptors.Remove(item);
126128
}
129+
130+
ImmutableInterlocked.InterlockedExchange(ref _descriptors, descriptors.ToImmutableArray());
127131
}
128132

129133
public IDisposable Add(params IJsonRpcHandler[] handlers)
130134
{
131135
var cd = new CompositeDisposable();
132136
foreach (var handler in handlers)
133137
{
134-
if (_handlers.Any(z => z.Handler == handler)) continue;
138+
if (_descriptors.Any(z => z.Handler == handler)) continue;
135139
cd.Add(Add(GetMethodName(handler.GetType()), handler, null));
136140
}
137141
return cd;
@@ -167,27 +171,27 @@ public IDisposable Add(string method, IJsonRpcHandler handler, JsonRpcHandlerOpt
167171
.OfType<ProcessAttribute>()
168172
.FirstOrDefault()?.Type;
169173

170-
var h = new HandlerInstance(method, handler, @interface, @params, response, requestProcessType, () => Remove(handler));
171-
_handlers.Add(h);
172-
return h;
174+
var descriptor = new HandlerInstance(method, handler, @interface, @params, response, requestProcessType, () => Remove(handler));
175+
ImmutableInterlocked.InterlockedExchange(ref _descriptors, _descriptors.Add(descriptor));
176+
return descriptor;
173177
}
174178

175179
public IDisposable AddLink(string sourceMethod, string destinationMethod)
176180
{
177-
var source = _handlers.Find(z => z.Method == sourceMethod);
178-
var h = new LinkedHandler(destinationMethod, source, () => _handlers.RemoveAll(z => z.Method == destinationMethod));
179-
_handlers.Add(h);
180-
return h;
181+
var source = _descriptors.FirstOrDefault(z => z.Method == sourceMethod);
182+
var descriptor = new LinkedHandler(destinationMethod, source, () => _descriptors.RemoveAll(z => z.Method == destinationMethod));
183+
ImmutableInterlocked.InterlockedExchange(ref _descriptors, _descriptors.Add(descriptor));
184+
return descriptor;
181185
}
182186

183187
public bool ContainsHandler(Type type)
184188
{
185-
return _handlers.Any(z => type.IsAssignableFrom(z.HandlerType));
189+
return _descriptors.Any(z => type.IsAssignableFrom(z.HandlerType));
186190
}
187191

188192
public bool ContainsHandler(TypeInfo type)
189193
{
190-
return _handlers.Any(z => type.IsAssignableFrom(z.HandlerType));
194+
return _descriptors.Any(z => type.IsAssignableFrom(z.HandlerType));
191195
}
192196

193197
private static readonly Type[] HandlerTypes = {

src/Protocol/Constants.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Protocol
1+
namespace OmniSharp.Extensions.LanguageServer.Protocol
22
{
3-
internal static class Constants
3+
public static class Constants
44
{
5-
public const string Proposal =
5+
internal const string Proposal =
66
"Proposed for the next version of the language server. May not work with all clients. May be removed or changed in the future.";
7+
8+
public const string PrivateHandlerId = "$$__handler_id__$$";
79
}
810
}

src/Protocol/Document/ICodeLensHandler.cs

+16-16
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ protected PartialCodeLensHandlerBase(CodeLensRegistrationOptions registrationOpt
5858
public virtual Guid Id { get; } = Guid.NewGuid();
5959
}
6060

61-
public abstract class CodeLensHandlerBase<T> : CodeLensHandler where T : class
61+
public abstract class CodeLensHandlerBase<T> : CodeLensHandler where T : HandlerIdentity, new()
6262
{
6363
private readonly ISerializer _serializer;
6464

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

7777
public sealed override async Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
7878
{
79-
var response = await HandleResolve(request.From<T>(_serializer), cancellationToken);
80-
return response.To(_serializer);
79+
var response = await HandleResolve(request, cancellationToken);
80+
return response;
8181
}
8282

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

87-
public abstract class PartialCodeLensHandlerBase<T> : PartialCodeLensHandlerBase where T : class
87+
public abstract class PartialCodeLensHandlerBase<T> : PartialCodeLensHandlerBase where T : HandlerIdentity, new()
8888
{
8989
private readonly ISerializer _serializer;
9090

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

105105
public sealed override async Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
106106
{
107-
var response = await HandleResolve(request.From<T>(_serializer), cancellationToken);
108-
return response.To(_serializer);
107+
var response = await HandleResolve(request, cancellationToken);
108+
return response;
109109
}
110110

111111
protected abstract void Handle(CodeLensParams request, IObserver<IEnumerable<CodeLens<T>>> results, CancellationToken cancellationToken);
@@ -148,7 +148,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
148148
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
149149
Func<CodeLensParams, CodeLensCapability, CancellationToken, Task<CodeLensContainer<T>>> handler,
150150
Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> resolveHandler,
151-
CodeLensRegistrationOptions registrationOptions) where T : class
151+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
152152
{
153153
registrationOptions ??= new CodeLensRegistrationOptions();
154154
registrationOptions.ResolveProvider = true;
@@ -196,7 +196,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
196196
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
197197
Func<CodeLensParams, CancellationToken, Task<CodeLensContainer<T>>> handler,
198198
Func<CodeLens<T>, CancellationToken, Task<CodeLens<T>>> resolveHandler,
199-
CodeLensRegistrationOptions registrationOptions) where T : class
199+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
200200
{
201201
registrationOptions ??= new CodeLensRegistrationOptions();
202202
registrationOptions.ResolveProvider = true;
@@ -244,7 +244,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
244244
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
245245
Func<CodeLensParams, Task<CodeLensContainer<T>>> handler,
246246
Func<CodeLens<T>, Task<CodeLens<T>>> resolveHandler,
247-
CodeLensRegistrationOptions registrationOptions) where T : class
247+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
248248
{
249249
registrationOptions ??= new CodeLensRegistrationOptions();
250250
registrationOptions.ResolveProvider = true;
@@ -295,7 +295,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
295295
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
296296
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CodeLensCapability, CancellationToken> handler,
297297
Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> resolveHandler,
298-
CodeLensRegistrationOptions registrationOptions) where T : class
298+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
299299
{
300300
registrationOptions ??= new CodeLensRegistrationOptions();
301301
registrationOptions.ResolveProvider = true;
@@ -346,7 +346,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
346346
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
347347
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CancellationToken> handler,
348348
Func<CodeLens<T>, CancellationToken, Task<CodeLens<T>>> resolveHandler,
349-
CodeLensRegistrationOptions registrationOptions) where T : class
349+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
350350
{
351351
registrationOptions ??= new CodeLensRegistrationOptions();
352352
registrationOptions.ResolveProvider = true;
@@ -397,7 +397,7 @@ public static ILanguageServerRegistry OnCodeLens(this ILanguageServerRegistry re
397397
public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry registry,
398398
Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>> handler,
399399
Func<CodeLens<T>, Task<CodeLens<T>>> resolveHandler,
400-
CodeLensRegistrationOptions registrationOptions) where T : class
400+
CodeLensRegistrationOptions registrationOptions) where T : HandlerIdentity, new()
401401
{
402402
registrationOptions ??= new CodeLensRegistrationOptions();
403403
registrationOptions.ResolveProvider = true;
@@ -412,7 +412,7 @@ public static ILanguageServerRegistry OnCodeLens<T>(this ILanguageServerRegistry
412412
);
413413
}
414414

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

437-
class DelegatingPartialCodeLensHandler<T> : PartialCodeLensHandlerBase<T> where T : class
437+
class DelegatingPartialCodeLensHandler<T> : PartialCodeLensHandlerBase<T> where T : HandlerIdentity, new()
438438
{
439439
private readonly Action<CodeLensParams, IObserver<IEnumerable<CodeLens<T>>>, CodeLensCapability, CancellationToken> _handleParams;
440440
private readonly Func<CodeLens<T>, CodeLensCapability, CancellationToken, Task<CodeLens<T>>> _handleResolve;

0 commit comments

Comments
 (0)