-
Notifications
You must be signed in to change notification settings - Fork 418
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
[Alpha] Language Server Protocol #969
Changes from 6 commits
22531ca
d89bc7b
6ae34e9
1dbdeee
379fc46
f9af5e2
e619220
a5ad0d6
247ff2a
6619ea2
87cd734
93b3b6b
d08895c
78ef0e8
6616047
8ffc10d
5fcb2b7
0e507ef
7b9cabe
483fcb0
00cfbd5
76f4555
da2075c
d214876
88cd26e
9f8afd9
2a47bce
ee0a0c5
7a6b8c9
e14fd60
7ccd1d6
b995a63
f5c0f19
a349680
5dd4421
cc34932
bbe6137
801daa4
85da6f6
be45851
e88689b
62249dc
25cafe1
541be2e
b5c9475
e5a5459
b30d431
5d8195e
215d250
4a3531f
803dab7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: InternalsVisibleTo("TestUtility")] | ||
[assembly: InternalsVisibleTo("OmniSharp")] | ||
[assembly: InternalsVisibleTo("OmniSharp.Stdio.Tests")] | ||
[assembly: InternalsVisibleTo("OmniSharp.LanguageServer.Tests")] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Linq; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using OmniSharp.Eventing; | ||
using OmniSharp.Extensions.LanguageServer; | ||
using OmniSharp.Extensions.LanguageServer.Models; | ||
using OmniSharp.Extensions.LanguageServer.Protocol; | ||
using OmniSharp.Models.Diagnostics; | ||
using OmniSharp.Models.Events; | ||
using OmniSharp.Stdio.Protocol; | ||
using OmniSharp.Stdio.Services; | ||
|
||
namespace OmniSharp.LanguageServerProtocol.Eventing | ||
{ | ||
public class LanguageServerEventEmitter : IEventEmitter | ||
{ | ||
private readonly LanguageServer _server; | ||
|
||
public LanguageServerEventEmitter(LanguageServer server) | ||
{ | ||
_server = server; | ||
} | ||
|
||
public void Emit(string kind, object args) | ||
{ | ||
switch (kind) | ||
{ | ||
case EventTypes.Diagnostic: | ||
if (args is DiagnosticMessage message) | ||
{ | ||
var groups = message.Results | ||
// TODO: Make this is correct | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what a funny comment! I don't know whether to ask you to correct the typo, or to correct the thing that needs correction. 😄 |
||
.GroupBy(z => Helpers.ToUri(z.FileName), z => z.QuickFixes); | ||
|
||
foreach (var group in groups) | ||
{ | ||
_server.PublishDiagnostics(new PublishDiagnosticsParams() | ||
{ | ||
Uri = group.Key, | ||
Diagnostics = group | ||
.SelectMany(z => z.Select(v => v.ToDiagnostic())) | ||
.ToArray() | ||
}); | ||
} | ||
} | ||
break; | ||
case EventTypes.ProjectAdded: | ||
case EventTypes.ProjectChanged: | ||
case EventTypes.ProjectRemoved: | ||
case EventTypes.Error: | ||
case EventTypes.PackageRestoreStarted: | ||
case EventTypes.PackageRestoreFinished: | ||
case EventTypes.UnresolvedDependencies: | ||
// TODO: | ||
break; | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Composition; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using OmniSharp.Extensions.LanguageServer.Capabilities.Client; | ||
using OmniSharp.Extensions.LanguageServer.Models; | ||
using OmniSharp.Extensions.LanguageServer.Protocol; | ||
using OmniSharp.Mef; | ||
using OmniSharp.Models.GotoDefinition; | ||
using static OmniSharp.LanguageServerProtocol.Helpers; | ||
|
||
namespace OmniSharp.LanguageServerProtocol.Handlers | ||
{ | ||
[Shared, Export(typeof(DefinitionHandler))] | ||
class DefinitionHandler : IDefinitionHandler | ||
{ | ||
private DefinitionCapability _capability; | ||
private readonly IRequestHandler<GotoDefinitionRequest, GotoDefinitionResponse> _definitionHandler; | ||
private readonly DocumentSelector _documentSelector; | ||
|
||
[ImportingConstructor] | ||
public DefinitionHandler(IEnumerable<IRequestHandler> handlers, DocumentSelector documentSelector) | ||
{ | ||
_definitionHandler = handlers.OfType<IRequestHandler<GotoDefinitionRequest, GotoDefinitionResponse>>().Single(); | ||
_documentSelector = documentSelector; | ||
} | ||
|
||
public TextDocumentRegistrationOptions GetRegistrationOptions() | ||
{ | ||
return new TextDocumentRegistrationOptions() | ||
{ | ||
DocumentSelector = _documentSelector | ||
}; | ||
} | ||
|
||
public async Task<LocationOrLocations> Handle(TextDocumentPositionParams request, CancellationToken token) | ||
{ | ||
var omnisharpRequest = new GotoDefinitionRequest() | ||
{ | ||
FileName = Helpers.FromUri(request.TextDocument.Uri), | ||
Column = Convert.ToInt32(request.Position.Character), | ||
Line = Convert.ToInt32(request.Position.Line) | ||
}; | ||
|
||
var omnisharpResponse = await _definitionHandler.Handle(omnisharpRequest); | ||
|
||
return new LocationOrLocations(new Location() | ||
{ | ||
Uri = Helpers.ToUri(omnisharpResponse.FileName), | ||
Range = ToRange((omnisharpResponse.Column, omnisharpResponse.Line)) | ||
}); | ||
} | ||
|
||
public void SetCapability(DefinitionCapability capability) | ||
{ | ||
_capability = capability; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,62 @@ | ||||||||
using System; | ||||||||
using System.Collections.Generic; | ||||||||
using System.Composition; | ||||||||
using System.Linq; | ||||||||
using System.Threading; | ||||||||
using System.Threading.Tasks; | ||||||||
using OmniSharp.Extensions.LanguageServer.Capabilities.Client; | ||||||||
using OmniSharp.Extensions.LanguageServer.Models; | ||||||||
using OmniSharp.Extensions.LanguageServer.Protocol; | ||||||||
using OmniSharp.Mef; | ||||||||
using OmniSharp.Models.TypeLookup; | ||||||||
|
||||||||
namespace OmniSharp.LanguageServerProtocol.Handlers | ||||||||
{ | ||||||||
[Shared, Export(typeof(HoverHandler))] | ||||||||
class HoverHandler : IHoverHandler | ||||||||
{ | ||||||||
private HoverCapability _capability; | ||||||||
private readonly IRequestHandler<TypeLookupRequest, TypeLookupResponse> _definitionHandler; | ||||||||
private readonly DocumentSelector _documentSelector; | ||||||||
|
||||||||
[ImportingConstructor] | ||||||||
public HoverHandler(IEnumerable<IRequestHandler> handlers, DocumentSelector documentSelector) | ||||||||
{ | ||||||||
_definitionHandler = handlers.OfType<IRequestHandler<TypeLookupRequest, TypeLookupResponse>>().Single(); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is multiple languages supported? E.g. in the Cake PR we register a second handler of this type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I came to that realization last night, and added a comment about changing that around. I'll be thinking about that today and probably figure out a decent solution fairly soon. The note wasn't near that code however omnisharp-roslyn/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs Lines 105 to 107 in f9af5e2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great! This is how we currently resolve |
||||||||
_documentSelector = documentSelector; | ||||||||
} | ||||||||
|
||||||||
public TextDocumentRegistrationOptions GetRegistrationOptions() | ||||||||
{ | ||||||||
return new TextDocumentRegistrationOptions() | ||||||||
{ | ||||||||
DocumentSelector = _documentSelector | ||||||||
}; | ||||||||
} | ||||||||
|
||||||||
public async Task<Hover> Handle(TextDocumentPositionParams request, CancellationToken token) | ||||||||
{ | ||||||||
var omnisharpRequest = new TypeLookupRequest() | ||||||||
{ | ||||||||
FileName = Helpers.FromUri(request.TextDocument.Uri), | ||||||||
Column = Convert.ToInt32(request.Position.Character), | ||||||||
Line = Convert.ToInt32(request.Position.Line), | ||||||||
IncludeDocumentation = true | ||||||||
}; | ||||||||
|
||||||||
var omnisharpResponse = await _definitionHandler.Handle(omnisharpRequest); | ||||||||
|
||||||||
return new Hover() | ||||||||
{ | ||||||||
// TODO: Range? We don't currently have that! | ||||||||
// Range = | ||||||||
Contents = new MarkedStringContainer(omnisharpResponse.Type, omnisharpResponse.Documentation) | ||||||||
}; | ||||||||
} | ||||||||
|
||||||||
public void SetCapability(HoverCapability capability) | ||||||||
{ | ||||||||
_capability = capability; | ||||||||
} | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a case-insensitive comparison?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command line stuff specifically uses lowercase, but I'll change in case that ever changes.