Skip to content

Commit 7a1d7f6

Browse files
Added the latest changes from 1.16 spec. Moniker, CodeAction Resolve, DefaultBehavior and more (OmniSharp#382)
1 parent ee04c9a commit 7a1d7f6

File tree

68 files changed

+2401
-230
lines changed

Some content is hidden

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

68 files changed

+2401
-230
lines changed

LSP.sln.DotSettings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantBraces/@EntryIndexedValue">WARNING</s:String>
1515
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnnecessaryWhitespace/@EntryIndexedValue">WARNING</s:String>
1616
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseNullPropagationWhenPossible/@EntryIndexedValue">SUGGESTION</s:String>
17+
<s:String x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:String>
1718
<s:Boolean x:Key="/Default/CodeInspection/Roslyn/UseRoslynInSwea/@EntryValue">True</s:Boolean>
1819
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full_0020Cleanup/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Full Cleanup"&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="False" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="False" /&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSMakeAutoPropertyGetOnly&gt;True&lt;/CSMakeAutoPropertyGetOnly&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSharpFormatDocComments&gt;True&lt;/CSharpFormatDocComments&gt;&lt;XAMLCollapseEmptyTags&gt;False&lt;/XAMLCollapseEmptyTags&gt;&lt;IDEA_SETTINGS&gt;&amp;lt;profile version="1.0"&amp;gt;&#xD;
1920
&amp;lt;option name="myName" value="Full Cleanup" /&amp;gt;&#xD;
@@ -238,6 +239,7 @@
238239
&lt;/Entry&gt;&#xD;
239240
&lt;/TypePattern&gt;&#xD;
240241
&lt;/Patterns&gt;</s:String>
242+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
241243
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
242244
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
243245
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>

language-server-protocol.sha.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-- This is the last commit we caught up with https://github.com/Microsoft/language-server-protocol/commits/gh-pages
2-
lastSha: 56cf06cf95a2eea4e528558fb228d1698d952571
2+
lastSha: 1cf527d8410a493789de4992f78ee9874a4fd215
33

44
https://github.com/Microsoft/language-server-protocol/compare/<lastSha>..gh-pages

src/Client/LanguageClientRegistrationManager.cs

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ internal class LanguageClientRegistrationManager : IRegisterCapabilityHandler, I
2525
private readonly ILspHandlerTypeDescriptorProvider _handlerTypeDescriptorProvider;
2626
private readonly ILogger<LanguageClientRegistrationManager> _logger;
2727
private readonly ConcurrentDictionary<string, Registration> _registrations;
28-
private readonly ReplaySubject<IEnumerable<Registration>> _registrationSubject;
28+
private ReplaySubject<IEnumerable<Registration>> _registrationSubject = new ReplaySubject<IEnumerable<Registration>>(1);
2929

3030
public LanguageClientRegistrationManager(
3131
ISerializer serializer,
3232
ILspHandlerTypeDescriptorProvider handlerTypeDescriptorProvider,
33-
ILogger<LanguageClientRegistrationManager> logger)
33+
ILogger<LanguageClientRegistrationManager> logger
34+
)
3435
{
3536
_serializer = serializer;
3637
_handlerTypeDescriptorProvider = handlerTypeDescriptorProvider;
3738
_logger = logger;
3839
_registrations = new ConcurrentDictionary<string, Registration>(StringComparer.OrdinalIgnoreCase);
39-
_registrationSubject = new ReplaySubject<IEnumerable<Registration>>(1);
4040
}
4141

4242
Task<Unit> IRequestHandler<RegistrationParams, Unit>.Handle(RegistrationParams request, CancellationToken cancellationToken)
@@ -46,7 +46,11 @@ Task<Unit> IRequestHandler<RegistrationParams, Unit>.Handle(RegistrationParams r
4646
Register(request.Registrations.ToArray());
4747
}
4848

49-
_registrationSubject.OnNext(_registrations.Values);
49+
if (!_registrationSubject.IsDisposed)
50+
{
51+
_registrationSubject.OnNext(_registrations.Values);
52+
}
53+
5054
return Unit.Task;
5155
}
5256

@@ -60,15 +64,17 @@ Task<Unit> IRequestHandler<UnregistrationParams, Unit>.Handle(UnregistrationPara
6064
}
6165
}
6266

