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

Checkin current changes

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