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

Updated lsp library to fix issue with signature help, etc #1890

Merged
merged 10 commits into from
Aug 18, 2020
4 changes: 2 additions & 2 deletions build/Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
<PackageReference Update="NuGet.ProjectModel" Version="$(NuGetPackageVersion)" />
<PackageReference Update="NuGet.Versioning" Version="$(NuGetPackageVersion)" />

<PackageReference Update="OmniSharp.Extensions.LanguageServer" Version="0.18.0-beta0003" />
<PackageReference Update="OmniSharp.Extensions.LanguageProtocol.Testing" Version="0.18.0-beta0003" />
<PackageReference Update="OmniSharp.Extensions.LanguageServer" Version="0.18.0-beta0079" />
<PackageReference Update="OmniSharp.Extensions.LanguageProtocol.Testing" Version="0.18.0-beta0079" />

<PackageReference Update="SQLitePCLRaw.bundle_green" Version="1.1.2" />
<PackageReference Update="System.Collections.Immutable" Version="1.4.0" />
Expand Down
174 changes: 88 additions & 86 deletions tests/OmniSharp.Lsp.Tests/AbstractLanguageServerTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ public async Task Restart(IConfiguration configuration = null, IDictionary<strin
Client.Dispose();
OmniSharpTestHost.Dispose();

_setupConfiguration ??= new Microsoft.Extensions.Configuration.ConfigurationBuilder()
_setupConfiguration = configuration ?? new Microsoft.Extensions.Configuration.ConfigurationBuilder()
.AddInMemoryCollection(configurationData ?? new Dictionary<string, string>())
.Build();
await InitializeAsync();
}

public async Task InitializeAsync()
{
Client = await InitializeClient(x =>
var(client, configurationProvider) = await InitializeClientWithConfiguration(x =>
{
x.WithCapability(new WorkspaceEditCapability()
{
Expand All @@ -117,107 +117,109 @@ public async Task InitializeAsync()
ResourceOperationKind.Create, ResourceOperationKind.Delete, ResourceOperationKind.Rename
}
});
});
Client.Register(c => c.OnApplyWorkspaceEdit(async @params =>
{
if (@params.Edit?.Changes != null)
x.OnApplyWorkspaceEdit(async @params =>
{
foreach (var change in @params.Edit.Changes)
if (@params.Edit?.Changes != null)
{
var changes = change.Value
.Select(change => new LinePositionSpanTextChange()
{
NewText = change.NewText,
StartColumn = Convert.ToInt32(change.Range.Start.Character),
StartLine = Convert.ToInt32(change.Range.Start.Line),
EndColumn = Convert.ToInt32(change.Range.End.Character),
EndLine = Convert.ToInt32(change.Range.End.Line),
})
.ToArray();

await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(new UpdateBufferRequest()
foreach (var change in @params.Edit.Changes)
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.Key),
Changes = changes
});
var changes = change.Value
.Select(change => new LinePositionSpanTextChange()
{
NewText = change.NewText,
StartColumn = Convert.ToInt32(change.Range.Start.Character),
StartLine = Convert.ToInt32(change.Range.Start.Line),
EndColumn = Convert.ToInt32(change.Range.End.Character),
EndLine = Convert.ToInt32(change.Range.End.Line),
})
.ToArray();

await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(new UpdateBufferRequest()
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.Key),
Changes = changes
});
}
}
}
else if (@params.Edit?.DocumentChanges != null)
{
foreach (var change in @params.Edit.DocumentChanges)
else if (@params.Edit?.DocumentChanges != null)
{
if (change.IsTextDocumentEdit)
foreach (var change in @params.Edit.DocumentChanges)
{
var contentChanges = change.TextDocumentEdit.Edits.ToArray();
if (contentChanges.Length == 1 && contentChanges[0].Range == null)
if (change.IsTextDocumentEdit)
{
var c = contentChanges[0];
await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(
new UpdateBufferRequest()
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.TextDocumentEdit
.TextDocument.Uri),
Buffer = c.NewText
});
}
else
{
var changes = contentChanges
.Select(change => new LinePositionSpanTextChange()
{
NewText = change.NewText,
StartColumn = Convert.ToInt32(change.Range.Start.Character),
StartLine = Convert.ToInt32(change.Range.Start.Line),
EndColumn = Convert.ToInt32(change.Range.End.Character),
EndLine = Convert.ToInt32(change.Range.End.Line),
})
.ToArray();
var contentChanges = change.TextDocumentEdit.Edits.ToArray();
if (contentChanges.Length == 1 && contentChanges[0].Range == null)
{
var c = contentChanges[0];
await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(
new UpdateBufferRequest()
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.TextDocumentEdit
.TextDocument.Uri),
Buffer = c.NewText
});
}
else
{
var changes = contentChanges
.Select(change => new LinePositionSpanTextChange()
{
NewText = change.NewText,
StartColumn = Convert.ToInt32(change.Range.Start.Character),
StartLine = Convert.ToInt32(change.Range.Start.Line),
EndColumn = Convert.ToInt32(change.Range.End.Character),
EndLine = Convert.ToInt32(change.Range.End.Line),
})
.ToArray();

await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(
new UpdateBufferRequest()
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.TextDocumentEdit
.TextDocument.Uri),
Changes = changes
});
await OmniSharpTestHost.Workspace.BufferManager.UpdateBufferAsync(
new UpdateBufferRequest()
{
FileName = LanguageServerProtocol.Helpers.FromUri(change.TextDocumentEdit
.TextDocument.Uri),
Changes = changes
});
}
}
}

