| File: Analyzers\AnalyzerReferenceInformationProvider.cs | Web Access |
| Project: src\sdk\src\Dotnet.Format\dotnet-format\dotnet-format.csproj (dotnet-format) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; using System.Reflection; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; using Microsoft.Extensions.Logging; namespace Microsoft.CodeAnalysis.Tools.Analyzers { internal class AnalyzerReferenceInformationProvider : IAnalyzerInformationProvider { private static readonly Dictionary<string, Assembly> s_pathsToAssemblies = new(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Assembly> s_namesToAssemblies = new(StringComparer.OrdinalIgnoreCase); private static readonly object s_guard = new(); public ImmutableDictionary<ProjectId, AnalyzersAndFixers> GetAnalyzersAndFixers( Workspace workspace, Solution solution, FormatOptions formatOptions, ILogger logger) { return solution.Projects .ToImmutableDictionary(project => project.Id, project => GetAnalyzersAndFixers(workspace, project)); } private static AnalyzersAndFixers GetAnalyzersAndFixers(Workspace workspace, Project project) { var analyzerAssemblies = project.AnalyzerReferences .Select(reference => TryLoadAssemblyFrom(workspace, reference.FullPath, reference)) .OfType<Assembly>() .ToImmutableArray(); var analyzers = project.AnalyzerReferences.SelectMany(reference => reference.GetAnalyzers(project.Language)).ToImmutableArray(); return new AnalyzersAndFixers(analyzers, AnalyzerFinderHelpers.LoadFixers(analyzerAssemblies, project.Language)); } private static Assembly? TryLoadAssemblyFrom(Workspace workspace, string? path, AnalyzerReference analyzerReference) { // Since we are not deploying these assemblies we need to ensure the files exist. if (path is null || !File.Exists(path)) { return null; } lock (s_guard) { if (s_pathsToAssemblies.TryGetValue(path, out var cachedAssembly)) { return cachedAssembly; } try { Assembly analyzerAssembly; if (analyzerReference is AnalyzerFileReference analyzerFileReference) { // If we have access to the analyzer file reference, we can update our // cache and return the assembly. analyzerAssembly = analyzerFileReference.GetAssembly(); s_namesToAssemblies.TryAdd(analyzerAssembly.GetName().FullName, analyzerAssembly); } else { var analyzerService = workspace.Services.GetService<IAnalyzerService>() ?? throw new NotSupportedException(); var loader = analyzerService.GetLoader(); analyzerAssembly = loader.LoadFromPath(path); } s_pathsToAssemblies.Add(path, analyzerAssembly); return analyzerAssembly; } catch { } } return null; } public DiagnosticSeverity GetSeverity(FormatOptions formatOptions) => formatOptions.AnalyzerSeverity; } }