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 @@ -101,7 +101,7 @@ public async Task TestGetSimplifierOptionsOnTypeScriptDocument()

private async Task<VSTypeScriptTestLspServer> CreateTsTestLspServerAsync(string workspaceXml, InitializationOptions? options = null)
{
var testWorkspace = CreateWorkspace(options, mutatingLspWorkspace: false, workspaceKind: null);
var testWorkspace = await CreateWorkspaceAsync(options, mutatingLspWorkspace: false, workspaceKind: null);
testWorkspace.InitializeDocuments(XElement.Parse(workspaceXml), openDocuments: false);

return await VSTypeScriptTestLspServer.CreateAsync(testWorkspace, new InitializationOptions(), TestOutputLspLogger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.UnitTests;
using Microsoft.VisualStudio.Composition;
using Newtonsoft.Json.Linq;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
Expand Down Expand Up @@ -604,7 +605,7 @@ protected static async Task<Tuple<Solution, Solution>> TestOperationsAsync(
if (TestWorkspace.IsWorkspaceElement(expectedText))
{
var newSolutionWithLinkedFiles = await newSolution.WithMergedLinkedFileChangesAsync(oldSolution);
await VerifyAgainstWorkspaceDefinitionAsync(expectedText, newSolutionWithLinkedFiles, workspace.Composition);
await VerifyAgainstWorkspaceDefinitionAsync(expectedText, newSolutionWithLinkedFiles, workspace.ExportProvider);
return Tuple.Create(oldSolution, newSolution);
}

Expand Down Expand Up @@ -669,9 +670,9 @@ protected static Document GetDocumentToVerify(DocumentId expectedChangedDocument
return document;
}

private static async Task VerifyAgainstWorkspaceDefinitionAsync(string expectedText, Solution newSolution, TestComposition composition)
private static async Task VerifyAgainstWorkspaceDefinitionAsync(string xmlDefinition, Solution newSolution, ExportProvider exportProvider)
{
using var expectedWorkspace = TestWorkspace.Create(expectedText, composition: composition);
using var expectedWorkspace = TestWorkspace.Create(XElement.Parse(xmlDefinition), exportProvider);
var expectedSolution = expectedWorkspace.CurrentSolution;
Assert.Equal(expectedSolution.Projects.Count(), newSolution.Projects.Count());
foreach (var project in newSolution.Projects)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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 Microsoft.CodeAnalysis.LanguageServer.HostWorkspace;
using Microsoft.CodeAnalysis.LanguageServer.UnitTests.Miscellaneous;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.UnitTests;
using Microsoft.CodeAnalysis.Workspaces.ProjectSystem;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.Composition;
using Roslyn.Test.Utilities;
using Xunit.Abstractions;

namespace Microsoft.CodeAnalysis.LanguageServer.UnitTests;

public sealed class FileBasedProgramsWorkspaceTests : AbstractLspMiscellaneousFilesWorkspaceTests, IDisposable
{
private readonly ILoggerFactory _loggerFactory;
private readonly TestOutputLoggerProvider _loggerProvider;
private readonly TempRoot _tempRoot;
private readonly TempDirectory _mefCacheDirectory;

public FileBasedProgramsWorkspaceTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
_loggerProvider = new TestOutputLoggerProvider(testOutputHelper);
_loggerFactory = new LoggerFactory([_loggerProvider]);
_tempRoot = new();
_mefCacheDirectory = _tempRoot.CreateDirectory();
}

public void Dispose()
{
_tempRoot.Dispose();
_loggerProvider.Dispose();
}

protected override async ValueTask<ExportProvider> CreateExportProviderAsync()
{
AsynchronousOperationListenerProvider.Enable(enable: true);

var (exportProvider, _) = await LanguageServerTestComposition.CreateExportProviderAsync(
_loggerFactory,
includeDevKitComponents: false,
cacheDirectory: _mefCacheDirectory.Path,
extensionPaths: []);

return exportProvider;
}

private protected override async ValueTask<Document> AddDocumentAsync(TestLspServer testLspServer, string filePath, string content)
{
// For the file-based programs, we want to put them in the real workspace via the real host service
var workspaceFactory = testLspServer.TestWorkspace.ExportProvider.GetExportedValue<LanguageServerWorkspaceFactory>();
var project = await workspaceFactory.HostProjectFactory.CreateAndAddToWorkspaceAsync(
Guid.NewGuid().ToString(),
LanguageNames.CSharp,
new ProjectSystemProjectCreationInfo { AssemblyName = Guid.NewGuid().ToString() },
workspaceFactory.ProjectSystemHostInfo);

project.AddSourceFile(filePath);

return workspaceFactory.HostWorkspace.CurrentSolution.GetRequiredProject(project.Id).Documents.Single();
}

private protected override Workspace GetHostWorkspace(TestLspServer testLspServer)
{
var workspaceFactory = testLspServer.TestWorkspace.ExportProvider.GetExportedValue<LanguageServerWorkspaceFactory>();
return workspaceFactory.HostWorkspace;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@

</PropertyGroup>

<ItemGroup>
<!-- Include just the logger; pulling in the full project carries along a lot of dependencies -->
<Compile Include="..\..\Workspaces\CoreTestUtilities\Logging\TestOutputLoggerProvider.cs" Link="TestOutputLoggerProvider.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Compilers\Test\Core\Microsoft.CodeAnalysis.Test.Utilities.csproj" />
<ProjectReference Include="..\Microsoft.CodeAnalysis.LanguageServer\Microsoft.CodeAnalysis.LanguageServer.csproj" />
<ProjectReference Include="..\Protocol.TestUtilities\Microsoft.CodeAnalysis.LanguageServer.Protocol.Test.Utilities.csproj" />
<ProjectReference Include="..\Protocol\Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj" />

<ProjectReference Include="..\..\VisualStudio\DevKit\Impl\Microsoft.VisualStudio.LanguageServices.DevKit.csproj" ReferenceOutputAssembly="false" Private="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal sealed class LanguageServerTestComposition
var extensionManager = ExtensionAssemblyManager.Create(serverConfiguration, loggerFactory);
var assemblyLoader = new CustomExportAssemblyLoader(extensionManager, loggerFactory);

var exportProvider = await LanguageServerExportProviderBuilder.CreateExportProviderAsync(extensionManager, assemblyLoader, devKitDependencyPath, cacheDirectory, loggerFactory, CancellationToken.None);
var exportProvider = await LanguageServerExportProviderBuilder.CreateExportProviderAsync(TestPaths.GetLanguageServerDirectory(), extensionManager, assemblyLoader, devKitDependencyPath, cacheDirectory, loggerFactory, CancellationToken.None);
exportProvider.GetExportedValue<ServerConfigurationFactory>().InitializeConfiguration(serverConfiguration);
return (exportProvider, assemblyLoader);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public static string GetDevKitExtensionPath()
private const string LanguageServerSubdirectory = "RoslynLSP";
private const string LanguageServerAssemblyFileName = "Microsoft.CodeAnalysis.LanguageServer.dll";

public static string GetLanguageServerDirectory()
=> Path.Combine(AppContext.BaseDirectory, LanguageServerSubdirectory);
public static string GetLanguageServerPath()
=> Path.Combine(AppContext.BaseDirectory, LanguageServerSubdirectory, LanguageServerAssemblyFileName);
=> Path.Combine(GetLanguageServerDirectory(), LanguageServerAssemblyFileName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ private LanguageServerExportProviderBuilder(
}

public static async Task<ExportProvider> CreateExportProviderAsync(
string baseDirectory,
ExtensionAssemblyManager extensionManager,
IAssemblyLoader assemblyLoader,
string? devKitDependencyPath,
string cacheDirectory,
ILoggerFactory loggerFactory,
CancellationToken cancellationToken)
{
var baseDirectory = AppContext.BaseDirectory;

// Load any Roslyn assemblies from the extension directory
using var _ = ArrayBuilder<string>.GetInstance(out var assemblyPathsBuilder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static async Task RunAsync(ServerConfiguration serverConfiguration, Cancellation

var cacheDirectory = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location)!, "cache");

using var exportProvider = await LanguageServerExportProviderBuilder.CreateExportProviderAsync(extensionManager, assemblyLoader, serverConfiguration.DevKitDependencyPath, cacheDirectory, loggerFactory, cancellationToken);
using var exportProvider = await LanguageServerExportProviderBuilder.CreateExportProviderAsync(AppContext.BaseDirectory, extensionManager, assemblyLoader, serverConfiguration.DevKitDependencyPath, cacheDirectory, loggerFactory, cancellationToken);

// LSP server doesn't have the pieces yet to support 'balanced' mode for source-generators. Hardcode us to
// 'automatic' for now.
Expand Down
Loading
Loading