Repository: dotnet/roslyn
File: src/VisualStudio/Core/Def/ProjectSystem/SdkAnalyzerAssemblyRedirector.cs (C#)

Code before:
        Dictionary<string, string>? versions;

        try
        {
            versions = JsonSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllText(metadataFilePath));
        }
        catch (Exception ex)
        {
            Log($"Failed to read or parse metadata file '{metadataFilePath}'. {ex}", __ACTIVITYLOG_ENTRYTYPE.ALE_WARNING);
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        if (versions is null || versions.Count == 0)
        {
            Log($"Versions are empty: {metadataFilePath}", __ACTIVITYLOG_ENTRYTYPE.ALE_WARNING);
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        var builder = ImmutableDictionary.CreateBuilder<string, List<AnalyzerInfo>>(StringComparer.OrdinalIgnoreCase);

        // Expects layout like:
        // VsInstallDir\DotNetRuntimeAnalyzers\WindowsDesktopAnalyzers\analyzers\dotnet\System.Windows.Forms.Analyzers.dll
        //                                     ~~~~~~~~~~~~~~~~~~~~~~~                                                     = topLevelDirectory
        //                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ = analyzerPath

        foreach (var topLevelDirectory in Directory.EnumerateDirectories(insertedAnalyzersDirectory))
        {
            var subsetName = Path.GetFileName(topLevelDirectory);

            foreach (var analyzerPath in Directory.EnumerateFiles(topLevelDirectory, "*.dll", SearchOption.AllDirectories))
            {
                if (!analyzerPath.StartsWith(topLevelDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    // We can't continue, because computations in code below assume this.
                    Debug.Fail($"Analyzer path '{analyzerPath}' must start with '{topLevelDirectory}'.");
                    continue;
                }

                if (!versions.TryGetValue(subsetName, out var version))
                {
                    continue;
                }

                var analyzerName = Path.GetFileNameWithoutExtension(analyzerPath);
                var pathSuffix = analyzerPath.Substring(topLevelDirectory.Length + 1 /* slash */);
                pathSuffix = Path.GetDirectoryName(pathSuffix);

                AnalyzerInfo analyzer = new() { FullPath = analyzerPath, ProductVersion = version, PathSuffix = pathSuffix };

                if (builder.TryGetValue(analyzerName, out var existing))
                {

Review comment (suggestion):
Is there a way we can produce a file that produces all this up front so we don't need to search for binaries that ship in the product? This is having the user pay a cost for things we can absolutely determine because we insert these binaries.

Code after:

        try
        {
            metadata = JsonSerializer.Deserialize<Dictionary<string, MetadataEntry>>(File.ReadAllText(metadataFilePath));
        }
        catch (Exception ex)
        {
            Log($"Failed to read or parse metadata file '{metadataFilePath}'. {ex}", __ACTIVITYLOG_ENTRYTYPE.ALE_WARNING);
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        if (metadata is null || metadata.Count == 0)
        {
            Log($"Metadata dictionary is empty: {metadataFilePath}", __ACTIVITYLOG_ENTRYTYPE.ALE_WARNING);
            return ImmutableDictionary<string, List<AnalyzerInfo>>.Empty;
        }

        var builder = ImmutableDictionary.CreateBuilder<string, List<AnalyzerInfo>>(StringComparer.OrdinalIgnoreCase);

        // Expects layout like:
        // VsInstallDir\DotNetRuntimeAnalyzers\WindowsDesktopAnalyzers\analyzers\dotnet\System.Windows.Forms.Analyzers.dll
        //                                     ~~~~~~~~~~~~~~~~~~~~~~~                                                     = subsetName
        //                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ = pathSuffix

        foreach (var (subsetName, entry) in metadata)
        {
            foreach (var file in entry.Files)
            {
                var analyzerFullPath = Path.Combine(insertedAnalyzersDirectory, subsetName, file);

                AnalyzerInfo analyzer = new()
                {
                    FullPath = analyzerFullPath,
                    ProductVersion = entry.Version,
                    PathSuffix = Path.GetDirectoryName(file),
                };

                var analyzerName = Path.GetFileNameWithoutExtension(file);

                if (builder.TryGetValue(analyzerName, out var existing))
                {
                    existing.Add(analyzer);
                }
                else
                {
                    builder.Add(analyzerName, [analyzer]);
                }
            }
        }

        Log($"Loaded analyzer map ({builder.Count}): {insertedAnalyzersDirectory}");