提交 d44739a2 编写于 作者: H Heejae Chang

added more oop unit tests and some code refactoring

上级 591bea8f
......@@ -53,6 +53,8 @@ public static async Task<RemoteHostClient> CreateAsync(Workspace workspace, Canc
_rpc.Disconnected += OnRpcDisconnected;
}
public AssetStorage AssetStorage => _inprocServices.AssetStorage;
protected override async Task<Session> CreateServiceSessionAsync(string serviceName, PinnedRemotableDataScope snapshot, object callbackTarget, CancellationToken cancellationToken)
{
// get stream from service hub to communicate snapshot/asset related information
......@@ -80,14 +82,46 @@ private void OnRpcDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
Disconnected();
}
public class ServiceProvider : IServiceProvider
{
private static readonly TraceSource s_traceSource = new TraceSource("inprocRemoteClient");
private readonly AssetStorage _storage;
public ServiceProvider()
{
_storage = new AssetStorage(enableCleanup: false);
}
public AssetStorage AssetStorage => _storage;
public object GetService(Type serviceType)
{
if (typeof(TraceSource) == serviceType)
{
return s_traceSource;
}
if (typeof(AssetStorage) == serviceType)
{
return _storage;
}
throw ExceptionUtilities.UnexpectedValue(serviceType);
}
}
private class InProcRemoteServices
{
private static readonly IServiceProvider s_serviceProvider = new ServiceProvider();
private readonly ServiceProvider _serviceProvider;
public InProcRemoteServices()
{
_serviceProvider = new ServiceProvider();
}
public AssetStorage AssetStorage => _serviceProvider.AssetStorage;
public Task<Stream> RequestServiceAsync(string serviceName, CancellationToken cancellationToken)
{
switch (serviceName)
......@@ -95,48 +129,28 @@ public Task<Stream> RequestServiceAsync(string serviceName, CancellationToken ca
case WellKnownRemoteHostServices.RemoteHostService:
{
var tuple = FullDuplexStream.CreateStreams();
return Task.FromResult<Stream>(new WrappedStream(new RemoteHostService(tuple.Item1, s_serviceProvider), tuple.Item2));
return Task.FromResult<Stream>(new WrappedStream(new RemoteHostService(tuple.Item1, _serviceProvider), tuple.Item2));
}
case WellKnownServiceHubServices.CodeAnalysisService:
{
var tuple = FullDuplexStream.CreateStreams();
return Task.FromResult<Stream>(new WrappedStream(new CodeAnalysisService(tuple.Item1, s_serviceProvider), tuple.Item2));
return Task.FromResult<Stream>(new WrappedStream(new CodeAnalysisService(tuple.Item1, _serviceProvider), tuple.Item2));
}
case WellKnownServiceHubServices.SnapshotService:
{
var tuple = FullDuplexStream.CreateStreams();
return Task.FromResult<Stream>(new WrappedStream(new SnapshotService(tuple.Item1, s_serviceProvider), tuple.Item2));
return Task.FromResult<Stream>(new WrappedStream(new SnapshotService(tuple.Item1, _serviceProvider), tuple.Item2));
}
case WellKnownServiceHubServices.RemoteSymbolSearchUpdateEngine:
{
var tuple = FullDuplexStream.CreateStreams();
return Task.FromResult<Stream>(new WrappedStream(new RemoteSymbolSearchUpdateEngine(tuple.Item1, s_serviceProvider), tuple.Item2));
return Task.FromResult<Stream>(new WrappedStream(new RemoteSymbolSearchUpdateEngine(tuple.Item1, _serviceProvider), tuple.Item2));
}
}
throw ExceptionUtilities.UnexpectedValue(serviceName);
}
private class ServiceProvider : IServiceProvider
{
private static readonly TraceSource s_traceSource = new TraceSource("inprocRemoteClient");
public object GetService(Type serviceType)
{
if (typeof(TraceSource) == serviceType)
{
return s_traceSource;
}
if (typeof(AssetStorage) == serviceType)
{
return AssetStorage.Default;
}
throw ExceptionUtilities.UnexpectedValue(serviceType);
}
}
private class WrappedStream : Stream
{
private readonly IDisposable _service;
......
......@@ -160,7 +160,7 @@ private void AddGlobalAssets(CancellationToken cancellationToken)
using (Logger.LogBlock(FunctionId.RemoteHostClientService_AddGlobalAssetsAsync, cancellationToken))
{
var snapshotService = _workspace.Services.GetService<ISolutionSynchronizationService>();
var assetBuilder = new CustomAssetBuilder(_workspace.CurrentSolution);
var assetBuilder = new CustomAssetBuilder(_workspace);
foreach (var reference in _analyzerService.GetHostAnalyzerReferences())
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Remote;
using Roslyn.Test.Utilities;
using Xunit;
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
public class AssetServiceTests
{
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestAssets()
{
var sessionId = 0;
var checksum = new Checksum(Guid.NewGuid().ToByteArray());
var data = new object();
var storage = new AssetStorage(enableCleanup: false);
var source = new MyAssetSource(storage, sessionId, checksum, data);
var service = new AssetService(sessionId, storage);
var stored = await service.GetAssetAsync<object>(checksum, CancellationToken.None);
Assert.Equal(data, stored);
var stored2 = await service.GetAssetsAsync<object>(new[] { checksum }, CancellationToken.None);
Assert.Equal(1, stored2.Count);
Assert.Equal(checksum, stored2[0].Item1);
Assert.Equal(data, stored2[0].Item2);
}
private class MyAssetSource : AssetSource
{
private readonly Checksum _checksum;
private readonly object _data;
public MyAssetSource(AssetStorage assetStorage, int sessionId, Checksum checksum, object data) :
base(assetStorage, sessionId)
{
_checksum = checksum;
_data = data;
}
public override Task<IList<(Checksum, object)>> RequestAssetsAsync(int serviceId, ISet<Checksum> checksums, CancellationToken cancellationToken)
{
if (checksums.Contains(_checksum))
{
return Task.FromResult<IList<(Checksum, object)>>(new List<(Checksum, object)>() { ValueTuple.Create(_checksum, _data) });
}
// fail
Assert.True(false);
return null;
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Remote;
using Roslyn.Test.Utilities;
using Xunit;
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
public class AssetStorageTests
{
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestCreation()
{
var sessionId = 0;
var storage = new AssetStorage(enableCleanup: false);
var source = new MyAssetSource(storage, sessionId);
var stored = storage.TryGetAssetSource(sessionId);
Assert.Equal(source, stored);
storage.UnregisterAssetSource(sessionId);
var none = storage.TryGetAssetSource(sessionId);
Assert.Null(none);
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestGetAssets()
{
var sessionId = 0;
var storage = new AssetStorage(enableCleanup: false);
var source = new MyAssetSource(storage, sessionId);
var checksum = new Checksum(Guid.NewGuid().ToByteArray());
var data = new object();
Assert.True(storage.TryAddAsset(checksum, data));
object stored;
Assert.True(storage.TryGetAsset(checksum, out stored));
}
private class MyAssetSource : AssetSource
{
public MyAssetSource(AssetStorage assetStorage, int sessionId) :
base(assetStorage, sessionId)
{
}
public override Task<IList<(Checksum, object)>> RequestAssetsAsync(int serviceId, ISet<Checksum> checksums, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Serialization;
using Xunit;
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
internal static class ChecksumUtils
{
public static Dictionary<Checksum, object> GetAssetMap(this Solution solution)
{
var map = new Dictionary<Checksum, object>();
SolutionStateChecksums solutionChecksums;
Assert.True(solution.State.TryGetStateChecksums(out solutionChecksums));
solutionChecksums.Find(solution.State, Flatten(solutionChecksums), map, CancellationToken.None);
foreach (var project in solution.Projects)
{
ProjectStateChecksums projectChecksums;
Assert.True(project.State.TryGetStateChecksums(out projectChecksums));
projectChecksums.Find(project.State, Flatten(projectChecksums), map, CancellationToken.None);
foreach (var document in project.Documents)
{
DocumentStateChecksums documentChecksums;
Assert.True(document.State.TryGetStateChecksums(out documentChecksums));
documentChecksums.Find(document.State, Flatten(documentChecksums), map, CancellationToken.None);
// fix up due to source text can't be obtained synchronously in product code
map[documentChecksums.Text] = document.State.GetTextSynchronously(CancellationToken.None);
}
}
return map;
}
private static HashSet<Checksum> Flatten(ChecksumWithChildren checksums)
{
var set = new HashSet<Checksum>();
set.Add(checksums.Checksum);
foreach (var child in checksums.Children)
{
var checksum = child as Checksum;
if (checksum != null)
{
set.Add(checksum);
}
var collection = child as ChecksumCollection;
if (collection != null)
{
foreach (var item in collection)
{
set.Add(item);
}
}
}
return set;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Serialization;
using Roslyn.Test.Utilities;
using Roslyn.Test.Utilities.Remote;
using Xunit;
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
public class ServiceHubServicesTests
{
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestRemoteHostCreation()
{
var remoteHostService = CreateService();
Assert.NotNull(remoteHostService);
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestRemoteHostConnect()
{
var remoteHostService = CreateService();
var input = "Test";
var output = remoteHostService.Connect(input);
Assert.Equal(input, output);
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestRemoteHostSynchronize()
{
var code = @"class Test { void Method() { } }";
using (var workspace = await TestWorkspace.CreateCSharpAsync(code))
{
var solution = workspace.CurrentSolution;
var client = (InProcRemoteHostClient)(await InProcRemoteHostClient.CreateAsync(workspace, CancellationToken.None));
using (var session = await client.CreateServiceSessionAsync(WellKnownRemoteHostServices.RemoteHostService, solution, CancellationToken.None))
{
await session.InvokeAsync(WellKnownRemoteHostServices.RemoteHostService_SynchronizeAsync);
}
var storage = client.AssetStorage;
var map = solution.GetAssetMap();
object data;
foreach (var kv in map)
{
Assert.True(storage.TryGetAsset(kv.Key, out data));
}
}
}
private static RemoteHostService CreateService()
{
var stream = new MemoryStream();
return new RemoteHostService(stream, new InProcRemoteHostClient.ServiceProvider());
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Remote;
using Roslyn.Test.Utilities;
using Xunit;
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
public class SolutionServiceTests
{
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestCreation()
{
var code = @"class Test { void Method() { } }";
using (var workspace = await TestWorkspace.CreateCSharpAsync(code))
{
var solution = workspace.CurrentSolution;
var solutionChecksum = await solution.State.GetChecksumAsync(CancellationToken.None);
var map = solution.GetAssetMap();
var sessionId = 0;
var storage = new AssetStorage(enableCleanup: false);
var source = new MyAssetSource(storage, sessionId, map);
var service = new SolutionService(new AssetService(sessionId, storage));
var synched = await service.GetSolutionAsync(solutionChecksum, CancellationToken.None);
Assert.Equal(solutionChecksum, await synched.State.GetChecksumAsync(CancellationToken.None));
}
}
private class MyAssetSource : AssetSource
{
private readonly Dictionary<Checksum, object> _map;
public MyAssetSource(AssetStorage assetStorage, int sessionId, Dictionary<Checksum, object> map) :
base(assetStorage, sessionId)
{
_map = map;
}
public override Task<IList<(Checksum, object)>> RequestAssetsAsync(int serviceId, ISet<Checksum> checksums, CancellationToken cancellationToken)
{
var list = new List<(Checksum, object)>();
foreach (var checksum in checksums)
{
object data;
Assert.True(_map.TryGetValue(checksum, out data));
list.Add(ValueTuple.Create(checksum, data));
}
return Task.FromResult<IList<(Checksum, object)>>(list);
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
......@@ -12,12 +13,14 @@
using Microsoft.CodeAnalysis.CSharp.Diagnostics.TypeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Execution;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.VisualBasic.UseNullPropagation;
using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
using Microsoft.VisualStudio.LanguageServices.Implementation.Diagnostics;
using Microsoft.VisualStudio.LanguageServices.Remote;
using Moq;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Roslyn.VisualStudio.Next.UnitTests.Mocks;
......@@ -25,7 +28,7 @@
namespace Roslyn.VisualStudio.Next.UnitTests.Remote
{
public class CalculateDiagnosticsTests
public class VisualStudioDiagnosticAnalyzerExecutorTests
{
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestCSharpAnalyzerOptions()
......@@ -119,6 +122,51 @@ public async Task TestCancellation()
}
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestHostAnalyzers()
{
var code = @"class Test
{
void Method()
{
var t = new Test();
}
}";
using (var workspace = await CreateWorkspaceAsync(LanguageNames.CSharp, code))
{
var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer);
var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader());
var mockAnalyzerService = CreateMockDiagnosticAnalyzerService(new[] { analyzerReference });
// add host analyzer as global assets
var snapshotService = workspace.Services.GetService<ISolutionSynchronizationService>();
var assetBuilder = new CustomAssetBuilder(workspace);
foreach (var reference in mockAnalyzerService.GetHostAnalyzerReferences())
{
var asset = assetBuilder.Build(reference, CancellationToken.None);
snapshotService.AddGlobalAsset(reference, asset, CancellationToken.None);
}
// set option
workspace.Options = workspace.Options.WithChangedOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, new CodeStyleOption<bool>(false, NotificationOption.Suggestion));
// run analysis
var project = workspace.CurrentSolution.Projects.First();
var executor = new VisualStudioDiagnosticAnalyzerExecutor(mockAnalyzerService, new MyUpdateSource(workspace));
var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers(analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray());
var result = await executor.AnalyzeAsync(analyzerDriver, project, CancellationToken.None);
var analyzerResult = result.AnalysisResult[analyzerDriver.Analyzers[0]];
// check result
var diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()];
Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id);
}
}
private static async Task<DiagnosticAnalysisResult> AnalyzeAsync(TestWorkspace workspace, ProjectId projectId, Type analyzerType, CancellationToken cancellationToken = default(CancellationToken))
{
var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticAnalyzerService>();
......@@ -146,6 +194,13 @@ private async Task<TestWorkspace> CreateWorkspaceAsync(string language, string c
return workspace;
}
private IDiagnosticAnalyzerService CreateMockDiagnosticAnalyzerService(IEnumerable<AnalyzerReference> references)
{
var mock = new Mock<IDiagnosticAnalyzerService>(MockBehavior.Strict);
mock.Setup(a => a.GetHostAnalyzerReferences()).Returns(references);
return mock.Object;
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
private class MyAnalyzer : DiagnosticAnalyzer
{
......
......@@ -181,9 +181,7 @@
<None Include="app.config" />
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="RemoteWorkspace\" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<InternalsVisibleToMoq Include="DynamicProxyGenAssembly2" />
</ItemGroup>
......@@ -191,7 +189,12 @@
<Compile Include="Mocks\TestHostServices.cs" />
<Compile Include="Mocks\InProcRemoteHostClientFactory.cs" />
<Compile Include="Remote\RemoteHostClientServiceFactoryTests.cs" />
<Compile Include="ServiceHub\CalculateDiagnosticsTests.cs" />
<Compile Include="Services\ChecksumUtils.cs" />
<Compile Include="Services\SolutionServiceTests.cs" />
<Compile Include="Services\AssetStorageTests.cs" />
<Compile Include="Services\AssetServiceTests.cs" />
<Compile Include="Services\ServiceHubServicesTests.cs" />
<Compile Include="Services\VisualStudioDiagnosticAnalyzerExecutorTests.cs" />
</ItemGroup>
<Import Project="..\..\..\..\build\Targets\Imports.targets" />
</Project>
\ No newline at end of file
......@@ -32,7 +32,7 @@ public Storage(AssetStorages owner, SolutionState solutionState)
{
SolutionState = solutionState;
_serializer = new Serializer(SolutionState.Workspace.Services);
_serializer = new Serializer(SolutionState.Workspace);
}
public SolutionState SolutionState { get; }
......
......@@ -4,6 +4,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Serialization;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Execution
{
......@@ -14,9 +15,17 @@ internal class CustomAssetBuilder
{
private readonly Serializer _serializer;
public CustomAssetBuilder(Solution solution)
public CustomAssetBuilder(Solution solution) : this(solution.Workspace)
{
_serializer = new Serializer(solution.Workspace.Services);
}
public CustomAssetBuilder(Workspace workspace) : this(workspace.Services)
{
}
public CustomAssetBuilder(HostWorkspaceServices services)
{
_serializer = new Serializer(services);
}
public CustomAsset Build(OptionSet options, string language, CancellationToken cancellationToken)
......
......@@ -25,6 +25,14 @@ internal partial class Serializer
private readonly IReferenceSerializationService _hostSerializationService;
private readonly ConcurrentDictionary<string, IOptionsSerializationService> _lazyLanguageSerializationService;
public Serializer(Solution solution) : this(solution.Workspace)
{
}
public Serializer(Workspace workspace) : this(workspace.Services)
{
}
public Serializer(HostWorkspaceServices workspaceServices)
{
_workspaceServices = workspaceServices;
......
......@@ -29,7 +29,7 @@ private async Task<ProjectStateChecksums> ComputeChecksumsAsync(CancellationToke
var documentChecksumsTasks = DocumentIds.Select(id => DocumentStates[id].GetChecksumAsync(cancellationToken));
var additionalDocumentChecksumTasks = AdditionalDocumentIds.Select(id => AdditionalDocumentStates[id].GetChecksumAsync(cancellationToken));
var serializer = new Serializer(_solutionServices.Workspace.Services);
var serializer = new Serializer(_solutionServices.Workspace);
var infoChecksum = serializer.CreateChecksum(ProjectInfo.Attributes, cancellationToken);
......
......@@ -28,7 +28,7 @@ private async Task<SolutionStateChecksums> ComputeChecksumsAsync(CancellationTok
// get states by id order to have deterministic checksum
var projectChecksumTasks = ProjectIds.Select(id => ProjectStates[id].GetChecksumAsync(cancellationToken));
var serializer = new Serializer(_solutionServices.Workspace.Services);
var serializer = new Serializer(_solutionServices.Workspace);
var infoChecksum = serializer.CreateChecksum(SolutionInfo.Attributes, cancellationToken);
var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false);
......
......@@ -265,6 +265,7 @@ public DocumentStateChecksums With(Checksum infoChecksum = null, Checksum textCh
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
// verify input
Contract.ThrowIfFalse(state.TryGetStateChecksums(out var stateChecksum));
Contract.ThrowIfFalse(this == stateChecksum);
......
......@@ -27,7 +27,7 @@ private async Task<DocumentStateChecksums> ComputeChecksumsAsync(CancellationTok
{
var textTask = GetTextAsync(cancellationToken);
var serializer = new Serializer(solutionServices.Workspace.Services);
var serializer = new Serializer(solutionServices.Workspace);
var infoChecksum = serializer.CreateChecksum(Info.Attributes, cancellationToken);
var textChecksum = serializer.CreateChecksum(await textTask.ConfigureAwait(false), cancellationToken);
......
......@@ -232,7 +232,7 @@ public async Task MetadataReference_RoundTrip_Test()
var workspace = new AdhocWorkspace(hostServices);
var reference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var serializer = new Serializer(workspace.Services);
var serializer = new Serializer(workspace);
var assetFromFile = SolutionAsset.Create(serializer.CreateChecksum(reference, CancellationToken.None), reference, serializer);
var assetFromStorage = await CloneAssetAsync(serializer, assetFromFile).ConfigureAwait(false);
......@@ -347,7 +347,7 @@ public async Task OptionSet_Serialization_CustomValue()
public async Task Missing_Metadata_Serailization_Test()
{
var workspace = new AdhocWorkspace();
var serializer = new Serializer(workspace.Services);
var serializer = new Serializer(workspace);
var reference = new MissingMetadataReference();
......@@ -361,7 +361,7 @@ public async Task Missing_Metadata_Serailization_Test()
public async Task Missing_Analyzer_Serailization_Test()
{
var workspace = new AdhocWorkspace();
var serializer = new Serializer(workspace.Services);
var serializer = new Serializer(workspace);
var reference = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());
......@@ -378,7 +378,7 @@ public async Task Missing_Analyzer_Serailization_Desktop_Test()
MefHostServices.DefaultAssemblies.Add(typeof(Host.TemporaryStorageServiceFactory.TemporaryStorageService).Assembly));
var workspace = new AdhocWorkspace(hostServices);
var serializer = new Serializer(workspace.Services);
var serializer = new Serializer(workspace);
var reference = new AnalyzerFileReference("missing_reference", new MissingAnalyzerLoader());
......@@ -429,7 +429,7 @@ public async Task UnknownLanguageTest()
public async Task EmptyAssetChecksumTest()
{
var document = new AdhocWorkspace().CurrentSolution.AddProject("empty", "empty", LanguageNames.CSharp).AddDocument("empty", SourceText.From(""));
var serializer = new Serializer(document.Project.Solution.Workspace.Services);
var serializer = new Serializer(document.Project.Solution);
var source = serializer.CreateChecksum(await document.GetTextAsync().ConfigureAwait(false), CancellationToken.None);
var metadata = serializer.CreateChecksum(new MissingMetadataReference(), CancellationToken.None);
......@@ -454,8 +454,8 @@ public async Task VBParseOptionsInCompilationOptions()
private static async Task VerifyOptionSetsAsync(Workspace workspace, string language)
{
var assetBuilder = new CustomAssetBuilder(workspace.CurrentSolution);
var serializer = new Serializer(workspace.Services);
var assetBuilder = new CustomAssetBuilder(workspace);
var serializer = new Serializer(workspace);
var asset = assetBuilder.Build(workspace.Options, language, CancellationToken.None);
......
......@@ -21,7 +21,7 @@ namespace Microsoft.CodeAnalysis.Remote
internal class AssetService
{
// PREVIEW: unfortunately, I need dummy workspace since workspace services can be workspace specific
private static readonly Serializer s_serializer = new Serializer(new AdhocWorkspace(RoslynServices.HostServices, workspaceKind: "dummy").Services);
private static readonly Serializer s_serializer = new Serializer(new AdhocWorkspace(RoslynServices.HostServices, workspaceKind: "dummy"));
private readonly int _sessionId;
private readonly AssetStorage _assetStorage;
......
......@@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.Remote
/// </summary>
internal class AssetStorage
{
public static readonly AssetStorage Default = new AssetStorage();
public static readonly AssetStorage Default = new AssetStorage(enableCleanup: true);
private const int CleanupInterval = 3; // 3 minutes
private const int PurgeAfter = 30; // 30 minutes
......@@ -30,9 +30,12 @@ internal class AssetStorage
private readonly ConcurrentDictionary<Checksum, Entry> _assets =
new ConcurrentDictionary<Checksum, Entry>(concurrencyLevel: 4, capacity: 10);
public AssetStorage()
public AssetStorage(bool enableCleanup)
{
Task.Run(CleanAssetsAsync, CancellationToken.None);
if (enableCleanup)
{
Task.Run(CleanAssetsAsync, CancellationToken.None);
}
}
public AssetSource TryGetAssetSource(int sessionId)
......
......@@ -78,8 +78,6 @@
<InternalsVisibleToTest Include="Roslyn.Services.Test.Utilities2" />
<InternalsVisibleToTest Include="Roslyn.VisualStudio.Next.UnitTests" />
</ItemGroup>
<ItemGroup>
<Folder Include="Storage\" />
</ItemGroup>
<ItemGroup />
<Import Project="..\..\..\..\build\Targets\Imports.targets" />
</Project>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册