提交 bbb448bb 编写于 作者: J John Hamby

Diagnostics API changes for registering compilation actions, code block actions, and end actions

This change set introduces the notions of registering compilation actions and code block actions into the diagnostics API. Compilation actions differ from compilation end actions in that they do not have access to per-compilation analyzer state and do not introduce action execution ordering constraints. Code block actions differ from code block end actions in that they do not have access to per-block analyzer state and do not introduce action execution ordering constraints.

This change set also removes RegisterXEndAction methods on contexts other than the corresponding StartXAnalysisContext types. This change is intended to guide analyzer authors towards introducing analyzer state with appropriate lifetime.

Some internal mechanism for the removed registration methods remains. This keeps the mechanism fully general and imposes a very marginal execution cost.

The specific API changes:
 -- Removal of AnalysisContext.RegisterCompilationEndAction. CompilationStartAnalysisContext.RegisterCompilationEndAction remains.
 -- Removal of AnalysisContext.RegisterCodeBlockEndAction and CompilationStartAnalysisContext.RegisterCodeBlockEndAction. CodeBlockStartAnalysisContext.RegisterCodeBlockEndAction remains.
 -- Introduction of AnalysisContext.RegisterCompilationAction.
 -- Introduction of AnalysisContext.RegisterCodeBlockAction and CompilationStartAnalysisContext.RegisterCodeBlockAction.
 -- Renaming of CompilationEndAnalysisContext to CompilationAnalysisContext.
 -- Renaming of CodeBlockEndAnalysisContext to CodeBlockAnalysisContext.
