提交 69f9e6f7 编写于 作者: H Heejae Chang 提交者: GitHub

Merge pull request #14629 from heejaechang/projectcache

implements IProjectCacheHostService in OOP.
......@@ -623,8 +623,6 @@
<Compile Include="Implementation\Workspaces\EditorErrorReportingServiceFactory.cs" />
<Compile Include="Implementation\Workspaces\ProjectCacheServiceFactory.cs" />
<Compile Include="Implementation\Workspaces\EditorTextFactoryService.cs" />
<Compile Include="Implementation\Workspaces\ProjectCacheService.cs" />
<Compile Include="Implementation\Workspaces\ProjectCacheService.SimpleMRUCache.cs" />
<Compile Include="Implementation\Workspaces\TextUndoHistoryWorkspaceServiceFactoryService.cs" />
<Compile Include="Implementation\Workspaces\WorkspaceTaskSchedulerFactoryFactory.cs" />
<Compile Include="IRefactorNotifyService.cs" />
......
......@@ -14,6 +14,11 @@ internal partial class ProjectCacheHostServiceFactory : IWorkspaceServiceFactory
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
if (workspaceServices.Workspace.Kind != WorkspaceKind.Host)
{
return new ProjectCacheService(workspaceServices.Workspace);
}
var service = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS);
// Also clear the cache when the solution is cleared or removed.
......
......@@ -58,6 +58,7 @@
<InternalsVisibleTo Include="MonoDevelop.Refactoring" />
<InternalsVisibleTo Include="MonoDevelop.CSharpBinding" />
<InternalsVisibleTo Include="MonoDevelop.VBNetBinding" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Remote.Workspaces" />
<InternalsVisibleToTest Include="Roslyn.DebuggerVisualizers" />
<InternalsVisibleTo Include="Roslyn.Hosting.Diagnostics" />
<InternalsVisibleToTest Include="Roslyn.InteractiveHost.UnitTests" />
......@@ -681,6 +682,8 @@
<Compile Include="UseObjectInitializer\AbstractUseObjectInitializerCodeFixProvider.cs" />
<Compile Include="Workspace\BackgroundCompiler.cs" />
<Compile Include="Workspace\BackgroundParser.cs" />
<Compile Include="Workspace\ProjectCacheService.cs" />
<Compile Include="Workspace\ProjectCacheService.SimpleMRUCache.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FeaturesResources.resx">
......
......@@ -3,12 +3,11 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces
namespace Microsoft.CodeAnalysis.Host
{
internal partial class ProjectCacheService : IProjectCacheHostService
{
......
......@@ -6,7 +6,7 @@
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces
namespace Microsoft.CodeAnalysis.Host
{
/// <summary>
/// This service will implicitly cache previous Compilations used by each supported Workspace implementation.
......@@ -27,18 +27,18 @@ internal partial class ProjectCacheService : IProjectCacheHostService
private readonly SimpleMRUCache _implicitCache;
private readonly ImplicitCacheMonitor _implicitCacheMonitor;
public ProjectCacheService(Workspace workspace)
{
_workspace = workspace;
}
public ProjectCacheService(Workspace workspace, int implicitCacheTimeout)
{
_workspace = workspace;
// Only create implicit cache for Visual Studio Workspace (the cost of the
// cache likely outweighs the benefit for the other types of Workspaces).
if (workspace?.Kind == WorkspaceKind.Host)
{
_implicitCache = new SimpleMRUCache();
_implicitCacheMonitor = new ImplicitCacheMonitor(this, implicitCacheTimeout);
}
_implicitCache = new SimpleMRUCache();
_implicitCacheMonitor = new ImplicitCacheMonitor(this, implicitCacheTimeout);
}
public bool IsImplicitCacheEmpty
......
......@@ -27,6 +27,11 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
private static IWorkspaceService GetMiscProjectCache(HostWorkspaceServices workspaceServices)
{
if (workspaceServices.Workspace.Kind != WorkspaceKind.Host)
{
return new ProjectCacheService(workspaceServices.Workspace);
}
var projectCacheService = new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS);
// Also clear the cache when the solution is cleared or removed.
......
......@@ -8,6 +8,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.Telemetry;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
using Roslyn.Utilities;
......@@ -39,6 +40,20 @@ public DiagnosticComputer(Project project)
return DiagnosticAnalysisResultMap.Create(ImmutableDictionary<string, DiagnosticAnalysisResultBuilder>.Empty, ImmutableDictionary<string, AnalyzerTelemetryInfo>.Empty);
}
var cacheService = _project.Solution.Workspace.Services.GetService<IProjectCacheService>();
using (var cache = cacheService.EnableCaching(_project.Id))
{
return await AnalyzeAsync(analyzerMap, analyzers, reportSuppressedDiagnostics, logAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false);
}
}
private async Task<DiagnosticAnalysisResultMap<string, DiagnosticAnalysisResultBuilder>> AnalyzeAsync(
BidirectionalMap<string, DiagnosticAnalyzer> analyzerMap,
ImmutableArray<DiagnosticAnalyzer> analyzers,
bool reportSuppressedDiagnostics,
bool logAnalyzerExecutionTime,
CancellationToken cancellationToken)
{
var compilation = await _project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
// TODO: can we support analyzerExceptionFilter in remote host?
......@@ -70,9 +85,10 @@ public DiagnosticComputer(Project project)
var builderMap = analysisResult.ToResultBuilderMap(_project, VersionStamp.Default, compilation, analysisResult.Analyzers, cancellationToken);
return DiagnosticAnalysisResultMap.Create(builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value),
analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value),
_exceptions.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value.ToImmutableArray()));
return DiagnosticAnalysisResultMap.Create(
builderMap.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value),
analysisResult.AnalyzerTelemetryInfo.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value),
_exceptions.ToImmutableDictionary(kv => GetAnalyzerId(analyzerMap, kv.Key), kv => kv.Value.ToImmutableArray()));
}
private void OnAnalyzerException(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diagnostic)
......
......@@ -68,7 +68,9 @@
<Compile Include="Services\AssetSource.cs" />
<Compile Include="Services\AssetService.cs" />
<Compile Include="Services\AssetStorage.cs" />
<Compile Include="Services\ChecksumSourceText.cs" />
<Compile Include="Services\CompilationService.cs" />
<Compile Include="Services\ProjectCacheHostServiceFactory.cs" />
<Compile Include="Services\RoslynServices.cs" />
<Compile Include="Services\SolutionService.cs" />
<Compile Include="Storage\RemotePersistentStorageLocationService.cs" />
......
// 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.IO;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Remote
{
/// <summary>
/// source text that has checksum tied to it
/// </summary>
internal class ChecksumSourceText : SourceText
{
private readonly SourceText _sourceText;
public ChecksumSourceText(Checksum checksum, SourceText sourceText)
{
Checksum = checksum;
_sourceText = sourceText;
}
public Checksum Checksum { get; }
public override char this[int position] => _sourceText[position];
public override Encoding Encoding => _sourceText.Encoding;
public override int Length => _sourceText.Length;
public override SourceTextContainer Container => _sourceText.Container;
public override SourceText WithChanges(IEnumerable<TextChange> changes) => _sourceText.WithChanges(changes);
public override SourceText GetSubText(TextSpan span) => _sourceText.GetSubText(span);
public override IReadOnlyList<TextChange> GetTextChanges(SourceText oldText) => _sourceText.GetTextChanges(oldText);
public override IReadOnlyList<TextChangeRange> GetChangeRanges(SourceText oldText) => _sourceText.GetChangeRanges(oldText);
public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) =>
_sourceText.CopyTo(sourceIndex, destination, destinationIndex, count);
public override void Write(TextWriter writer, TextSpan span, CancellationToken cancellationToken = default(CancellationToken)) =>
_sourceText.Write(writer, span, cancellationToken);
public override bool Equals(object obj) => _sourceText.Equals(obj);
public override int GetHashCode() => _sourceText.GetHashCode();
public override string ToString() => _sourceText.ToString();
public override string ToString(TextSpan span) => _sourceText.ToString(span);
protected override TextLineCollection GetLinesCore() => _sourceText.Lines;
protected override bool ContentEqualsImpl(SourceText other)
{
var otherChecksum = other as ChecksumSourceText;
if (otherChecksum != null)
{
return Checksum == otherChecksum.Checksum;
}
return _sourceText.ContentEquals(other);
}
}
}
// 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.Composition;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.CodeAnalysis.Remote
{
[ExportWorkspaceServiceFactory(typeof(IProjectCacheHostService), ServiceLayer.Host)]
[Shared]
internal partial class ProjectCacheHostServiceFactory : IWorkspaceServiceFactory
{
private const int ImplicitCacheTimeoutInMS = 10000;
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
return new ProjectCacheService(workspaceServices.Workspace, ImplicitCacheTimeoutInMS);
}
}
}
......@@ -102,7 +102,9 @@ private async Task<Solution> CreateSolutionAsync(Checksum solutionChecksum, Canc
var textLoader = TextLoader.From(
TextAndVersion.Create(
await _assetService.GetAssetAsync<SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false),
new ChecksumSourceText(
documentSnapshot.Text,
await _assetService.GetAssetAsync<SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false)),
VersionStamp.Create(),
documentInfo.FilePath));
......@@ -155,7 +157,9 @@ private async Task<Solution> CreateSolutionAsync(Checksum solutionChecksum, Canc
var textLoader = TextLoader.From(
TextAndVersion.Create(
await _assetService.GetAssetAsync<SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false),
new ChecksumSourceText(
documentSnapshot.Text,
await _assetService.GetAssetAsync<SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false)),
VersionStamp.Create(),
documentInfo.FilePath));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册