63-
_registrationSubject.OnNext(_registrations.Values);
67+
if (!_registrationSubject.IsDisposed)
68+
{
69+
_registrationSubject.OnNext(_registrations.Values);
70+
}
71+
6472
return Unit.Task;
6573
}
6674

6775
public void RegisterCapabilities(ServerCapabilities serverCapabilities)
6876
{
69-
foreach (var registrationOptions in LspHandlerDescriptorHelpers.GetStaticRegistrationOptions(
70-
serverCapabilities
71-
))
77+
foreach (var registrationOptions in LspHandlerDescriptorHelpers.GetStaticRegistrationOptions(serverCapabilities))
7278
{
7379
var method = _handlerTypeDescriptorProvider.GetMethodForRegistrationOptions(registrationOptions);
7480
if (method == null)
@@ -88,34 +94,30 @@ public void RegisterCapabilities(ServerCapabilities serverCapabilities)
8894
}
8995
}
9096

91-
if (serverCapabilities.Workspace == null)
97+
if (serverCapabilities.Workspace != null)
9298
{
93-
_registrationSubject.OnNext(_registrations.Values);
94-
return;
95-
}
96-
97-
foreach (var registrationOptions in LspHandlerDescriptorHelpers.GetStaticRegistrationOptions(
98-
serverCapabilities
99-
.Workspace
100-
))
101-
{
102-
var method = _handlerTypeDescriptorProvider.GetMethodForRegistrationOptions(registrationOptions);
103-
if (method == null)
99+
foreach (var registrationOptions in LspHandlerDescriptorHelpers.GetStaticRegistrationOptions(serverCapabilities.Workspace))
104100
{
105-
// TODO: Log this
106-
continue;
107-
}
108-
109-
if (registrationOptions.Id != null)
110-
{
111-
var reg = new Registration {
112-
Id = registrationOptions.Id,
113-
Method = method,
114-
RegisterOptions = registrationOptions
115-
};
116-
_registrations.AddOrUpdate(registrationOptions.Id, x => reg, (a, b) => reg);
101+
var method = _handlerTypeDescriptorProvider.GetMethodForRegistrationOptions(registrationOptions);
102+
if (method == null)
103+
{
104+
// TODO: Log this
105+
continue;
106+
}
107+
108+
if (registrationOptions.Id != null)
109+
{
110+
var reg = new Registration {
111+
Id = registrationOptions.Id,
112+
Method = method,
113+
RegisterOptions = registrationOptions
114+
};
115+
_registrations.AddOrUpdate(registrationOptions.Id, x => reg, (a, b) => reg);
116+
}
117117
}
118118
}
119+
120+
_registrationSubject.OnNext(_registrations.Values);
119121
}
120122

121123
private void Register(params Registration[] registrations)
@@ -145,7 +147,18 @@ private void Register(Registration registration)
145147
_registrations.AddOrUpdate(deserializedRegistration.Id, x => deserializedRegistration, (a, b) => deserializedRegistration);
146148
}
147149

148-
public IObservable<IEnumerable<Registration>> Registrations => _registrationSubject.AsObservable();
150+
public IObservable<IEnumerable<Registration>> Registrations
151+
{
152+
get {
153+
if (_registrationSubject.IsDisposed)
154+
{
155+
return Observable.Empty<IEnumerable<Registration>>();
156+
}
157+
158+
return _registrationSubject.AsObservable();
159+
}
160+
}
161+
149162
public IEnumerable<Registration> CurrentRegistrations => _registrations.Values;
150163

