diff --git a/CHANGELOG.md b/CHANGELOG.md index fbf505a8f2..0ff52c9511 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All changes to the project will be documented in this file. ## [1.34.3] - not yet released * Added support for `CheckForOverflowUnderflow ` in csproj files (PR: [#1587](https://github.com/OmniSharp/omnisharp-roslyn/pull/1587)) +* Updated LSP libraries to 0.13 which fixes problems with clients not supporting dynamic registrations. ([#1505](https://github.com/OmniSharp/omnisharp-roslyn/issues/1505), [#1525](https://github.com/OmniSharp/omnisharp-roslyn/issues/1525), PR: [#1562](https://github.com/OmniSharp/omnisharp-roslyn/pull/1562)) ## [1.34.2] - 2019-08-16 * Update to Roslyn `3.3.0-beta2-19401-05` which fixes a 1.34.1 regression resulting in StackOverflowException on code analysis of partial classes (PR: [#1579](https://github.com/OmniSharp/omnisharp-roslyn/pull/1579)) diff --git a/build/Packages.props b/build/Packages.props index 4bd771e31e..8003e4f04b 100644 --- a/build/Packages.props +++ b/build/Packages.props @@ -63,7 +63,7 @@ - + diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/CodeLensHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeLensHandler.cs similarity index 75% rename from src/OmniSharp.LanguageServerProtocol/Handlers/CodeLensHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeLensHandler.cs index a1f58e1c74..9b79e8da0b 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/CodeLensHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeLensHandler.cs @@ -15,7 +15,7 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - internal sealed class CodeLensHandler : ICodeLensHandler, ICodeLensResolveHandler + internal sealed class OmniSharpCodeLensHandler : CodeLensHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { @@ -24,26 +24,28 @@ public static IEnumerable Enumerate(RequestHandlers handlers) Mef.IRequestHandler, Mef.IRequestHandler>()) { - yield return new CodeLensHandler(membersAsTreeHandler, findUsagesHandler, selector); + yield return new OmniSharpCodeLensHandler(membersAsTreeHandler, findUsagesHandler, selector); } } - private CodeLensCapability _capability; private readonly Mef.IRequestHandler _membersAsTreeHandler; private readonly Mef.IRequestHandler _findUsagesHandler; - private readonly DocumentSelector _documentSelector; - public CodeLensHandler( + public OmniSharpCodeLensHandler( Mef.IRequestHandler membersAsTreeHandler, Mef.IRequestHandler findUsagesHandler, DocumentSelector documentSelector) + : base(new CodeLensRegistrationOptions() + { + DocumentSelector = documentSelector, + ResolveProvider = true + }) { _membersAsTreeHandler = membersAsTreeHandler; _findUsagesHandler = findUsagesHandler; - _documentSelector = documentSelector; } - public async Task Handle(CodeLensParams request, CancellationToken token) + public async override Task Handle(CodeLensParams request, CancellationToken token) { var omnisharpRequest = new MembersTreeRequest() { @@ -61,13 +63,13 @@ public async Task Handle(CodeLensParams request, Cancellation return codeLenseContainer; } - public async Task Handle(CodeLens request, CancellationToken token) + public async override Task Handle(CodeLens request, CancellationToken token) { var omnisharpRequest = new FindUsagesRequest { FileName = Helpers.FromUri(request.Data.ToObject()), - Column = (int) request.Range.Start.Character, - Line = (int) request.Range.Start.Line, + Column = (int)request.Range.Start.Character, + Line = (int)request.Range.Start.Line, OnlyThisFile = false, ExcludeDefinition = true }; @@ -85,21 +87,6 @@ public async Task Handle(CodeLens request, CancellationToken token) return request; } - - public CodeLensRegistrationOptions GetRegistrationOptions() - { - return new CodeLensRegistrationOptions() - { - DocumentSelector = _documentSelector, - ResolveProvider = true - }; - } - - public void SetCapability(CodeLensCapability capability) - { - _capability = capability; - } - private static void ToCodeLens(TextDocumentIdentifier textDocument, FileMemberElement node, List codeLensContainer) { var codeLens = new CodeLens @@ -121,12 +108,12 @@ private static void ToCodeLens(TextDocumentIdentifier textDocument, FileMemberEl } } - public bool CanResolve(CodeLens value) + public override bool CanResolve(CodeLens value) { var textDocumentUri = value.Data.ToObject(); return textDocumentUri != null && - _documentSelector.IsMatch(new TextDocumentAttributes(textDocumentUri, string.Empty)); + GetRegistrationOptions().DocumentSelector.IsMatch(new TextDocumentAttributes(textDocumentUri, string.Empty)); } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/CompletionHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCompletionHandler.cs similarity index 76% rename from src/OmniSharp.LanguageServerProtocol/Handlers/CompletionHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCompletionHandler.cs index a16b34250f..620093cf37 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/CompletionHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCompletionHandler.cs @@ -10,7 +10,7 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - class CompletionHandler : ICompletionHandler + class OmniSharpCompletionHandler : CompletionHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { @@ -18,12 +18,10 @@ public static IEnumerable Enumerate(RequestHandlers handlers) foreach (var (selector, handler) in handlers .OfType>>()) if (handler != null) - yield return new CompletionHandler(handler, selector); + yield return new OmniSharpCompletionHandler(handler, selector); } - private CompletionCapability _capability; private readonly Mef.IRequestHandler> _autoCompleteHandler; - private readonly DocumentSelector _documentSelector; private static readonly IDictionary _kind = new Dictionary{ // types @@ -58,20 +56,26 @@ private static CompletionItemKind GetCompletionItemKind(string key) { return CompletionItemKind.Property; } - if(_kind.TryGetValue(key, out var completionItemKind)) + if (_kind.TryGetValue(key, out var completionItemKind)) { return completionItemKind; } return CompletionItemKind.Property; } - public CompletionHandler(Mef.IRequestHandler> autoCompleteHandler, DocumentSelector documentSelector) + public OmniSharpCompletionHandler(Mef.IRequestHandler> autoCompleteHandler, DocumentSelector documentSelector) + : base(new CompletionRegistrationOptions() + { + DocumentSelector = documentSelector, + // TODO: Come along and add a service for getting autocompletion details after the fact. + ResolveProvider = false, + TriggerCharacters = new[] { ".", }, + }) { _autoCompleteHandler = autoCompleteHandler; - _documentSelector = documentSelector; } - public async Task Handle(CompletionParams request, CancellationToken token) + public async override Task Handle(CompletionParams request, CancellationToken token) { var omnisharpRequest = new AutoCompleteRequest() { @@ -81,7 +85,7 @@ public async Task Handle(CompletionParams request, CancellationT WantKind = true, WantDocumentationForEveryCompletionResult = true, WantReturnType = true, - WantSnippet =_capability.CompletionItem?.SnippetSupport ?? false + WantSnippet = Capability.CompletionItem?.SnippetSupport ?? false }; var omnisharpResponse = await _autoCompleteHandler.Handle(omnisharpRequest); @@ -89,11 +93,12 @@ public async Task Handle(CompletionParams request, CancellationT var completions = new Dictionary>(); foreach (var response in omnisharpResponse) { - var isSnippet = !string.IsNullOrEmpty(response.Snippet); - var text = isSnippet ? response.Snippet : response.CompletionText; + var isSnippet = !string.IsNullOrEmpty(response.Snippet); + var text = isSnippet ? response.Snippet : response.CompletionText; var textFormat = isSnippet ? InsertTextFormat.Snippet : InsertTextFormat.PlainText; - var completionItem = new CompletionItem { + var completionItem = new CompletionItem + { Label = response.CompletionText, Detail = !string.IsNullOrEmpty(response.ReturnType) ? response.DisplayText : @@ -104,7 +109,7 @@ public async Task Handle(CompletionParams request, CancellationT InsertTextFormat = textFormat, }; - if(!completions.ContainsKey(completionItem.Label)) + if (!completions.ContainsKey(completionItem.Label)) { completions[completionItem.Label] = new List(); } @@ -129,18 +134,14 @@ public async Task Handle(CompletionParams request, CancellationT return new CompletionList(result); } - public CompletionRegistrationOptions GetRegistrationOptions() + public override Task Handle(CompletionItem request, CancellationToken cancellationToken) { - return new CompletionRegistrationOptions() - { - DocumentSelector = _documentSelector, - TriggerCharacters = new[] { "." }, - }; + throw new NotImplementedException(); } - public void SetCapability(CompletionCapability capability) + public override bool CanResolve(CompletionItem value) { - _capability = capability; + return false; } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/DefinitionHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDefinitionHandler.cs similarity index 66% rename from src/OmniSharp.LanguageServerProtocol/Handlers/DefinitionHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDefinitionHandler.cs index bcbd817109..42003e07b4 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/DefinitionHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDefinitionHandler.cs @@ -11,34 +11,27 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - class DefinitionHandler : IDefinitionHandler + class OmniSharpDefinitionHandler : DefinitionHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { foreach (var (selector, handler) in handlers.OfType>()) if (handler != null) - yield return new DefinitionHandler(handler, selector); + yield return new OmniSharpDefinitionHandler(handler, selector); } - private DefinitionCapability _capability; private readonly Mef.IRequestHandler _definitionHandler; - private readonly DocumentSelector _documentSelector; - public DefinitionHandler(Mef.IRequestHandler definitionHandler, DocumentSelector documentSelector) + public OmniSharpDefinitionHandler(Mef.IRequestHandler definitionHandler, DocumentSelector documentSelector) + : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector + }) { _definitionHandler = definitionHandler; - _documentSelector = documentSelector; } - public TextDocumentRegistrationOptions GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector - }; - } - - public async Task Handle(DefinitionParams request, CancellationToken token) + public async override Task Handle(DefinitionParams request, CancellationToken token) { var omnisharpRequest = new GotoDefinitionRequest() { @@ -60,10 +53,5 @@ public async Task Handle(DefinitionParams request, Canc Range = ToRange((omnisharpResponse.Column, omnisharpResponse.Line)) }); } - - public void SetCapability(DefinitionCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormatRangeHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormatRangeHandler.cs new file mode 100644 index 0000000000..28c7ef90bd --- /dev/null +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormatRangeHandler.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using OmniSharp.Models.Format; + +namespace OmniSharp.LanguageServerProtocol.Handlers +{ + internal sealed class OmniSharpDocumentFormatRangeHandler : DocumentRangeFormattingHandler + { + public static IEnumerable Enumerate(RequestHandlers handlers) + { + foreach (var (selector, handler) in handlers + .OfType>()) + if (handler != null) + yield return new OmniSharpDocumentFormatRangeHandler(handler, selector); + } + + private readonly Mef.IRequestHandler _formatRangeHandler; + + public OmniSharpDocumentFormatRangeHandler(Mef.IRequestHandler formatRangeHandler, DocumentSelector documentSelector) : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector, + }) + { + _formatRangeHandler = formatRangeHandler; + } + + public async override Task Handle(DocumentRangeFormattingParams request, CancellationToken cancellationToken) + { + var omnisharpRequest = new FormatRangeRequest() + { + FileName = Helpers.FromUri(request.TextDocument.Uri), + Line = Convert.ToInt32(request.Range.Start.Line), + Column = Convert.ToInt32(request.Range.Start.Character), + EndLine = Convert.ToInt32(request.Range.End.Line), + EndColumn = Convert.ToInt32(request.Range.End.Character), + }; + + var omnisharpResponse = await _formatRangeHandler.Handle(omnisharpRequest); + return omnisharpResponse.Changes.Select(change => new TextEdit() + { + NewText = change.NewText, + Range = new Range(new Position(change.StartLine, change.StartColumn), new Position(change.EndLine, change.EndColumn)) + }).ToArray(); + } + } +} diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormattingHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormattingHandler.cs new file mode 100644 index 0000000000..eee8d46c7e --- /dev/null +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentFormattingHandler.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using OmniSharp.Models.CodeFormat; +using OmniSharp.Models.MembersTree; +using OmniSharp.Models.V2.CodeStructure; + +namespace OmniSharp.LanguageServerProtocol.Handlers +{ + internal sealed class OmniSharpDocumentFormattingHandler : DocumentFormattingHandler + { + public static IEnumerable Enumerate(RequestHandlers handlers) + { + foreach (var (selector, handler) in handlers + .OfType>()) + if (handler != null) + yield return new OmniSharpDocumentFormattingHandler(handler, selector); + } + + private readonly Mef.IRequestHandler _codeFormatHandler; + + public OmniSharpDocumentFormattingHandler(Mef.IRequestHandler codeFormatHandler, DocumentSelector documentSelector) : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector, + }) + { + _codeFormatHandler = codeFormatHandler; + } + + public async override Task Handle(DocumentFormattingParams request, CancellationToken cancellationToken) + { + var omnisharpRequest = new CodeFormatRequest() + { + FileName = Helpers.FromUri(request.TextDocument.Uri), + WantsTextChanges = true + }; + + var omnisharpResponse = await _codeFormatHandler.Handle(omnisharpRequest); + return omnisharpResponse.Changes.Select(change => new TextEdit() + { + NewText = change.NewText, + Range = new Range(new Position(change.StartLine, change.StartColumn), new Position(change.EndLine, change.EndColumn)) + }).ToArray(); + } + } +} diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentOnTypeFormatHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentOnTypeFormatHandler.cs new file mode 100644 index 0000000000..8869f592d8 --- /dev/null +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentOnTypeFormatHandler.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using OmniSharp.Models.Format; + +namespace OmniSharp.LanguageServerProtocol.Handlers +{ + internal sealed class OmniSharpDocumentOnTypeFormatHandler : DocumentOnTypeFormatHandler + { + public static IEnumerable Enumerate(RequestHandlers handlers) + { + foreach (var (selector, handler) in handlers + .OfType>()) + if (handler != null) + yield return new OmniSharpDocumentOnTypeFormatHandler(handler, selector); + } + + private readonly Mef.IRequestHandler _formatAfterKeystrokeHandler; + + public OmniSharpDocumentOnTypeFormatHandler(Mef.IRequestHandler formatAfterKeystrokeHandler, DocumentSelector documentSelector) : base(new DocumentOnTypeFormattingRegistrationOptions() + { + DocumentSelector = documentSelector, + FirstTriggerCharacter = ";", + // TODO: What should these be? + MoreTriggerCharacter = new[] { "}", ")" } + }) + { + _formatAfterKeystrokeHandler = formatAfterKeystrokeHandler; + } + + public async override Task Handle(DocumentOnTypeFormattingParams request, CancellationToken cancellationToken) + { + // TODO: request.options + var omnisharpRequest = new FormatAfterKeystrokeRequest() + { + Character = request.Character, + Line = Convert.ToInt32(request.Position.Line), + Column = Convert.ToInt32(request.Position.Character), + FileName = Helpers.FromUri(request.TextDocument.Uri), + }; + + var omnisharpResponse = await _formatAfterKeystrokeHandler.Handle(omnisharpRequest); + return omnisharpResponse.Changes.Select(change => new TextEdit() + { + NewText = change.NewText, + Range = new Range(new Position(change.StartLine, change.StartColumn), new Position(change.EndLine, change.EndColumn)) + }).ToArray(); + } + } +} diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/DocumentSymbolHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentSymbolHandler.cs similarity index 79% rename from src/OmniSharp.LanguageServerProtocol/Handlers/DocumentSymbolHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentSymbolHandler.cs index a6ac4c6a08..73af1e33fb 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/DocumentSymbolHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpDocumentSymbolHandler.cs @@ -12,19 +12,17 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - internal sealed class DocumentSymbolHandler : IDocumentSymbolHandler + internal sealed class OmniSharpDocumentSymbolHandler : DocumentSymbolHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { foreach (var (selector, handler) in handlers .OfType>()) if (handler != null) - yield return new DocumentSymbolHandler(handler, selector); + yield return new OmniSharpDocumentSymbolHandler(handler, selector); } - private DocumentSymbolCapability _capability; private readonly Mef.IRequestHandler _codeStructureHandler; - private readonly DocumentSelector _documentSelector; private static readonly IDictionary Kinds = new Dictionary { @@ -46,13 +44,16 @@ public static IEnumerable Enumerate(RequestHandlers handlers) { OmniSharp.Models.V2.SymbolKinds.Unknown, SymbolKind.Class }, }; - public DocumentSymbolHandler(Mef.IRequestHandler codeStructureHandler, DocumentSelector documentSelector) + public OmniSharpDocumentSymbolHandler(Mef.IRequestHandler codeStructureHandler, DocumentSelector documentSelector) + : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector + }) { _codeStructureHandler = codeStructureHandler; - _documentSelector = documentSelector; } - public async Task Handle(DocumentSymbolParams request, CancellationToken token) + public async override Task Handle(DocumentSymbolParams request, CancellationToken token) { var omnisharpRequest = new CodeStructureRequest() { @@ -65,19 +66,6 @@ public async Task Handle(DocumentSym Array.Empty(); } - public TextDocumentRegistrationOptions GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector - }; - } - - public void SetCapability(DocumentSymbolCapability capability) - { - _capability = capability; - } - private static SymbolInformationOrDocumentSymbol ToDocumentSymbolInformationOrDocumentSymbol(CodeElement node) { return new SymbolInformationOrDocumentSymbol(ToDocumentSymbol(node)); diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/HoverHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpHoverHandler.cs similarity index 67% rename from src/OmniSharp.LanguageServerProtocol/Handlers/HoverHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpHoverHandler.cs index 38a53d7781..7aee8060a4 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/HoverHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpHoverHandler.cs @@ -10,35 +10,28 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - class HoverHandler : IHoverHandler + class OmniSharpHoverHandler : HoverHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { foreach (var (selector, handler) in handlers .OfType>()) if (handler != null) - yield return new HoverHandler(handler, selector); + yield return new OmniSharpHoverHandler(handler, selector); } - private HoverCapability _capability; private readonly Mef.IRequestHandler _definitionHandler; - private readonly DocumentSelector _documentSelector; - public HoverHandler(Mef.IRequestHandler definitionHandler, DocumentSelector documentSelector) + public OmniSharpHoverHandler(Mef.IRequestHandler definitionHandler, DocumentSelector documentSelector) + : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector + }) { _definitionHandler = definitionHandler; - _documentSelector = documentSelector; } - public TextDocumentRegistrationOptions GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector - }; - } - - public async Task Handle(HoverParams request, CancellationToken token) + public async override Task Handle(HoverParams request, CancellationToken token) { var omnisharpRequest = new TypeLookupRequest() { @@ -57,10 +50,5 @@ public async Task Handle(HoverParams request, CancellationToken token) Contents = new MarkedStringsOrMarkupContent(new MarkedStringContainer(Helpers.EscapeMarkdown(omnisharpResponse.Type), Helpers.EscapeMarkdown(omnisharpResponse.Documentation))) }; } - - public void SetCapability(HoverCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/ReferencesHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpReferencesHandler.cs similarity index 65% rename from src/OmniSharp.LanguageServerProtocol/Handlers/ReferencesHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpReferencesHandler.cs index 310fb7df1e..98ab2c1339 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/ReferencesHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpReferencesHandler.cs @@ -12,27 +12,28 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - internal sealed class ReferencesHandler : IReferencesHandler + internal sealed class OmniSharpReferencesHandler : ReferencesHandler { public static IEnumerable Enumerate(RequestHandlers handlers) { foreach (var (selector, handler) in handlers .OfType>()) if (handler != null) - yield return new ReferencesHandler(handler, selector); + yield return new OmniSharpReferencesHandler(handler, selector); } - private ReferencesCapability _capability; private readonly Mef.IRequestHandler _findUsagesHandler; - private readonly DocumentSelector _documentSelector; - public ReferencesHandler(Mef.IRequestHandler findUsagesHandler, DocumentSelector documentSelector) + public OmniSharpReferencesHandler(Mef.IRequestHandler findUsagesHandler, DocumentSelector documentSelector) + : base(new TextDocumentRegistrationOptions() + { + DocumentSelector = documentSelector + }) { _findUsagesHandler = findUsagesHandler; - _documentSelector = documentSelector; } - public async Task Handle(ReferenceParams request, CancellationToken token) + public async override Task Handle(ReferenceParams request, CancellationToken token) { var omnisharpRequest = new FindUsagesRequest { @@ -51,18 +52,5 @@ public async Task Handle(ReferenceParams request, Cancellatio Range = x.ToRange() }).ToArray(); } - - public TextDocumentRegistrationOptions GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector - }; - } - - public void SetCapability(ReferencesCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/RenameHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpRenameHandler.cs similarity index 70% rename from src/OmniSharp.LanguageServerProtocol/Handlers/RenameHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpRenameHandler.cs index 647b599717..9f33960399 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/RenameHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpRenameHandler.cs @@ -11,16 +11,18 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - internal class RenameHandler : IRenameHandler + internal class OmniSharpRenameHandler : RenameHandler { private readonly Mef.IRequestHandler _renameHandler; - private readonly DocumentSelector _documentSelector; - private RenameCapability _capability; - public RenameHandler(Mef.IRequestHandler renameHandler, DocumentSelector documentSelector) + public OmniSharpRenameHandler(Mef.IRequestHandler renameHandler, DocumentSelector documentSelector) + : base(new RenameRegistrationOptions() + { + DocumentSelector = documentSelector, + PrepareProvider = false + }) { _renameHandler = renameHandler; - _documentSelector = documentSelector; } public static IEnumerable Enumerate(RequestHandlers handlers) @@ -28,10 +30,10 @@ public static IEnumerable Enumerate(RequestHandlers handlers) foreach (var (selector, handler) in handlers .OfType>()) if (handler != null) - yield return new RenameHandler(handler, selector); + yield return new OmniSharpRenameHandler(handler, selector); } - public async Task Handle(RenameParams request, CancellationToken token) + public async override Task Handle(RenameParams request, CancellationToken token) { var omnisharpRequest = new RenameRequest { @@ -51,7 +53,7 @@ public async Task Handle(RenameParams request, CancellationToken return new WorkspaceEdit(); } - var changes = omnisharpResponse.Changes.ToDictionary(change => + var changes = omnisharpResponse.Changes.ToDictionary(change => Helpers.ToUri(change.FileName), x => x.Changes.Select(edit => new TextEdit { @@ -64,18 +66,5 @@ public async Task Handle(RenameParams request, CancellationToken Changes = changes }; } - - public RenameRegistrationOptions GetRegistrationOptions() - { - return new RenameRegistrationOptions - { - DocumentSelector = _documentSelector - }; - } - - public void SetCapability(RenameCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/SignatureHelpHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpSignatureHelpHandler.cs similarity index 71% rename from src/OmniSharp.LanguageServerProtocol/Handlers/SignatureHelpHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpSignatureHelpHandler.cs index 0382118165..76a748c15a 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/SignatureHelpHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpSignatureHelpHandler.cs @@ -11,16 +11,18 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - internal class SignatureHelpHandler : ISignatureHelpHandler + internal class OmniSharpSignatureHelpHandler : SignatureHelpHandler { private readonly Mef.IRequestHandler _signatureHandler; - private readonly DocumentSelector _documentSelector; - private SignatureHelpCapability _capability; - public SignatureHelpHandler(Mef.IRequestHandler signatureHandler, DocumentSelector documentSelector) + public OmniSharpSignatureHelpHandler(Mef.IRequestHandler signatureHandler, DocumentSelector documentSelector) + : base(new SignatureHelpRegistrationOptions() + { + DocumentSelector = documentSelector, + TriggerCharacters = new[] { ".", "?", "[" } + }) { _signatureHandler = signatureHandler; - _documentSelector = documentSelector; } public static IEnumerable Enumerate(RequestHandlers handlers) @@ -28,10 +30,10 @@ public static IEnumerable Enumerate(RequestHandlers handlers) foreach (var (selector, handler) in handlers .OfType>()) if (handler != null) - yield return new SignatureHelpHandler(handler, selector); + yield return new OmniSharpSignatureHelpHandler(handler, selector); } - public async Task Handle(SignatureHelpParams request, CancellationToken token) + public async override Task Handle(SignatureHelpParams request, CancellationToken token) { var omnisharpRequest = new SignatureHelpRequest { @@ -67,18 +69,5 @@ public async Task Handle(SignatureHelpParams request, Cancellatio Signatures = signatures }; } - - public SignatureHelpRegistrationOptions GetRegistrationOptions() - { - return new SignatureHelpRegistrationOptions - { - DocumentSelector = _documentSelector - }; - } - - public void SetCapability(SignatureHelpCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/TextDocumentSyncHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpTextDocumentSyncHandler.cs similarity index 70% rename from src/OmniSharp.LanguageServerProtocol/Handlers/TextDocumentSyncHandler.cs rename to src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpTextDocumentSyncHandler.cs index 5669e3082c..c4f4b39975 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/TextDocumentSyncHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpTextDocumentSyncHandler.cs @@ -18,7 +18,7 @@ namespace OmniSharp.LanguageServerProtocol.Handlers { - class TextDocumentSyncHandler : ITextDocumentSyncHandler + class OmniSharpTextDocumentSyncHandler : TextDocumentSyncHandler { public static IEnumerable Enumerate( RequestHandlers handlers, @@ -33,44 +33,43 @@ public static IEnumerable Enumerate( // TODO: Fix once cake has working support for incremental var documentSyncKind = TextDocumentSyncKind.Incremental; if (selector.ToString().IndexOf(".cake") > -1) documentSyncKind = TextDocumentSyncKind.Full; - yield return new TextDocumentSyncHandler(openHandler, closeHandler, bufferHandler, selector, documentSyncKind, workspace); + yield return new OmniSharpTextDocumentSyncHandler(openHandler, closeHandler, bufferHandler, selector, documentSyncKind, workspace); } } // TODO Make this configurable? - private readonly DocumentSelector _documentSelector; - private SynchronizationCapability _capability; private readonly Mef.IRequestHandler _openHandler; private readonly Mef.IRequestHandler _closeHandler; private readonly Mef.IRequestHandler _bufferHandler; private readonly OmniSharpWorkspace _workspace; - public TextDocumentSyncHandler( + public OmniSharpTextDocumentSyncHandler( Mef.IRequestHandler openHandler, Mef.IRequestHandler closeHandler, Mef.IRequestHandler bufferHandler, DocumentSelector documentSelector, TextDocumentSyncKind documentSyncKind, OmniSharpWorkspace workspace) + : base(documentSyncKind, new TextDocumentSaveRegistrationOptions() + { + DocumentSelector = documentSelector, + IncludeText = true, + }) { _openHandler = openHandler; _closeHandler = closeHandler; _bufferHandler = bufferHandler; _workspace = workspace; - _documentSelector = documentSelector; - Change = documentSyncKind; } - public TextDocumentSyncKind Change { get; } - - public TextDocumentAttributes GetTextDocumentAttributes(Uri uri) + public override TextDocumentAttributes GetTextDocumentAttributes(Uri uri) { var document = _workspace.GetDocument(Helpers.FromUri(uri)); if (document == null) return new TextDocumentAttributes(uri, ""); return new TextDocumentAttributes(uri, ""); } - public async Task Handle(DidChangeTextDocumentParams notification, CancellationToken cancellationToken) + public async override Task Handle(DidChangeTextDocumentParams notification, CancellationToken cancellationToken) { var contentChanges = notification.ContentChanges.ToArray(); if (contentChanges.Length == 1 && contentChanges[0].Range == null) @@ -105,7 +104,7 @@ await _bufferHandler.Handle(new UpdateBufferRequest() return Unit.Value; } - public async Task Handle(DidOpenTextDocumentParams notification, CancellationToken cancellationToken) + public async override Task Handle(DidOpenTextDocumentParams notification, CancellationToken cancellationToken) { if (_openHandler != null) { @@ -119,7 +118,7 @@ await _openHandler.Handle(new FileOpenRequest() return Unit.Value; } - public async Task Handle(DidCloseTextDocumentParams notification, CancellationToken cancellationToken) + public async override Task Handle(DidCloseTextDocumentParams notification, CancellationToken cancellationToken) { if (_closeHandler != null) { @@ -132,9 +131,9 @@ await _closeHandler.Handle(new FileCloseRequest() return Unit.Value; } - public async Task Handle(DidSaveTextDocumentParams notification, CancellationToken cancellationToken) + public async override Task Handle(DidSaveTextDocumentParams notification, CancellationToken cancellationToken) { - if (_capability?.DidSave == true) + if (Capability?.DidSave == true) { await _bufferHandler.Handle(new UpdateBufferRequest() { @@ -144,36 +143,5 @@ await _bufferHandler.Handle(new UpdateBufferRequest() } return Unit.Value; } - - TextDocumentChangeRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentChangeRegistrationOptions() - { - DocumentSelector = _documentSelector, - SyncKind = Change - }; - } - - TextDocumentRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector, - }; - } - - TextDocumentSaveRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentSaveRegistrationOptions() - { - DocumentSelector = _documentSelector, - IncludeText = true - }; - } - - public void SetCapability(SynchronizationCapability capability) - { - _capability = capability; - } } } diff --git a/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs b/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs index 9402f16120..e5a6662283 100644 --- a/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs +++ b/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs @@ -153,15 +153,18 @@ private Task Initialize(Extensions.LanguageServer.Server.ILanguageServer server, var workspace = _compositionHost.GetExport(); _compositionHost.GetExport().IsEnabled = true; - foreach (var handler in TextDocumentSyncHandler.Enumerate(_handlers, workspace) - .Concat(DefinitionHandler.Enumerate(_handlers)) - .Concat(HoverHandler.Enumerate(_handlers)) - .Concat(CompletionHandler.Enumerate(_handlers)) - .Concat(SignatureHelpHandler.Enumerate(_handlers)) - .Concat(RenameHandler.Enumerate(_handlers)) - .Concat(DocumentSymbolHandler.Enumerate(_handlers)) - .Concat(ReferencesHandler.Enumerate(_handlers)) - .Concat(CodeLensHandler.Enumerate(_handlers))) + foreach (var handler in OmniSharpTextDocumentSyncHandler.Enumerate(_handlers, workspace) + .Concat(OmniSharpDefinitionHandler.Enumerate(_handlers)) + .Concat(OmniSharpHoverHandler.Enumerate(_handlers)) + .Concat(OmniSharpCompletionHandler.Enumerate(_handlers)) + .Concat(OmniSharpSignatureHelpHandler.Enumerate(_handlers)) + .Concat(OmniSharpRenameHandler.Enumerate(_handlers)) + .Concat(OmniSharpDocumentSymbolHandler.Enumerate(_handlers)) + .Concat(OmniSharpReferencesHandler.Enumerate(_handlers)) + .Concat(OmniSharpCodeLensHandler.Enumerate(_handlers)) + .Concat(OmniSharpDocumentFormattingHandler.Enumerate(_handlers)) + .Concat(OmniSharpDocumentFormatRangeHandler.Enumerate(_handlers)) + .Concat(OmniSharpDocumentOnTypeFormatHandler.Enumerate(_handlers))) { server.AddHandlers(handler); } diff --git a/tests/OmniSharp.MSBuild.Tests/ProjectWithComplexAnalyzersTests.cs b/tests/OmniSharp.MSBuild.Tests/ProjectWithComplexAnalyzersTests.cs index a8ec00e1e5..4a19dd8833 100644 --- a/tests/OmniSharp.MSBuild.Tests/ProjectWithComplexAnalyzersTests.cs +++ b/tests/OmniSharp.MSBuild.Tests/ProjectWithComplexAnalyzersTests.cs @@ -12,7 +12,8 @@ public ProjectWithComplexAnalyzersTests(ITestOutputHelper output) : base(output) { } - [Fact] + // possible thread starvation on *nix when running in Azure DevOps + [ConditionalFact(typeof(WindowsOnly))] public async Task CanLoadComplexAnalyzers() { using (var testProject = await TestAssets.Instance.GetTestProjectAsync("ProjectWithComplexAnalyzers")) diff --git a/tests/TestUtility/ConditionalFactAttribute.cs b/tests/TestUtility/ConditionalFactAttribute.cs index 6d2f7bd5df..69ebe89c80 100644 --- a/tests/TestUtility/ConditionalFactAttribute.cs +++ b/tests/TestUtility/ConditionalFactAttribute.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; using OmniSharp.Utilities; using Xunit;