private static void InitializeFullSolutionAnalysisState(Workspace workspace, IErrorList2 errorList2)
        {
            // Initialize the error list toggle state based on full solution analysis state for all supported languages.
            var fullAnalysisState = workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis) &&
                                    ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace.Options, LanguageNames.CSharp) &&
                                    ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace.Options, LanguageNames.VisualBasic) &&
                                    ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace.Options, TypeScriptLanguageName);

            errorList2.AnalysisToggleState = fullAnalysisState;
        }
예제 #2
0
            private bool CheckOptions(Document document)
            {
                if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_workspace, document.Project.Language) &&
                    _workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
                {
                    return(true);
                }

                return(document.IsOpen());
            }
예제 #3
0
        private bool IsUserOptionOn()
        {
            // check languages currently on solution. since we only show info bar once, we don't need to track solution changes.
            var languages = _workspace.CurrentSolution.Projects.Select(p => p.Language).Distinct();

            foreach (var language in languages)
            {
                if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_workspace.Options, language))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #4
0
            private static async Task <bool> FullAnalysisEnabledAsync(Project project, bool ignoreFullAnalysisOptions, CancellationToken cancellationToken)
            {
                if (ignoreFullAnalysisOptions)
                {
                    return(await project.HasSuccessfullyLoadedAsync(cancellationToken).ConfigureAwait(false));
                }

                if (!ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project) ||
                    !project.Solution.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
                {
                    return(false);
                }

                return(await project.HasSuccessfullyLoadedAsync(cancellationToken).ConfigureAwait(false));
            }
            private static bool FullAnalysisEnabled(Project project, bool forceAnalyzerRun)
            {
                if (forceAnalyzerRun)
                {
                    // asked to ignore any checks.
                    return(true);
                }

                if (!ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project) ||
                    !project.Solution.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
                {
                    return(false);
                }

                return(true);
            }
예제 #6
0
            public async Task MergeAsync(ActiveFileState state, Document document)
            {
                Contract.ThrowIfFalse(state.DocumentId == document.Id);

                // merge active file state to project state
                var lastResult = _lastResult;

                var syntax   = state.GetAnalysisData(AnalysisKind.Syntax);
                var semantic = state.GetAnalysisData(AnalysisKind.Semantic);

                AnalyzerABTestLogger.LogDocumentDiagnostics(document, _owner.StateName, syntax.Items, semantic.Items);

                var project = document.Project;

                // if project didn't successfully loaded, then it is same as FSA off
                var fullAnalysis = ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project) &&
                                   await project.HasSuccessfullyLoadedAsync(CancellationToken.None).ConfigureAwait(false);

                // keep from build flag if full analysis is off
                var fromBuild = fullAnalysis ? false : lastResult.FromBuild;

                var openFileOnlyAnalyzer = _owner.Analyzer.IsOpenFileOnly(document.Project.Solution.Workspace);

                // if it is allowed to keep project state, check versions and if they are same, bail out.
                // if full solution analysis is off or we are asked to reset document state, we always merge.
                if (fullAnalysis && !openFileOnlyAnalyzer &&
                    syntax.Version != VersionStamp.Default &&
                    syntax.Version == semantic.Version &&
                    syntax.Version == lastResult.Version)
                {
                    // all data is in sync already.
                    return;
                }

                // we have mixed versions or full analysis is off, set it to default so that it can be re-calculated next time so data can be in sync.
                var version = VersionStamp.Default;

                // serialization can't be cancelled.
                var serializer = new DiagnosticDataSerializer(_owner.AnalyzerVersion, version);

                // save active file diagnostics back to project state
                await SerializeAsync(serializer, document, document.Id, _owner.SyntaxStateName, syntax.Items).ConfigureAwait(false);
                await SerializeAsync(serializer, document, document.Id, _owner.SemanticStateName, semantic.Items).ConfigureAwait(false);

                // save last aggregated form of analysis result
                _lastResult = _lastResult.UpdateAggregatedResult(version, state.DocumentId, fromBuild);
            }