151164
public IEnumerable<Registration> GetRegistrationsForMethod(string method) => _registrations.Select(z => z.Value).Where(x => x.Method == method);
@@ -154,19 +167,25 @@ public IEnumerable<Registration> GetRegistrationsMatchingSelector(DocumentSelect
154167
_registrations
155168
.Select(z => z.Value)
156169
.Where(
157-
x => x.RegisterOptions is ITextDocumentRegistrationOptions ro && ro.DocumentSelector
158-
.Join(
159-
documentSelector,
160-
z => z.HasLanguage ? z.Language :
161-
z.HasScheme ? z.Scheme :
162-
z.HasPattern ? z.Pattern : string.Empty,
163-
z => z.HasLanguage ? z.Language :
164-
z.HasScheme ? z.Scheme :
165-
z.HasPattern ? z.Pattern : string.Empty, (a, b) => a
166-
)
167-
.Any(y => y.HasLanguage || y.HasPattern || y.HasScheme)
170+
x => x.RegisterOptions is ITextDocumentRegistrationOptions ro &&
171+
ro.DocumentSelector != null &&
172+
ro.DocumentSelector
173+
.Join(
174+
documentSelector,
175+
z => z.HasLanguage ? z.Language :
176+
z.HasScheme ? z.Scheme :
177+
z.HasPattern ? z.Pattern : string.Empty,
178+
z => z.HasLanguage ? z.Language :
179+
z.HasScheme ? z.Scheme :
180+
z.HasPattern ? z.Pattern : string.Empty, (a, b) => a
181+
)
182+
.Any(y => y.HasLanguage || y.HasPattern || y.HasScheme)
168183
);
169184

170-
public void Dispose() => _registrationSubject.Dispose();
185+
public void Dispose()
186+
{
187+
if (_registrationSubject.IsDisposed) return;
188+
_registrationSubject.Dispose();
189+
}
171190
}
172191
}

src/Client/LanguageClientWorkspaceFoldersManager.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public LanguageClientWorkspaceFoldersManager(IWorkspaceLanguageClient client, IE
3434

3535
Task<Container<WorkspaceFolder>?> IRequestHandler<WorkspaceFolderParams, Container<WorkspaceFolder>?>.
3636
Handle(WorkspaceFolderParams request, CancellationToken cancellationToken) =>
37-
Task.FromResult< Container<WorkspaceFolder>?>(new Container<WorkspaceFolder>(_workspaceFolders.Values));
37+
Task.FromResult<Container<WorkspaceFolder>?>(new Container<WorkspaceFolder>(_workspaceFolders.Values));
3838

3939
public void Add(DocumentUri uri, string name) => Add(new WorkspaceFolder { Name = name, Uri = uri });
4040

@@ -60,7 +60,10 @@ public void Add(IEnumerable<WorkspaceFolder> workspaceFolders)
6060
}
6161
}
6262
);
63-
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
63+
if (!_workspaceFoldersSubject.IsDisposed)
64+
{
65+
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
66+
}
6467
}
6568

6669
public void Remove(DocumentUri name) => Remove(_workspaceFolders.Values.Where(z => z.Uri == name));
@@ -89,13 +92,20 @@ public void Remove(IEnumerable<WorkspaceFolder> items)
8992
}
9093
}
9194
);
92-
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
95+
if (!_workspaceFoldersSubject.IsDisposed)
96+
{
97+
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
98+
}
9399
}
94100

95-
public IObservable<IEnumerable<WorkspaceFolder>> WorkspaceFolders => _workspaceFoldersSubject.AsObservable();
101+
public IObservable<IEnumerable<WorkspaceFolder>> WorkspaceFolders => _workspaceFoldersSubject.IsDisposed ? Observable.Empty<IEnumerable<WorkspaceFolder>>() : _workspaceFoldersSubject.AsObservable();
96102

97103
public IEnumerable<WorkspaceFolder> CurrentWorkspaceFolders => _workspaceFolders.Values;
98104

99-
public void Dispose() => _workspaceFoldersSubject.Dispose();
105+
public void Dispose()
106+
{
107+
if (_workspaceFoldersSubject.IsDisposed) return;
108+
_workspaceFoldersSubject.Dispose();
109+
}
100110
}
101111
}

src/Dap.Client/ProgressObservable.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,29 @@ public ProgressObservable(ProgressToken token)
2626

2727
public ProgressToken ProgressToken { get; }
2828

29-
void IObserver<ProgressEvent>.OnCompleted() => _dataSubject.OnCompleted();
29+
void IObserver<ProgressEvent>.OnCompleted()
30+
{
31+
if (_dataSubject.IsDisposed) return;
32+
_dataSubject.OnCompleted();
33+
}
3034

31-
void IObserver<ProgressEvent>.OnError(Exception error) => _dataSubject.OnError(error);
35+
void IObserver<ProgressEvent>.OnError(Exception error)
36+
{
37+
if (_dataSubject.IsDisposed) return;
38+
_dataSubject.OnError(error);
39+
}
3240

