Пример #1
0
            private async Task <IEnumerable <Diagnostic> > ComputeDiagnosticAnalyzerDiagnosticsAsync(
                CompilationWithAnalyzers analyzerDriverOpt, Document document, DiagnosticAnalyzer analyzer, AnalysisKind kind, TextSpan?spanOpt, CancellationToken cancellationToken)
            {
                // quick optimization to reduce allocations.
                if (analyzerDriverOpt == null || !_owner.SupportAnalysisKind(analyzer, document.Project.Language, kind))
                {
                    return(ImmutableArray <Diagnostic> .Empty);
                }

                // REVIEW: more unnecessary allocations just to get diagnostics per analyzer
                var oneAnalyzers = ImmutableArray.Create(analyzer);

                switch (kind)
                {
                case AnalysisKind.Syntax:
                    var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    var diagnostics = await analyzerDriverOpt.GetAnalyzerSyntaxDiagnosticsAsync(tree, oneAnalyzers, cancellationToken).ConfigureAwait(false);

                    Contract.Requires(diagnostics.Count() == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, analyzerDriverOpt.Compilation).Count());
                    return(diagnostics.ToImmutableArrayOrEmpty());

                case AnalysisKind.Semantic:
                    var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    diagnostics = await analyzerDriverOpt.GetAnalyzerSemanticDiagnosticsAsync(model, spanOpt, oneAnalyzers, cancellationToken).ConfigureAwait(false);

                    Contract.Requires(diagnostics.Count() == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, analyzerDriverOpt.Compilation).Count());
                    return(diagnostics.ToImmutableArrayOrEmpty());

                default:
                    return(Contract.FailWithReturn <ImmutableArray <Diagnostic> >("shouldn't reach here"));
                }
            }
            private async Task <bool> TryGetDocumentDiagnosticsAsync(
                StateSet stateSet,
                AnalysisKind kind,
                DiagnosticsGetterAsync diagnosticGetterAsync,
                List <DiagnosticData> list,
                CancellationToken cancellationToken)
            {
                if (!_owner.SupportAnalysisKind(stateSet.Analyzer, stateSet.Language, kind))
                {
                    return(true);
                }

                // make sure we get state even when none of our analyzer has ran yet.
                // but this shouldn't create analyzer that doesn't belong to this project (language)
                var state = stateSet.GetActiveFileState(_document.Id);

                // see whether we can use existing info
                var existingData = state.GetAnalysisData(kind);
                var version      = await GetDiagnosticVersionAsync(_document.Project, cancellationToken).ConfigureAwait(false);

                if (existingData.Version == version)
                {
                    if (existingData.Items.IsEmpty)
                    {
                        return(true);
                    }

                    list.AddRange(existingData.Items.Where(ShouldInclude));
                    return(true);
                }

                cancellationToken.ThrowIfCancellationRequested();

                // check whether we want up-to-date document wide diagnostics
                var supportsSemanticInSpan = stateSet.Analyzer.SupportsSpanBasedSemanticDiagnosticAnalysis();

                if (!BlockForData(kind, supportsSemanticInSpan))
                {
                    return(false);
                }

                var dx = await diagnosticGetterAsync(stateSet.Analyzer, cancellationToken).ConfigureAwait(false);

                if (dx != null)
                {
                    // no state yet
                    list.AddRange(dx.Where(ShouldInclude));
                }

                return(true);
            }