if (change.IsRenameFile)
{
var documents =
OmniSharpTestHost.Workspace.GetDocuments(change.RenameFile.OldUri.GetFileSystemPath());
foreach (var oldDocument in documents)
if (change.IsRenameFile)
{
var text = await oldDocument.GetTextAsync();
var newFilePath = change.RenameFile.NewUri.GetFileSystemPath();
var newFileName = Path.GetFileName(newFilePath);
OmniSharpTestHost.Workspace.TryApplyChanges(
OmniSharpTestHost.Workspace.CurrentSolution
.RemoveDocument(oldDocument.Id)
.AddDocument(
DocumentId.CreateNewId(oldDocument.Project.Id, newFileName),
newFileName,
text,
oldDocument.Folders,
newFilePath
)
);
var documents =
OmniSharpTestHost.Workspace.GetDocuments(
change.RenameFile.OldUri.GetFileSystemPath());
foreach (var oldDocument in documents)
{
var text = await oldDocument.GetTextAsync();
var newFilePath = change.RenameFile.NewUri.GetFileSystemPath();
var newFileName = Path.GetFileName(newFilePath);
OmniSharpTestHost.Workspace.TryApplyChanges(
OmniSharpTestHost.Workspace.CurrentSolution
.RemoveDocument(oldDocument.Id)
.AddDocument(
DocumentId.CreateNewId(oldDocument.Project.Id, newFileName),
newFileName,
text,
oldDocument.Folders,
newFilePath
)
);
}
}
}
}
}

await ClientEvents.SettleNext();
await ClientEvents.SettleNext();

return new ApplyWorkspaceEditResponse()
{
Applied = true
};
});
});
Client = client;

return new ApplyWorkspaceEditResponse()
{
Applied = true
};
}));
await startUpTask;
Configuration = new ConfigurationProvider(Server, Client, CancellationToken);
Client.Register(x => x.AddHandler(Configuration));
Configuration = new ConfigurationProvider(Server, Client, configurationProvider, CancellationToken);
}

public Task DisposeAsync()
Expand Down
135 changes: 10 additions & 125 deletions tests/OmniSharp.Lsp.Tests/ConfigurationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@
using MediatR;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using OmniSharp.Extensions.LanguageProtocol.Testing;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Client;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
using OmniSharp.Extensions.LanguageServer.Protocol.Workspace;
using TestUtility;

