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,33 +3,39 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Collections.Generic;
using System.Composition;
using System.IO;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.ExternalAccess.VSTypeScript;
using Microsoft.CodeAnalysis.ExternalAccess.VSTypeScript.Api;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServer;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.LanguageServer.Protocol;
using Microsoft.CommonLanguageServerProtocol.Framework;
using Nerdbank.Streams;
using Roslyn.LanguageServer.Protocol;
using Roslyn.Test.Utilities;
using StreamJsonRpc;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.CodeAnalysis.LanguageServer.UnitTests;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.LanguageServer;

public class VSTypeScriptHandlerTests : AbstractLanguageServerProtocolTests
{
public VSTypeScriptHandlerTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
}

protected override TestComposition Composition => base.Composition.AddParts(typeof(TypeScriptHandlerFactory));
protected override TestComposition Composition => EditorTestCompositions.LanguageServerProtocolEditorFeatures
Copy link
Member Author

Choose a reason for hiding this comment

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

requires Editor features here as the VS typescript EA components live in editor features.

.AddParts(typeof(TypeScriptHandlerFactory))
.AddParts(typeof(TestWorkspaceRegistrationService));

[Fact]
public async Task TestExternalAccessTypeScriptHandlerInvoked()
Expand Down Expand Up @@ -88,43 +94,50 @@ public async Task TestGetSimplifierOptionsOnTypeScriptDocument()
Assert.Same(SimplifierOptions.CommonDefaults, simplifierOptions);
}

private async Task<TestLspServer> CreateTsTestLspServerAsync(string workspaceXml, InitializationOptions? options = null)
private async Task<VSTypeScriptTestLspServer> CreateTsTestLspServerAsync(string workspaceXml, InitializationOptions? options = null)
{
var (clientStream, serverStream) = FullDuplexStream.CreatePair();

var testWorkspace = CreateWorkspace(options, mutatingLspWorkspace: false, workspaceKind: null);
testWorkspace.InitializeDocuments(XElement.Parse(workspaceXml), openDocuments: false);

// Ensure workspace operations are completed so we don't get unexpected workspace changes while running.
await WaitForWorkspaceOperationsAsync(testWorkspace);
var languageServerTarget = CreateLanguageServer(serverStream, serverStream, testWorkspace);

return await TestLspServer.CreateAsync(testWorkspace, new ClientCapabilities(), languageServerTarget, clientStream);
return await VSTypeScriptTestLspServer.CreateAsync(testWorkspace, new InitializationOptions(), TestOutputLspLogger);
}

private static RoslynLanguageServer CreateLanguageServer(Stream inputStream, Stream outputStream, EditorTestWorkspace workspace)
private class VSTypeScriptTestLspServer : AbstractTestLspServer<LspTestWorkspace, TestHostDocument, TestHostProject, TestHostSolution>
{
var capabilitiesProvider = workspace.ExportProvider.GetExportedValue<ExperimentalCapabilitiesProvider>();
var servicesProvider = workspace.ExportProvider.GetExportedValue<VSTypeScriptLspServiceProvider>();

var messageFormatter = RoslynLanguageServer.CreateJsonMessageFormatter();
var jsonRpc = new JsonRpc(new HeaderDelimitedMessageHandler(outputStream, inputStream, messageFormatter))
public VSTypeScriptTestLspServer(LspTestWorkspace testWorkspace, Dictionary<string, IList<Roslyn.LanguageServer.Protocol.Location>> locations, InitializationOptions options, AbstractLspLogger logger) : base(testWorkspace, locations, options, logger)
{
ExceptionStrategy = ExceptionProcessing.ISerializable,
};

var logger = NoOpLspLogger.Instance;
}

var languageServer = new RoslynLanguageServer(
servicesProvider, jsonRpc, messageFormatter.JsonSerializerOptions,
capabilitiesProvider,
logger,
workspace.Services.HostServices,
[InternalLanguageNames.TypeScript],
WellKnownLspServerKinds.RoslynTypeScriptLspServer);
protected override RoslynLanguageServer CreateLanguageServer(Stream inputStream, Stream outputStream, WellKnownLspServerKinds serverKind, AbstractLspLogger logger)
{
var capabilitiesProvider = TestWorkspace.ExportProvider.GetExportedValue<ExperimentalCapabilitiesProvider>();
var servicesProvider = TestWorkspace.ExportProvider.GetExportedValue<VSTypeScriptLspServiceProvider>();

var messageFormatter = RoslynLanguageServer.CreateJsonMessageFormatter();
var jsonRpc = new JsonRpc(new HeaderDelimitedMessageHandler(outputStream, inputStream, messageFormatter))
{
ExceptionStrategy = ExceptionProcessing.ISerializable,
};

var languageServer = new RoslynLanguageServer(
servicesProvider, jsonRpc, messageFormatter.JsonSerializerOptions,
capabilitiesProvider,
logger,
TestWorkspace.Services.HostServices,
[InternalLanguageNames.TypeScript],
WellKnownLspServerKinds.RoslynTypeScriptLspServer);

jsonRpc.StartListening();
return languageServer;
}

