예제 #1
0
        public async Task <IEnumerable <Diagnostic> > GetSyntaxDiagnosticsAsync(DiagnosticAnalyzer analyzer)
        {
            var compilation = this.document.Project.SupportsCompilation ? await this.document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false) : null;

            Contract.ThrowIfNull(this.document);
            Contract.ThrowIfFalse(analyzer.SupportsSyntaxDiagnosticAnalysis(this));

            using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject())
            {
                var diagnostics = pooledObject.Object;

                this.cancellationToken.ThrowIfCancellationRequested();
                var documentAnalyzer = analyzer as DocumentDiagnosticAnalyzer;
                if (documentAnalyzer != null)
                {
                    try
                    {
                        await documentAnalyzer.AnalyzeSyntaxAsync(this.document, diagnostics.Add, this.cancellationToken).ConfigureAwait(false);

                        return(diagnostics.ToImmutableArrayOrEmpty());
                    }
                    catch (Exception e) when(CatchAnalyzerException(e, analyzer))
                    {
                        var exceptionDiagnostics = AnalyzerExceptionToDiagnostics(analyzer, e, cancellationToken);

                        return(GetFilteredDocumentDiagnostics(exceptionDiagnostics, compilation).ToImmutableArray());
                    }
                }

                var analyzerActions = await this.GetAnalyzerActionsAsync(analyzer, diagnostics.Add).ConfigureAwait(false);

                DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)logAggregator);

                if (analyzerActions != null)
                {
                    if (this.document.SupportsSyntaxTree)
                    {
                        AnalyzerDriverHelper.ExecuteSyntaxTreeActions(analyzerActions, this.root.SyntaxTree,
                                                                      this.analyzerOptions, diagnostics.Add, CatchAnalyzerException, this.cancellationToken);
                    }
                }

                if (diagnostics.Count == 0)
                {
                    return(SpecializedCollections.EmptyEnumerable <Diagnostic>());
                }

                return(GetFilteredDocumentDiagnostics(diagnostics, compilation).ToImmutableArray());
            }
        }
예제 #2
0
        private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, List <Diagnostic> diagnostics, Action <Project, DiagnosticAnalyzer, CancellationToken> forceAnalyzeAllDocuments)
        {
            Contract.ThrowIfFalse(this.project.SupportsCompilation);

            var analyzerActionsAndDiagnostics = GetSessionAnalyzerActionsAndDiagnostics(analyzer);
            var analyzerActions = analyzerActionsAndDiagnostics.Item1;

            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            diagnostics.AddRange(CompilationWithAnalyzers.GetEffectiveDiagnostics(analyzerActionsAndDiagnostics.Item2, compilation));

            DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)logAggregator);

            if (analyzerActions == null || (analyzerActions.CompilationStartActionsCount == 0 && analyzerActions.CompilationEndActionsCount == 0))
            {
                return;
            }

            using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject())
            {
                var localDiagnostics = pooledObject.Object;

                // Get all the analyzer actions, including the per-compilation actions.
                var allAnalyzerActions = await GetAnalyzerActionsAsync(analyzer, localDiagnostics.Add).ConfigureAwait(false);

                if (analyzerActions.CompilationEndActionsCount < allAnalyzerActions.CompilationEndActionsCount && forceAnalyzeAllDocuments != null)
                {
                    if (allAnalyzerActions.CodeBlockEndActionsCount > analyzerActions.CodeBlockEndActionsCount ||
                        allAnalyzerActions.CodeBlockStartActionsCount > analyzerActions.CodeBlockStartActionsCount ||
                        allAnalyzerActions.SemanticModelActionsCount > analyzerActions.SemanticModelActionsCount ||
                        allAnalyzerActions.SymbolActionsCount > analyzerActions.SymbolActionsCount ||
                        allAnalyzerActions.SyntaxNodeActionsCount > analyzerActions.SyntaxNodeActionsCount ||
                        allAnalyzerActions.SyntaxTreeActionsCount > analyzerActions.SyntaxTreeActionsCount)
                    {
                        // Analyzer registered a compilation end action and at least one other analyzer action during it's 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);
                    }
                }

                // CompilationEnd actions.
                AnalyzerDriverHelper.ExecuteCompilationEndActions(allAnalyzerActions, compilation, analyzerOptions, localDiagnostics.Add, CatchAnalyzerException, cancellationToken);
                diagnostics.AddRange(CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation));
            }
        }
예제 #3
0
        public async Task <AnalyzerActions> GetAnalyzerActionsAsync(DiagnosticAnalyzer analyzer, Action <Diagnostic> addDiagnostic)
        {
            var analyzerActions = GetSessionAnalyzerActions(analyzer);

            DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)logAggregator);

            if (analyzerActions != null)
            {
                if (this.project.SupportsCompilation && analyzerActions.CompilationStartActionsCount > 0)
                {
                    var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                    var analyzerCompilationActions = GetPerCompilationAnalyzerActions(analyzer, analyzerActions, compilation, addDiagnostic);

                    if (analyzerCompilationActions != null)
                    {
                        analyzerActions = analyzerActions.Append(analyzerCompilationActions);
                        DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)logAggregator);
                    }
                }
            }

            return(analyzerActions);
        }