namespace OmniSharp.Lsp.Tests
{
public class ConfigurationProvider: IConfigurationHandler
public class ConfigurationProvider
{
private readonly ILanguageServer _server;
private readonly ILanguageClient _client;
private readonly TestConfigurationProvider _configurationProvider;
private readonly CancellationToken _cancellationToken;

private readonly ConcurrentDictionary<(string section, DocumentUri scope), IConfiguration> _scopedConfigurations =
new ConcurrentDictionary<(string section, DocumentUri scope), IConfiguration>();

public ConfigurationProvider(ILanguageServer server, ILanguageClient client,
public ConfigurationProvider(
ILanguageServer server,
ILanguageClient client,
TestConfigurationProvider configurationProvider,
CancellationToken cancellationToken)
{
_server = server;
_client = client;
_configurationProvider = configurationProvider;
_cancellationToken = cancellationToken;
}

Expand All @@ -54,7 +54,7 @@ public Task Update(string section, DocumentUri documentUri, IDictionary<string,
public Task Update(string section, DocumentUri documentUri, IConfiguration configuration)
{
if (configuration == null) return Task.CompletedTask;
_scopedConfigurations.AddOrUpdate((section, documentUri), configuration, (a, _) => configuration);
_configurationProvider.Update(section, documentUri, configuration);
return TriggerChange();
}

Expand All @@ -65,128 +65,13 @@ public Task Reset(string section)

public Task Reset(string section, DocumentUri documentUri)
{
_scopedConfigurations.TryRemove((section, documentUri), out _);
_client.Workspace.DidChangeConfiguration(new DidChangeConfigurationParams());
_configurationProvider.Reset(section, documentUri);
return TriggerChange();
}

private IConfiguration Get(ConfigurationItem configurationItem)
{
if (_scopedConfigurations.TryGetValue(
(configurationItem.Section, configurationItem.ScopeUri),
out var configuration)
)
{
return new Microsoft.Extensions.Configuration.ConfigurationBuilder()
.AddConfiguration(configuration, false)
.Build();
}

return new Microsoft.Extensions.Configuration.ConfigurationBuilder().Build();
}

private async Task TriggerChange()
{
_client.Workspace.DidChangeConfiguration(new DidChangeConfigurationParams());
await _server.Configuration.WaitForChange(_cancellationToken);
}

Task<Container<JToken>> IRequestHandler<ConfigurationParams, Container<JToken>>. Handle(ConfigurationParams request, CancellationToken cancellationToken)
{
var results = new List<JToken>();
foreach (var item in request.Items)
{
var config = Get(item);
results.Add(Parse(config.AsEnumerable(true).Where(x => x.Value != null)));
}

return Task.FromResult<Container<JToken>>(results);
}

private JObject Parse(IEnumerable<KeyValuePair<string, string>> values)
{
if (values == null)
{
throw new ArgumentNullException(nameof(values));
}

var result = new JObject();
foreach (var item in values)
{
var keys = item.Key.Split(new [] { ":" }, StringSplitOptions.RemoveEmptyEntries);
var prop = keys.Last();
JToken root = result;

// This produces a simple look ahead
var zippedKeys = keys
.Zip(keys.Skip(1), (prev, current) => (prev, current));

foreach (var (key, next) in zippedKeys)
{
if (int.TryParse(next, out var value))
{
root = SetValueToToken(root, key, new JArray());
}
else
{
root = SetValueToToken(root, key, new JObject());
}
}

SetValueToToken(root, prop, new JValue(item.Value));
}
return result;
}
private T SetValueToToken<T>(JToken root, string key, T value)
where T : JToken
{
var currentValue = GetValueFromToken(root, key);
if (currentValue == null || currentValue.Type == JTokenType.Null)
{
if (root is JArray arr)
{
if (int.TryParse(key, out var index))
{
if (arr.Count <= index)
{
while (arr.Count < index)
arr.Add(null!);
arr.Add(value);
}
else
{
arr[index] = value;
}

return value;
}
}
else
{
root[key] = value;
return value;
}
}

if (root is JArray arr2 && int.TryParse(key, out var i))
{
return (T)arr2[i];
}
return root[key] as T;
}

private static JToken GetValueFromToken(JToken root, string key)
{
if (root is JArray arr)
{
if (int.TryParse(key, out var index))
{
if (arr.Count <= index) return null;
return arr[index];
}
throw new IndexOutOfRangeException(key);
}
return root[key];
}
}
}
Loading