Repository: dotnet/roslyn
File: src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalysisResultBuilder.cs (C#)

Code before:
            var analyzersSet = analyzers.ToImmutableHashSet();
            Func<Diagnostic, bool> shouldInclude = analysisScope.ShouldInclude;
            lock (_gate)
            {
                localSyntaxDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localSyntaxDiagnosticsOpt);
                localSemanticDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localSemanticDiagnosticsOpt);
                localAdditionalFileDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localAdditionalFileDiagnosticsOpt);
                nonLocalDiagnostics = GetImmutable(analyzersSet, shouldInclude, _nonLocalDiagnosticsOpt);
            }

            cancellationToken.ThrowIfCancellationRequested();
            var analyzerTelemetryInfo = GetTelemetryInfo(analyzers);
            return new AnalysisResult(analyzers, localSyntaxDiagnostics, localSemanticDiagnostics, localAdditionalFileDiagnostics, nonLocalDiagnostics, analyzerTelemetryInfo);
        }

        private static ImmutableDictionary<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>> GetImmutable<TKey>(
            ImmutableHashSet<DiagnosticAnalyzer> analyzers,
            Func<Diagnostic, bool> shouldInclude,
            Dictionary<TKey, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? localDiagnosticsOpt)
            where TKey : class
        {
            if (localDiagnosticsOpt == null)
            {
                return ImmutableDictionary<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>>.Empty;
            }

            var builder = ImmutableDictionary.CreateBuilder<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>>();
            var perTreeBuilder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>();

            foreach (var diagnosticsByTree in localDiagnosticsOpt)
            {
                var key = diagnosticsByTree.Key;
                foreach (var diagnosticsByAnalyzer in diagnosticsByTree.Value)
                {
                    if (analyzers.Contains(diagnosticsByAnalyzer.Key))
                    {
                        var diagnostics = diagnosticsByAnalyzer.Value.Where(shouldInclude).ToImmutableArray();
                        if (!diagnostics.IsEmpty)
                        {
                            perTreeBuilder.Add(diagnosticsByAnalyzer.Key, diagnostics);
                        }
                    }
                }

                builder.Add(key, perTreeBuilder.ToImmutable());
                perTreeBuilder.Clear();
            }

            return builder.ToImmutable();
        }


Review comment (suggestion):
>HashSet [](http://example.com/codeflow?start=12&length=7)

Could we use `IReadOnlySet` instead? Since we want the set to remain unchanged. #Closed

Code after:
            var analyzersSet = PooledHashSet<DiagnosticAnalyzer>.GetInstance();
            analyzersSet.AddRange(analyzers);

            Func<Diagnostic, bool> shouldInclude = analysisScope.ShouldInclude;
            lock (_gate)
            {
                localSyntaxDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localSyntaxDiagnosticsOpt);
                localSemanticDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localSemanticDiagnosticsOpt);
                localAdditionalFileDiagnostics = GetImmutable(analyzersSet, shouldInclude, _localAdditionalFileDiagnosticsOpt);
                nonLocalDiagnostics = GetImmutable(analyzersSet, shouldInclude, _nonLocalDiagnosticsOpt);
            }

            analyzersSet.Free();
            cancellationToken.ThrowIfCancellationRequested();
            var analyzerTelemetryInfo = GetTelemetryInfo(analyzers);
            return new AnalysisResult(analyzers, localSyntaxDiagnostics, localSemanticDiagnostics, localAdditionalFileDiagnostics, nonLocalDiagnostics, analyzerTelemetryInfo);
        }

        /// <summary>
        /// Gets an immutable dictionary from the given local diagnostics map.
        /// </summary>
        /// <param name="analyzers">Limits the analyzers included. Is not modified.</param>
        /// <param name="shouldInclude">Filter determining whether a diagnostic should be included</param>
        /// <param name="localDiagnosticsOpt">Diagnostic map to operate on</param>
        private static ImmutableDictionary<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>> GetImmutable<TKey>(
            HashSet<DiagnosticAnalyzer> analyzers, // Will not be modified
            Func<Diagnostic, bool> shouldInclude,
            Dictionary<TKey, Dictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>.Builder>>? localDiagnosticsOpt)
            where TKey : class
        {
            if (localDiagnosticsOpt == null)
            {
                return ImmutableDictionary<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>>.Empty;
            }

            var builder = ImmutableDictionary.CreateBuilder<TKey, ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>>();
            var perTreeBuilder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ImmutableArray<Diagnostic>>();

            foreach (var diagnosticsByTree in localDiagnosticsOpt)
            {
                var key = diagnosticsByTree.Key;
                foreach (var diagnosticsByAnalyzer in diagnosticsByTree.Value)
                {
                    if (analyzers.Contains(diagnosticsByAnalyzer.Key))
                    {
                        var diagnostics = diagnosticsByAnalyzer.Value.Where(shouldInclude).ToImmutableArray();
                        if (!diagnostics.IsEmpty)
                        {
                            perTreeBuilder.Add(diagnosticsByAnalyzer.Key, diagnostics);
                        }
                    }