jsonRpc.StartListening();
return languageServer;
public static async Task<VSTypeScriptTestLspServer> CreateAsync(LspTestWorkspace testWorkspace, InitializationOptions options, AbstractLspLogger logger)
{
var locations = await GetAnnotatedLocationsAsync(testWorkspace, testWorkspace.CurrentSolution);
var server = new VSTypeScriptTestLspServer(testWorkspace, locations, options, logger);
await server.InitializeAsync();
return server;
}
}

internal record TSRequest(Uri Document, string Project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,26 @@

namespace Microsoft.CodeAnalysis.Test.Utilities;

public partial class EditorTestWorkspace : TestWorkspace<EditorTestHostDocument, EditorTestHostProject, EditorTestHostSolution>, ILspWorkspace
public partial class EditorTestWorkspace : TestWorkspace<EditorTestHostDocument, EditorTestHostProject, EditorTestHostSolution>
Copy link
Member Author

Choose a reason for hiding this comment

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

we're not using this anymore for any LSP tests that require mutation, so no need for it to implement the LSP mutation methods. Only used by doc outline tests at the moment (which work with any workspace).

{
private const string ReferencesOnDiskAttributeName = "ReferencesOnDisk";

private readonly Dictionary<string, ITextBuffer2> _createdTextBuffers = [];
private readonly bool _supportsLspMutation;

internal EditorTestWorkspace(
TestComposition? composition = null,
string? workspaceKind = WorkspaceKind.Host,
Guid solutionTelemetryId = default,
bool disablePartialSolutions = true,
bool ignoreUnchangeableDocumentsWhenApplyingChanges = true,
WorkspaceConfigurationOptions? configurationOptions = null,
bool supportsLspMutation = false)
WorkspaceConfigurationOptions? configurationOptions = null)
: base(composition ?? EditorTestCompositions.EditorFeatures,
workspaceKind,
solutionTelemetryId,
disablePartialSolutions,
ignoreUnchangeableDocumentsWhenApplyingChanges,
configurationOptions)
{
_supportsLspMutation = supportsLspMutation;
}

bool ILspWorkspace.SupportsMutation => _supportsLspMutation;

ValueTask ILspWorkspace.UpdateTextIfPresentAsync(DocumentId documentId, SourceText sourceText, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(_supportsLspMutation);
OnDocumentTextChanged(documentId, sourceText, PreservationMode.PreserveIdentity, requireDocumentPresent: false);
return ValueTaskFactory.CompletedTask;
}

internal override ValueTask TryOnDocumentClosedAsync(DocumentId documentId, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(_supportsLspMutation);
return base.TryOnDocumentClosedAsync(documentId, cancellationToken);
}

private protected override EditorTestHostDocument CreateDocument(
Expand Down
3 changes: 0 additions & 3 deletions src/Features/Lsif/GeneratorTest/FoldingRangeTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Roslyn.LanguageServer.Protocol
Imports Roslyn.Test.Utilities
Imports Roslyn.Utilities

Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests
<UseExportProvider>
Expand Down Expand Up @@ -52,7 +50,6 @@ using System.Linq;|}", "...")>
</Document>
</Project>
</Workspace>, openDocuments:=False, composition:=TestLsifOutput.TestComposition)

Dim annotatedLocations = Await AbstractLanguageServerProtocolTests.GetAnnotatedLocationsAsync(workspace, workspace.CurrentSolution)
Dim expectedRanges = annotatedLocations.SelectMany(Function(kvp) kvp.Value.Select(Function(location) CreateFoldingRange(kvp.Key, location.Range, collapsedText))).OrderByDescending(Function(range) range.StartLine).ToArray()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\EditorFeatures\TestUtilities\Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj" />
<ProjectReference Include="..\..\..\LanguageServer\Protocol.TestUtilities\Microsoft.CodeAnalysis.LanguageServer.Protocol.Test.Utilities.csproj" />
<ProjectReference Include="..\..\..\Workspaces\TestAnalyzerReference\Microsoft.CodeAnalysis.TestAnalyzerReference.csproj" />
<ProjectReference Include="..\Generator\Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Features.DiagnosticsTests.Utilities" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Features.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Features.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.LanguageServer.Protocol.Test.Utilities" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.LanguageServer.Protocol.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.EditorFeatures.UnitTests" />
Expand Down
Loading
Loading