Beispiel #1
0
        /// <summary>
        /// Return all cached local diagnostics (syntax, semantic) that belong to given document for the given StateSet (analyzer).
        /// Also returns empty diagnostics for suppressed analyzer.
        /// Returns null if the diagnostics need to be computed.
        /// </summary>
        private DocumentAnalysisData?TryGetCachedDocumentAnalysisData(
            TextDocument document, StateSet stateSet,
            AnalysisKind kind, VersionStamp version,
            BackgroundAnalysisScope analysisScope, bool isActiveDocument,
            bool isOpenDocument, bool isGeneratedRazorDocument,
            CancellationToken cancellationToken)
        {
            Debug.Assert(isActiveDocument || isOpenDocument || isGeneratedRazorDocument);

            try
            {
                var state        = stateSet.GetOrCreateActiveFileState(document.Id);
                var existingData = state.GetAnalysisData(kind);

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

                // Perf optimization: Check whether analyzer is suppressed for project or document and avoid getting diagnostics if suppressed.
                if (!DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(stateSet.Analyzer, document.Project, GlobalOptions) ||
                    !IsAnalyzerEnabledForDocument(stateSet.Analyzer, analysisScope, isActiveDocument, isOpenDocument, isGeneratedRazorDocument))
                {
                    return(new DocumentAnalysisData(version, existingData.Items, ImmutableArray <DiagnosticData> .Empty));
                }

                return(null);
            }
            catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken))
            {
                throw ExceptionUtilities.Unreachable;
            }
            private bool ShouldIncludeStateSet(Project project, StateSet stateSet)
            {
                if (!DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(stateSet.Analyzer, project, Owner.GlobalOptions))
                {
                    return(false);
                }

                if (_diagnosticIds != null && Owner.DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(stateSet.Analyzer).All(d => !_diagnosticIds.Contains(d.Id)))
                {
                    return(false);
                }

                return(true);
            }
Beispiel #3
0
        private async Task AnalyzeProjectAsync(Project project, bool forceAnalyzerRun, CancellationToken cancellationToken)
        {
            try
            {
                var stateSets = GetStateSetsForFullSolutionAnalysis(_stateManager.GetOrUpdateStateSets(project), project);

                // get driver only with active analyzers.
                var ideOptions = AnalyzerService.GlobalOptions.GetIdeAnalyzerOptions(project);

                // PERF: get analyzers that are not suppressed and marked as open file only
                // this is perf optimization. we cache these result since we know the result. (no diagnostics)
                var activeAnalyzers = stateSets
                                      .Select(s => s.Analyzer)
                                      .Where(a => DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(a, project, GlobalOptions) && !a.IsOpenFileOnly(ideOptions.CleanupOptions?.SimplifierOptions));

                CompilationWithAnalyzers?compilationWithAnalyzers = null;

                if (forceAnalyzerRun || GlobalOptions.IsFullSolutionAnalysisEnabled(project.Language))
                {
                    compilationWithAnalyzers = await DocumentAnalysisExecutor.CreateCompilationWithAnalyzersAsync(project, ideOptions, activeAnalyzers, includeSuppressedDiagnostics : true, cancellationToken).ConfigureAwait(false);
                }

                var result = await GetProjectAnalysisDataAsync(compilationWithAnalyzers, project, ideOptions, stateSets, forceAnalyzerRun, cancellationToken).ConfigureAwait(false);

                if (result.OldResult == null)
                {
                    RaiseProjectDiagnosticsIfNeeded(project, stateSets, result.Result);
                    return;
                }

                // no cancellation after this point.
                // any analyzer that doesn't have result will be treated as returned empty set
                // which means we will remove those from error list
                foreach (var stateSet in stateSets)
                {
                    var state = stateSet.GetOrCreateProjectState(project.Id);

                    await state.SaveToInMemoryStorageAsync(project, result.GetResult(stateSet.Analyzer)).ConfigureAwait(false);
                }

                RaiseProjectDiagnosticsIfNeeded(project, stateSets, result.OldResult, result.Result);
            }
            catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
            public static async Task <LatestDiagnosticsForSpanGetter> CreateAsync(
                DiagnosticIncrementalAnalyzer owner,
                Document document,
                TextSpan?range,
                bool blockForData,
                Func <string, IDisposable?>?addOperationScope,
                bool includeSuppressedDiagnostics,
                CodeActionRequestPriority priority,
                Func <string, bool>?shouldIncludeDiagnostic,
                CancellationToken cancellationToken)
            {
                var stateSets = owner._stateManager
                                .GetOrCreateStateSets(document.Project).Where(s => DocumentAnalysisExecutor.IsAnalyzerEnabledForProject(s.Analyzer, document.Project, owner.GlobalOptions));

                var crashOnAnalyzerException = owner.GlobalOptions.GetOption(InternalDiagnosticsOptions.CrashOnAnalyzerException);
                var compilationWithAnalyzers = await GetOrCreateCompilationWithAnalyzersAsync(document.Project, stateSets, includeSuppressedDiagnostics, crashOnAnalyzerException, cancellationToken).ConfigureAwait(false);

                return(new LatestDiagnosticsForSpanGetter(
                           owner, compilationWithAnalyzers, document, stateSets, shouldIncludeDiagnostic, range,
                           blockForData, addOperationScope, includeSuppressedDiagnostics, priority));
            }