From 349d1c2d79638718e1ce56665d45e239031ad991 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 19 Jun 2024 17:16:46 -0500 Subject: [PATCH] Simplify HostAnalysisScope since it is only ever used in the context of a single analyzer --- .../DiagnosticAnalyzer/AnalyzerExecutor.cs | 27 +- ...nalyzerManager.AnalyzerExecutionContext.cs | 12 +- .../DiagnosticAnalyzer/AnalyzerManager.cs | 20 +- .../DiagnosticStartAnalysisScope.cs | 300 +++++++----------- 4 files changed, 128 insertions(+), 231 deletions(-) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs index 51afbb74f6e48..c29f5e6e78307 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs @@ -189,7 +189,6 @@ internal ImmutableDictionary AnalyzerExecutionTime /// /// Executes the for the given analyzer. /// - /// Analyzer to get session wide analyzer actions. /// Session scope to store register session wide analyzer actions. /// Severity filter for analysis. /// Cancellation token. @@ -198,18 +197,15 @@ internal ImmutableDictionary AnalyzerExecutionTime /// Use API /// to get execute these actions to get the per-compilation analyzer actions. /// - public void ExecuteInitializeMethod(DiagnosticAnalyzer analyzer, HostSessionStartAnalysisScope sessionScope, SeverityFilter severityFilter, CancellationToken cancellationToken) + public void ExecuteInitializeMethod(HostSessionStartAnalysisScope sessionScope, SeverityFilter severityFilter, CancellationToken cancellationToken) { - if (analyzer != sessionScope.Analyzer) - throw new InvalidOperationException(); - - var context = new AnalyzerAnalysisContext(analyzer, sessionScope, severityFilter); + var context = new AnalyzerAnalysisContext(sessionScope, severityFilter); // The Initialize method should be run asynchronously in case it is not well behaved, e.g. does not terminate. ExecuteAndCatchIfThrows( - analyzer, + sessionScope.Analyzer, data => data.analyzer.Initialize(data.context), - (analyzer, context), + (analyzer: sessionScope.Analyzer, context), contextInfo: null, cancellationToken); } @@ -226,7 +222,7 @@ public void ExecuteCompilationStartActions(ImmutableArray /// Symbol whose symbol start actions are to be executed. - /// Analyzer whose symbol start actions are to be executed. /// whose symbol start actions are to be executed. /// Symbol scope to store the analyzer actions. /// Flag indicating if the symbol being analyzed is generated code. /// Cancellation token. public void ExecuteSymbolStartActions( ISymbol symbol, - DiagnosticAnalyzer analyzer, ImmutableArray actions, HostSymbolStartAnalysisScope symbolScope, bool isGeneratedCodeSymbol, @@ -257,21 +251,18 @@ public void ExecuteSymbolStartActions( TextSpan? filterSpan, CancellationToken cancellationToken) { - if (analyzer != symbolScope.Analyzer) - throw new InvalidOperationException(); - - if (isGeneratedCodeSymbol && _shouldSkipAnalysisOnGeneratedCode(analyzer) || - IsAnalyzerSuppressedForSymbol(analyzer, symbol, cancellationToken)) + if (isGeneratedCodeSymbol && _shouldSkipAnalysisOnGeneratedCode(symbolScope.Analyzer) || + IsAnalyzerSuppressedForSymbol(symbolScope.Analyzer, symbol, cancellationToken)) { return; } foreach (var startAction in actions) { - Debug.Assert(startAction.Analyzer == analyzer); + Debug.Assert(startAction.Analyzer == symbolScope.Analyzer); cancellationToken.ThrowIfCancellationRequested(); - var context = new AnalyzerSymbolStartAnalysisContext(startAction.Analyzer, symbolScope, + var context = new AnalyzerSymbolStartAnalysisContext(symbolScope, symbol, Compilation, AnalyzerOptions, isGeneratedCodeSymbol, filterTree, filterSpan, cancellationToken); ExecuteAndCatchIfThrows( diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.AnalyzerExecutionContext.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.AnalyzerExecutionContext.cs index d6c28cc39decb..70d2f7d5e7776 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.AnalyzerExecutionContext.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.AnalyzerExecutionContext.cs @@ -91,7 +91,7 @@ static Task getSessionAnalysisScopeTaskSlowAsync( return Task.Run(() => { var sessionScope = new HostSessionStartAnalysisScope(context._analyzer); - executor.ExecuteInitializeMethod(context._analyzer, sessionScope, executor.SeverityFilter, cancellationToken); + executor.ExecuteInitializeMethod(sessionScope, executor.SeverityFilter, cancellationToken); return sessionScope; }, cancellationToken); } @@ -117,11 +117,9 @@ public Task GetCompilationAnalysisScopeAsync( { _lazyCompilationScopeTask = Task.Run(() => { - if (sessionScope.Analyzer != _analyzer) - throw new InvalidOperationException(); - + Debug.Assert(sessionScope.Analyzer == _analyzer); var compilationAnalysisScope = new HostCompilationStartAnalysisScope(sessionScope); - analyzerExecutor.ExecuteCompilationStartActions(sessionScope.GetAnalyzerActions(_analyzer).CompilationStartActions, compilationAnalysisScope, cancellationToken); + analyzerExecutor.ExecuteCompilationStartActions(sessionScope.GetAnalyzerActions().CompilationStartActions, compilationAnalysisScope, cancellationToken); return compilationAnalysisScope; }, cancellationToken); } @@ -161,9 +159,9 @@ public Task GetSymbolAnalysisScopeAsync( HostSymbolStartAnalysisScope getSymbolAnalysisScopeCore() { var symbolAnalysisScope = new HostSymbolStartAnalysisScope(_analyzer); - analyzerExecutor.ExecuteSymbolStartActions(symbol, _analyzer, symbolStartActions, symbolAnalysisScope, isGeneratedCodeSymbol, filterTree, filterSpan, cancellationToken); + analyzerExecutor.ExecuteSymbolStartActions(symbol, symbolStartActions, symbolAnalysisScope, isGeneratedCodeSymbol, filterTree, filterSpan, cancellationToken); - var symbolEndActions = symbolAnalysisScope.GetAnalyzerActions(_analyzer); + var symbolEndActions = symbolAnalysisScope.GetAnalyzerActions(); if (symbolEndActions.SymbolEndActionsCount > 0) { var dependentSymbols = getDependentSymbols(); diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.cs index 0115a0fd02c44..7d27857248c4b 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerManager.cs @@ -56,15 +56,11 @@ private Dictionary CreateAnalyzerE "https://github.com/dotnet/roslyn/issues/26778", OftenCompletesSynchronously = true)] private async ValueTask GetCompilationAnalysisScopeAsync( - DiagnosticAnalyzer analyzer, HostSessionStartAnalysisScope sessionScope, AnalyzerExecutor analyzerExecutor, CancellationToken cancellationToken) { - if (analyzer != sessionScope.Analyzer) - throw new InvalidOperationException(); - - var analyzerExecutionContext = GetAnalyzerExecutionContext(analyzer); + var analyzerExecutionContext = GetAnalyzerExecutionContext(sessionScope.Analyzer); return await GetCompilationAnalysisScopeCoreAsync(sessionScope, analyzerExecutor, analyzerExecutionContext, cancellationToken).ConfigureAwait(false); } @@ -172,13 +168,13 @@ private async ValueTask GetSessionAnalysisScopeCo public async ValueTask GetAnalyzerActionsAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor, CancellationToken cancellationToken) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor, cancellationToken).ConfigureAwait(false); - if (sessionScope.GetAnalyzerActions(analyzer).CompilationStartActionsCount > 0 && analyzerExecutor.Compilation != null) + if (sessionScope.GetAnalyzerActions().CompilationStartActionsCount > 0 && analyzerExecutor.Compilation != null) { - var compilationScope = await GetCompilationAnalysisScopeAsync(analyzer, sessionScope, analyzerExecutor, cancellationToken).ConfigureAwait(false); - return compilationScope.GetAnalyzerActions(analyzer); + var compilationScope = await GetCompilationAnalysisScopeAsync(sessionScope, analyzerExecutor, cancellationToken).ConfigureAwait(false); + return compilationScope.GetAnalyzerActions(); } - return sessionScope.GetAnalyzerActions(analyzer); + return sessionScope.GetAnalyzerActions(); } /// @@ -202,7 +198,7 @@ public async ValueTask GetPerSymbolAnalyzerActionsAsync( if (filteredSymbolStartActions.Length > 0) { var symbolScope = await GetSymbolAnalysisScopeAsync(symbol, isGeneratedCodeSymbol, filterTree, filterSpan, analyzer, filteredSymbolStartActions, analyzerExecutor, cancellationToken).ConfigureAwait(false); - return symbolScope.GetAnalyzerActions(analyzer); + return symbolScope.GetAnalyzerActions(); } } @@ -237,7 +233,7 @@ ImmutableArray getFilteredActionsByKind(ImmutableArra public async Task IsConcurrentAnalyzerAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor, CancellationToken cancellationToken) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor, cancellationToken).ConfigureAwait(false); - return sessionScope.IsConcurrentAnalyzer(analyzer); + return sessionScope.IsConcurrentAnalyzer(); } /// @@ -247,7 +243,7 @@ public async Task IsConcurrentAnalyzerAsync(DiagnosticAnalyzer analyzer, A public async Task GetGeneratedCodeAnalysisFlagsAsync(DiagnosticAnalyzer analyzer, AnalyzerExecutor analyzerExecutor, CancellationToken cancellationToken) { var sessionScope = await GetSessionAnalysisScopeAsync(analyzer, analyzerExecutor, cancellationToken).ConfigureAwait(false); - return sessionScope.GetGeneratedCodeAnalysisFlags(analyzer); + return sessionScope.GetGeneratedCodeAnalysisFlags(); } /// diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticStartAnalysisScope.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticStartAnalysisScope.cs index 9c21de75f860a..72cc321b44703 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticStartAnalysisScope.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticStartAnalysisScope.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Concurrent; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; @@ -20,15 +19,10 @@ namespace Microsoft.CodeAnalysis.Diagnostics /// internal sealed class AnalyzerAnalysisContext : AnalysisContext { - private readonly DiagnosticAnalyzer _analyzer; private readonly HostSessionStartAnalysisScope _scope; - public AnalyzerAnalysisContext(DiagnosticAnalyzer analyzer, HostSessionStartAnalysisScope scope, SeverityFilter severityFilter) + public AnalyzerAnalysisContext(HostSessionStartAnalysisScope scope, SeverityFilter severityFilter) { - if (analyzer != scope.Analyzer) - throw new InvalidOperationException(); - - _analyzer = analyzer; _scope = scope; MinimumReportedSeverity = severityFilter.GetMinimumUnfilteredSeverity(); } @@ -36,89 +30,89 @@ public AnalyzerAnalysisContext(DiagnosticAnalyzer analyzer, HostSessionStartAnal public override void RegisterCompilationStartAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCompilationStartAction(_analyzer, action); + _scope.RegisterCompilationStartAction(action); } public override void RegisterCompilationAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCompilationAction(_analyzer, action); + _scope.RegisterCompilationAction(action); } public override void RegisterSyntaxTreeAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSyntaxTreeAction(_analyzer, action); + _scope.RegisterSyntaxTreeAction(action); } public override void RegisterAdditionalFileAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterAdditionalFileAction(_analyzer, action); + _scope.RegisterAdditionalFileAction(action); } public override void RegisterSemanticModelAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSemanticModelAction(_analyzer, action); + _scope.RegisterSemanticModelAction(action); } public override void RegisterSymbolAction(Action action, ImmutableArray symbolKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, symbolKinds); - _scope.RegisterSymbolAction(_analyzer, action, symbolKinds); + _scope.RegisterSymbolAction(action, symbolKinds); } public override void RegisterSymbolStartAction(Action action, SymbolKind symbolKind) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSymbolStartAction(_analyzer, action, symbolKind); + _scope.RegisterSymbolStartAction(action, symbolKind); } public override void RegisterCodeBlockStartAction(Action> action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockStartAction(_analyzer, action); + _scope.RegisterCodeBlockStartAction(action); } public override void RegisterCodeBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockAction(_analyzer, action); + _scope.RegisterCodeBlockAction(action); } public override void RegisterSyntaxNodeAction(Action action, ImmutableArray syntaxKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, syntaxKinds); - _scope.RegisterSyntaxNodeAction(_analyzer, action, syntaxKinds); + _scope.RegisterSyntaxNodeAction(action, syntaxKinds); } public override void RegisterOperationAction(Action action, ImmutableArray operationKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, operationKinds); - _scope.RegisterOperationAction(_analyzer, action, operationKinds); + _scope.RegisterOperationAction(action, operationKinds); } public override void RegisterOperationBlockStartAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockStartAction(_analyzer, action); + _scope.RegisterOperationBlockStartAction(action); } public override void RegisterOperationBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockAction(_analyzer, action); + _scope.RegisterOperationBlockAction(action); } public override void EnableConcurrentExecution() { - _scope.EnableConcurrentExecution(_analyzer); + _scope.EnableConcurrentExecution(); } public override void ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags mode) { - _scope.ConfigureGeneratedCodeAnalysis(_analyzer, mode); + _scope.ConfigureGeneratedCodeAnalysis(mode); } public override DiagnosticSeverity MinimumReportedSeverity { get; } @@ -129,12 +123,10 @@ public override void ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags m /// internal sealed class AnalyzerCompilationStartAnalysisContext : CompilationStartAnalysisContext { - private readonly DiagnosticAnalyzer _analyzer; private readonly HostCompilationStartAnalysisScope _scope; private readonly CompilationAnalysisValueProviderFactory _compilationAnalysisValueProviderFactory; public AnalyzerCompilationStartAnalysisContext( - DiagnosticAnalyzer analyzer, HostCompilationStartAnalysisScope scope, Compilation compilation, AnalyzerOptions options, @@ -142,10 +134,6 @@ public AnalyzerCompilationStartAnalysisContext( CancellationToken cancellationToken) : base(compilation, options, cancellationToken) { - if (analyzer != scope.Analyzer) - throw new InvalidOperationException(); - - _analyzer = analyzer; _scope = scope; _compilationAnalysisValueProviderFactory = compilationAnalysisValueProviderFactory; } @@ -153,73 +141,73 @@ public AnalyzerCompilationStartAnalysisContext( public override void RegisterCompilationEndAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCompilationEndAction(_analyzer, action); + _scope.RegisterCompilationEndAction(action); } public override void RegisterSyntaxTreeAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSyntaxTreeAction(_analyzer, action); + _scope.RegisterSyntaxTreeAction(action); } public override void RegisterAdditionalFileAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterAdditionalFileAction(_analyzer, action); + _scope.RegisterAdditionalFileAction(action); } public override void RegisterSemanticModelAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSemanticModelAction(_analyzer, action); + _scope.RegisterSemanticModelAction(action); } public override void RegisterSymbolAction(Action action, ImmutableArray symbolKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, symbolKinds); - _scope.RegisterSymbolAction(_analyzer, action, symbolKinds); + _scope.RegisterSymbolAction(action, symbolKinds); } public override void RegisterSymbolStartAction(Action action, SymbolKind symbolKind) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSymbolStartAction(_analyzer, action, symbolKind); + _scope.RegisterSymbolStartAction(action, symbolKind); } public override void RegisterCodeBlockStartAction(Action> action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockStartAction(_analyzer, action); + _scope.RegisterCodeBlockStartAction(action); } public override void RegisterCodeBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockAction(_analyzer, action); + _scope.RegisterCodeBlockAction(action); } public override void RegisterSyntaxNodeAction(Action action, ImmutableArray syntaxKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, syntaxKinds); - _scope.RegisterSyntaxNodeAction(_analyzer, action, syntaxKinds); + _scope.RegisterSyntaxNodeAction(action, syntaxKinds); } public override void RegisterOperationBlockStartAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockStartAction(_analyzer, action); + _scope.RegisterOperationBlockStartAction(action); } public override void RegisterOperationBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockAction(_analyzer, action); + _scope.RegisterOperationBlockAction(action); } public override void RegisterOperationAction(Action action, ImmutableArray operationKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, operationKinds); - _scope.RegisterOperationAction(_analyzer, action, operationKinds); + _scope.RegisterOperationAction(action, operationKinds); } internal override bool TryGetValueCore(TKey key, AnalysisValueProvider valueProvider, [MaybeNullWhen(false)] out TValue value) @@ -234,10 +222,9 @@ internal override bool TryGetValueCore(TKey key, AnalysisValueProv /// internal sealed class AnalyzerSymbolStartAnalysisContext : SymbolStartAnalysisContext { - private readonly DiagnosticAnalyzer _analyzer; private readonly HostSymbolStartAnalysisScope _scope; - internal AnalyzerSymbolStartAnalysisContext(DiagnosticAnalyzer analyzer, + internal AnalyzerSymbolStartAnalysisContext( HostSymbolStartAnalysisScope scope, ISymbol owningSymbol, Compilation compilation, @@ -248,53 +235,49 @@ internal AnalyzerSymbolStartAnalysisContext(DiagnosticAnalyzer analyzer, CancellationToken cancellationToken) : base(owningSymbol, compilation, options, isGeneratedCode, filterTree, filterSpan, cancellationToken) { - if (analyzer != scope.Analyzer) - throw new InvalidOperationException(); - - _analyzer = analyzer; _scope = scope; } public override void RegisterSymbolEndAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterSymbolEndAction(_analyzer, action); + _scope.RegisterSymbolEndAction(action); } public override void RegisterCodeBlockStartAction(Action> action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockStartAction(_analyzer, action); + _scope.RegisterCodeBlockStartAction(action); } public override void RegisterCodeBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterCodeBlockAction(_analyzer, action); + _scope.RegisterCodeBlockAction(action); } public override void RegisterSyntaxNodeAction(Action action, ImmutableArray syntaxKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, syntaxKinds); - _scope.RegisterSyntaxNodeAction(_analyzer, action, syntaxKinds); + _scope.RegisterSyntaxNodeAction(action, syntaxKinds); } public override void RegisterOperationBlockStartAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockStartAction(_analyzer, action); + _scope.RegisterOperationBlockStartAction(action); } public override void RegisterOperationBlockAction(Action action) { DiagnosticAnalysisContextHelpers.VerifyArguments(action); - _scope.RegisterOperationBlockAction(_analyzer, action); + _scope.RegisterOperationBlockAction(action); } public override void RegisterOperationAction(Action action, ImmutableArray operationKinds) { DiagnosticAnalysisContextHelpers.VerifyArguments(action, operationKinds); - _scope.RegisterOperationAction(_analyzer, action, operationKinds); + _scope.RegisterOperationAction(action, operationKinds); } } @@ -378,50 +361,34 @@ public override void RegisterOperationAction(Action ac internal sealed class HostSessionStartAnalysisScope(DiagnosticAnalyzer analyzer) : HostAnalysisScope(analyzer) { - private ImmutableHashSet _concurrentAnalyzers = ImmutableHashSet.Empty; - private readonly ConcurrentDictionary _generatedCodeConfigurationMap = new ConcurrentDictionary(); + private bool _isConcurrent; + private GeneratedCodeAnalysisFlags _generatedCodeConfiguration = AnalyzerDriver.DefaultGeneratedCodeAnalysisFlags; - public bool IsConcurrentAnalyzer(DiagnosticAnalyzer analyzer) + public bool IsConcurrentAnalyzer() { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - return _concurrentAnalyzers.Contains(analyzer); + return _isConcurrent; } - public GeneratedCodeAnalysisFlags GetGeneratedCodeAnalysisFlags(DiagnosticAnalyzer analyzer) + public GeneratedCodeAnalysisFlags GetGeneratedCodeAnalysisFlags() { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - GeneratedCodeAnalysisFlags mode; - return _generatedCodeConfigurationMap.TryGetValue(analyzer, out mode) ? mode : AnalyzerDriver.DefaultGeneratedCodeAnalysisFlags; + return _generatedCodeConfiguration; } - public void RegisterCompilationStartAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterCompilationStartAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CompilationStartAnalyzerAction analyzerAction = new CompilationStartAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCompilationStartAction(analyzerAction); + CompilationStartAnalyzerAction analyzerAction = new CompilationStartAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCompilationStartAction(analyzerAction); } - public void EnableConcurrentExecution(DiagnosticAnalyzer analyzer) + public void EnableConcurrentExecution() { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - _concurrentAnalyzers = _concurrentAnalyzers.Add(analyzer); - GetOrCreateAnalyzerActions(analyzer).Value.EnableConcurrentExecution(); + _isConcurrent = true; + GetOrCreateAnalyzerActions().Value.EnableConcurrentExecution(); } - public void ConfigureGeneratedCodeAnalysis(DiagnosticAnalyzer analyzer, GeneratedCodeAnalysisFlags mode) + public void ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags mode) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - _generatedCodeConfigurationMap.AddOrUpdate(analyzer, addValue: mode, updateValueFactory: (a, c) => mode); + _generatedCodeConfiguration = mode; } } @@ -438,10 +405,10 @@ public HostCompilationStartAnalysisScope(HostSessionStartAnalysisScope sessionSc _sessionScope = sessionScope; } - public override AnalyzerActions GetAnalyzerActions(DiagnosticAnalyzer analyzer) + public override AnalyzerActions GetAnalyzerActions() { - AnalyzerActions compilationActions = base.GetAnalyzerActions(analyzer); - AnalyzerActions sessionActions = _sessionScope.GetAnalyzerActions(analyzer); + AnalyzerActions compilationActions = base.GetAnalyzerActions(); + AnalyzerActions sessionActions = _sessionScope.GetAnalyzerActions(); if (sessionActions.IsEmpty) { @@ -524,70 +491,49 @@ public void RegisterOperationAction(DiagnosticAnalyzer analyzer, Action> _analyzerActions = new ConcurrentDictionary>(); + private StrongBox? _analyzerActions; internal DiagnosticAnalyzer Analyzer { get; } = analyzer; - public virtual AnalyzerActions GetAnalyzerActions(DiagnosticAnalyzer analyzer) + public virtual AnalyzerActions GetAnalyzerActions() { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - return this.GetOrCreateAnalyzerActions(analyzer).Value; + return this.GetOrCreateAnalyzerActions().Value; } - public void RegisterCompilationAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterCompilationAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCompilationAction(analyzerAction); + CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCompilationAction(analyzerAction); } - public void RegisterCompilationEndAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterCompilationEndAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCompilationEndAction(analyzerAction); + CompilationAnalyzerAction analyzerAction = new CompilationAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCompilationEndAction(analyzerAction); } - public void RegisterSemanticModelAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterSemanticModelAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - SemanticModelAnalyzerAction analyzerAction = new SemanticModelAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSemanticModelAction(analyzerAction); + SemanticModelAnalyzerAction analyzerAction = new SemanticModelAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSemanticModelAction(analyzerAction); } - public void RegisterSyntaxTreeAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterSyntaxTreeAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - SyntaxTreeAnalyzerAction analyzerAction = new SyntaxTreeAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSyntaxTreeAction(analyzerAction); + SyntaxTreeAnalyzerAction analyzerAction = new SyntaxTreeAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSyntaxTreeAction(analyzerAction); } - public void RegisterAdditionalFileAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterAdditionalFileAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - var analyzerAction = new AdditionalFileAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddAdditionalFileAction(analyzerAction); + var analyzerAction = new AdditionalFileAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddAdditionalFileAction(analyzerAction); } - public void RegisterSymbolAction(DiagnosticAnalyzer analyzer, Action action, ImmutableArray symbolKinds) + public void RegisterSymbolAction(Action action, ImmutableArray symbolKinds) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - SymbolAnalyzerAction analyzerAction = new SymbolAnalyzerAction(action, symbolKinds, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSymbolAction(analyzerAction); + SymbolAnalyzerAction analyzerAction = new SymbolAnalyzerAction(action, symbolKinds, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSymbolAction(analyzerAction); // The SymbolAnalyzerAction does not handle SymbolKind.Parameter because the compiler // does not make CompilationEvents for them. As a workaround, handle them specially by @@ -597,7 +543,6 @@ public void RegisterSymbolAction(DiagnosticAnalyzer analyzer, Action { ImmutableArray parameters; @@ -640,102 +585,69 @@ public void RegisterSymbolAction(DiagnosticAnalyzer analyzer, Action action, SymbolKind symbolKind) + public void RegisterSymbolStartAction(Action action, SymbolKind symbolKind) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - var analyzerAction = new SymbolStartAnalyzerAction(action, symbolKind, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSymbolStartAction(analyzerAction); + var analyzerAction = new SymbolStartAnalyzerAction(action, symbolKind, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSymbolStartAction(analyzerAction); } - public void RegisterSymbolEndAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterSymbolEndAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - var analyzerAction = new SymbolEndAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSymbolEndAction(analyzerAction); + var analyzerAction = new SymbolEndAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSymbolEndAction(analyzerAction); } - public void RegisterCodeBlockStartAction(DiagnosticAnalyzer analyzer, Action> action) where TLanguageKindEnum : struct + public void RegisterCodeBlockStartAction(Action> action) where TLanguageKindEnum : struct { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CodeBlockStartAnalyzerAction analyzerAction = new CodeBlockStartAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCodeBlockStartAction(analyzerAction); + CodeBlockStartAnalyzerAction analyzerAction = new CodeBlockStartAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCodeBlockStartAction(analyzerAction); } - public void RegisterCodeBlockEndAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterCodeBlockEndAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCodeBlockEndAction(analyzerAction); + CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCodeBlockEndAction(analyzerAction); } - public void RegisterCodeBlockAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterCodeBlockAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddCodeBlockAction(analyzerAction); + CodeBlockAnalyzerAction analyzerAction = new CodeBlockAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddCodeBlockAction(analyzerAction); } - public void RegisterSyntaxNodeAction(DiagnosticAnalyzer analyzer, Action action, ImmutableArray syntaxKinds) where TLanguageKindEnum : struct + public void RegisterSyntaxNodeAction(Action action, ImmutableArray syntaxKinds) where TLanguageKindEnum : struct { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - SyntaxNodeAnalyzerAction analyzerAction = new SyntaxNodeAnalyzerAction(action, syntaxKinds, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddSyntaxNodeAction(analyzerAction); + SyntaxNodeAnalyzerAction analyzerAction = new SyntaxNodeAnalyzerAction(action, syntaxKinds, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddSyntaxNodeAction(analyzerAction); } - public void RegisterOperationBlockStartAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterOperationBlockStartAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - OperationBlockStartAnalyzerAction analyzerAction = new OperationBlockStartAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddOperationBlockStartAction(analyzerAction); + OperationBlockStartAnalyzerAction analyzerAction = new OperationBlockStartAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddOperationBlockStartAction(analyzerAction); } - public void RegisterOperationBlockEndAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterOperationBlockEndAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - OperationBlockAnalyzerAction analyzerAction = new OperationBlockAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddOperationBlockEndAction(analyzerAction); + OperationBlockAnalyzerAction analyzerAction = new OperationBlockAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddOperationBlockEndAction(analyzerAction); } - public void RegisterOperationBlockAction(DiagnosticAnalyzer analyzer, Action action) + public void RegisterOperationBlockAction(Action action) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - OperationBlockAnalyzerAction analyzerAction = new OperationBlockAnalyzerAction(action, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddOperationBlockAction(analyzerAction); + OperationBlockAnalyzerAction analyzerAction = new OperationBlockAnalyzerAction(action, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddOperationBlockAction(analyzerAction); } - public void RegisterOperationAction(DiagnosticAnalyzer analyzer, Action action, ImmutableArray operationKinds) + public void RegisterOperationAction(Action action, ImmutableArray operationKinds) { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - OperationAnalyzerAction analyzerAction = new OperationAnalyzerAction(action, operationKinds, analyzer); - this.GetOrCreateAnalyzerActions(analyzer).Value.AddOperationAction(analyzerAction); + OperationAnalyzerAction analyzerAction = new OperationAnalyzerAction(action, operationKinds, Analyzer); + this.GetOrCreateAnalyzerActions().Value.AddOperationAction(analyzerAction); } - protected StrongBox GetOrCreateAnalyzerActions(DiagnosticAnalyzer analyzer) + protected StrongBox GetOrCreateAnalyzerActions() { - if (analyzer != Analyzer) - throw new InvalidOperationException(); - - return _analyzerActions.GetOrAdd(analyzer, _ => new StrongBox(AnalyzerActions.Empty)); + return InterlockedOperations.Initialize(ref _analyzerActions, static () => new StrongBox(AnalyzerActions.Empty)); } }