33-
public void OnNext(ProgressEvent value) => _dataSubject.OnNext(value);
41+
public void OnNext(ProgressEvent value)
42+
{
43+
if (_dataSubject.IsDisposed) return;
44+
_dataSubject.OnNext(value);
45+
}
3446

35-
public void Dispose() => _disposable.Dispose();
47+
public void Dispose()
48+
{
49+
if (_disposable.IsDisposed) return;
50+
_disposable.Dispose();
51+
}
3652

3753
public IDisposable Subscribe(IObserver<ProgressEvent> observer) => _disposable.IsDisposed ? Disposable.Empty : _dataSubject.Subscribe(observer);
3854
}

src/JsonRpc/AggregateResponse.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,23 @@
44

55
namespace OmniSharp.Extensions.JsonRpc
66
{
7-
public class AggregateResponse<T> where T : IEnumerable
7+
public class AggregateResponse<T>: IEnumerable where T : IEnumerable
88
{
99
public IEnumerable<T> Items { get; }
1010

1111
public AggregateResponse(IEnumerable<T> items) => Items = items.ToArray();
1212

1313
public AggregateResponse(IEnumerable<object> items) => Items = items.OfType<T>().ToArray();
14+
15+
public IEnumerator GetEnumerator()
16+
{
17+
foreach (var item in Items)
18+
{
19+
foreach (var v in item)
20+
{
21+
yield return v;
22+
}
23+
}
24+
}
1425
}
1526
}

src/JsonRpc/OutputHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ ILogger<OutputHandler> logger
6464

6565
public void Send(object? value)
6666
{
67-
if (_queue.IsDisposed || value == null) return;
67+
if (_queue.IsDisposed || _disposable.IsDisposed || value == null) return;
6868
_queue.OnNext(value);
6969
}
7070

src/JsonRpc/RequestRouterBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.Linq;
@@ -109,7 +110,7 @@ public virtual async Task<ErrorResponse> RouteRequest(IRequestDescriptor<TDescri
109110

110111
using var scope = _serviceScopeFactory.CreateScope();
111112
// TODO: Do we want to support more handlers as "aggregate"?
112-
if (typeof(IEnumerable<object>).IsAssignableFrom(descriptors.Default!.Response) && !typeof(JToken).IsAssignableFrom(descriptors.Default!.Response))
113+
if (typeof(IEnumerable).IsAssignableFrom(descriptors.Default!.Response) && typeof(string) != descriptors.Default!.Response && !typeof(JToken).IsAssignableFrom(descriptors.Default!.Response))
113114
{
114115
var responses = await Task.WhenAll(descriptors.Select(descriptor => InnerRoute(_serviceScopeFactory, request, descriptor, @params, token, _logger))).ConfigureAwait(false);
115116
var errorResponse = responses.FirstOrDefault(x => x.IsError);

src/JsonRpc/ResponseRouter.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,22 @@ public async Task<TResponse> Returning<TResponse>(CancellationToken cancellation
8181

8282
cancellationToken.ThrowIfCancellationRequested();
8383

84-
_router.OutputHandler.Value.Send(
85-
new OutgoingRequest {
86-
Method = _method,
87-
Params = _params,
88-
Id = nextId
89-
}
90-
);
91-
cancellationToken.Register(
92-
() => {
93-
if (tcs.Task.IsCompleted) return;
94-
_router.CancelRequest(new CancelParams { Id = nextId });
95-
}
96-
);
97-
9884
try
9985
{
86+
_router.OutputHandler.Value.Send(
87+
new OutgoingRequest {
88+
Method = _method,
89+
Params = _params,
90+
Id = nextId
91+
}
92+
);
93+
cancellationToken.Register(
94+
() => {
95+
if (tcs.Task.IsCompleted) return;
96+
_router.CancelRequest(new CancelParams { Id = nextId });
97+
}
98+
);
99+
100100
var result = await tcs.Task.ConfigureAwait(false);
101101
if (typeof(TResponse) == typeof(Unit))
102102
{
@@ -105,6 +105,10 @@ public async Task<TResponse> Returning<TResponse>(CancellationToken cancellation
105105

106106
return result.ToObject<TResponse>(_router.Serializer.JsonSerializer);
107107
}
108+
catch (ObjectDisposedException)
109+
{
110+
throw;
111+
}
108112
finally
109113
{
110114
_router.Requests.TryRemove(nextId, out _);

0 commit comments

Comments
 (0)