private static bool CheckTelemetry(DiagnosticAnalyzer analyzer, IDiagnosticAnalyzerService serviceOpt)
        {
            if (analyzer.IsCompilerAnalyzer())
            {
                return(true);
            }

            if (analyzer is IBuiltInAnalyzer)
            {
                // if it is builtin analyzer, telemetry is always allowed
                return(true);
            }

            ImmutableArray <DiagnosticDescriptor> diagDescriptors;

            try
            {
                // SupportedDiagnostics is potentially user code and can throw an exception.
                diagDescriptors = serviceOpt != null?serviceOpt.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics;
            }
            catch (Exception)
            {
                return(false);
            }

            if (diagDescriptors == null)
            {
                return(false);
            }

            // find if the first diagnostic in this analyzer allows telemetry
            DiagnosticDescriptor diagnostic = diagDescriptors.Length > 0 ? diagDescriptors[0] : null;

            return(diagnostic == null ? false : diagnostic.CustomTags.Any(t => t == WellKnownDiagnosticTags.Telemetry));
        }
        // *DO NOT DELETE*
        // This is used by Ruleset Editor from ManagedSourceCodeAnalysis.dll.
        public IReadOnlyDictionary <string, IEnumerable <DiagnosticDescriptor> > GetAllDiagnosticDescriptors(IVsHierarchy hierarchyOpt)
        {
            if (hierarchyOpt == null)
            {
                return(Transform(_diagnosticService.GetDiagnosticDescriptors(projectOpt: null)));
            }

            // Analyzers are only supported for C# and VB currently.
            var projectsWithHierarchy = _workspace.ProjectTracker.ImmutableProjects
                                        .Where(p => p.Language == LanguageNames.CSharp || p.Language == LanguageNames.VisualBasic)
                                        .Where(p => p.Hierarchy == hierarchyOpt)
                                        .Select(p => _workspace.CurrentSolution.GetProject(p.Id));

            if (projectsWithHierarchy.Count() <= 1)
            {
                return(Transform(_diagnosticService.GetDiagnosticDescriptors(projectsWithHierarchy.FirstOrDefault())));
            }
            else
            {
                // Multiple workspace projects map to the same hierarchy, return a union of descriptors for all projects.
                // For example, this can happen for web projects where we create on the fly projects for aspx files.
                var descriptorsMap = ImmutableDictionary.CreateBuilder <string, IEnumerable <DiagnosticDescriptor> >();
                foreach (var project in projectsWithHierarchy)
                {
                    var newDescriptorTuples = _diagnosticService.GetDiagnosticDescriptors(project);
                    foreach (var kvp in newDescriptorTuples)
                    {
                        IEnumerable <DiagnosticDescriptor> existingDescriptors;
                        if (descriptorsMap.TryGetValue(kvp.Key, out existingDescriptors))
                        {
                            descriptorsMap[kvp.Key] = existingDescriptors.Concat(kvp.Value).Distinct();
                        }
                        else
                        {
                            descriptorsMap[kvp.Key] = kvp.Value;
                        }
                    }
                }

                return(descriptorsMap.ToImmutable());
            }
        }
        private IEnumerable <BaseDiagnosticItem> GetDiagnosticItems(string language, CompilationOptions options, ImmutableDictionary <string, ReportDiagnostic> analyzerConfigSpecificDiagnosticOptions)
        {
            // Within an analyzer assembly, an individual analyzer may report multiple different diagnostics
            // with the same ID. Or, multiple analyzers may report diagnostics with the same ID. Or a
            // combination of the two may occur.
            // We only want to show one node in Solution Explorer for a given ID. So we pick one, but we need
            // to be consistent in which one we pick. Diagnostics with the same ID may have different
            // descriptions or messages, and it would be strange if the node's name changed from one run of
            // VS to another. So we group the diagnostics by ID, sort them within a group, and take the first
            // one.

            return(AnalyzerReference.GetAnalyzers(language)
                   .SelectMany(a => _diagnosticAnalyzerService.GetDiagnosticDescriptors(a))
                   .GroupBy(d => d.Id)
                   .OrderBy(g => g.Key, StringComparer.CurrentCulture)
                   .Select(g =>
            {
                var selectedDiagnostic = g.OrderBy(d => d, s_comparer).First();
                var effectiveSeverity = selectedDiagnostic.GetEffectiveSeverity(options, analyzerConfigSpecificDiagnosticOptions);
                return CreateItem(selectedDiagnostic, effectiveSeverity);
            }));
        }
        private IEnumerable <DiagnosticItem> GetDiagnosticItems(string language)
        {
            // Within an analyzer assembly, an individual analyzer may report multiple different diagnostics
            // with the same ID. Or, multiple analyzers may report diagnostics with the same ID. Or a
            // combination of the two may occur.
            // We only want to show one node in Solution Explorer for a given ID. So we pick one, but we need
            // to be consistent in which one we pick. Diagnostics with the same ID may have different
            // descriptions or messages, and it would be strange if the node's name changed from one run of
            // VS to another. So we group the diagnostics by ID, sort them within a group, and take the first
            // one.

            return(_item.AnalyzerReference.GetAnalyzers(language)
                   .SelectMany(a => _diagnosticAnalyzerService.GetDiagnosticDescriptors(a))
                   .GroupBy(d => d.Id)
                   .OrderBy(g => g.Key, StringComparer.CurrentCulture)
                   .Select(g =>
            {
                var selectedDiagnostic = g.OrderBy(d => d, s_comparer).First();
                var effectiveSeverity = GetEffectiveSeverity(selectedDiagnostic.Id, _specificDiagnosticOptions, _generalDiagnosticOption, selectedDiagnostic.DefaultSeverity, selectedDiagnostic.IsEnabledByDefault);
                return new DiagnosticItem(_item, selectedDiagnostic, effectiveSeverity, _commandHandler.DiagnosticContextMenuController);
            }));
        }