提交 f4591e0c 编写于 作者: M Manish Vasani

Checkin current changes

上级 953ce91b
......@@ -9,7 +9,7 @@
<Import_RootNamespace>AnalyzerDriver</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)AnalyzerDriverHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)AnalyzerManager_ExecuteHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)AnalyzerExceptionDiagnosticArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)AnalyzerManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)DeclarationComputer.cs" />
......
......@@ -12,20 +12,24 @@
namespace Microsoft.CodeAnalysis.Diagnostics
{
/// <summary>
/// Manages properties of analyzers (such as registered actions, supported diagnostics) for analyzer host's lifetime.
/// Manages properties of analyzers (such as registered actions, supported diagnostics) for analyzer host's lifetime
/// and executes the callbacks into the analyzers.
///
/// It ensures the following for the lifetime of analyzer host:
/// 1) <see cref="DiagnosticAnalyzer.Initialize(AnalysisContext)"/> is invoked only once per-analyzer.
/// 2) <see cref="DiagnosticAnalyzer.SupportedDiagnostics"/> is invoked only once per-analyzer.
/// 3) <see cref="CompilationStartAnalyzerAction"/> registered during Initialize are invoked only once per-analyzer per-compilation.
/// </summary>
internal class AnalyzerManager
internal partial class AnalyzerManager
{
public static readonly AnalyzerManager Default = new AnalyzerManager();
/// <summary>
/// Gets the default instance of the AnalyzerManager for the lifetime of the analyzer host process.
/// </summary>
public static readonly AnalyzerManager Instance = new AnalyzerManager();
// This map stores the tasks 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.
private ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>> _sessionScopeMap =
private readonly ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>> _sessionScopeMap =
new ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>>();
// This map stores the tasks to compute HostCompilationStartAnalysisScope for per-compilation analyzer actions, i.e. AnalyzerActions registered by analyzer's CompilationStartActions.
......@@ -40,7 +44,7 @@ internal class AnalyzerManager
/// </summary>
private readonly ConditionalWeakTable<DiagnosticAnalyzer, IReadOnlyList<DiagnosticDescriptor>> _descriptorCache =
new ConditionalWeakTable<DiagnosticAnalyzer, IReadOnlyList<DiagnosticDescriptor>>();
private Task<HostCompilationStartAnalysisScope> GetCompilationAnalysisScopeCoreAsync(
DiagnosticAnalyzer analyzer,
HostSessionStartAnalysisScope sessionScope,
......@@ -54,7 +58,7 @@ internal class AnalyzerManager
return Task.Run(() =>
{
var compilationAnalysisScope = new HostCompilationStartAnalysisScope(sessionScope);
AnalyzerDriverHelper.ExecuteCompilationStartActions(sessionScope.CompilationStartActions, compilationAnalysisScope, compilation,
ExecuteCompilationStartActions(sessionScope.CompilationStartActions, compilationAnalysisScope, compilation,
analyzerOptions, continueOnAnalyzerException, cancellationToken);
return compilationAnalysisScope;
}, cancellationToken);
......@@ -102,7 +106,7 @@ internal class AnalyzerManager
return Task.Run(() =>
{
var sessionScope = new HostSessionStartAnalysisScope();
AnalyzerDriverHelper.ExecuteInitializeMethod(a, sessionScope, continueOnAnalyzerException, cancellationToken);
ExecuteInitializeMethod(a, sessionScope, continueOnAnalyzerException, cancellationToken);
return sessionScope;
}, cancellationToken);
};
......@@ -167,12 +171,121 @@ internal class AnalyzerManager
var supportedDiagnostics = ImmutableArray<DiagnosticDescriptor>.Empty;
// Catch Exception from analyzer.SupportedDiagnostics
AnalyzerDriverHelper.ExecuteAndCatchIfThrows(analyzer, continueOnAnalyzerException, () => { supportedDiagnostics = analyzer.SupportedDiagnostics; }, cancellationToken);
ExecuteAndCatchIfThrows(analyzer, continueOnAnalyzerException, () => { supportedDiagnostics = analyzer.SupportedDiagnostics; }, cancellationToken);
return supportedDiagnostics;
});
return (ImmutableArray<DiagnosticDescriptor>)descriptors;
}
/// <summary>
/// Returns true if all the diagnostics that can be produced by this analyzer are suppressed through options.
/// </summary>
internal bool IsDiagnosticAnalyzerSuppressed(
DiagnosticAnalyzer analyzer,
CompilationOptions options,
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
Func<DiagnosticAnalyzer, bool> isCompilerAnalyzer,
CancellationToken cancellationToken)
{
if (isCompilerAnalyzer(analyzer))
{
// Compiler analyzer must always be executed for compiler errors, which cannot be suppressed or filtered.
return false;
}
var supportedDiagnostics = GetSupportedDiagnosticDescriptors(analyzer, continueOnAnalyzerException, cancellationToken);
var diagnosticOptions = options.SpecificDiagnosticOptions;
foreach (var diag in supportedDiagnostics)
{
if (diag.IsNotConfigurable())
{
// If diagnostic descriptor is not configurable, then diagnostics created through it cannot be suppressed.
return false;
}
// Is this diagnostic suppressed by default (as written by the rule author)
var isSuppressed = !diag.IsEnabledByDefault;
// If the user said something about it, that overrides the author.
if (diagnosticOptions.ContainsKey(diag.Id))
{
isSuppressed = diagnosticOptions[diag.Id] == ReportDiagnostic.Suppress;
}
if (isSuppressed)
{
continue;
}
else
{
return false;
}
}
return true;
}
internal static bool HasNotConfigurableTag(IEnumerable<string> customTags)
{
foreach (var customTag in customTags)
{
if (customTag == WellKnownDiagnosticTags.NotConfigurable)
{
return true;
}
}
return false;
}
internal EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Diagnostic, bool> addAnalyzerExceptionDiagnostic)
{
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic =
(sender, args) => addAnalyzerExceptionDiagnostic(args.Diagnostic);
return RegisterAnalyzerExceptionDiagnosticHandler(analyzers, onAnalyzerExceptionDiagnostic);
}
internal EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(ImmutableArray<DiagnosticAnalyzer> analyzers, Action<object, AnalyzerExceptionDiagnosticArgs> onAnayzerExceptionDiagnostic)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (analyzers.Contains(args.FaultedAnalyzer))
{
onAnayzerExceptionDiagnostic(sender, args);
}
};
_analyzerExceptionDiagnostic += handler;
return handler;
}
internal EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer, Func<Diagnostic, bool> addAnalyzerExceptionDiagnostic)
{
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic =
(sender, args) => addAnalyzerExceptionDiagnostic(args.Diagnostic);
return RegisterAnalyzerExceptionDiagnosticHandler(analyzer, onAnalyzerExceptionDiagnostic);
}
internal EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer, Action<object, AnalyzerExceptionDiagnosticArgs> onAnayzerExceptionDiagnostic)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (analyzer == args.FaultedAnalyzer)
{
onAnayzerExceptionDiagnostic(sender, args);
}
};
_analyzerExceptionDiagnostic += handler;
return handler;
}
internal void UnregisterAnalyzerExceptionDiagnosticHandler(EventHandler<AnalyzerExceptionDiagnosticArgs> handler)
{
_analyzerExceptionDiagnostic -= handler;
}
}
}
......@@ -11,12 +11,12 @@
namespace Microsoft.CodeAnalysis.Diagnostics
{
internal class AnalyzerDriverHelper
internal partial class AnalyzerManager
{
private const string DiagnosticId = "AD0001";
private const string DiagnosticCategory = "Compiler";
private static event EventHandler<AnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
private event EventHandler<AnalyzerExceptionDiagnosticArgs> _analyzerExceptionDiagnostic;
/// <summary>
/// Executes the <see cref="DiagnosticAnalyzer.Initialize(AnalysisContext)"/> for the given analyzer.
......@@ -30,7 +30,7 @@ internal class AnalyzerDriverHelper
/// Use <see cref="ExecuteCompilationStartActions(ImmutableArray{CompilationStartAnalyzerAction}, HostCompilationStartAnalysisScope, Compilation, AnalyzerOptions, Func{Exception, DiagnosticAnalyzer, bool}, CancellationToken)"/> API
/// to get execute these actions to get the per-compilation analyzer actions.
/// </remarks>
public static void ExecuteInitializeMethod(
public void ExecuteInitializeMethod(
DiagnosticAnalyzer analyzer,
HostSessionStartAnalysisScope sessionScope,
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
......@@ -52,7 +52,7 @@ internal class AnalyzerDriverHelper
/// <param name="analyzerOptions">Analyzer options.</param>
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteCompilationStartActions(
public void ExecuteCompilationStartActions(
ImmutableArray<CompilationStartAnalyzerAction> actions,
HostCompilationStartAnalysisScope compilationScope,
Compilation compilation,
......@@ -79,7 +79,7 @@ internal class AnalyzerDriverHelper
/// <param name="addDiagnostic">Delegate to add diagnostics.</param>
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteCompilationEndActions(
public void ExecuteCompilationEndActions(
AnalyzerActions actions,
Compilation compilation,
AnalyzerOptions analyzerOptions,
......@@ -110,7 +110,7 @@ internal class AnalyzerDriverHelper
/// <param name="addDiagnostic">Delegate to add diagnostics.</param>
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteSymbolActions(
public void ExecuteSymbolActions(
AnalyzerActions actions,
IEnumerable<ISymbol> symbols,
Compilation compilation,
......@@ -146,7 +146,7 @@ internal class AnalyzerDriverHelper
/// <param name="addDiagnostic">Delegate to add diagnostics.</param>
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteSemanticModelActions(
public void ExecuteSemanticModelActions(
AnalyzerActions actions,
SemanticModel semanticModel,
AnalyzerOptions analyzerOptions,
......@@ -176,7 +176,7 @@ internal class AnalyzerDriverHelper
/// <param name="addDiagnostic">Delegate to add diagnostics.</param>
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteSyntaxTreeActions(
public void ExecuteSyntaxTreeActions(
AnalyzerActions actions,
SyntaxTree syntaxTree,
AnalyzerOptions analyzerOptions,
......@@ -208,7 +208,7 @@ internal class AnalyzerDriverHelper
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
/// <param name="getKind">Delegate to compute language specific syntax kind for a syntax node.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteSyntaxNodeActions<TLanguageKindEnum>(
public void ExecuteSyntaxNodeActions<TLanguageKindEnum>(
AnalyzerActions actions,
IEnumerable<SyntaxNode> nodes,
SemanticModel semanticModel,
......@@ -236,7 +236,7 @@ internal class AnalyzerDriverHelper
}
}
internal static void ExecuteSyntaxNodeAction(
internal void ExecuteSyntaxNodeAction(
Action<SyntaxNodeAnalysisContext> syntaxNodeAction,
SyntaxNode node,
DiagnosticAnalyzer analyzer,
......@@ -263,7 +263,7 @@ internal class AnalyzerDriverHelper
/// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from any action should be handled or not.</param>
/// <param name="getKind">Delegate to compute language specific syntax kind for a syntax node.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static void ExecuteCodeBlockActions<TLanguageKindEnum>(
public void ExecuteCodeBlockActions<TLanguageKindEnum>(
AnalyzerActions actions,
IEnumerable<DeclarationInfo> declarationsInNode,
SemanticModel semanticModel,
......@@ -296,7 +296,7 @@ internal class AnalyzerDriverHelper
}
}
internal static void ExecuteCodeBlockActions<TLanguageKindEnum>(
internal void ExecuteCodeBlockActions<TLanguageKindEnum>(
IEnumerable<CodeBlockStartAnalyzerAction<TLanguageKindEnum>> codeBlockStartActions,
IEnumerable<CodeBlockEndAnalyzerAction> codeBlockEndActions,
SyntaxNode declaredNode,
......@@ -386,7 +386,7 @@ internal class AnalyzerDriverHelper
return map;
}
internal static void ExecuteSyntaxNodeActions<TLanguageKindEnum>(
internal void ExecuteSyntaxNodeActions<TLanguageKindEnum>(
IEnumerable<SyntaxNode> nodesToAnalyze,
IDictionary<TLanguageKindEnum, ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>> nodeActionsByKind,
SemanticModel model,
......@@ -432,7 +432,7 @@ internal static bool CanHaveExecutableCodeBlock(ISymbol symbol)
}
}
internal static void ExecuteAndCatchIfThrows(DiagnosticAnalyzer analyzer, Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException, Action analyze, CancellationToken cancellationToken)
internal void ExecuteAndCatchIfThrows(DiagnosticAnalyzer analyzer, Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException, Action analyze, CancellationToken cancellationToken)
{
try
{
......@@ -445,7 +445,7 @@ internal static void ExecuteAndCatchIfThrows(DiagnosticAnalyzer analyzer, Func<E
// Raise an event with a diagnostic for analyzer exception
var diagnostic = GetAnalyzerDiagnostic(analyzer, oce);
var args = new AnalyzerExceptionDiagnosticArgs(analyzer, diagnostic);
AnalyzerExceptionDiagnostic?.Invoke(analyze, args);
_analyzerExceptionDiagnostic?.Invoke(analyze, args);
}
}
catch (Exception e) when (continueOnAnalyzerException(e, analyzer))
......@@ -453,7 +453,7 @@ internal static void ExecuteAndCatchIfThrows(DiagnosticAnalyzer analyzer, Func<E
// Raise an event with a diagnostic for analyzer exception
var diagnostic = GetAnalyzerDiagnostic(analyzer, e);
var args = new AnalyzerExceptionDiagnosticArgs(analyzer, diagnostic);
AnalyzerExceptionDiagnostic?.Invoke(analyze, args);
_analyzerExceptionDiagnostic?.Invoke(analyze, args);
}
}
......@@ -490,52 +490,5 @@ internal static bool IsAnalyzerExceptionDiagnostic(Diagnostic diagnostic)
return false;
}
internal static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Diagnostic, bool> addAnalyzerExceptionDiagnostic)
{
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic =
(sender, args) => addAnalyzerExceptionDiagnostic(args.Diagnostic);
return RegisterAnalyzerExceptionDiagnosticHandler(analyzers, onAnalyzerExceptionDiagnostic);
}
internal static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(ImmutableArray<DiagnosticAnalyzer> analyzers, Action<object, AnalyzerExceptionDiagnosticArgs> onAnayzerExceptionDiagnostic)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (analyzers.Contains(args.FaultedAnalyzer))
{
onAnayzerExceptionDiagnostic(sender, args);
}
};
AnalyzerExceptionDiagnostic += handler;
return handler;
}
internal static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer, Func<Diagnostic, bool> addAnalyzerExceptionDiagnostic)
{
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic =
(sender, args) => addAnalyzerExceptionDiagnostic(args.Diagnostic);
return RegisterAnalyzerExceptionDiagnosticHandler(analyzer, onAnalyzerExceptionDiagnostic);
}
internal static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer, Action<object, AnalyzerExceptionDiagnosticArgs> onAnayzerExceptionDiagnostic)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (analyzer == args.FaultedAnalyzer)
{
onAnayzerExceptionDiagnostic(sender, args);
}
};
AnalyzerExceptionDiagnostic += handler;
return handler;
}
internal static void UnregisterAnalyzerExceptionDiagnosticHandler(EventHandler<AnalyzerExceptionDiagnosticArgs> handler)
{
AnalyzerExceptionDiagnostic -= handler;
}
}
}
......@@ -333,14 +333,15 @@ private int RunCore(TextWriter consoleOutput, CancellationToken cancellationToke
var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create<AdditionalText, AdditionalTextFile>(additionalTextFiles));
AnalyzerDriver analyzerDriver = null;
AnalyzerManager analyzerManager = null;
ConcurrentSet<Diagnostic> analyzerExceptionDiagnostics = null;
EventHandler<AnalyzerExceptionDiagnosticArgs> analyzerExceptionDiagnosticsHandler = null;
if (!analyzers.IsDefaultOrEmpty)
{
analyzerManager = new AnalyzerManager();
analyzerExceptionDiagnostics = new ConcurrentSet<Diagnostic>();
analyzerExceptionDiagnosticsHandler = AnalyzerDriverHelper.RegisterAnalyzerExceptionDiagnosticHandler(analyzers, analyzerExceptionDiagnostics.Add);
analyzerExceptionDiagnosticsHandler = analyzerManager.RegisterAnalyzerExceptionDiagnosticHandler(analyzers, analyzerExceptionDiagnostics.Add);
var analyzerManager = new AnalyzerManager();
analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, analyzerOptions, analyzerManager, out compilation, cancellationToken);
}
......@@ -450,7 +451,7 @@ private int RunCore(TextWriter consoleOutput, CancellationToken cancellationToke
{
var analyzerDiagnostics = analyzerDriver.GetDiagnosticsAsync().Result;
var allAnalyzerDiagnostics = analyzerDiagnostics.AddRange(analyzerExceptionDiagnostics);
AnalyzerDriverHelper.UnregisterAnalyzerExceptionDiagnosticHandler(analyzerExceptionDiagnosticsHandler);
analyzerManager.UnregisterAnalyzerExceptionDiagnosticHandler(analyzerExceptionDiagnosticsHandler);
if (PrintErrors(allAnalyzerDiagnostics, consoleOutput))
{
......
......@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.CodeAnalysis
{
......@@ -204,20 +205,7 @@ public override int GetHashCode()
/// </summary>
internal bool IsNotConfigurable()
{
return IsNotConfigurable(this.CustomTags);
}
internal static bool IsNotConfigurable(IEnumerable<string> customTags)
{
foreach (var customTag in customTags)
{
if (customTag == WellKnownDiagnosticTags.NotConfigurable)
{
return true;
}
}
return false;
return AnalyzerManager.HasNotConfigurableTag(this.CustomTags);
}
}
}
......@@ -27,7 +27,7 @@ internal abstract class AnalyzerDriver : IDisposable
private readonly Action<Diagnostic> _addDiagnostic;
private readonly ImmutableArray<DiagnosticAnalyzer> _analyzers;
private readonly CancellationTokenRegistration _queueRegistration;
private readonly AnalyzerManager _analyzerManager;
protected readonly AnalyzerManager analyzerManager;
protected readonly AnalyzerOptions analyzerOptions;
internal readonly Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException;
......@@ -77,7 +77,7 @@ private void Initialize(Compilation comp, CancellationToken cancellationToken)
_compilation = comp;
// Compute the set of effective actions based on suppression, and running the initial analyzers
var analyzerActionsTask = GetAnalyzerActionsAsync(_analyzers, _analyzerManager, comp, analyzerOptions, _addDiagnostic, continueOnAnalyzerException, cancellationToken);
var analyzerActionsTask = GetAnalyzerActionsAsync(_analyzers, analyzerManager, comp, analyzerOptions, continueOnAnalyzerException, cancellationToken);
var initializeTask = analyzerActionsTask.ContinueWith(t =>
{
this.analyzerActions = t.Result;
......@@ -126,7 +126,7 @@ private Task ExecuteSyntaxTreeActions(CancellationToken cancellationToken)
foreach (var syntaxTreeAction in analyzerAndActions)
{
// Catch Exception from executing the action
AnalyzerDriverHelper.ExecuteAndCatchIfThrows(syntaxTreeAction.Analyzer, continueOnAnalyzerException, () =>
analyzerManager.ExecuteAndCatchIfThrows(syntaxTreeAction.Analyzer, continueOnAnalyzerException, () =>
{
var context = new SyntaxTreeAnalysisContext(tree, analyzerOptions, _addDiagnostic, cancellationToken);
syntaxTreeAction.Action(context);
......@@ -201,7 +201,7 @@ protected AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerO
{
_analyzers = analyzers;
this.analyzerOptions = options;
_analyzerManager = analyzerManager;
this.analyzerManager = analyzerManager;
this.CompilationEventQueue = new AsyncQueue<CompilationEvent>();
this.DiagnosticQueue = new AsyncQueue<Diagnostic>();
......@@ -436,7 +436,7 @@ private void AddTasksForExecutingSymbolActions(SymbolDeclaredCompilationEvent sy
Debug.Assert(da.Analyzer == analyzer);
// Catch Exception from analyzing the symbol
AnalyzerDriverHelper.ExecuteAndCatchIfThrows(da.Analyzer, continueOnAnalyzerException, () =>
analyzerManager.ExecuteAndCatchIfThrows(da.Analyzer, continueOnAnalyzerException, () =>
{
cancellationToken.ThrowIfCancellationRequested();
var symbolContext = new SymbolAnalysisContext(symbol, _compilation, this.analyzerOptions, addDiagnosticForSymbol, cancellationToken);
......@@ -483,7 +483,7 @@ private Task ProcessCompilationUnitCompleted(CompilationUnitCompletedEvent compl
Debug.Assert(semanticModelAction.Analyzer == analyzerAndActions.Key);
// Catch Exception from semanticModelAction
AnalyzerDriverHelper.ExecuteAndCatchIfThrows(semanticModelAction.Analyzer, continueOnAnalyzerException, () =>
analyzerManager.ExecuteAndCatchIfThrows(semanticModelAction.Analyzer, continueOnAnalyzerException, () =>
{
cancellationToken.ThrowIfCancellationRequested();
var semanticModelContext = new SemanticModelAnalysisContext(semanticModel, this.analyzerOptions, _addDiagnostic, cancellationToken);
......@@ -519,7 +519,7 @@ private async Task ProcessCompilationCompletedAsync(CompilationCompletedEvent en
Debug.Assert(endAction.Analyzer == analyzerAndActions.Key);
// Catch Exception from endAction
AnalyzerDriverHelper.ExecuteAndCatchIfThrows(endAction.Analyzer, continueOnAnalyzerException, () =>
analyzerManager.ExecuteAndCatchIfThrows(endAction.Analyzer, continueOnAnalyzerException, () =>
{
cancellationToken.ThrowIfCancellationRequested();
var compilationContext = new CompilationEndAnalysisContext(_compilation, this.analyzerOptions, _addDiagnostic, cancellationToken);
......@@ -703,7 +703,6 @@ internal protected Action<Diagnostic> GetDiagnosticSinkWithSuppression(ISymbol s
AnalyzerManager analyzerManager,
Compilation compilation,
AnalyzerOptions analyzerOptions,
Action<Diagnostic> addDiagnostic,
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
CancellationToken cancellationToken)
{
......@@ -712,7 +711,7 @@ internal protected Action<Diagnostic> GetDiagnosticSinkWithSuppression(ISymbol s
AnalyzerActions allAnalyzerActions = new AnalyzerActions();
foreach (var analyzer in analyzers)
{
if (!IsDiagnosticAnalyzerSuppressed(analyzer, analyzerManager, compilation.Options, addDiagnostic, continueOnAnalyzerException, cancellationToken))
if (!IsDiagnosticAnalyzerSuppressed(analyzer, analyzerManager, compilation.Options, continueOnAnalyzerException, cancellationToken))
{
var analyzerActions = await analyzerManager.GetAnalyzerActionsAsync(analyzer,
compilation, analyzerOptions, continueOnAnalyzerException, cancellationToken).ConfigureAwait(false);
......@@ -731,49 +730,18 @@ internal protected Action<Diagnostic> GetDiagnosticSinkWithSuppression(ISymbol s
DiagnosticAnalyzer analyzer,
AnalyzerManager analyzerManager,
CompilationOptions options,
Action<Diagnostic> addDiagnostic,
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
CancellationToken cancellationToken)
{
if (analyzer is CompilerDiagnosticAnalyzer)
{
// Compiler analyzer must always be executed for compiler errors, which cannot be suppressed or filtered.
return false;
}
var supportedDiagnostics = analyzerManager.GetSupportedDiagnosticDescriptors(analyzer, continueOnAnalyzerException, cancellationToken);
var diagnosticOptions = options.SpecificDiagnosticOptions;
foreach (var diag in supportedDiagnostics)
{
if (diag.IsNotConfigurable())
{
// If diagnostic descriptor is not configurable, then diagnostics created through it cannot be suppressed.
return false;
}
// Is this diagnostic suppressed by default (as written by the rule author)
var isSuppressed = !diag.IsEnabledByDefault;
// If the user said something about it, that overrides the author.
if (diagnosticOptions.ContainsKey(diag.Id))
{
isSuppressed = diagnosticOptions[diag.Id] == ReportDiagnostic.Suppress;
}
if (isSuppressed)
{
continue;
}
else
{
return false;
}
}
return analyzerManager.IsDiagnosticAnalyzerSuppressed(analyzer, options, continueOnAnalyzerException, IsCompilerAnalyzer, cancellationToken);
}
return true;
private static bool IsCompilerAnalyzer(DiagnosticAnalyzer analyzer)
{
return analyzer is CompilerDiagnosticAnalyzer;
}
public void Dispose()
{
this.CompilationEventQueue.TryComplete();
......@@ -829,7 +797,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
ImmutableDictionary<TLanguageKindEnum, ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>> actionsByKind;
if (analzerAndActions.Any())
{
actionsByKind = AnalyzerDriverHelper.GetNodeActionsByKind(analzerAndActions, addDiagnostic);
actionsByKind = AnalyzerManager.GetNodeActionsByKind(analzerAndActions, addDiagnostic);
}
else
{
......@@ -923,7 +891,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
{
var symbol = symbolEvent.Symbol;
var executeSyntaxNodeActions = this.NodeActionsByKind.Any();
var executeCodeBlockActions = AnalyzerDriverHelper.CanHaveExecutableCodeBlock(symbol) && (this.CodeBlockStartActionsByAnalyer.Any() || this.CodeBlockEndActionsByAnalyer.Any());
var executeCodeBlockActions = AnalyzerManager.CanHaveExecutableCodeBlock(symbol) && (this.CodeBlockStartActionsByAnalyer.Any() || this.CodeBlockEndActionsByAnalyer.Any());
if (executeSyntaxNodeActions || executeCodeBlockActions)
{
......@@ -963,7 +931,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
{
Action executeStatelessNodeActions = () =>
ExecuteStatelessNodeActions(analyzerAndActions.Value, syntax, symbol, declarationsInNode, semanticModel,
reportDiagnostic, this.continueOnAnalyzerException, this.analyzerOptions, _getKind, cancellationToken);
reportDiagnostic, this.continueOnAnalyzerException, this.analyzerOptions, _getKind, analyzerManager, cancellationToken);
AddAnalyzerActionsExecutor(taskMap, analyzerAndActions.Key, executeStatelessNodeActions, cancellationToken);
}
......@@ -994,7 +962,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
this.CodeBlockEndActionsByAnalyer[analyzerAndActions.Key] :
ImmutableArray<CodeBlockEndAnalyzerAction>.Empty;
AnalyzerDriverHelper.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
analyzerManager.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
syntax, symbol, executableCodeBlocks, analyzerOptions,
semanticModel, reportDiagnostic, this.continueOnAnalyzerException, _getKind, cancellationToken);
};
......@@ -1013,7 +981,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
var codeBlockStartActions = ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>.Empty;
var codeBlockEndActions = analyzerAndActions.Value;
AnalyzerDriverHelper.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
analyzerManager.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
syntax, symbol, executableCodeBlocks, analyzerOptions,
semanticModel, reportDiagnostic, this.continueOnAnalyzerException, _getKind, cancellationToken);
};
......@@ -1035,6 +1003,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
AnalyzerOptions analyzerOptions,
Func<SyntaxNode, TLanguageKindEnum> getKind,
AnalyzerManager analyzerManager,
CancellationToken cancellationToken)
{
// Eliminate syntax nodes for descendant member declarations within declarations.
......@@ -1076,7 +1045,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
declaredNode.DescendantNodesAndSelf(descendIntoTrivia: true) :
declaredNode.DescendantNodesAndSelf(n => !descendantDeclsToSkip.Contains(n), descendIntoTrivia: true).Except(descendantDeclsToSkip);
AnalyzerDriverHelper.ExecuteSyntaxNodeActions(nodesToAnalyze, actionsByKind, semanticModel,
analyzerManager.ExecuteSyntaxNodeActions(nodesToAnalyze, actionsByKind, semanticModel,
analyzerOptions, addDiagnostic, continueOnAnalyzerException, getKind, cancellationToken);
}
......
......@@ -29,7 +29,7 @@ public Compilation Compilation
public CompilationWithAnalyzers(Compilation compilation, ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken)
{
_cancellationToken = cancellationToken;
_driver = AnalyzerDriver.Create(compilation, analyzers, options, AnalyzerManager.Default, out _compilation, _cancellationToken);
_driver = AnalyzerDriver.Create(compilation, analyzers, options, AnalyzerManager.Instance, out _compilation, _cancellationToken);
}
/// <summary>
......@@ -110,8 +110,7 @@ public static bool IsDiagnosticAnalyzerSuppressed(DiagnosticAnalyzer analyzer, C
throw new ArgumentNullException(nameof(continueOnAnalyzerException));
}
Action<Diagnostic> dummy = _ => { };
return AnalyzerDriver.IsDiagnosticAnalyzerSuppressed(analyzer, AnalyzerManager.Default, options, dummy, continueOnAnalyzerException, CancellationToken.None);
return AnalyzerDriver.IsDiagnosticAnalyzerSuppressed(analyzer, AnalyzerManager.Instance, options, continueOnAnalyzerException, CancellationToken.None);
}
}
}
......@@ -56,11 +56,11 @@ public static void VerifyAnalyzerEngineIsSafeAgainstExceptions(Func<DiagnosticAn
handled[i] = analyzer.Thrown ? true : (bool?)null;
if (analyzer.Thrown)
{
Assert.True(diagnostics.Any(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic));
Assert.True(diagnostics.Any(AnalyzerManager.IsAnalyzerExceptionDiagnostic));
}
else
{
Assert.False(diagnostics.Any(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic));
Assert.False(diagnostics.Any(AnalyzerManager.IsAnalyzerExceptionDiagnostic));
}
}
catch (DeliberateException)
......
......@@ -77,7 +77,8 @@ public class DeclarePublicAPIAnalyzer : DiagnosticAnalyzer
MethodKind.EventRemove
};
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DeclareNewApiRule, RemoveDeletedApiRule);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics // ImmutableArray.Create(DeclareNewApiRule, RemoveDeletedApiRule);
{ get { throw new Exception(); } }
public override void Initialize(AnalysisContext context)
{
......
......@@ -431,7 +431,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests
diagnostics = exceptionDiagnosticsSource.TestOnly_GetReportedDiagnostics(analyzer)
Assert.Equal(1, diagnostics.Count())
Dim diagnostic = diagnostics.First()
Assert.True(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic(diagnostic.ToDiagnostic(document.GetSyntaxTreeAsync().Result)))
Assert.True(AnalyzerManager.IsAnalyzerExceptionDiagnostic(diagnostic.ToDiagnostic(document.GetSyntaxTreeAsync().Result)))
Assert.Contains("CodeBlockStartedAnalyzer", diagnostic.Message)
End Using
End Sub
......
......@@ -46,17 +46,20 @@ protected void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
private void OnAnalyzerExceptionDiagnostic(object sender, WorkspaceAnalyzerExceptionDiagnosticArgs args)
{
if (this.Workspace != args.Workspace)
// If the diagnostic is to be reported for a specific workspace (non-null value of args.Workspace),
// then ensure it matches our workspace.
// Otherwise, if args.Workspace is null, then report the diagnostic for all workspaces.
if (args.Workspace != null && this.Workspace != args.Workspace)
{
return;
}
Contract.ThrowIfFalse(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic(args.Diagnostic));
Contract.ThrowIfFalse(AnalyzerManager.IsAnalyzerExceptionDiagnostic(args.Diagnostic));
bool raiseDiagnosticsUpdated = true;
var diagnosticData = args.ProjectOpt != null ?
DiagnosticData.Create(args.ProjectOpt, args.Diagnostic) :
DiagnosticData.Create(args.Workspace, args.Diagnostic);
DiagnosticData.Create(this.Workspace, args.Diagnostic);
var dxs = ImmutableInterlocked.AddOrUpdate(ref _analyzerHostDiagnosticsMap,
args.FaultedAnalyzer,
......
......@@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics
{
internal abstract partial class AbstractHostDiagnosticUpdateSource
{
internal static event EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
private static event EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
protected AbstractHostDiagnosticUpdateSource()
{
......@@ -36,7 +36,7 @@ private static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExc
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic = (sender, args) =>
ReportAnalyzerExceptionDiagnostic(sender, args, workspace, project);
return AnalyzerDriverHelper.RegisterAnalyzerExceptionDiagnosticHandler(analyzers, onAnalyzerExceptionDiagnostic);
return AnalyzerManager.Instance.RegisterAnalyzerExceptionDiagnosticHandler(analyzers, onAnalyzerExceptionDiagnostic);
}
internal static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer, Workspace workspace)
......@@ -54,12 +54,12 @@ private static EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExc
Action<object, AnalyzerExceptionDiagnosticArgs> onAnalyzerExceptionDiagnostic = (sender, args) =>
ReportAnalyzerExceptionDiagnostic(sender, args, workspace, project);
return AnalyzerDriverHelper.RegisterAnalyzerExceptionDiagnosticHandler(analyzer, onAnalyzerExceptionDiagnostic);
return AnalyzerManager.Instance.RegisterAnalyzerExceptionDiagnosticHandler(analyzer, onAnalyzerExceptionDiagnostic);
}
internal static void UnregisterAnalyzerExceptionDiagnosticHandler(EventHandler<AnalyzerExceptionDiagnosticArgs> handler)
{
AnalyzerDriverHelper.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
AnalyzerManager.Instance.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
}
internal static void ReportAnalyzerExceptionDiagnostic(object sender, DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Workspace workspace)
......
......@@ -27,7 +27,7 @@ private bool ShouldAnalyze(SyntaxNode node, ImmutableArray<TLanguageKindEnum> ki
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
CancellationToken cancellationToken)
{
AnalyzerDriverHelper.ExecuteSyntaxNodeActions(actions, descendantNodes, semanticModel,
AnalyzerManager.Instance.ExecuteSyntaxNodeActions(actions, descendantNodes, semanticModel,
analyzerOptions, reportDiagnostic, continueOnAnalyzerException, this.GetKind, cancellationToken);
}
......@@ -40,7 +40,7 @@ private bool ShouldAnalyze(SyntaxNode node, ImmutableArray<TLanguageKindEnum> ki
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
CancellationToken cancellationToken)
{
AnalyzerDriverHelper.ExecuteCodeBlockActions(actions, declarationsInNode,
AnalyzerManager.Instance.ExecuteCodeBlockActions(actions, declarationsInNode,
semanticModel, analyzerOptions, reportDiagnostic, continueOnAnalyzerException, this.GetKind, cancellationToken);
}
}
......
......@@ -274,7 +274,7 @@ public async Task<ImmutableArray<Diagnostic>> GetSyntaxDiagnosticsAsync(Diagnost
{
if (_document.SupportsSyntaxTree)
{
AnalyzerDriverHelper.ExecuteSyntaxTreeActions(analyzerActions, _root.SyntaxTree,
AnalyzerManager.Instance.ExecuteSyntaxTreeActions(analyzerActions, _root.SyntaxTree,
_analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken);
}
}
......@@ -312,7 +312,7 @@ private IEnumerable<Diagnostic> GetFilteredDocumentDiagnosticsCore(IEnumerable<D
internal void ReportAnalyzerExceptionDiagnostic(DiagnosticAnalyzer analyzer, Diagnostic exceptionDiagnostic, Compilation compilation)
{
Contract.ThrowIfFalse(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic(exceptionDiagnostic));
Contract.ThrowIfFalse(AnalyzerManager.IsAnalyzerExceptionDiagnostic(exceptionDiagnostic));
if (compilation != null)
{
......@@ -338,12 +338,30 @@ public async Task<AnalyzerActions> GetAnalyzerActionsAsync(DiagnosticAnalyzer an
return actions;
}
public bool IsAnalyzerSuppressed(DiagnosticAnalyzer analyzer)
{
var options = this.Project.CompilationOptions;
if (options == null)
{
return false;
}
var handler = AbstractHostDiagnosticUpdateSource.RegisterAnalyzerExceptionDiagnosticHandler(analyzer, this.Project);
// Skip telemetry logging if the exception is thrown as we are computing supported diagnostics and
// we can't determine if any descriptors support getting telemetry without having the descriptors.
var suppressed = AnalyzerManager.Instance.IsDiagnosticAnalyzerSuppressed(analyzer, options, CatchAnalyzerException_NoTelemetryLogging, AnalyzerHelper.IsCompilerAnalyzer, CancellationToken);
AbstractHostDiagnosticUpdateSource.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return suppressed;
}
private async Task<AnalyzerActions> GetAnalyzerActionsCoreAsync(DiagnosticAnalyzer analyzer)
{
var compilation = _project.SupportsCompilation ?
await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false) :
null;
var analyzerActions = await AnalyzerManager.Default.GetAnalyzerActionsAsync(analyzer, compilation, _analyzerOptions, CatchAnalyzerException, _cancellationToken).ConfigureAwait(false);
var analyzerActions = await AnalyzerManager.Instance.GetAnalyzerActionsAsync(analyzer, compilation, _analyzerOptions, CatchAnalyzerException, _cancellationToken).ConfigureAwait(false);
DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)_logAggregator);
return analyzerActions;
}
......@@ -394,7 +412,7 @@ public async Task<ImmutableArray<Diagnostic>> GetSemanticDiagnosticsAsync(Diagno
// SemanticModel actions.
if (analyzerActions.SemanticModelActionsCount > 0)
{
AnalyzerDriverHelper.ExecuteSemanticModelActions(analyzerActions, model, _analyzerOptions,
AnalyzerManager.Instance.ExecuteSemanticModelActions(analyzerActions, model, _analyzerOptions,
diagnostics.Add, CatchAnalyzerException, _cancellationToken);
}
......@@ -402,7 +420,7 @@ public async Task<ImmutableArray<Diagnostic>> GetSemanticDiagnosticsAsync(Diagno
if (analyzerActions.SymbolActionsCount > 0)
{
var symbols = this.GetSymbolsToAnalyze(model);
AnalyzerDriverHelper.ExecuteSymbolActions(analyzerActions, symbols, compilation,
AnalyzerManager.Instance.ExecuteSymbolActions(analyzerActions, symbols, compilation,
_analyzerOptions, diagnostics.Add, CatchAnalyzerException, _cancellationToken);
}
......@@ -502,7 +520,7 @@ private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, L
// CompilationEnd actions.
var compilation = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
AnalyzerDriverHelper.ExecuteCompilationEndActions(analyzerActions, compilation, _analyzerOptions, localDiagnostics.Add, CatchAnalyzerException, _cancellationToken);
AnalyzerManager.Instance.ExecuteCompilationEndActions(analyzerActions, compilation, _analyzerOptions, localDiagnostics.Add, CatchAnalyzerException, _cancellationToken);
AbstractHostDiagnosticUpdateSource.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
var filteredDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation);
......@@ -515,7 +533,7 @@ private static Diagnostic AnalyzerExceptionToDiagnostic(DiagnosticAnalyzer analy
if (!IsCanceled(e, cancellationToken))
{
// Create a info diagnostic saying that the analyzer failed
return AnalyzerDriverHelper.GetAnalyzerDiagnostic(analyzer, e);
return AnalyzerManager.GetAnalyzerDiagnostic(analyzer, e);
}
return null;
......@@ -532,6 +550,11 @@ private bool CatchAnalyzerException(Exception e, DiagnosticAnalyzer analyzer)
return CatchAnalyzerException(e, analyzer, _testOnly_DonotCatchAnalyzerExceptions);
}
private bool CatchAnalyzerException_NoTelemetryLogging(Exception e, DiagnosticAnalyzer analyzer)
{
return CatchAnalyzerException_NoTelemetryLogging(e, analyzer, _testOnly_DonotCatchAnalyzerExceptions);
}
internal bool CatchAnalyzerExceptionHandler(Exception e, DiagnosticAnalyzer analyzer)
{
return CatchAnalyzerException(e, analyzer, testOnly_DonotCatchAnalyzerExceptions: false);
......@@ -541,6 +564,11 @@ private bool CatchAnalyzerException(Exception e, DiagnosticAnalyzer analyzer, bo
{
DiagnosticAnalyzerLogger.LogAnalyzerCrashCount(analyzer, e, _logAggregator);
return CatchAnalyzerException_NoTelemetryLogging(e, analyzer, testOnly_DonotCatchAnalyzerExceptions);
}
private bool CatchAnalyzerException_NoTelemetryLogging(Exception e, DiagnosticAnalyzer analyzer, bool testOnly_DonotCatchAnalyzerExceptions)
{
if (testOnly_DonotCatchAnalyzerExceptions)
{
return false;
......
......@@ -110,7 +110,6 @@ private async Task AnalyzeSyntaxAsync(Document document, ImmutableHashSet<string
var fullSpan = root == null ? null : (TextSpan?)root.FullSpan;
var userDiagnosticDriver = new DiagnosticAnalyzerDriver(document, fullSpan, root, _diagnosticLogAggregator, cancellationToken);
var options = document.Project.CompilationOptions;
var openedDocument = document.IsOpen();
foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(document.Project, cancellationToken).ConfigureAwait(false))
......@@ -118,7 +117,7 @@ private async Task AnalyzeSyntaxAsync(Document document, ImmutableHashSet<string
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
if (IsAnalyzerSuppressed(provider, options, userDiagnosticDriver))
if (userDiagnosticDriver.IsAnalyzerSuppressed(provider))
{
await HandleSuppressedAnalyzerAsync(document, StateType.Syntax, providerId, provider, cancellationToken).ConfigureAwait(false);
}
......@@ -191,15 +190,14 @@ private async Task AnalyzeBodyDocumentAsync(Document document, SyntaxNode member
var spanBasedDriver = new DiagnosticAnalyzerDriver(document, member.FullSpan, root, _diagnosticLogAggregator, cancellationToken);
var documentBasedDriver = new DiagnosticAnalyzerDriver(document, root.FullSpan, root, _diagnosticLogAggregator, cancellationToken);
var options = document.Project.CompilationOptions;
foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(document.Project, cancellationToken).ConfigureAwait(false))
{
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
bool supportsSemanticInSpan;
if (IsAnalyzerSuppressed(provider, options, spanBasedDriver))
if (spanBasedDriver.IsAnalyzerSuppressed(provider))
{
await HandleSuppressedAnalyzerAsync(document, StateType.Document, providerId, provider, cancellationToken).ConfigureAwait(false);
}
......@@ -241,14 +239,13 @@ private async Task AnalyzeDocumentAsync(Document document, VersionArgument versi
var userDiagnosticDriver = new DiagnosticAnalyzerDriver(document, fullSpan, root, _diagnosticLogAggregator, cancellationToken);
bool openedDocument = document.IsOpen();
var options = document.Project.CompilationOptions;
foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(document.Project, cancellationToken).ConfigureAwait(false))
{
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
if (IsAnalyzerSuppressed(provider, options, userDiagnosticDriver))
if (userDiagnosticDriver.IsAnalyzerSuppressed(provider))
{
await HandleSuppressedAnalyzerAsync(document, StateType.Document, providerId, provider, cancellationToken).ConfigureAwait(false);
}
......@@ -297,15 +294,14 @@ private async Task AnalyzeProjectAsync(Project project, ImmutableHashSet<string>
var projectVersion = await project.GetDependentVersionAsync(cancellationToken).ConfigureAwait(false);
var semanticVersion = await project.GetDependentSemanticVersionAsync(cancellationToken).ConfigureAwait(false);
var userDiagnosticDriver = new DiagnosticAnalyzerDriver(project, _diagnosticLogAggregator, cancellationToken);
var options = project.CompilationOptions;
var versions = new VersionArgument(VersionStamp.Default, semanticVersion, projectVersion);
foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(project, cancellationToken).ConfigureAwait(false))
{
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
if (IsAnalyzerSuppressed(provider, options, userDiagnosticDriver))
if (userDiagnosticDriver.IsAnalyzerSuppressed(provider))
{
await HandleSuppressedAnalyzerAsync(project, providerId, provider, cancellationToken).ConfigureAwait(false);
}
......@@ -463,15 +459,14 @@ public override async Task<IEnumerable<DiagnosticData>> GetDiagnosticsForSpanAsy
// Share the diagnostic analyzer driver across all analyzers.
var spanBasedDriver = new DiagnosticAnalyzerDriver(document, range, root, _diagnosticLogAggregator, cancellationToken);
var documentBasedDriver = new DiagnosticAnalyzerDriver(document, fullSpan, root, _diagnosticLogAggregator, cancellationToken);
var options = document.Project.CompilationOptions;
foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(document.Project, cancellationToken).ConfigureAwait(false))
{
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
bool supportsSemanticInSpan;
if (!IsAnalyzerSuppressed(provider, options, spanBasedDriver) &&
if (!spanBasedDriver.IsAnalyzerSuppressed(provider) &&
ShouldRunProviderForStateType(stateType, provider, spanBasedDriver, out supportsSemanticInSpan))
{
var userDiagnosticDriver = supportsSemanticInSpan ? spanBasedDriver : documentBasedDriver;
......@@ -580,7 +575,7 @@ private bool ShouldRunProviderForClosedFile(bool openedDocument, DiagnosticAnaly
private static bool ShouldRunProviderForStateType(StateType stateTypeId, DiagnosticAnalyzer provider, DiagnosticAnalyzerDriver driver,
out bool supportsSemanticInSpan, ImmutableHashSet<string> diagnosticIds = null, Func<DiagnosticAnalyzer, ImmutableArray<DiagnosticDescriptor>> getDescriptor = null)
{
Debug.Assert(!IsAnalyzerSuppressed(provider, driver.Project.CompilationOptions, driver));
Debug.Assert(!driver.IsAnalyzerSuppressed(provider));
supportsSemanticInSpan = false;
if (diagnosticIds != null && getDescriptor(provider).All(d => !diagnosticIds.Contains(d.Id)))
......@@ -604,17 +599,6 @@ private bool ShouldRunProviderForClosedFile(bool openedDocument, DiagnosticAnaly
}
}
private static bool IsAnalyzerSuppressed(DiagnosticAnalyzer provider, CompilationOptions options, DiagnosticAnalyzerDriver driver)
{
if (options != null && CompilationWithAnalyzers.IsDiagnosticAnalyzerSuppressed(provider, options, driver.CatchAnalyzerExceptionHandler))
{
// All diagnostics that are generated by this DiagnosticAnalyzer will be suppressed, so we need not run the analyzer.
return true;
}
return false;
}
// internal for testing purposes only.
internal void ForceAnalyzeAllDocuments(Project project, DiagnosticAnalyzer analyzer, CancellationToken cancellationToken)
{
......
......@@ -323,7 +323,7 @@ public LatestDiagnosticsGetter(DiagnosticIncrementalAnalyzer owner, ImmutableHas
var provider = providerAndId.Key;
var providerId = providerAndId.Value;
if (IsAnalyzerSuppressed(provider, project.CompilationOptions, driver) ||
if (driver.IsAnalyzerSuppressed(provider) ||
!this.Owner.ShouldRunProviderForStateType(stateType, provider, driver, this.DiagnosticIds))
{
continue;
......
......@@ -75,15 +75,16 @@ public string GetAnalyzerReferenceIdentity(AnalyzerReference reference)
/// </summary>
public ImmutableArray<DiagnosticDescriptor> GetDiagnosticDescriptors(DiagnosticAnalyzer analyzer)
{
// TODO: report diagnostics from exceptions thrown in DiagnosticAnalyzer.SupportedDiagnostics
var handler = AbstractHostDiagnosticUpdateSource.RegisterAnalyzerExceptionDiagnosticHandler(analyzer, workspace: null);
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException = (ex, a) => !AnalyzerHelper.IsBuiltInAnalyzer(analyzer);
return AnalyzerManager.Default.GetSupportedDiagnosticDescriptors(analyzer, continueOnAnalyzerException, CancellationToken.None);
var descriptors = AnalyzerManager.Instance.GetSupportedDiagnosticDescriptors(analyzer, continueOnAnalyzerException, CancellationToken.None);
AbstractHostDiagnosticUpdateSource.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return descriptors;
}
/// <summary>
/// Get <see cref="AnalyzerReference"/> identity and <see cref="DiagnosticAnalyzer"/>s map for given <paramref name="language"/>
/// </summary>
/// </summary>
public ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> GetHostDiagnosticAnalyzersPerReference(string language)
{
return _hostDiagnosticAnalyzersPerLanguageMap.GetOrAdd(language, CreateHostDiagnosticAnalyzers);
......
......@@ -137,14 +137,14 @@ public static ImmutableArray<Diagnostic> GetAnalyzerDiagnostics<TCompilation>(th
var analyzersArray = analyzers.ToImmutableArray();
var exceptionDiagnostics = new ConcurrentSet<Diagnostic>();
var handler = AnalyzerDriverHelper.RegisterAnalyzerExceptionDiagnosticHandler(analyzersArray, exceptionDiagnostics.Add);
var handler = AnalyzerManager.Instance.RegisterAnalyzerExceptionDiagnosticHandler(analyzersArray, exceptionDiagnostics.Add);
Compilation newCompilation;
var driver = AnalyzerDriver.Create(c, analyzersArray, options, AnalyzerManager.Default, out newCompilation, continueOnAnalyzerException, CancellationToken.None);
var driver = AnalyzerDriver.Create(c, analyzersArray, options, AnalyzerManager.Instance, out newCompilation, continueOnAnalyzerException, CancellationToken.None);
var discarded = newCompilation.GetDiagnostics();
diagnostics = driver.GetDiagnosticsAsync().Result.AddRange(exceptionDiagnostics);
AnalyzerDriverHelper.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
AnalyzerManager.Instance.UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return (TCompilation)newCompilation; // note this is a new compilation
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册