예제 #7
0
        private static void LogErrors(Project project, string action, Guid target, Dictionary <string, int> map)
        {
            if (map.Count == 0)
            {
                // nothing to report
                return;
            }

            var fsa = ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project);

            Logger.Log(FunctionId.Experiment_ABTesting, KeyValueLogMessage.Create(LogType.UserAction, m =>
            {
                m[nameof(Name)]   = Name;
                m[nameof(action)] = action;
                m[nameof(target)] = target.ToString();
                m["FSA"]          = fsa;
                m["errors"]       = string.Join("|", map.Select(kv => $"{kv.Key}={kv.Value}"));
            }));
        }
        private static void SetFullSolutionAnalysisState(Workspace workspace, IErrorList2 errorList2)
        {
            // Set error list toggle state based on current analysis state for all languages for projects in current solution.
            var fullAnalysisState = workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis);

            if (fullAnalysisState)
            {
                var languages = workspace.CurrentSolution.Projects.Select(p => p.Language).Distinct();
                foreach (var language in languages)
                {
                    if (!ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace, language))
                    {
                        fullAnalysisState = false;
                        break;
                    }
                }
            }

            errorList2.AnalysisToggleState = fullAnalysisState;
        }
예제 #9
0
            public async Task MergeAsync(ActiveFileState state, Document document)
            {
                Contract.ThrowIfFalse(state.DocumentId == document.Id);

                // merge active file state to project state
                var lastResult = _lastResult;

                var syntax   = state.GetAnalysisData(AnalysisKind.Syntax);
                var semantic = state.GetAnalysisData(AnalysisKind.Semantic);

                var project      = document.Project;
                var fullAnalysis = ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project);

                // keep from build flag if full analysis is off
                var fromBuild = fullAnalysis ? false : lastResult.FromBuild;

                // if it is allowed to keep project state, check versions and if they are same, bail out
                // if full solution analysis is off or we are asked to reset document state, we always merge.
                if (fullAnalysis &&
                    syntax.Version != VersionStamp.Default &&
                    syntax.Version == semantic.Version &&
                    syntax.Version == lastResult.Version)
                {
                    // all data is in sync already.
                    return;
                }

                // we have mixed versions or full analysis is off, set it to default so that it can be re-calculated next time so data can be in sync.
                var version = VersionStamp.Default;

                // serialization can't be cancelled.
                var serializer = new DiagnosticDataSerializer(_owner.AnalyzerVersion, version);

                // save active file diagnostics back to project state
                await SerializeAsync(serializer, document, document.Id, _owner.SyntaxStateName, syntax.Items).ConfigureAwait(false);
                await SerializeAsync(serializer, document, document.Id, _owner.SemanticStateName, semantic.Items).ConfigureAwait(false);

                // save last aggregated form of analysis result
                _lastResult = new DiagnosticAnalysisResult(_lastResult.ProjectId, version, _lastResult.DocumentIdsOrEmpty.Add(state.DocumentId), isEmpty: false, fromBuild: fromBuild);
            }
        private IEnumerable <StateSet> GetStateSetsForFullSolutionAnalysis(IEnumerable <StateSet> stateSets, Project project)
        {
            // Get stateSets that should be run for full analysis

            // if full analysis is off, remove state that is from build.
            // this will make sure diagnostics (converted from build to live) from build will never be cleared
            // until next build.
            if (!ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project.Solution.Workspace, project.Language))
            {
                stateSets = stateSets.Where(s => !s.FromBuild(project.Id));
            }

            // include all analyzers if option is on
            if (project.Solution.Workspace.Options.GetOption(InternalDiagnosticsOptions.ProcessHiddenDiagnostics))
            {
                return(stateSets);
            }

            // Include only one we want to run for full solution analysis.
            // stateSet not included here will never be saved because result is unknown.
            return(stateSets.Where(s => ShouldRunForFullProject(s.Analyzer, project)));
        }
예제 #11
0
            private bool SupportedLiveDiagnosticId(Project project, Compilation compilation, string id)
            {
                var projectId = project.Id;

                lock (_liveDiagnosticIdMap)
                {
                    if (_liveDiagnosticIdMap.TryGetValue(projectId, out var ids))
                    {
                        return(ids.Contains(id));
                    }

                    var fullSolutionAnalysis = ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(project);
                    if (!project.SupportsCompilation || fullSolutionAnalysis)
                    {
                        return(IsSupportedDiagnosticId(project.Id, id));
                    }

                    // set ids set
                    var builder           = ImmutableHashSet.CreateBuilder <string>();
                    var diagnosticService = _owner._diagnosticService;
                    foreach (var analyzer in diagnosticService.GetDiagnosticAnalyzers(project))
                    {
                        if (diagnosticService.IsCompilationEndAnalyzer(analyzer, project, compilation))
                        {
                            continue;
                        }

                        var diagnosticIds = diagnosticService.GetDiagnosticDescriptors(analyzer).Select(d => d.Id);
                        builder.UnionWith(diagnosticIds);
                    }

                    var set = builder.ToImmutable();
                    _liveDiagnosticIdMap.Add(projectId, set);

                    return(set.Contains(id));
                }
            }