Skip to content
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

Merged
merged 51 commits into from
Jan 9, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
22531ca
started on lsp
david-driscoll Sep 23, 2017
d89bc7b
Fixed it so things actually start kind of...
david-driscoll Sep 23, 2017
6ae34e9
fixed issue where server wasn't starting
david-driscoll Sep 24, 2017
1dbdeee
Fixed issue with path not being return correctly from helper method
david-driscoll Sep 25, 2017
379fc46
Split out definition handler and created handlers folder
david-driscoll Sep 25, 2017
f9af5e2
Cleaned up logging. Added range helper. Added hover handler
david-driscoll Sep 25, 2017
e619220
Added support for multiple languages, and create the document selecto…
david-driscoll Oct 7, 2017
a5ad0d6
Merge latest changes
david-driscoll Oct 7, 2017
247ff2a
Updated how handlers will resolve with multiple languages
david-driscoll Oct 7, 2017
6619ea2
Update to latest version of lsp
david-driscoll Oct 8, 2017
87cd734
Updated to latest lsp package
david-driscoll Oct 8, 2017
93b3b6b
fixed orientation for position elements so that goto definition works…
david-driscoll Oct 8, 2017
d08895c
Adds CompletionHandler.
bjorkstromm Oct 9, 2017
78ef0e8
Merge pull request #977 from mholo65/lsp-completionhandler
david-driscoll Oct 10, 2017
6616047
Updated to latest master
david-driscoll Oct 10, 2017
8ffc10d
Updated to latest lsp
david-driscoll Oct 10, 2017
5fcb2b7
Merge branch 'master' into lsp
david-driscoll Oct 15, 2017
0e507ef
Fixed language server host to use latest lsp library
david-driscoll Oct 16, 2017
7b9cabe
Use a custom logger factory to ignore any additional providers when u…
david-driscoll Oct 16, 2017
483fcb0
fixed lsp logger
david-driscoll Oct 16, 2017
00cfbd5
Merge branch 'master' into lsp
DustinCampbell Oct 18, 2017
76f4555
Merge branch 'master' into lsp
DustinCampbell Oct 19, 2017
da2075c
Updated to latest server library... fixed an issue with method not fo…
david-driscoll Oct 19, 2017
d214876
Adds SignatureHelpHandler
RLittlesII Oct 19, 2017
88cd26e
Merge pull request #986 from RLittlesII/signature-help
david-driscoll Oct 25, 2017
9f8afd9
react to feedback
david-driscoll Oct 25, 2017
2a47bce
Merge branch 'lsp' of github.com:OmniSharp/omnisharp-roslyn into lsp
david-driscoll Oct 25, 2017
ee0a0c5
merge with master
david-driscoll Oct 25, 2017
7a6b8c9
Updated lsp version
david-driscoll Oct 25, 2017
e14fd60
Added additional trace logging, removed unneeded MEF attributes from …
david-driscoll Oct 26, 2017
7ccd1d6
Update package version
david-driscoll Oct 27, 2017
b995a63
Merge branch 'master' into lsp
david-driscoll Oct 27, 2017
f5c0f19
Merge branch 'lsp' of github.com:OmniSharp/omnisharp-roslyn into lsp
david-driscoll Oct 27, 2017
a349680
fix null ref exception
david-driscoll Oct 27, 2017
5dd4421
merge with latest master
david-driscoll Oct 27, 2017
cc34932
Updated to latest lsp to fix small exception
david-driscoll Oct 27, 2017
bbe6137
bump to 0.7.0
david-driscoll Oct 31, 2017
801daa4
Merge branch 'master' into lsp
david-driscoll Nov 1, 2017
85da6f6
Adds RenameHandler
RLittlesII Oct 26, 2017
be45851
Merge branch 'master' into lsp
DustinCampbell Nov 7, 2017
e88689b
Merge pull request #997 from RLittlesII/rename
david-driscoll Nov 7, 2017
62249dc
Merge branch 'master' into lsp
david-driscoll Nov 8, 2017
25cafe1
Merge remote-tracking branch 'origin/master' into lsp
david-driscoll Nov 15, 2017
541be2e
Merge branch 'master' into lsp
david-driscoll Nov 16, 2017
b5c9475
Add DocumentSymbolHandler
bjorkstromm Dec 18, 2017
e5a5459
allow plugins to be specified by a dll file path
jonsequitur Dec 19, 2017
b30d431
use LoadFrom instead of LoadFile
jonsequitur Dec 19, 2017
5d8195e
call existing loader implementations
jonsequitur Dec 21, 2017
215d250
Merge pull request #1069 from jonsequitur/allow-plugin-specified-by-d…
Jan 2, 2018
4a3531f
Merge pull request #1068 from mholo65/lsp-document-symbols
david-driscoll Jan 8, 2018
803dab7
Merge remote-tracking branch 'origin/master' into lsp
david-driscoll Jan 8, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 10 additions & 178 deletions OmniSharp.sln

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/OmniSharp.Abstractions/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
[assembly: InternalsVisibleTo("OmniSharp.Roslyn")]
[assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp")]
[assembly: InternalsVisibleTo("OmniSharp.DotNetTest.Tests")]
[assembly: InternalsVisibleTo("OmniSharp.Tests")]
[assembly: InternalsVisibleTo("OmniSharp.Tests")]
[assembly: InternalsVisibleTo("OmniSharp")]
18 changes: 9 additions & 9 deletions src/OmniSharp.Abstractions/Models/Events/EventTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ namespace OmniSharp.Models.Events
{
public static class EventTypes
{
public static readonly string ProjectAdded = nameof(ProjectAdded);
public static readonly string ProjectChanged = nameof(ProjectChanged);
public static readonly string ProjectRemoved = nameof(ProjectRemoved);
public static readonly string Error = nameof(Error);
public static readonly string Diagnostic = nameof(Diagnostic);
public static readonly string PackageRestoreStarted = nameof(PackageRestoreStarted);
public static readonly string PackageRestoreFinished = nameof(PackageRestoreFinished);
public static readonly string UnresolvedDependencies = nameof(UnresolvedDependencies);
public const string ProjectAdded = nameof(ProjectAdded);
public const string ProjectChanged = nameof(ProjectChanged);
public const string ProjectRemoved = nameof(ProjectRemoved);
public const string Error = nameof(Error);
public const string Diagnostic = nameof(Diagnostic);
public const string PackageRestoreStarted = nameof(PackageRestoreStarted);
public const string PackageRestoreFinished = nameof(PackageRestoreFinished);
public const string UnresolvedDependencies = nameof(UnresolvedDependencies);
}
}
}
16 changes: 10 additions & 6 deletions src/OmniSharp.Host/CompositionHostBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,17 @@ public class CompositionHostBuilder
{
private readonly IServiceProvider _serviceProvider;
private readonly IOmniSharpEnvironment _environment;
private readonly ISharedTextWriter _writer;
private readonly IEventEmitter _eventEmitter;
private readonly IEnumerable<Assembly> _assemblies;

public CompositionHostBuilder(
IServiceProvider serviceProvider,
IOmniSharpEnvironment environment,
ISharedTextWriter writer,
IEventEmitter eventEmitter,
IEnumerable<Assembly> assemblies = null)
{
_serviceProvider = serviceProvider;
_environment = environment;
_writer = writer;
_eventEmitter = eventEmitter;
_assemblies = assemblies ?? Array.Empty<Assembly>();
}
Expand Down Expand Up @@ -64,7 +61,6 @@ public CompositionHost Build()
.WithProvider(MefValueProvider.From(memoryCache))
.WithProvider(MefValueProvider.From(loggerFactory))
.WithProvider(MefValueProvider.From(_environment))
.WithProvider(MefValueProvider.From(_writer))
.WithProvider(MefValueProvider.From(options.CurrentValue))
.WithProvider(MefValueProvider.From(options.CurrentValue.FormattingOptions))
.WithProvider(MefValueProvider.From(assemblyLoader))
Expand Down Expand Up @@ -95,13 +91,21 @@ public CompositionHostBuilder WithOmniSharpAssemblies()
var assemblies = DiscoverOmniSharpAssemblies();

return new CompositionHostBuilder(
_serviceProvider, _environment, _writer, _eventEmitter, assemblies);
_serviceProvider,
_environment,
_eventEmitter,
_assemblies.Concat(assemblies).Distinct()
);
}

