Example #1
0
        /// <summary>
        /// Executes the <see cref="DiagnosticAnalyzer.Initialize(AnalysisContext)"/> for the given analyzer and returns the set of registered sessions.
        /// </summary>
        /// <param name="analyzer">Analyzer to get session wide analyzer actions.</param>
        /// <param name="addDiagnostic">Delegate to add diagnostics.</param>
        /// <param name="continueOnAnalyzerException">Predicate to decide if exceptions from the action should be handled or not.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <remarks>
        /// Note that this API doesn't execute any <see cref="CompilationStartAnalyzerAction"/> registered by the Initialize invocation.
        /// Use <see cref="ExecuteCompilationStartActions(AnalyzerActions, DiagnosticAnalyzer, Compilation, AnalyzerOptions, Action{Diagnostic}, Func{Exception, DiagnosticAnalyzer, bool}, CancellationToken)"/> API
        /// to get execute these actions to get the per-compilation analyzer actions.
        /// </remarks>
        public static AnalyzerActions GetSessionAnalyzerActions(
            DiagnosticAnalyzer analyzer,
            Action <Diagnostic> addDiagnostic,
            Func <Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
            CancellationToken cancellationToken)
        {
            VerifyArguments(analyzer, addDiagnostic, continueOnAnalyzerException);

            HostSessionStartAnalysisScope sessionScope = new HostSessionStartAnalysisScope();

            ExecuteAndCatchIfThrows(analyzer, addDiagnostic, continueOnAnalyzerException, () =>
            {
                // The Initialize method should be run asynchronously in case it is not well behaved, e.g. does not terminate.
                analyzer.Initialize(new AnalyzerAnalysisContext(analyzer, sessionScope));
            }, cancellationToken);

            return(sessionScope.GetAnalyzerActions(analyzer));
        }
Example #2
0
        private static bool?GetOrComputeIsCompilationEndAnalyzer(
            DiagnosticAnalyzer analyzer,
            AnalyzerOptions analyzerOptions,
            Compilation compilation,
            ConcurrentDictionary <DiagnosticAnalyzer, bool?> endAnalyzerMap)
        {
            return(endAnalyzerMap.AddOrUpdate(
                       analyzer,
                       addValueFactory: ComputeIsCompilationEndAnalyzer,
                       updateValueFactory: (a, currentValue) => currentValue != null ? currentValue : ComputeIsCompilationEndAnalyzer(a)));

            // Local functions
            bool?ComputeIsCompilationEndAnalyzer(DiagnosticAnalyzer analyzer)
            {
                Contract.ThrowIfNull(compilation);

                try
                {
                    // currently, this is only way to see whether analyzer has compilation end analysis or not.
                    // also, analyzer being compilation end analyzer or not is dynamic. so this can return different value based on
                    // given compilation or options.
                    //
                    // but for now, this is what we decided in design meeting until we decide how to deal with compilation end analyzer
                    // long term
                    var context = new CollectCompilationActionsContext(compilation, analyzerOptions);
                    analyzer.Initialize(context);

                    return(context.IsCompilationEndAnalyzer);
                }
                catch
                {
                    // analyzer.initialize can throw. when that happens, we will try again next time.
                    // we are not logging anything here since it will be logged by CompilationWithAnalyzer later
                    // in the error list
                    return(null);
                }
            }
        }
Example #3
0
 /// <summary>
 /// Executes the <see cref="DiagnosticAnalyzer.Initialize(AnalysisContext)"/> for the given analyzer.
 /// </summary>
 /// <param name="analyzer">Analyzer to get session wide analyzer actions.</param>
 /// <param name="sessionScope">Session scope to store register session wide analyzer actions.</param>
 /// <remarks>
 /// Note that this API doesn't execute any <see cref="CompilationStartAnalyzerAction"/> registered by the Initialize invocation.
 /// Use <see cref="ExecuteCompilationStartActions(ImmutableArray{CompilationStartAnalyzerAction}, HostCompilationStartAnalysisScope)"/> API
 /// to get execute these actions to get the per-compilation analyzer actions.
 /// </remarks>
 public void ExecuteInitializeMethod(DiagnosticAnalyzer analyzer, HostSessionStartAnalysisScope sessionScope)
 {
     // The Initialize method should be run asynchronously in case it is not well behaved, e.g. does not terminate.
     ExecuteAndCatchIfThrows(analyzer, () => analyzer.Initialize(new AnalyzerAnalysisContext(analyzer, sessionScope)));
 }