提交 67ad810c 编写于 作者: M Manish Vasani

Address PR feedback

上级 106fe577
......@@ -298,7 +298,7 @@ private static void TestDescriptorIsExceptionSafeCore(DiagnosticDescriptor descr
var exceptionDiagnostics = new List<Diagnostic>();
Action<Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException = (ex, a, diag) => exceptionDiagnostics.Add(diag);
var analyzerManager = new AnalyzerManager();
var analyzerManager = new AnalyzerManager(analyzer);
var analyzerExecutor = AnalyzerExecutor.CreateForSupportedDiagnostics(onAnalyzerException, analyzerManager);
var descriptors = analyzerManager.GetSupportedDiagnosticDescriptors(analyzer, analyzerExecutor);
......
......@@ -577,7 +577,7 @@ private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancellat
if (!analyzers.IsEmpty)
{
analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
analyzerManager = new AnalyzerManager();
analyzerManager = new AnalyzerManager(analyzers);
analyzerExceptionDiagnostics = new ConcurrentSet<Diagnostic>();
Action<Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic);
var analyzerOptions = new AnalyzerOptions(ImmutableArray<AdditionalText>.CastUp(additionalTextFiles));
......
......@@ -14,24 +14,22 @@ private sealed class AnalyzerExecutionContext
{
private readonly object _gate = new object();
// Task to compute HostSessionStartAnalysisScope for session wide analyzer actions, i.e. AnalyzerActions registered by analyzer's Initialize method.
// These are run only once per every analyzer.
/// <summary>
/// Task to compute HostSessionStartAnalysisScope for session wide analyzer actions, i.e. AnalyzerActions registered by analyzer's Initialize method.
/// These are run only once per every analyzer.
/// </summary>
private Task<HostSessionStartAnalysisScope> _lazySessionScopeTask;
// This map stores the tasks to compute HostCompilationStartAnalysisScope for per-compilation analyzer actions, i.e. AnalyzerActions registered by analyzer's CompilationStartActions.
// Compilation start actions will get executed once per-each AnalyzerAndOptions as user might want to return different set of custom actions for each compilation/analyzer options.
private readonly Dictionary<AnalyzerOptions, Task<HostCompilationStartAnalysisScope>> _compilationScopeMap;
/// <summary>
/// Task to compute HostCompilationStartAnalysisScope for per-compilation analyzer actions, i.e. AnalyzerActions registered by analyzer's CompilationStartActions.
/// </summary>
private Task<HostCompilationStartAnalysisScope> _lazyCompilationScopeTask;
/// <summary>
/// Supported descriptors for diagnostic analyzer.
/// </summary>
private ImmutableArray<DiagnosticDescriptor> _lazyDescriptors = default(ImmutableArray<DiagnosticDescriptor>);
public AnalyzerExecutionContext()
{
_compilationScopeMap = new Dictionary<AnalyzerOptions, Task<HostCompilationStartAnalysisScope>>();
}
public Task<HostSessionStartAnalysisScope> GetSessionAnalysisScopeTask(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor)
{
lock (_gate)
......@@ -68,28 +66,25 @@ public void ClearSessionScopeTask()
{
lock (_gate)
{
Task<HostCompilationStartAnalysisScope> task;
if (!_compilationScopeMap.TryGetValue(analyzerExecutor.AnalyzerOptions, out task))
if (_lazyCompilationScopeTask == null)
{
task = Task.Run(() =>
_lazyCompilationScopeTask = Task.Run(() =>
{
var compilationAnalysisScope = new HostCompilationStartAnalysisScope(sessionScope);
analyzerExecutor.ExecuteCompilationStartActions(sessionScope.CompilationStartActions, compilationAnalysisScope);
return compilationAnalysisScope;
}, analyzerExecutor.CancellationToken);
_compilationScopeMap.Add(analyzerExecutor.AnalyzerOptions, task);
}
return task;
return _lazyCompilationScopeTask;
}
}
public void ClearCompilationScopeMap(AnalyzerOptions analyzerOptions)
public void ClearCompilationScopeTask()
{
lock (_gate)
{
_compilationScopeMap.Remove(analyzerOptions);
_lazyCompilationScopeTask = null;
}
}
......
......@@ -3,8 +3,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics
{
......@@ -22,24 +22,31 @@ internal partial class AnalyzerManager
private readonly object _gate = new object();
// This cache stores the analyzer execution context per-analyzer (i.e. registered actions, supported descriptors, etc.).
private readonly Dictionary<DiagnosticAnalyzer, AnalyzerExecutionContext> _analyzerExecutionContextMap =
new Dictionary<DiagnosticAnalyzer, AnalyzerExecutionContext>();
private readonly ImmutableDictionary<DiagnosticAnalyzer, AnalyzerExecutionContext> _analyzerExecutionContextMap;
private AnalyzerExecutionContext GetAnalyzerExecutionContext(DiagnosticAnalyzer analyzer)
public AnalyzerManager(ImmutableArray<DiagnosticAnalyzer> analyzers)
{
AnalyzerExecutionContext analyzerExecutionContext;
lock (_gate)
_analyzerExecutionContextMap = CreateAnalyzerExecutionContextMap(analyzers);
}
public AnalyzerManager(DiagnosticAnalyzer analyzer)
{
_analyzerExecutionContextMap = CreateAnalyzerExecutionContextMap(SpecializedCollections.SingletonEnumerable(analyzer));
}
private ImmutableDictionary<DiagnosticAnalyzer, AnalyzerExecutionContext> CreateAnalyzerExecutionContextMap(IEnumerable<DiagnosticAnalyzer> analyzers)
{
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, AnalyzerExecutionContext>();
foreach (var analyzer in analyzers)
{
if (!_analyzerExecutionContextMap.TryGetValue(analyzer, out analyzerExecutionContext))
{
analyzerExecutionContext = new AnalyzerExecutionContext();
_analyzerExecutionContextMap.Add(analyzer, analyzerExecutionContext);
}
builder.Add(analyzer, new AnalyzerExecutionContext());
}
return analyzerExecutionContext;
return builder.ToImmutable();
}
private AnalyzerExecutionContext GetAnalyzerExecutionContext(DiagnosticAnalyzer analyzer) => _analyzerExecutionContextMap[analyzer];
private async Task<HostCompilationStartAnalysisScope> GetCompilationAnalysisScopeAsync(
DiagnosticAnalyzer analyzer,
HostSessionStartAnalysisScope sessionScope,
......@@ -61,8 +68,8 @@ private AnalyzerExecutionContext GetAnalyzerExecutionContext(DiagnosticAnalyzer
catch (OperationCanceledException)
{
// Task to compute the scope was cancelled.
// Clear the entry in scope map for analyzer, so we can attempt a retry.
analyzerExecutionContext.ClearCompilationScopeMap(analyzerExecutor.AnalyzerOptions);
// Clear the compilation scope for analyzer, so we can attempt a retry.
analyzerExecutionContext.ClearCompilationScopeTask();
analyzerExecutor.CancellationToken.ThrowIfCancellationRequested();
return await GetCompilationAnalysisScopeCoreAsync(sessionScope, analyzerExecutor, analyzerExecutionContext).ConfigureAwait(false);
......
......@@ -132,7 +132,7 @@ private CompilationWithAnalyzers(Compilation compilation, ImmutableArray<Diagnos
_compilationData = new CompilationData(_compilation);
_analysisState = new AnalysisState(analyzers, _compilationData, _compilation.Options);
_analysisResultBuilder = new AnalysisResultBuilder(analysisOptions.LogAnalyzerExecutionTime, analyzers);
_analyzerManager = new AnalyzerManager();
_analyzerManager = new AnalyzerManager(analyzers);
_driverPool = new ObjectPool<AnalyzerDriver>(() => _compilation.AnalyzerForLanguage(analyzers, _analyzerManager));
_executingConcurrentTreeTasksOpt = analysisOptions.ConcurrentAnalysis ? new Dictionary<SyntaxTree, Tuple<Task, CancellationTokenSource>>() : null;
_concurrentTreeTaskTokensOpt = analysisOptions.ConcurrentAnalysis ? new Dictionary<Task, int>() : null;
......@@ -1131,7 +1131,7 @@ private static IEnumerable<Diagnostic> GetEffectiveDiagnosticsImpl(ImmutableArra
throw new ArgumentNullException(nameof(options));
}
var analyzerManager = new AnalyzerManager();
var analyzerManager = new AnalyzerManager(analyzer);
var analyzerExecutor = AnalyzerExecutor.CreateForSupportedDiagnostics(onAnalyzerException, analyzerManager);
return AnalyzerDriver.IsDiagnosticAnalyzerSuppressed(analyzer, options, analyzerManager, analyzerExecutor);
}
......
......@@ -227,7 +227,7 @@ public static TCompilation VerifyDiagnostics<TCompilation>(this TCompilation c,
c = (TCompilation)c.WithOptions(c.Options.WithReportSuppressedDiagnostics(reportSuppressedDiagnostics));
}
var analyzerManager = new AnalyzerManager();
var analyzerManager = new AnalyzerManager(analyzersArray);
Compilation newCompilation;
var driver = AnalyzerDriver.CreateAndAttachToCompilation(c, analyzersArray, options, analyzerManager, onAnalyzerException, null, false, out newCompilation, CancellationToken.None);
var discarded = newCompilation.GetDiagnostics();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册