Skip to content

Commit

Permalink
Merge pull request #1890 from OmniSharp/fix/lsp
Browse files Browse the repository at this point in the history
Updated lsp library to fix issue with signature help, etc
  • Loading branch information
JoeRobich authored Aug 18, 2020
2 parents b28a4ae + 3eb991d commit efd7929
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 246 deletions.
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

0 comments on commit efd7929

Please sign in to comment.