上级 d7c33a65
......@@ -863,7 +863,7 @@ public override void Initialize(AnalysisContext context)
if (_isCodeBlockAnalyzer)
{
context.RegisterCodeBlockStartAction<SyntaxKind>(OnCodeBlockStarted);
context.RegisterCodeBlockEndAction(OnCodeBlockEnded);
context.RegisterCodeBlockAction(OnCodeBlockEnded);
}
else
{
......@@ -874,7 +874,7 @@ public override void Initialize(AnalysisContext context)
}
}
public static void OnCodeBlockEnded(CodeBlockEndAnalysisContext context)
public static void OnCodeBlockEnded(CodeBlockAnalysisContext context)
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, Location.None));
}
......
......@@ -118,25 +118,16 @@ public void ExecuteCompilationStartActions(ImmutableArray<CompilationStartAnalyz
}
/// <summary>
/// Executes the compilation end actions.
/// Executes compilation actions or compilation end actions.
/// </summary>
/// <param name="actions"><see cref="AnalyzerActions"/> whose compilation end actions are to be executed.</param>
public void ExecuteCompilationEndActions(AnalyzerActions actions)
/// <param name="compilationActions">Compilation actions to be executed.</param>
public void ExecuteCompilationActions(ImmutableArray<CompilationAnalyzerAction> compilationActions)
{
ExecuteCompilationEndActions(actions.CompilationEndActions);
}
/// <summary>
/// Executes the compilation end actions.
/// </summary>
/// <param name="compilationEndActions">Compilation end actions to be executed.</param>
public void ExecuteCompilationEndActions(ImmutableArray<CompilationEndAnalyzerAction> compilationEndActions)
{
foreach (var endAction in compilationEndActions)
foreach (var endAction in compilationActions)
{
_cancellationToken.ThrowIfCancellationRequested();
ExecuteAndCatchIfThrows(endAction.Analyzer,
() => endAction.Action(new CompilationEndAnalysisContext(_compilation, _analyzerOptions, _addDiagnostic, _cancellationToken)));
() => endAction.Action(new CompilationAnalysisContext(_compilation, _analyzerOptions, _addDiagnostic, _cancellationToken)));
}
}
......@@ -293,9 +284,10 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
where TLanguageKindEnum : struct
{
var codeBlockStartActions = actions.GetCodeBlockStartActions<TLanguageKindEnum>();
var codeBlockActions = actions.CodeBlockActions;
var codeBlockEndActions = actions.CodeBlockEndActions;
if (!codeBlockStartActions.Any() && !codeBlockEndActions.Any())
if (!codeBlockStartActions.Any() && !codeBlockActions.Any() && !codeBlockEndActions.Any())
{
return;
}
......@@ -308,7 +300,7 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
if (declaredSymbol != null && declInfo.ExecutableCodeBlocks.Any())
{
ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
ExecuteCodeBlockActions(codeBlockStartActions, codeBlockActions, codeBlockEndActions,
declaredNode, declaredSymbol, executableCodeBlocks, semanticModel, getKind);
}
}
......@@ -316,7 +308,8 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
internal void ExecuteCodeBlockActions<TLanguageKindEnum>(
IEnumerable<CodeBlockStartAnalyzerAction<TLanguageKindEnum>> codeBlockStartActions,
IEnumerable<CodeBlockEndAnalyzerAction> codeBlockEndActions,
IEnumerable<CodeBlockAnalyzerAction> codeBlockActions,
IEnumerable<CodeBlockAnalyzerAction> codeBlockEndActions,
SyntaxNode declaredNode,
ISymbol declaredSymbol,
ImmutableArray<SyntaxNode> executableCodeBlocks,
......@@ -327,15 +320,19 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
Debug.Assert(declaredNode != null);
Debug.Assert(declaredSymbol != null);
Debug.Assert(CanHaveExecutableCodeBlock(declaredSymbol));
Debug.Assert(codeBlockStartActions.Any() || codeBlockEndActions.Any());
Debug.Assert(codeBlockStartActions.Any() || codeBlockEndActions.Any() || codeBlockActions.Any());
Debug.Assert(executableCodeBlocks.Any());
// Compute the sets of code block end and stateful syntax node actions.
var endedActions = PooledHashSet<CodeBlockEndAnalyzerAction>.GetInstance();
// Compute the sets of code block end, code block, and stateful syntax node actions.
var blockEndActions = PooledHashSet<CodeBlockAnalyzerAction>.GetInstance();
var blockActions = PooledHashSet<CodeBlockAnalyzerAction>.GetInstance();
var executableNodeActions = ArrayBuilder<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>.GetInstance();
// Include the stateless code block actions.
endedActions.AddAll(codeBlockEndActions);
// Include the code block actions.
blockActions.AddAll(codeBlockActions);
// Include the initial code block end actions.
blockEndActions.AddAll(codeBlockEndActions);
// Include the stateful actions.
foreach (var da in codeBlockStartActions)
......@@ -347,7 +344,7 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
var blockStartContext = new AnalyzerCodeBlockStartAnalysisContext<TLanguageKindEnum>(da.Analyzer,
codeBlockScope, declaredNode, declaredSymbol, semanticModel, _analyzerOptions, _cancellationToken);
da.Action(blockStartContext);
endedActions.AddAll(codeBlockScope.CodeBlockEndActions);
blockEndActions.AddAll(codeBlockScope.CodeBlockEndActions);
executableNodeActions.AddRange(codeBlockScope.SyntaxNodeActions);
});
}
......@@ -361,15 +358,21 @@ public void ExecuteSyntaxTreeActions(ImmutableArray<SyntaxTreeAnalyzerAction> sy
ExecuteSyntaxNodeActions(nodesToAnalyze, executableNodeActionsByKind, semanticModel, getKind);
}
// Execute code block end actions.
foreach (var endedAction in endedActions)
executableNodeActions.Free();
ExecuteCodeBlockActions(blockActions, declaredNode, declaredSymbol, semanticModel);
ExecuteCodeBlockActions(blockEndActions, declaredNode, declaredSymbol, semanticModel);
}
private void ExecuteCodeBlockActions(PooledHashSet<CodeBlockAnalyzerAction> blockActions, SyntaxNode declaredNode, ISymbol declaredSymbol, SemanticModel semanticModel)
{
foreach (var blockAction in blockActions)
{
ExecuteAndCatchIfThrows(endedAction.Analyzer,
() => endedAction.Action(new CodeBlockEndAnalysisContext(declaredNode, declaredSymbol, semanticModel, _analyzerOptions, _addDiagnostic, _cancellationToken)));
ExecuteAndCatchIfThrows(blockAction.Analyzer,
() => blockAction.Action(new CodeBlockAnalysisContext(declaredNode, declaredSymbol, semanticModel, _analyzerOptions, _addDiagnostic, _cancellationToken)));
}
endedActions.Free();
executableNodeActions.Free();
blockActions.Free();
}
internal static ImmutableDictionary<TLanguageKindEnum, ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>> GetNodeActionsByKind<TLanguageKindEnum>(
......
......@@ -62,17 +62,17 @@ public CompilationStartAnalyzerAction(Action<CompilationStartAnalysisContext> ac
public Action<CompilationStartAnalysisContext> Action { get { return _action; } }
}
internal sealed class CompilationEndAnalyzerAction : AnalyzerAction
internal sealed class CompilationAnalyzerAction : AnalyzerAction
{
private readonly Action<CompilationEndAnalysisContext> _action;
private readonly Action<CompilationAnalysisContext> _action;
public CompilationEndAnalyzerAction(Action<CompilationEndAnalysisContext> action, DiagnosticAnalyzer analyzer)
public CompilationAnalyzerAction(Action<CompilationAnalysisContext> action, DiagnosticAnalyzer analyzer)
: base(analyzer)
{
_action = action;
}
public Action<CompilationEndAnalysisContext> Action { get { return _action; } }
public Action<CompilationAnalysisContext> Action { get { return _action; } }
}
internal sealed class SemanticModelAnalyzerAction : AnalyzerAction
......@@ -114,16 +114,16 @@ public CodeBlockStartAnalyzerAction(Action<CodeBlockStartAnalysisContext<TLangua
public Action<CodeBlockStartAnalysisContext<TLanguageKindEnum>> Action { get { return _action; } }
}
internal sealed class CodeBlockEndAnalyzerAction : AnalyzerAction
internal sealed class CodeBlockAnalyzerAction : AnalyzerAction
{
private readonly Action<CodeBlockEndAnalysisContext> _action;
private readonly Action<CodeBlockAnalysisContext> _action;
public CodeBlockEndAnalyzerAction(Action<CodeBlockEndAnalysisContext> action, DiagnosticAnalyzer analyzer)
public CodeBlockAnalyzerAction(Action<CodeBlockAnalysisContext> action, DiagnosticAnalyzer analyzer)
: base(analyzer)
{
_action = action;
}
public Action<CodeBlockEndAnalysisContext> Action { get { return _action; } }
public Action<CodeBlockAnalysisContext> Action { get { return _action; } }
}
}
......@@ -28,10 +28,10 @@ public override void RegisterCompilationStartAction(Action<CompilationStartAnaly
_scope.RegisterCompilationStartAction(_analyzer, action);
}
public override void RegisterCompilationEndAction(Action<CompilationEndAnalysisContext> action)
public override void RegisterCompilationAction(Action<CompilationAnalysisContext> action)
{
DiagnosticAnalysisContextHelpers.VerifyArguments(action);
_scope.RegisterCompilationEndAction(_analyzer, action);
_scope.RegisterCompilationAction(_analyzer, action);
}
public override void RegisterSyntaxTreeAction(Action<SyntaxTreeAnalysisContext> action)
......@@ -58,10 +58,10 @@ public override void RegisterCodeBlockStartAction<TLanguageKindEnum>(Action<Code
_scope.RegisterCodeBlockStartAction<TLanguageKindEnum>(_analyzer, action);
}
public override void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action)
public override void RegisterCodeBlockAction(Action<CodeBlockAnalysisContext> action)
{
DiagnosticAnalysisContextHelpers.VerifyArguments(action);
_scope.RegisterCodeBlockEndAction(_analyzer, action);
_scope.RegisterCodeBlockAction(_analyzer, action);
}
public override void RegisterSyntaxNodeAction<TLanguageKindEnum>(Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds)
......@@ -86,7 +86,7 @@ public AnalyzerCompilationStartAnalysisContext(DiagnosticAnalyzer analyzer, Host
_scope = scope;
}
public override void RegisterCompilationEndAction(Action<CompilationEndAnalysisContext> action)
public override void RegisterCompilationEndAction(Action<CompilationAnalysisContext> action)
{
_scope.RegisterCompilationEndAction(_analyzer, action);
}
......@@ -111,9 +111,9 @@ public override void RegisterCodeBlockStartAction<TLanguageKindEnum>(Action<Code
_scope.RegisterCodeBlockStartAction<TLanguageKindEnum>(_analyzer, action);
}
public override void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action)
public override void RegisterCodeBlockAction(Action<CodeBlockAnalysisContext> action)
{
_scope.RegisterCodeBlockEndAction(_analyzer, action);
_scope.RegisterCodeBlockAction(_analyzer, action);
}
public override void RegisterSyntaxNodeAction<TLanguageKindEnum>(Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds)
......@@ -143,7 +143,7 @@ internal sealed class AnalyzerCodeBlockStartAnalysisContext<TLanguageKindEnum> :
_scope = scope;
}
public override void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action)
public override void RegisterCodeBlockEndAction(Action<CodeBlockAnalysisContext> action)
{
_scope.RegisterCodeBlockEndAction(_analyzer, action);
}
......@@ -186,7 +186,7 @@ public HostCompilationStartAnalysisScope(HostSessionStartAnalysisScope sessionSc
_sessionScope = sessionScope;
}
public override ImmutableArray<CompilationEndAnalyzerAction> CompilationEndActions
public override ImmutableArray<CompilationAnalyzerAction> CompilationEndActions
{
get { return base.CompilationEndActions.AddRange(_sessionScope.CompilationEndActions); }
}
......@@ -206,16 +206,26 @@ public override ImmutableArray<SymbolAnalyzerAction> SymbolActions
get { return base.SymbolActions.AddRange(_sessionScope.SymbolActions); }
}
public override ImmutableArray<CodeBlockEndAnalyzerAction> CodeBlockEndActions
public override ImmutableArray<CodeBlockAnalyzerAction> CodeBlockEndActions
{
get { return base.CodeBlockEndActions.AddRange(_sessionScope.CodeBlockEndActions); }
}
public override ImmutableArray<CodeBlockAnalyzerAction> CodeBlockActions
{
get { return base.CodeBlockActions.AddRange(_sessionScope.CodeBlockActions); }
}
public override bool HasCodeBlockEndActions
{
get { return base.HasCodeBlockEndActions || _sessionScope.HasCodeBlockEndActions; }
}
public override bool HasCodeBlockActions
{
get { return base.HasCodeBlockActions || _sessionScope.HasCodeBlockActions; }
}
public override bool HasCodeBlockStartActions<TLanguageKindEnum>()
{
return
......@@ -262,10 +272,10 @@ public AnalyzerActions GetCompilationOnlyAnalyzerActions(DiagnosticAnalyzer anal
/// </summary>
internal sealed class HostCodeBlockStartAnalysisScope<TLanguageKindEnum> where TLanguageKindEnum : struct
{
private ImmutableArray<CodeBlockEndAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockEndAnalyzerAction>.Empty;
private ImmutableArray<CodeBlockAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
private ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>> _syntaxNodeActions = ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>.Empty;
public ImmutableArray<CodeBlockEndAnalyzerAction> CodeBlockEndActions
public ImmutableArray<CodeBlockAnalyzerAction> CodeBlockEndActions
{
get { return _codeBlockEndActions; }
}
......@@ -279,9 +289,9 @@ internal HostCodeBlockStartAnalysisScope()
{
}
public void RegisterCodeBlockEndAction(DiagnosticAnalyzer analyzer, Action<CodeBlockEndAnalysisContext> action)
public void RegisterCodeBlockEndAction(DiagnosticAnalyzer analyzer, Action<CodeBlockAnalysisContext> action)
{
_codeBlockEndActions = _codeBlockEndActions.Add(new CodeBlockEndAnalyzerAction(action, analyzer));
_codeBlockEndActions = _codeBlockEndActions.Add(new CodeBlockAnalyzerAction(action, analyzer));
}
public void RegisterSyntaxNodeAction(DiagnosticAnalyzer analyzer, Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds)
......@@ -292,16 +302,23 @@ public void RegisterSyntaxNodeAction(DiagnosticAnalyzer analyzer, Action<SyntaxN
internal abstract class HostAnalysisScope
{
private ImmutableArray<CompilationEndAnalyzerAction> _compilationEndActions = ImmutableArray<CompilationEndAnalyzerAction>.Empty;
private ImmutableArray<CompilationAnalyzerAction> _compilationActions = ImmutableArray<CompilationAnalyzerAction>.Empty;
private ImmutableArray<CompilationAnalyzerAction> _compilationEndActions = ImmutableArray<CompilationAnalyzerAction>.Empty;
private ImmutableArray<SemanticModelAnalyzerAction> _semanticModelActions = ImmutableArray<SemanticModelAnalyzerAction>.Empty;
private ImmutableArray<SyntaxTreeAnalyzerAction> _syntaxTreeActions = ImmutableArray<SyntaxTreeAnalyzerAction>.Empty;
private ImmutableArray<SymbolAnalyzerAction> _symbolActions = ImmutableArray<SymbolAnalyzerAction>.Empty;
private ImmutableArray<AnalyzerAction> _codeBlockStartActions = ImmutableArray<AnalyzerAction>.Empty;
private ImmutableArray<CodeBlockEndAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockEndAnalyzerAction>.Empty;
private ImmutableArray<CodeBlockAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
private ImmutableArray<CodeBlockAnalyzerAction> _codeBlockActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
private ImmutableArray<AnalyzerAction> _syntaxNodeActions = ImmutableArray<AnalyzerAction>.Empty;
private readonly Dictionary<DiagnosticAnalyzer, AnalyzerActions> _analyzerActions = new Dictionary<DiagnosticAnalyzer, AnalyzerActions>();
public virtual ImmutableArray<CompilationEndAnalyzerAction> CompilationEndActions
public ImmutableArray<CompilationAnalyzerAction> CompilationActions
{
get { return _compilationActions; }
}
public virtual ImmutableArray<CompilationAnalyzerAction> CompilationEndActions
{
get { return _compilationEndActions; }
}
......@@ -321,16 +338,26 @@ public virtual ImmutableArray<SymbolAnalyzerAction> SymbolActions
get { return _symbolActions; }
}
public virtual ImmutableArray<CodeBlockEndAnalyzerAction> CodeBlockEndActions
public virtual ImmutableArray<CodeBlockAnalyzerAction> CodeBlockEndActions
{
get { return _codeBlockEndActions; }
}
public virtual ImmutableArray<CodeBlockAnalyzerAction> CodeBlockActions
{
get { return _codeBlockActions; }
}
public virtual bool HasCodeBlockEndActions
{
get { return _codeBlockEndActions.Any(); }
}
public virtual bool HasCodeBlockActions
{
get { return _codeBlockActions.Any(); }
}
public virtual bool HasCodeBlockStartActions<TLanguageKindEnum>() where TLanguageKindEnum : struct
{
return _codeBlockStartActions.OfType<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>().Any();
......@@ -353,9 +380,16 @@ public virtual AnalyzerActions GetAnalyzerActions(DiagnosticAnalyzer analyzer)
return actions;
}
public void RegisterCompilationEndAction(DiagnosticAnalyzer analyzer, Action<CompilationEndAnalysisContext> action)
public void RegisterCompilationAction(DiagnosticAnalyzer analyzer, Action<CompilationAnalysisContext> action)
{
CompilationEndAnalyzerAction analyzerAction = new CompilationEndAnalyzerAction(action, analyzer);
CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, analyzer);
this.GetOrCreateAnalyzerActions(analyzer).AddCompilationAction(analyzerAction);
_compilationActions = _compilationActions.Add(analyzerAction);
}
public void RegisterCompilationEndAction(DiagnosticAnalyzer analyzer, Action<CompilationAnalysisContext> action)
{
CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, analyzer);
this.GetOrCreateAnalyzerActions(analyzer).AddCompilationEndAction(analyzerAction);
_compilationEndActions = _compilationEndActions.Add(analyzerAction);
}
......@@ -388,13 +422,20 @@ public void RegisterSymbolAction(DiagnosticAnalyzer analyzer, Action<SymbolAnaly
_codeBlockStartActions = _codeBlockStartActions.Add(analyzerAction);
}
public void RegisterCodeBlockEndAction(DiagnosticAnalyzer analyzer, Action<CodeBlockEndAnalysisContext> action)
public void RegisterCodeBlockEndAction(DiagnosticAnalyzer analyzer, Action<CodeBlockAnalysisContext> action)
{
CodeBlockEndAnalyzerAction analyzerAction = new CodeBlockEndAnalyzerAction(action, analyzer);
CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, analyzer);
this.GetOrCreateAnalyzerActions(analyzer).AddCodeBlockEndAction(analyzerAction);
_codeBlockEndActions = _codeBlockEndActions.Add(analyzerAction);
}
public void RegisterCodeBlockAction(DiagnosticAnalyzer analyzer, Action<CodeBlockAnalysisContext> action)
{
CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, analyzer);
this.GetOrCreateAnalyzerActions(analyzer).AddCodeBlockAction(analyzerAction);
_codeBlockActions = _codeBlockActions.Add(analyzerAction);
}
public void RegisterSyntaxNodeAction<TLanguageKindEnum>(DiagnosticAnalyzer analyzer, Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds) where TLanguageKindEnum : struct
{
SyntaxNodeAnalyzerAction<TLanguageKindEnum> analyzerAction = new SyntaxNodeAnalyzerAction<TLanguageKindEnum>(action, syntaxKinds, analyzer);
......@@ -425,12 +466,14 @@ protected AnalyzerActions GetOrCreateAnalyzerActions(DiagnosticAnalyzer analyzer
internal sealed class AnalyzerActions
{
private ImmutableArray<CompilationStartAnalyzerAction> _compilationStartActions = ImmutableArray<CompilationStartAnalyzerAction>.Empty;
private ImmutableArray<CompilationEndAnalyzerAction> _compilationEndActions = ImmutableArray<CompilationEndAnalyzerAction>.Empty;
private ImmutableArray<CompilationAnalyzerAction> _compilationEndActions = ImmutableArray<CompilationAnalyzerAction>.Empty;
private ImmutableArray<CompilationAnalyzerAction> _compilationActions = ImmutableArray<CompilationAnalyzerAction>.Empty;
private ImmutableArray<SyntaxTreeAnalyzerAction> _syntaxTreeActions = ImmutableArray<SyntaxTreeAnalyzerAction>.Empty;
private ImmutableArray<SemanticModelAnalyzerAction> _semanticModelActions = ImmutableArray<SemanticModelAnalyzerAction>.Empty;
private ImmutableArray<SymbolAnalyzerAction> _symbolActions = ImmutableArray<SymbolAnalyzerAction>.Empty;
private ImmutableArray<AnalyzerAction> _codeBlockStartActions = ImmutableArray<AnalyzerAction>.Empty;
private ImmutableArray<CodeBlockEndAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockEndAnalyzerAction>.Empty;
private ImmutableArray<CodeBlockAnalyzerAction> _codeBlockEndActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
private ImmutableArray<CodeBlockAnalyzerAction> _codeBlockActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
private ImmutableArray<AnalyzerAction> _syntaxNodeActions = ImmutableArray<AnalyzerAction>.Empty;
internal AnalyzerActions()
......@@ -439,23 +482,30 @@ internal AnalyzerActions()
public int CompilationStartActionsCount { get { return _compilationStartActions.Length; } }
public int CompilationEndActionsCount { get { return _compilationEndActions.Length; } }
public int CompilationActionsCount { get { return _compilationActions.Length; } }
public int SyntaxTreeActionsCount { get { return _syntaxTreeActions.Length; } }
public int SemanticModelActionsCount { get { return _semanticModelActions.Length; } }
public int SymbolActionsCount { get { return _symbolActions.Length; } }
public int SyntaxNodeActionsCount { get { return _syntaxNodeActions.Length; } }
public int CodeBlockStartActionsCount { get { return _codeBlockStartActions.Length; } }
public int CodeBlockEndActionsCount { get { return _codeBlockEndActions.Length; } }
public int CodeBlockActionsCount { get { return _codeBlockActions.Length; } }
internal ImmutableArray<CompilationStartAnalyzerAction> CompilationStartActions
{
get { return _compilationStartActions; }
}
internal ImmutableArray<CompilationEndAnalyzerAction> CompilationEndActions
internal ImmutableArray<CompilationAnalyzerAction> CompilationEndActions
{
get { return _compilationEndActions; }
}
internal ImmutableArray<CompilationAnalyzerAction> CompilationActions
{
get { return _compilationActions; }
}
internal ImmutableArray<SyntaxTreeAnalyzerAction> SyntaxTreeActions
{
get { return _syntaxTreeActions; }
......@@ -471,11 +521,16 @@ internal ImmutableArray<SymbolAnalyzerAction> SymbolActions
get { return _symbolActions; }
}
internal ImmutableArray<CodeBlockEndAnalyzerAction> CodeBlockEndActions
internal ImmutableArray<CodeBlockAnalyzerAction> CodeBlockEndActions
{
get { return _codeBlockEndActions; }
}
internal ImmutableArray<CodeBlockAnalyzerAction> CodeBlockActions
{
get { return _codeBlockActions; }
}
internal ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>> GetCodeBlockStartActions<TLanguageKindEnum>() where TLanguageKindEnum : struct
{
return _codeBlockStartActions.OfType<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>().ToImmutableArray();
......@@ -491,11 +546,16 @@ internal void AddCompilationStartAction(CompilationStartAnalyzerAction action)
_compilationStartActions = _compilationStartActions.Add(action);
}
internal void AddCompilationEndAction(CompilationEndAnalyzerAction action)
internal void AddCompilationEndAction(CompilationAnalyzerAction action)
{
_compilationEndActions = _compilationEndActions.Add(action);
}
internal void AddCompilationAction(CompilationAnalyzerAction action)
{
_compilationActions = _compilationActions.Add(action);
}
internal void AddSyntaxTreeAction(SyntaxTreeAnalyzerAction action)
{
_syntaxTreeActions = _syntaxTreeActions.Add(action);
......@@ -516,11 +576,16 @@ internal void AddSymbolAction(SymbolAnalyzerAction action)
_codeBlockStartActions = _codeBlockStartActions.Add(action);
}
internal void AddCodeBlockEndAction(CodeBlockEndAnalyzerAction action)
internal void AddCodeBlockEndAction(CodeBlockAnalyzerAction action)
{
_codeBlockEndActions = _codeBlockEndActions.Add(action);
}
internal void AddCodeBlockAction(CodeBlockAnalyzerAction action)
{
_codeBlockActions = _codeBlockActions.Add(action);
}
internal void AddSyntaxNodeAction<TLanguageKindEnum>(SyntaxNodeAnalyzerAction<TLanguageKindEnum> action) where TLanguageKindEnum : struct
{
_syntaxNodeActions = _syntaxNodeActions.Add(action);
......@@ -540,11 +605,13 @@ public AnalyzerActions Append(AnalyzerActions otherActions)
AnalyzerActions actions = new AnalyzerActions();
actions._compilationStartActions = _compilationStartActions.AddRange(otherActions._compilationStartActions);
actions._compilationEndActions = _compilationEndActions.AddRange(otherActions._compilationEndActions);
actions._compilationActions = _compilationActions.AddRange(otherActions._compilationActions);
actions._syntaxTreeActions = _syntaxTreeActions.AddRange(otherActions._syntaxTreeActions);
actions._semanticModelActions = _semanticModelActions.AddRange(otherActions._semanticModelActions);
actions._symbolActions = _symbolActions.AddRange(otherActions._symbolActions);
actions._codeBlockStartActions = _codeBlockStartActions.AddRange(otherActions._codeBlockStartActions);
actions._codeBlockEndActions = _codeBlockEndActions.AddRange(otherActions._codeBlockEndActions);
actions._codeBlockActions = _codeBlockActions.AddRange(otherActions._codeBlockActions);
actions._syntaxNodeActions = _syntaxNodeActions.AddRange(otherActions._syntaxNodeActions);
return actions;
......
......@@ -31,7 +31,7 @@ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
public override void Initialize(AnalysisContext analysisContext)
{
analysisContext.RegisterCompilationEndAction(
analysisContext.RegisterCompilationAction(
(context) =>
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(s_rule, Location.None, messageArgs: Id));
......
......@@ -34,7 +34,10 @@ internal abstract class AnalyzerDriver : IDisposable
internal AnalyzerActions analyzerActions;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<ImmutableArray<SymbolAnalyzerAction>>> _symbolActionsByKind;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<SemanticModelAnalyzerAction>> _semanticModelActionsMap;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationEndAnalyzerAction>> _compilationEndActionsMap;
// Compilation actions and compilation end actions have separate maps so that it is easy to
// execute the compilation actions before the compilation end actions.
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationAnalyzerAction>> _compilationActionsMap;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationAnalyzerAction>> _compilationEndActionsMap;
/// <summary>
/// Primary driver task which processes all <see cref="CompilationEventQueue"/> events, runs analyzer actions and signals completion of <see cref="DiagnosticQueue"/> at the end.
......@@ -82,7 +85,8 @@ private void Initialize(Compilation comp, AnalyzerExecutor analyzerExecutor, Can
this.analyzerActions = t.Result;
_symbolActionsByKind = MakeSymbolActionsByKind();
_semanticModelActionsMap = MakeSemanticModelActionsByAnalyzer();
_compilationEndActionsMap = MakeCompilationEndActionsByAnalyzer();
_compilationActionsMap = MakeCompilationActionsByAnalyzer(this.analyzerActions.CompilationActions);
_compilationEndActionsMap = MakeCompilationActionsByAnalyzer(this.analyzerActions.CompilationEndActions);
}, cancellationToken);
// create the primary driver task.
......@@ -312,10 +316,10 @@ public async Task<ImmutableArray<Diagnostic>> GetDiagnosticsAsync()
return builder.ToImmutable();
}
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationEndAnalyzerAction>> MakeCompilationEndActionsByAnalyzer()
private static ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationAnalyzerAction>> MakeCompilationActionsByAnalyzer(ImmutableArray<CompilationAnalyzerAction> compilationActions)
{
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<CompilationEndAnalyzerAction>>();
var actionsByAnalyzers = this.analyzerActions.CompilationEndActions.GroupBy(action => action.Analyzer);
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<CompilationAnalyzerAction>>();
var actionsByAnalyzers = compilationActions.GroupBy(action => action.Analyzer);
foreach (var analyzerAndActions in actionsByAnalyzers)
{
builder.Add(analyzerAndActions.Key, analyzerAndActions.ToImmutableArray());
......@@ -507,20 +511,8 @@ private async Task ProcessCompilationCompletedAsync(CompilationCompletedEvent en
{
try
{
// Execute analyzers in parallel.
var tasks = ArrayBuilder<Task>.GetInstance();
foreach (var analyzerAndActions in _compilationEndActionsMap)
{
var task = Task.Run(() =>
{
// Execute actions for a given analyzer sequentially.
analyzerExecutor.ExecuteCompilationEndActions(analyzerAndActions.Value);
}, cancellationToken);
tasks.Add(task);
}
await Task.WhenAll(tasks.ToArrayAndFree()).ConfigureAwait(false);
await ExecuteCompilationActionsAsync(_compilationActionsMap, cancellationToken).ConfigureAwait(false);
await ExecuteCompilationActionsAsync(_compilationEndActionsMap, cancellationToken).ConfigureAwait(false);
}
finally
{
......@@ -528,6 +520,24 @@ private async Task ProcessCompilationCompletedAsync(CompilationCompletedEvent en
}
}
private async Task ExecuteCompilationActionsAsync(ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CompilationAnalyzerAction>> compilationActionsMap, CancellationToken cancellationToken)
{
// Execute analyzers in parallel.
var tasks = ArrayBuilder<Task>.GetInstance();
foreach (var analyzerAndActions in compilationActionsMap)
{
var task = Task.Run(() =>
{
// Execute actions for a given analyzer sequentially.
analyzerExecutor.ExecuteCompilationActions(analyzerAndActions.Value);
}, cancellationToken);
tasks.Add(task);
}
await Task.WhenAll(tasks.ToArrayAndFree()).ConfigureAwait(false);
}
internal static Action<Diagnostic> GetDiagnosticSinkWithSuppression(Action<Diagnostic> addDiagnosticCore, Compilation compilation, ISymbol symbolOpt = null)
{
return diagnostic =>
......@@ -610,7 +620,10 @@ internal class AnalyzerDriver<TLanguageKindEnum> : AnalyzerDriver where TLanguag
private Func<SyntaxNode, TLanguageKindEnum> _getKind;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableDictionary<TLanguageKindEnum, ImmutableArray<SyntaxNodeAnalyzerAction<TLanguageKindEnum>>>> _lazyNodeActionsByKind = null;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>> _lazyCodeBlockStartActionsByAnalyzer = null;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockEndAnalyzerAction>> _lazyCodeBlockEndActionsByAnalyzer = null;
// Code block actions and code block end actions are kept separate so that it is easy to
// execute the code block actions before the code block end actions.
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> _lazyCodeBlockEndActionsByAnalyzer = null;
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> _lazyCodeBlockActionsByAnalyzer = null;
/// <summary>
/// Create an analyzer driver.
......@@ -665,7 +678,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
}
}
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>> CodeBlockStartActionsByAnalyer
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>> CodeBlockStartActionsByAnalyzer
{
get
{
......@@ -696,35 +709,43 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
}
}
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockEndAnalyzerAction>> CodeBlockEndActionsByAnalyer
private static ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> GetCodeBlockActionsByAnalyzer(
ref ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> lazyCodeBlockActionsByAnalyzer,
ImmutableArray<CodeBlockAnalyzerAction> codeBlockActions)
{
get
if (lazyCodeBlockActionsByAnalyzer == null)
{
if (_lazyCodeBlockEndActionsByAnalyzer == null)
ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> codeBlockActionsByAnalyzer;
if (!codeBlockActions.IsEmpty)
{
ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockEndAnalyzerAction>> codeBlockEndActionsByAnalyzer;
var codeBlockEndActions = this.analyzerActions.CodeBlockEndActions;
if (codeBlockEndActions.Any())
{
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<CodeBlockEndAnalyzerAction>>();
var actionsByAnalyzer = codeBlockEndActions.GroupBy(action => action.Analyzer);
foreach (var analyzerAndActions in actionsByAnalyzer)
{
builder.Add(analyzerAndActions.Key, analyzerAndActions.ToImmutableArrayOrEmpty());
}
codeBlockEndActionsByAnalyzer = builder.ToImmutable();
}
else
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>>();
var actionsByAnalyzer = codeBlockActions.GroupBy(action => action.Analyzer);
foreach (var analyzerAndActions in actionsByAnalyzer)
{
codeBlockEndActionsByAnalyzer = ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockEndAnalyzerAction>>.Empty;
builder.Add(analyzerAndActions.Key, analyzerAndActions.ToImmutableArrayOrEmpty());
}
Interlocked.CompareExchange(ref _lazyCodeBlockEndActionsByAnalyzer, codeBlockEndActionsByAnalyzer, null);
codeBlockActionsByAnalyzer = builder.ToImmutable();
}
else
{
codeBlockActionsByAnalyzer = ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>>.Empty;
}
return _lazyCodeBlockEndActionsByAnalyzer;
Interlocked.CompareExchange(ref lazyCodeBlockActionsByAnalyzer, codeBlockActionsByAnalyzer, null);
}
return lazyCodeBlockActionsByAnalyzer;
}
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> CodeBlockEndActionsByAnalyzer
{
get { return GetCodeBlockActionsByAnalyzer(ref _lazyCodeBlockEndActionsByAnalyzer, this.analyzerActions.CodeBlockEndActions); }
}
private ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<CodeBlockAnalyzerAction>> CodeBlockActionsByAnalyzer
{
get { return GetCodeBlockActionsByAnalyzer(ref _lazyCodeBlockActionsByAnalyzer, this.analyzerActions.CodeBlockActions); }
}
protected override void AddTasksForExecutingDeclaringReferenceActions(
......@@ -734,7 +755,7 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
{
var symbol = symbolEvent.Symbol;
var executeSyntaxNodeActions = this.NodeActionsByKind.Any();
var executeCodeBlockActions = AnalyzerExecutor.CanHaveExecutableCodeBlock(symbol) && (this.CodeBlockStartActionsByAnalyer.Any() || this.CodeBlockEndActionsByAnalyer.Any());
var executeCodeBlockActions = AnalyzerExecutor.CanHaveExecutableCodeBlock(symbol) && (!this.CodeBlockStartActionsByAnalyzer.IsEmpty || !this.CodeBlockEndActionsByAnalyzer.IsEmpty || !this.CodeBlockActionsByAnalyzer.IsEmpty);
if (executeSyntaxNodeActions || executeCodeBlockActions)
{
......@@ -795,40 +816,95 @@ internal AnalyzerDriver(ImmutableArray<DiagnosticAnalyzer> analyzers, Func<Synta
if (executableCodeBlocks.Any())
{
foreach (var analyzerAndActions in this.CodeBlockStartActionsByAnalyer)
foreach (var analyzerActions in GetCodeBlockActions())
{
Action executeCodeBlockActions = () =>
{
var codeBlockStartActions = analyzerAndActions.Value;
var codeBlockEndActions = this.CodeBlockEndActionsByAnalyer.ContainsKey(analyzerAndActions.Key) ?
this.CodeBlockEndActionsByAnalyer[analyzerAndActions.Key] :
ImmutableArray<CodeBlockEndAnalyzerAction>.Empty;
analyzerExecutor.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
analyzerExecutor.ExecuteCodeBlockActions(analyzerActions.CodeBlockStartActions, analyzerActions.CodeBlockActions, analyzerActions.CodeBlockEndActions,
syntax, symbol, executableCodeBlocks, semanticModel, _getKind);
};
AddAnalyzerActionsExecutor(taskMap, analyzerAndActions.Key, executeCodeBlockActions, cancellationToken);
AddAnalyzerActionsExecutor(taskMap, analyzerActions.Analyzer, executeCodeBlockActions, cancellationToken);
}
}
}
}
private struct CodeBlockAnalyzerActions
{
public DiagnosticAnalyzer Analyzer;
public ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>> CodeBlockStartActions;
public ImmutableArray<CodeBlockAnalyzerAction> CodeBlockActions;
public ImmutableArray<CodeBlockAnalyzerAction> CodeBlockEndActions;
}
private IEnumerable<CodeBlockAnalyzerActions> GetCodeBlockActions()
{
// Include analyzers with code block start actions.
// Execute code block end actions for analyzers which don't have corresponding code block start actions.
foreach (var analyzerAndActions in this.CodeBlockEndActionsByAnalyer)
foreach (var analyzerAndActions in this.CodeBlockStartActionsByAnalyzer)
{
ImmutableArray<CodeBlockAnalyzerAction> codeBlockActions;
if (!this.CodeBlockActionsByAnalyzer.TryGetValue(analyzerAndActions.Key, out codeBlockActions))
{
codeBlockActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
}
ImmutableArray<CodeBlockAnalyzerAction> codeBlockEndActions;
if (!this.CodeBlockEndActionsByAnalyzer.TryGetValue(analyzerAndActions.Key, out codeBlockEndActions))
{
codeBlockEndActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
}
yield return
new CodeBlockAnalyzerActions()
{
// skip analyzers executed above.
if (!CodeBlockStartActionsByAnalyer.ContainsKey(analyzerAndActions.Key))
{
Action executeCodeBlockActions = () =>
{
var codeBlockStartActions = ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>.Empty;
var codeBlockEndActions = analyzerAndActions.Value;
Analyzer = analyzerAndActions.Key,
CodeBlockStartActions = analyzerAndActions.Value,
CodeBlockActions = codeBlockActions,
CodeBlockEndActions = codeBlockEndActions
};
}
analyzerExecutor.ExecuteCodeBlockActions(codeBlockStartActions, codeBlockEndActions,
syntax, symbol, executableCodeBlocks, semanticModel, _getKind);
};
// Include analyzers with code block actions.
AddAnalyzerActionsExecutor(taskMap, analyzerAndActions.Key, executeCodeBlockActions, cancellationToken);
}
foreach (var analyzerAndActions in this.CodeBlockActionsByAnalyzer)
{
// Skip analyzers included above.
if (!CodeBlockStartActionsByAnalyzer.ContainsKey(analyzerAndActions.Key))
{
ImmutableArray<CodeBlockAnalyzerAction> codeBlockEndActions;
if (!this.CodeBlockEndActionsByAnalyzer.TryGetValue(analyzerAndActions.Key, out codeBlockEndActions))
{
codeBlockEndActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty;
}
yield return
new CodeBlockAnalyzerActions()
{
Analyzer = analyzerAndActions.Key,
CodeBlockStartActions = ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>.Empty,
CodeBlockActions = analyzerAndActions.Value,
CodeBlockEndActions = codeBlockEndActions
};
}
}
// Include analyzers with code block end actions.
foreach (var analyzerAndActions in this.CodeBlockEndActionsByAnalyzer)
{
// Skip analyzers included above.
if (!CodeBlockStartActionsByAnalyzer.ContainsKey(analyzerAndActions.Key) && !CodeBlockActionsByAnalyzer.ContainsKey(analyzerAndActions.Key))
{
yield return
new CodeBlockAnalyzerActions()
{
Analyzer = analyzerAndActions.Key,
CodeBlockStartActions = ImmutableArray<CodeBlockStartAnalyzerAction<TLanguageKindEnum>>.Empty,
CodeBlockActions = ImmutableArray<CodeBlockAnalyzerAction>.Empty,
CodeBlockEndActions = analyzerAndActions.Value
};
}
}
}
......
......@@ -43,7 +43,7 @@ public void AnalyzeSemanticModel(SemanticModelAnalysisContext context)
ReportDiagnostics(bodyDiagnostics, context.ReportDiagnostic, IsSourceLocation);
}
public static void AnalyzeCompilation(CompilationEndAnalysisContext context)
public static void AnalyzeCompilation(CompilationAnalysisContext context)
{
var diagnostics = context.Compilation.GetDeclarationDiagnostics(cancellationToken: context.CancellationToken);
ReportDiagnostics(diagnostics, context.ReportDiagnostic, location => !IsSourceLocation(location), s_declaration);
......
......@@ -41,7 +41,7 @@ public sealed override void Initialize(AnalysisContext context)
c.RegisterSemanticModelAction(analyzer.AnalyzeSemanticModel);
});
context.RegisterCompilationEndAction(CompilationAnalyzer.AnalyzeCompilation);
context.RegisterCompilationAction(CompilationAnalyzer.AnalyzeCompilation);
}
}
}
......@@ -47,11 +47,11 @@ public abstract class AnalysisContext
public abstract void RegisterCompilationStartAction(Action<CompilationStartAnalysisContext> action);
/// <summary>
/// Register an action to be executed at compilation end.
/// A compilation end action reports <see cref="Diagnostic"/>s about the <see cref="Compilation"/>.
/// Register an action to be executed for a complete compilation.
/// A compilation action reports <see cref="Diagnostic"/>s about the <see cref="Compilation"/>.
/// </summary>
/// <param name="action">Action to be executed at compilation end.</param>
public abstract void RegisterCompilationEndAction(Action<CompilationEndAnalysisContext> action);
public abstract void RegisterCompilationAction(Action<CompilationAnalysisContext> action);
/// <summary>
/// Register an action to be executed at completion of semantic analysis of a document,
......@@ -89,12 +89,12 @@ public void RegisterSymbolAction(Action<SymbolAnalysisContext> action, params Sy
/// <param name="action">Action to be executed at the start of semantic analysis of a code block.</param>
public abstract void RegisterCodeBlockStartAction<TLanguageKindEnum>(Action<CodeBlockStartAnalysisContext<TLanguageKindEnum>> action) where TLanguageKindEnum : struct;
/// <summary>
/// Register an action to be executed at the end of semantic analysis of a method body or an expression appearing outside a method body.
/// A code block end action reports <see cref="Diagnostic"/>s about code blocks.
/// </summary>
/// <param name="action">Action to be executed at the end of semantic analysis of a code block.</param>
public abstract void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action);
/// <summary>
/// Register an action to be executed after semantic analysis of a method body or an expression appearing outside a method body.
/// A code block action reports <see cref="Diagnostic"/>s about code blocks.
/// </summary>
/// <param name="action">Action to be executed for a code block.</param>
public abstract void RegisterCodeBlockAction(Action<CodeBlockAnalysisContext> action);
/// <summary>
/// Register an action to be executed at completion of parsing of a code document.
......@@ -187,7 +187,7 @@ protected CompilationStartAnalysisContext(Compilation compilation, AnalyzerOptio
/// A compilation end action reports <see cref="Diagnostic"/>s about the <see cref="CodeAnalysis.Compilation"/>.
/// </summary>
/// <param name="action">Action to be executed at compilation end.</param>
public abstract void RegisterCompilationEndAction(Action<CompilationEndAnalysisContext> action);
public abstract void RegisterCompilationEndAction(Action<CompilationAnalysisContext> action);
/// <summary>
/// Register an action to be executed at completion of semantic analysis of a document,
......@@ -224,13 +224,13 @@ public void RegisterSymbolAction(Action<SymbolAnalysisContext> action, params Sy
/// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which the action applies.</typeparam>
/// <param name="action">Action to be executed at the start of semantic analysis of a code block.</param>
public abstract void RegisterCodeBlockStartAction<TLanguageKindEnum>(Action<CodeBlockStartAnalysisContext<TLanguageKindEnum>> action) where TLanguageKindEnum : struct;
/// <summary>
/// Register an action to be executed at the end of semantic analysis of a method body or an expression appearing outside a method body.
/// A code block end action reports <see cref="Diagnostic"/>s about code blocks.
/// </summary>
/// <param name="action">Action to be executed at the end of semantic analysis of a code block.</param>
public abstract void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action);
/// <summary>
/// Register an action to be executed at the end of semantic analysis of a method body or an expression appearing outside a method body.
/// A code block action reports <see cref="Diagnostic"/>s about code blocks.
/// </summary>
/// <param name="action">Action to be executed for a code block.</param>
public abstract void RegisterCodeBlockAction(Action<CodeBlockAnalysisContext> action);
/// <summary>
/// Register an action to be executed at completion of parsing of a code document.
......@@ -264,10 +264,10 @@ public void RegisterSymbolAction(Action<SymbolAnalysisContext> action, params Sy
}
/// <summary>
/// Context for a compilation end action.
/// A compilation end action can use a <see cref="CompilationEndAnalysisContext"/> to report <see cref="Diagnostic"/>s about a <see cref="CodeAnalysis.Compilation"/>.
/// Context for a compilation action or compilation end action.
/// A compilation action or compilation end action can use a <see cref="CompilationAnalysisContext"/> to report <see cref="Diagnostic"/>s about a <see cref="CodeAnalysis.Compilation"/>.
/// </summary>
public struct CompilationEndAnalysisContext
public struct CompilationAnalysisContext
{
private readonly Compilation _compilation;
private readonly AnalyzerOptions _options;
......@@ -289,7 +289,7 @@ public struct CompilationEndAnalysisContext
/// </summary>
public CancellationToken CancellationToken { get { return _cancellationToken; } }
public CompilationEndAnalysisContext(Compilation compilation, AnalyzerOptions options, Action<Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
public CompilationAnalysisContext(Compilation compilation, AnalyzerOptions options, Action<Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
{
_compilation = compilation;
_options = options;
......@@ -474,7 +474,7 @@ protected CodeBlockStartAnalysisContext(SyntaxNode codeBlock, ISymbol owningSymb
/// A code block end action reports <see cref="Diagnostic"/>s about code blocks.
/// </summary>
/// <param name="action">Action to be executed at the end of semantic analysis of a code block.</param>
public abstract void RegisterCodeBlockEndAction(Action<CodeBlockEndAnalysisContext> action);
public abstract void RegisterCodeBlockEndAction(Action<CodeBlockAnalysisContext> action);
/// <summary>
/// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an appropriate Kind.
......@@ -500,9 +500,9 @@ public void RegisterSyntaxNodeAction(Action<SyntaxNodeAnalysisContext> action, p
/// <summary>
/// Context for a code block end action.
/// A code block end action can use a <see cref="CodeBlockEndAnalysisContext"/> to report <see cref="Diagnostic"/>s about a code block.
/// A code block end action can use a <see cref="CodeBlockAnalysisContext"/> to report <see cref="Diagnostic"/>s about a code block.
/// </summary>
public struct CodeBlockEndAnalysisContext
public struct CodeBlockAnalysisContext
{
private readonly SyntaxNode _codeBlock;
private readonly ISymbol _owningSymbol;
......@@ -536,7 +536,7 @@ public struct CodeBlockEndAnalysisContext
/// </summary>
public CancellationToken CancellationToken { get { return _cancellationToken; } }
public CodeBlockEndAnalysisContext(SyntaxNode codeBlock, ISymbol owningSymbol, SemanticModel semanticModel, AnalyzerOptions options, Action<Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
public CodeBlockAnalysisContext(SyntaxNode codeBlock, ISymbol owningSymbol, SemanticModel semanticModel, AnalyzerOptions options, Action<Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
{
_codeBlock = codeBlock;
_owningSymbol = owningSymbol;
......
......@@ -239,14 +239,14 @@ Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions.AnalyzerOptions(System.Collec
Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions.WithAdditionalFiles(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.AdditionalText> additionalFiles)
Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference
Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.AnalyzerReference()
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.CodeBlock.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.CodeBlockEndAnalysisContext(Microsoft.CodeAnalysis.SyntaxNode codeBlock, Microsoft.CodeAnalysis.ISymbol owningSymbol, Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions options, System.Action<Microsoft.CodeAnalysis.Diagnostic> reportDiagnostic, System.Threading.CancellationToken cancellationToken)
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.Options.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.OwningSymbol.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic diagnostic)
Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext.SemanticModel.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.CodeBlock.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.CodeBlockAnalysisContext(Microsoft.CodeAnalysis.SyntaxNode codeBlock, Microsoft.CodeAnalysis.ISymbol owningSymbol, Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions options, System.Action<Microsoft.CodeAnalysis.Diagnostic> reportDiagnostic, System.Threading.CancellationToken cancellationToken)
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.Options.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.OwningSymbol.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic diagnostic)
Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext.SemanticModel.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.CodeBlock.get
......@@ -255,12 +255,12 @@ Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEn
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.OwningSymbol.get
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.RegisterSyntaxNodeAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext> action, params TLanguageKindEnum[] syntaxKinds)
Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.SemanticModel.get
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext.Compilation.get
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext.CompilationEndAnalysisContext(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions options, System.Action<Microsoft.CodeAnalysis.Diagnostic> reportDiagnostic, System.Threading.CancellationToken cancellationToken)
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext.Options.get
Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext.ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic diagnostic)
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.Compilation.get
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.CompilationAnalysisContext(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions options, System.Action<Microsoft.CodeAnalysis.Diagnostic> reportDiagnostic, System.Threading.CancellationToken cancellationToken)
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.Options.get
Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic diagnostic)
Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.CancellationToken.get
Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.Compilation.get
......@@ -1520,9 +1520,9 @@ abstract Microsoft.CodeAnalysis.Diagnostic.Id.get
abstract Microsoft.CodeAnalysis.Diagnostic.Location.get
abstract Microsoft.CodeAnalysis.Diagnostic.Severity.get
abstract Microsoft.CodeAnalysis.Diagnostic.WarningLevel.get
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCodeBlockEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCodeBlockAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCodeBlockStartAction<TLanguageKindEnum>(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCompilationEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCompilationAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterCompilationStartAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterSemanticModelAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SemanticModelAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterSymbolAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SymbolAnalysisContext> action, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.SymbolKind> symbolKinds)
......@@ -1531,11 +1531,11 @@ abstract Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterSyntaxTreeAc
abstract Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.FullPath.get
abstract Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetAnalyzers(string language)
abstract Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetAnalyzersForAllLanguages()
abstract Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.RegisterCodeBlockEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.RegisterCodeBlockEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>.RegisterSyntaxNodeAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext> action, System.Collections.Immutable.ImmutableArray<TLanguageKindEnum> syntaxKinds)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterCodeBlockEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockEndAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterCodeBlockAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterCodeBlockStartAction<TLanguageKindEnum>(System.Action<Microsoft.CodeAnalysis.Diagnostics.CodeBlockStartAnalysisContext<TLanguageKindEnum>> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterCompilationEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CompilationEndAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterCompilationEndAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterSemanticModelAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SemanticModelAnalysisContext> action)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterSymbolAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.SymbolAnalysisContext> action, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.SymbolKind> symbolKinds)
abstract Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterSyntaxNodeAction<TLanguageKindEnum>(System.Action<Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext> action, System.Collections.Immutable.ImmutableArray<TLanguageKindEnum> syntaxKinds)
......
......@@ -46,21 +46,21 @@ public override void Initialize(AnalysisContext context)
context.RegisterCodeBlockStartAction<TLanguageKindEnum>(new NestedCodeBlockAnalyzer(this).Initialize);
context.RegisterCompilationEndAction(this.AnalyzeCompilation);
context.RegisterCompilationAction(this.AnalyzeCompilation);
context.RegisterSemanticModelAction(this.AnalyzeSemanticModel);
context.RegisterCodeBlockEndAction(this.AnalyzeCodeBlock);
context.RegisterCodeBlockAction(this.AnalyzeCodeBlock);
context.RegisterSymbolAction(this.AnalyzeSymbol, AllSymbolKinds.ToArray());
context.RegisterSyntaxTreeAction(this.AnalyzeSyntaxTree);
context.RegisterSyntaxNodeAction<TLanguageKindEnum>(this.AnalyzeNode, AllSyntaxKinds.ToArray());
}
private void AnalyzeCodeBlock(CodeBlockEndAnalysisContext context)
private void AnalyzeCodeBlock(CodeBlockAnalysisContext context)
{
OnAbstractMember("CodeBlock", context.CodeBlock, context.OwningSymbol);
OnOptions(context.Options);
}
private void AnalyzeCompilation(CompilationEndAnalysisContext context)
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
OnAbstractMember("Compilation");
OnOptions(context.Options);
......
......@@ -7049,12 +7049,15 @@ out
Inherits DiagnosticAnalyzer
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterCompilationStartAction(AddressOf CreateAnalyzerWithinCompilation)
context.RegisterCompilationEndAction(AddressOf AnalyzeCompilation)
context.RegisterCompilationStartAction(
Sub(startContext As CompilationStartAnalysisContext)
startContext.RegisterCompilationEndAction(AddressOf AnalyzeCompilation)
CreateAnalyzerWithinCompilation(startContext)
End Sub)
End Sub
Public MustOverride Sub CreateAnalyzerWithinCompilation(context As CompilationStartAnalysisContext)
Public MustOverride Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public MustOverride Sub AnalyzeCompilation(context As CompilationAnalysisContext)
End Class
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
......@@ -7067,7 +7070,7 @@ out
context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.ExternalSourceDirectiveTrivia)
End Sub
Public Overrides Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public Overrides Sub AnalyzeCompilation(context As CompilationAnalysisContext)
End Sub
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
......@@ -7092,7 +7095,7 @@ out
context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.EnableWarningDirectiveTrivia)
End Sub
Public Overrides Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public Overrides Sub AnalyzeCompilation(context As CompilationAnalysisContext)
End Sub
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
......@@ -7118,7 +7121,7 @@ out
context.RegisterSymbolAction(AddressOf AnalyzeSymbol, SymbolKind.NamedType)
End Sub
Public Overrides Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public Overrides Sub AnalyzeCompilation(context As CompilationAnalysisContext)
End Sub
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
......@@ -7143,7 +7146,7 @@ out
context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.DisableWarningDirectiveTrivia)
End Sub
Public Overrides Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public Overrides Sub AnalyzeCompilation(context As CompilationAnalysisContext)
End Sub
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
......
......@@ -532,10 +532,10 @@ End Namespace
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterCodeBlockEndAction(AddressOf OnCodeBlock)
context.RegisterCodeBlockAction(AddressOf OnCodeBlock)
End Sub
Private Shared Sub OnCodeBlock(context As CodeBlockEndAnalysisContext)
Private Shared Sub OnCodeBlock(context As CodeBlockAnalysisContext)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Descriptor, context.OwningSymbol.DeclaringSyntaxReferences.First.GetLocation))
End Sub
End Class
......
......@@ -14,22 +14,22 @@ public abstract partial class DiagnosticAnalyzerCorrectnessAnalyzer : Diagnostic
internal static readonly string AnalysisContextFullName = typeof(AnalysisContext).FullName;
internal static readonly string CompilationStartAnalysisContextFullName = typeof(CompilationStartAnalysisContext).FullName;
internal static readonly string CompilationEndAnalysisContextFullName = typeof(CompilationEndAnalysisContext).FullName;
internal static readonly string CompilationEndAnalysisContextFullName = typeof(CompilationAnalysisContext).FullName;
internal static readonly string SemanticModelAnalysisContextFullName = typeof(SemanticModelAnalysisContext).FullName;
internal static readonly string SymbolAnalysisContextFullName = typeof(SymbolAnalysisContext).FullName;
internal static readonly string SyntaxNodeAnalysisContextFullName = typeof(SyntaxNodeAnalysisContext).FullName;
internal static readonly string SyntaxTreeAnalysisContextFullName = typeof(SyntaxTreeAnalysisContext).FullName;
internal static readonly string CodeBlockStartAnalysisContextFullName = typeof(CodeBlockStartAnalysisContext<>).FullName;
internal static readonly string CodeBlockEndAnalysisContextFullName = typeof(CodeBlockEndAnalysisContext).FullName;
internal static readonly string CodeBlockEndAnalysisContextFullName = typeof(CodeBlockAnalysisContext).FullName;
internal static readonly string SymbolKindFullName = typeof(SymbolKind).FullName;
internal static readonly string RegisterSyntaxNodeActionName = nameof(AnalysisContext.RegisterSyntaxNodeAction);
internal static readonly string RegisterSymbolActionName = nameof(AnalysisContext.RegisterSymbolAction);
internal static readonly string RegisterCodeBlockStartActionName = nameof(AnalysisContext.RegisterCodeBlockStartAction);
internal static readonly string RegisterCodeBlockEndActionName = nameof(AnalysisContext.RegisterCodeBlockEndAction);
internal static readonly string RegisterCodeBlockActionName = nameof(AnalysisContext.RegisterCodeBlockAction);
internal static readonly string RegisterCompilationStartActionName = nameof(AnalysisContext.RegisterCompilationStartAction);
internal static readonly string RegisterCompilationEndActionName = nameof(CompilationStartAnalysisContext.RegisterCompilationEndAction);
internal static readonly string ReportDiagnosticName = nameof(CompilationEndAnalysisContext.ReportDiagnostic);
internal static readonly string RegisterCompilationActionName = nameof(AnalysisContext.RegisterCompilationAction);
internal static readonly string ReportDiagnosticName = nameof(CompilationAnalysisContext.ReportDiagnostic);
internal static readonly string SupportedDiagnosticsName = nameof(DiagnosticAnalyzer.SupportedDiagnostics);
internal static readonly string TLanguageKindEnumName = @"TLanguageKindEnum";
......
......@@ -93,7 +93,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
suppress = true;
}
public void AnalyzeCodeBlock(CodeBlockEndAnalysisContext context)
public void AnalyzeCodeBlock(CodeBlockAnalysisContext context)
{
if (!suppress)
{
......
......@@ -43,10 +43,10 @@ public override void Initialize(AnalysisContext analysisContext)
{
base.Initialize(analysisContext);
analysisContext.RegisterCompilationEndAction(AnalyzeCompilation);
analysisContext.RegisterCompilationAction(AnalyzeCompilation);
}
private void AnalyzeCompilation(CompilationEndAnalysisContext context)
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
var globalNamespaces = context.Compilation.GlobalNamespace.GetNamespaceMembers()
.Where(item => item.ContainingAssembly == context.Compilation.Assembly);
......
......@@ -74,7 +74,7 @@ public ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
}
}
public void AnalyzeCodeBlock(CodeBlockEndAnalysisContext context)
public void AnalyzeCodeBlock(CodeBlockAnalysisContext context)
{
if (IsEmptyFinalizer(context.CodeBlock, context.SemanticModel))
{
......
......@@ -65,7 +65,7 @@ public AbstractAnalyzer(INamedTypeSymbol disposableType)
_disposableType = disposableType;
}
public void AnalyzeCompilation(CompilationEndAnalysisContext context)
public void AnalyzeCompilation(CompilationAnalysisContext context)
{
foreach (var item in _fieldDisposedMap)
{
......
......@@ -38,10 +38,10 @@ public sealed class AssemblyAttributesDiagnosticAnalyzer : DiagnosticAnalyzer
public override void Initialize(AnalysisContext analysisContext)
{
analysisContext.RegisterCompilationEndAction(AnalyzeCompilation);
analysisContext.RegisterCompilationAction(AnalyzeCompilation);
}
private void AnalyzeCompilation(CompilationEndAnalysisContext context)
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
var assemblyVersionAttributeSymbol = WellKnownTypes.AssemblyVersionAttribute(context.Compilation);
var assemblyComplianceAttributeSymbol = WellKnownTypes.CLSCompliantAttribute(context.Compilation);
......
......@@ -34,10 +34,10 @@ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
public override void Initialize(AnalysisContext analysisContext)
{
analysisContext.RegisterCompilationEndAction(AnalyzeCompilation);
analysisContext.RegisterCompilationAction(AnalyzeCompilation);
}
private void AnalyzeCompilation(CompilationEndAnalysisContext context)
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
if (AssemblyHasPublicTypes(context.Compilation.Assembly))
{
......
......@@ -162,7 +162,7 @@ private void AddSymbolDeclarations(IEnumerable<ISymbol> symbols)
}
}
public void OnCompilationEnd(CompilationEndAnalysisContext context)
public void OnCompilationEnd(CompilationAnalysisContext context)
{
foreach (var kv in _used.Where(kv => !kv.Value && (kv.Key.Locations.FirstOrDefault()?.IsInSource == true)))
{
......
......@@ -142,7 +142,7 @@ internal void AnalyzeNamedType(SymbolAnalysisContext context)
}
}
internal void AnalyzeCompilationEnd(CompilationEndAnalysisContext context)
internal void AnalyzeCompilationEnd(CompilationAnalysisContext context)
{
foreach (var sourceSymbol in _sourceSymbolsToCheck)
{
......
......@@ -285,7 +285,7 @@ public ImmutableArray<SyntaxKind> SyntaxKindsOfInterest
}
}
public void AnalyzeCodeBlock(CodeBlockEndAnalysisContext context)
public void AnalyzeCodeBlock(CodeBlockAnalysisContext context)
{
}
......
......@@ -38,7 +38,7 @@ public void CreateAnalyzerWithinCompilation(CompilationStartAnalysisContext cont
context.RegisterCompilationEndAction(AnalyzeCompilation);
}
public void AnalyzeCompilation(CompilationEndAnalysisContext context)
public void AnalyzeCompilation(CompilationAnalysisContext context)
{
}
}
......
......@@ -1187,7 +1187,7 @@ public class B
End Sub
Private Class CodeBlockEndedAnalyzer
Public Sub AnalyzeCodeBlock(context As CodeBlockEndAnalysisContext)
Public Sub AnalyzeCodeBlock(context As CodeBlockAnalysisContext)
Throw New NotImplementedException()
End Sub
End Class
......@@ -1205,14 +1205,14 @@ public class B
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterCodeBlockEndAction(AddressOf AnalyzeCodeBlock)
context.RegisterCodeBlockAction(AddressOf AnalyzeCodeBlock)
' Register a compilation start action that doesn't do anything to make sure that doesn't confuse anything.
context.RegisterCompilationStartAction(Sub(c) Return)
' Register a compilation end action that doesn't do anything to make sure that doesn't confuse anything.
context.RegisterCompilationEndAction(Sub(c) Return)
' Register a compilation action that doesn't do anything to make sure that doesn't confuse anything.
context.RegisterCompilationAction(Sub(c) Return)
End Sub
Public Sub AnalyzeCodeBlock(context As CodeBlockEndAnalysisContext)
Public Sub AnalyzeCodeBlock(context As CodeBlockAnalysisContext)
Assert.NotNull(context.CodeBlock)
Assert.NotNull(context.OwningSymbol)
context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.CodeBlock.GetLocation))
......@@ -1232,11 +1232,11 @@ public class B
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterCodeBlockStartAction(Of TLanguageKindEnum)(AddressOf CreateAnalyzerWithinCodeBlock)
' Register a compilation end action that doesn't do anything to make sure that doesn't confuse anything.
context.RegisterCompilationEndAction(Sub(c) Return)
' Register a compilation action that doesn't do anything to make sure that doesn't confuse anything.
context.RegisterCompilationAction(Sub(c) Return)
End Sub
Public Sub AnalyzeCodeBlock(context As CodeBlockEndAnalysisContext)
Public Sub AnalyzeCodeBlock(context As CodeBlockAnalysisContext)
context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.CodeBlock.GetLocation))
End Sub
......@@ -1259,10 +1259,10 @@ public class B
Public Overrides Sub Initialize(context As AnalysisContext)
' Register a symbol analyzer that doesn't do anything to verify that that doesn't confuse anything.
context.RegisterSymbolAction(Sub(s) Return, SymbolKind.NamedType)
context.RegisterCompilationEndAction(AddressOf AnalyzeCompilation)
context.RegisterCompilationAction(AddressOf AnalyzeCompilation)
End Sub
Private Shared Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Private Shared Sub AnalyzeCompilation(context As CompilationAnalysisContext)
context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.None))
context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Compilation.SyntaxTrees(0).GetRoot().GetLocation))
End Sub
......@@ -1301,7 +1301,7 @@ public class B
symbolNames.Add(context.Symbol.Name)
End Sub
Public Sub AnalyzeCompilation(context As CompilationEndAnalysisContext)
Public Sub AnalyzeCompilation(context As CompilationAnalysisContext)
context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.None, symbolNames.Count))
End Sub
End Class
......@@ -1332,14 +1332,14 @@ public class B
Public Overrides Sub Initialize(context As AnalysisContext)
If _isCodeBlockAnalyzer Then
context.RegisterCodeBlockStartAction(Of CodeAnalysis.CSharp.SyntaxKind)(AddressOf OnCodeBlockStarted)
context.RegisterCodeBlockEndAction(AddressOf OnCodeBlockEnded)
context.RegisterCodeBlockAction(AddressOf OnCodeBlockEnded)
Else
Dim analyzer = New NodeAnalyzer
analyzer.Initialize(Sub(action, Kinds) context.RegisterSyntaxNodeAction(action, Kinds))
End If
End Sub
Public Shared Sub OnCodeBlockEnded(context As CodeBlockEndAnalysisContext)
Public Shared Sub OnCodeBlockEnded(context As CodeBlockAnalysisContext)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, context.CodeBlock.GetLocation()))
End Sub
......
......@@ -413,8 +413,8 @@ public async Task<ImmutableArray<Diagnostic>> GetSemanticDiagnosticsAsync(Diagno
this.SyntaxNodeAnalyzerService.ExecuteSyntaxNodeActions(analyzerActions, GetSyntaxNodesToAnalyze(), model, analyzerExecutor);
}
// CodeBlockStart, CodeBlockEnd, and generated SyntaxNode actions.
if (analyzerActions.CodeBlockStartActionsCount > 0 || analyzerActions.CodeBlockEndActionsCount > 0)
// CodeBlockStart, CodeBlock, CodeBlockEnd, and generated SyntaxNode actions.
if (analyzerActions.CodeBlockStartActionsCount > 0 || analyzerActions.CodeBlockActionsCount > 0 || analyzerActions.CodeBlockEndActionsCount > 0)
{
this.SyntaxNodeAnalyzerService.ExecuteCodeBlockActions(analyzerActions, this.GetDeclarationInfos(model), model, analyzerExecutor);
}
......@@ -479,13 +479,16 @@ private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, L
if (hasDependentCompilationEndAction && forceAnalyzeAllDocuments != null)
{
// Analyzer registered a compilation end action and at least one other analyzer action during it's compilation start action.
// Analyzer registered a compilation end action and at least one other analyzer action during its compilation start action.
// We need to ensure that we have force analyzed all documents in this project for this analyzer before executing the end actions.
forceAnalyzeAllDocuments(_project, analyzer, _cancellationToken);
}
// Compilation actions.
analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationActions);
// CompilationEnd actions.
analyzerExecutor.ExecuteCompilationEndActions(analyzerActions);
analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationEndActions);
var filteredDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation);
diagnostics.AddRange(filteredDiagnostics);
......
......@@ -11,8 +11,10 @@ internal class DiagnosticLogAggregator : LogAggregator
{
public static readonly string[] AnalyzerTypes =
{
"Analyzer.CodeBlock",
"Analyzer.CodeBlockEnd",
"Analyzer.CodeBlockStart",
"Analyzer.Compilation",
"Analyzer.CompilationEnd",
"Analyzer.CompilationStart",
"Analyzer.SemanticModel",
......@@ -61,26 +63,30 @@ public AnalyzerInfo(DiagnosticAnalyzer analyzer, AnalyzerActions analyzerActions
CLRType = analyzer.GetType();
Telemetry = telemetry;
Counts[0] = analyzerActions.CodeBlockEndActionsCount;
Counts[1] = analyzerActions.CodeBlockStartActionsCount;
Counts[2] = analyzerActions.CompilationEndActionsCount;
Counts[3] = analyzerActions.CompilationStartActionsCount;
Counts[4] = analyzerActions.SemanticModelActionsCount;
Counts[5] = analyzerActions.SymbolActionsCount;
Counts[6] = analyzerActions.SyntaxNodeActionsCount;
Counts[7] = analyzerActions.SyntaxTreeActionsCount;
Counts[0] = analyzerActions.CodeBlockActionsCount;
Counts[1] = analyzerActions.CodeBlockEndActionsCount;
Counts[2] = analyzerActions.CodeBlockStartActionsCount;
Counts[3] = analyzerActions.CompilationActionsCount;
Counts[4] = analyzerActions.CompilationEndActionsCount;
Counts[5] = analyzerActions.CompilationStartActionsCount;
Counts[6] = analyzerActions.SemanticModelActionsCount;
Counts[7] = analyzerActions.SymbolActionsCount;
Counts[8] = analyzerActions.SyntaxNodeActionsCount;
Counts[9] = analyzerActions.SyntaxTreeActionsCount;
}
public void SetAnalyzerTypeCount(AnalyzerActions analyzerActions)
{
Counts[0] = analyzerActions.CodeBlockEndActionsCount;
Counts[1] = analyzerActions.CodeBlockStartActionsCount;
Counts[2] = analyzerActions.CompilationEndActionsCount;
Counts[3] = analyzerActions.CompilationStartActionsCount;
Counts[4] = analyzerActions.SemanticModelActionsCount;
Counts[5] = analyzerActions.SymbolActionsCount;
Counts[6] = analyzerActions.SyntaxNodeActionsCount;
Counts[7] = analyzerActions.SyntaxTreeActionsCount;
Counts[0] = analyzerActions.CodeBlockActionsCount;
Counts[1] = analyzerActions.CodeBlockEndActionsCount;
Counts[2] = analyzerActions.CodeBlockStartActionsCount;
Counts[3] = analyzerActions.CompilationActionsCount;
Counts[4] = analyzerActions.CompilationEndActionsCount;
Counts[5] = analyzerActions.CompilationStartActionsCount;
Counts[6] = analyzerActions.SemanticModelActionsCount;
Counts[7] = analyzerActions.SymbolActionsCount;
Counts[8] = analyzerActions.SyntaxNodeActionsCount;
Counts[9] = analyzerActions.SyntaxTreeActionsCount;
}
}
}
......
......@@ -49,7 +49,7 @@ public static DiagnosticAnalyzerCategory GetDiagnosticAnalyzerCategory(this Diag
cantSupportSemanticSpanAnalysis = true;
}
if (analyzerActions.CompilationEndActionsCount > 0 || analyzerActions.CompilationStartActionsCount > 0)
if (analyzerActions.CompilationEndActionsCount > 0 || analyzerActions.CompilationActionsCount > 0 || analyzerActions.CompilationStartActionsCount > 0)
{
category |= DiagnosticAnalyzerCategory.ProjectAnalysis;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册