Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<StartupObject />
<TargetFramework>net472</TargetFramework>
<TargetFrameworks>$(NetRoslynAll);net472</TargetFrameworks>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CommonLanguageServerProtocol.Framework.UnitTests</RootNamespace>
<RoslynProjectType>UnitTest</RoslynProjectType>
</PropertyGroup>

<ItemGroup Label="Project References">
<ProjectReference Include="..\..\EditorFeatures\TestUtilities\Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj" />
<ProjectReference Include="..\..\Features\TestUtilities\Microsoft.CodeAnalysis.Features.Test.Utilities.csproj" />
<ProjectReference Include="..\Microsoft.CommonLanguageServerProtocol.Framework.Example\Microsoft.CommonLanguageServerProtocol.Framework.Example.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using StreamJsonRpc;
using Xunit;

namespace Microsoft.CommonLanguageServerProtocol.Framework.UnitTests;

public sealed class QueueItemTests
{
[Fact]
public async Task QueueItem_CancellationToken_Cancelled()
{
Mock<ILspLogger> mockLogger = new(MockBehavior.Strict);
mockLogger
.Setup(l => l.LogDebug("Starting request handler", Array.Empty<object>()))
.Verifiable();
mockLogger
.Setup(l => l.LogDebug(
It.Is<string>(message => message.Contains(ThrowLocalRpcExceptionMethodHandler.ErrorMessage)), Array.Empty<object>()))
.Verifiable();

var lspServices = TestLspServices.Create(
[(typeof(IMethodHandler), ThrowLocalRpcExceptionMethodHandler.Instance)],
supportsMethodHandlerProvider: false);
var queueItem = new QueueItem<int>(
ThrowLocalRpcExceptionMethodHandler.Name,
null,
lspServices,
mockLogger.Object,
CancellationToken.None);

var exception = await Assert.ThrowsAsync<LocalRpcException>(async () =>
{
await queueItem.StartRequestAsync<object?, object?>(
request: null,
context: 1,
ThrowLocalRpcExceptionMethodHandler.Instance,
string.Empty,
CancellationToken.None);
});
Assert.Equal(LspErrorCodes.ContentModified, exception.ErrorCode);

mockLogger.VerifyAll();
}

private sealed class ThrowLocalRpcExceptionMethodHandler : IRequestHandler<object?, object?, int>
{
public const string Name = "Test/Method";
public const string ErrorMessage = "Request resolve version does not match current version";

public static readonly ThrowLocalRpcExceptionMethodHandler Instance = new();

public bool MutatesSolutionState => false;

public Task<object?> HandleRequestAsync(object? request, int context, CancellationToken cancellationToken)
{
throw new LocalRpcException(ErrorMessage) { ErrorCode = LspErrorCodes.ContentModified };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ protected override ILspServices ConstructLspServices()
return base.ConstructLspServices();
}

private void _clientRpc_Disconnected(object sender, JsonRpcDisconnectedEventArgs e)
private void _clientRpc_Disconnected(object? sender, JsonRpcDisconnectedEventArgs e)
{
throw new NotImplementedException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.CodeAnalysis.LanguageServer.Handler;
namespace Microsoft.CommonLanguageServerProtocol.Framework;

/// <summary>
/// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#errorCodes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Threading;
using StreamJsonRpc;

namespace Microsoft.CommonLanguageServerProtocol.Framework;

Expand Down Expand Up @@ -45,7 +46,7 @@ internal sealed class QueueItem<TRequestContext> : IQueueItem<TRequestContext>

public object? SerializedRequest { get; }

private QueueItem(
internal QueueItem(
string methodName,
object? serializedRequest,
ILspServices lspServices,
Expand Down Expand Up @@ -106,7 +107,7 @@ public static (IQueueItem<TRequestContext>, Task<object?>) Create(
/// <summary>
/// Deserializes the request into the concrete type. If the deserialization fails we will fail the request and call TrySetException on the <see cref="_completionSource"/>
/// so that the client can observe the failure. If this is a mutating request, we will also let the exception bubble up so that the queue can handle it.
///
///
/// The caller is expected to return immediately and stop processing the request if this returns false.
/// </summary>
private bool TryDeserializeRequest<TRequest>(
Expand Down Expand Up @@ -232,7 +233,18 @@ public async Task StartRequestAsync<TRequest, TResponse>(TRequest request, TRequ
// Record logs and metrics on the exception.
// It's important that this can NEVER throw, or the queue will hang.
_requestTelemetryScope?.RecordException(ex);
_logger.LogException(ex);

if (ex is LocalRpcException { ErrorCode: LspErrorCodes.ContentModified })
{
// ContentModified exceptions are expected to be thrown during normal operation
// when the client is out of date with the server. Log them as debug messages
// so we don't alarm users.
_logger.LogDebug(ex.ToString());
}
else
{
_logger.LogException(ex);
}

_completionSource.TrySetException(ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.CodeLens;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CommonLanguageServerProtocol.Framework;
using StreamJsonRpc;
using LSP = Roslyn.LanguageServer.Protocol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.InlineHints;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CommonLanguageServerProtocol.Framework;
using Roslyn.LanguageServer.Protocol;
using StreamJsonRpc;
using LSP = Roslyn.LanguageServer.Protocol;
Expand Down
Loading