public bool IsFixableDiagnostic(Diagnostic diagnostic)
        {
            // We only offer fix for configurable code style diagnostics which have one of more editorconfig based storage locations.
            // Also skip suppressed diagnostics defensively, though the code fix engine should ideally never call us for suppressed diagnostics.
            if (
                diagnostic.IsSuppressed ||
                SuppressionHelpers.IsNotConfigurableDiagnostic(diagnostic) ||
                diagnostic.Location.SourceTree == null
                )
            {
                return(false);
            }

            var language = diagnostic.Location.SourceTree.Options.Language;

            return(IDEDiagnosticIdToOptionMappingHelper.TryGetMappedOptions(
                       diagnostic.Id,
                       language,
                       out var options
                       ) &&
                   !options.IsEmpty &&
                   options.All(
                       o => o.StorageLocations.Any(l => l is IEditorConfigStorageLocation2)
                       ));
        }
 private static void AddDiagnosticIdToFadingOptionMapping(string diagnosticId, PerLanguageOption2 <bool>?fadingOption)
 {
     if (fadingOption != null)
     {
         IDEDiagnosticIdToOptionMappingHelper.AddFadingOptionMapping(diagnosticId, fadingOption);
     }
 }
        private static ImmutableArray <(string diagnosticId, ImmutableHashSet <IOption2> codeStyleOptions)> GetIDEDiagnosticIdsAndOptions(
            string languageName)
        {
            const string diagnosticIdPrefix = "IDE";

            var diagnosticIdAndOptions = new List <(string diagnosticId, ImmutableHashSet <IOption2> options)>();
            var uniqueDiagnosticIds    = new HashSet <string>();

            foreach (var assembly in MefHostServices.DefaultAssemblies)
            {
                var analyzerReference = new AnalyzerFileReference(assembly.Location, TestAnalyzerAssemblyLoader.LoadFromFile);
                foreach (var analyzer in analyzerReference.GetAnalyzers(languageName))
                {
                    foreach (var descriptor in analyzer.SupportedDiagnostics)
                    {
                        var diagnosticId = descriptor.Id;
                        ValidateHelpLinkForDiagnostic(diagnosticId, descriptor.HelpLinkUri);

                        if (!diagnosticId.StartsWith(diagnosticIdPrefix) ||
                            !int.TryParse(diagnosticId.Substring(startIndex: diagnosticIdPrefix.Length), out _))
                        {
                            // Ignore non-IDE diagnostic IDs (such as ENCxxxx diagnostics) and
                            // diagnostic IDs for suggestions, fading, etc. (such as IDExxxxWithSuggestion)
                            continue;
                        }

                        if (!IDEDiagnosticIdToOptionMappingHelper.TryGetMappedOptions(diagnosticId, languageName, out var options))
                        {
                            options = ImmutableHashSet <IOption2> .Empty;
                        }

                        if (uniqueDiagnosticIds.Add(diagnosticId))
                        {
                            diagnosticIdAndOptions.Add((diagnosticId, options));
                        }
                        else
                        {
                            Assert.True(diagnosticIdAndOptions.All(tuple => tuple.diagnosticId != diagnosticId || tuple.options.SetEquals(options)));
                        }
                    }
                }
            }

            diagnosticIdAndOptions.Sort();
            return(diagnosticIdAndOptions.ToImmutableArray());
        }
        public async Task Test_FadingOptions(string diagnosticId, bool fadingOptionValue)
        {
            var analyzer    = new Analyzer(diagnosticId, throughAdditionalLocations: false);
            var analyzerMap = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> >
            {
                { LanguageNames.CSharp, ImmutableArray.Create <DiagnosticAnalyzer>(analyzer) }
            };

            using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }", "class E { }" }, parseOptions: CSharpParseOptions.Default, composition: SquiggleUtilities.CompositionWithSolutionCrawler);

            // Set fading option
            var fadingOption = GetFadingOptionForDiagnostic(diagnosticId);

            workspace.GlobalOptions.SetGlobalOption(new OptionKey(fadingOption, LanguageNames.CSharp), fadingOptionValue);

            // Add mapping from diagnostic ID to fading option
            IDEDiagnosticIdToOptionMappingHelper.AddFadingOptionMapping(diagnosticId, fadingOption);

            // Set up the tagger
            using var wrapper = new DiagnosticTaggerWrapper <DiagnosticsClassificationTaggerProvider, ClassificationTag>(workspace, analyzerMap);
            var tagger = wrapper.TaggerProvider.CreateTagger <ClassificationTag>(workspace.Documents.First().GetTextBuffer());

            using var disposable = tagger as IDisposable;
            // test first update
            await wrapper.WaitForTags();

            var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
            var spans    = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToList();

            if (!fadingOptionValue)
            {
                // We should get no tag spans when the fading option is disabled.
                Assert.Empty(spans);
            }
            else
            {
                // We should get a single tag span, which is diagnostic's primary location.
                Assert.Equal(1, spans.Count);

                Assert.Equal(new Span(0, 10), spans[0].Span.Span);

                Assert.Equal(ClassificationTypeDefinitions.UnnecessaryCode, spans[0].Tag.ClassificationType.Classification);
            }
        }
 private static void AddDiagnosticIdToOptionMapping(string diagnosticId, ImmutableHashSet <ILanguageSpecificOption> options, string language)
 => IDEDiagnosticIdToOptionMappingHelper.AddOptionMapping(diagnosticId, options, language);
 private static void AddDiagnosticIdToOptionMapping(string diagnosticId, ImmutableHashSet <IPerLanguageOption> options)
 => IDEDiagnosticIdToOptionMappingHelper.AddOptionMapping(diagnosticId, options);
        private async Task <ImmutableArray <(string diagnosticId, string?title)> > GetThirdPartyDiagnosticIdsAndTitlesAsync(Document document, CancellationToken cancellationToken)
        {
            var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var range = new TextSpan(0, tree.Length);

            // Compute diagnostics for everything that is not an IDE analyzer
            var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range,
                                                                                   shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId)),
                                                                                   includeCompilerDiagnostics: true, includeSuppressedDiagnostics: false,
                                                                                   cancellationToken: cancellationToken).ConfigureAwait(false));

            // ensure more than just known diagnostics were returned
            if (!diagnostics.Any())
            {
                return(ImmutableArray <(string diagnosticId, string?title)> .Empty);
            }

            return(diagnostics.SelectAsArray(static d => (d.Id, d.Title)).Distinct());