public CompositionHostBuilder WithAssemblies(params Assembly[] assemblies)
{
return new CompositionHostBuilder(
_serviceProvider, _environment, _writer, _eventEmitter, assemblies);
_serviceProvider,
_environment,
_eventEmitter,
_assemblies.Concat(assemblies).Distinct()
);
}

private List<Assembly> DiscoverOmniSharpAssemblies()
Expand Down
5 changes: 5 additions & 0 deletions src/OmniSharp.Host/Internal/CommandOptionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@ public static T GetValueOrDefault<T>(this CommandOption opt, T defaultValue)

return defaultValue;
}

public static bool GetValueOrDefault(this CommandOption opt, bool defaultValue)
{
return opt.Value() == "on" || defaultValue;
Copy link
Contributor

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?

Copy link
Member Author

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.

}
}
}
5 changes: 1 addition & 4 deletions src/OmniSharp.Http/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,20 @@ class Startup
{
private readonly IOmniSharpEnvironment _environment;
private readonly IEventEmitter _eventEmitter;
private readonly ISharedTextWriter _writer;
private readonly IConfigurationRoot _configuration;
private CompositionHost _compositionHost;

public Startup(IOmniSharpEnvironment environment, IEventEmitter eventEmitter, ISharedTextWriter writer)
{
_environment = environment;
_eventEmitter = eventEmitter;
_writer = writer;
_configuration = new ConfigurationBuilder(environment).Build();
}

public IServiceProvider ConfigureServices(IServiceCollection services)
{
var serviceProvider = CompositionHostBuilder.CreateDefaultServiceProvider(_configuration, services);
_compositionHost = new CompositionHostBuilder(serviceProvider, _environment, _writer, _eventEmitter)
_compositionHost = new CompositionHostBuilder(serviceProvider, _environment, _eventEmitter)
.WithOmniSharpAssemblies()
.Build();

Expand All @@ -46,7 +44,6 @@ public void Configure(
IServiceProvider serviceProvider,
ILoggerFactory loggerFactory,
IEventEmitter eventEmitter,
ISharedTextWriter writer,
HttpEnvironment httpEnvironment,
IOptionsMonitor<OmniSharpOptions> options)
{
Expand Down
6 changes: 6 additions & 0 deletions src/OmniSharp.LanguageServerProtocol/AssemblyInfo.cs
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
Copy link
Contributor

Choose a reason for hiding this comment

The 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;
}
}
}
}
63 changes: 63 additions & 0 deletions src/OmniSharp.LanguageServerProtocol/Handlers/DefinitionHandler.cs
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;
}
}
}
62 changes: 62 additions & 0 deletions src/OmniSharp.LanguageServerProtocol/Handlers/HoverHandler.cs
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();
Copy link
Member

Choose a reason for hiding this comment

The 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.

Copy link
Member Author

Choose a reason for hiding this comment

The 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

// TODO: Get these with metadata so we can attach languages
// This will thne let us build up a better document filter, and add handles foreach type of handler
// This will mean that we will have a strategy to create handlers from the interface type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_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;
}
}
}
Loading