#nullable enable using System; using System.Collections.Generic; using System.IO; using System.Linq; using Mono.Cecil; namespace ShrinkSDK.CodeGen { internal sealed class PathAssemblyResolver : IAssemblyResolver { private readonly Dictionary _paths = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _assemblies = new(StringComparer.OrdinalIgnoreCase); private AssemblyDefinition? _self; public PathAssemblyResolver(IEnumerable references) { foreach (var path in references.Where(File.Exists)) _paths[Path.GetFileNameWithoutExtension(path)] = Path.GetFullPath(path); } public void SetSelf(AssemblyDefinition assembly) => _self = assembly; public AssemblyDefinition? Resolve(AssemblyNameReference name) => Resolve(name, new ReaderParameters()); public AssemblyDefinition? Resolve(AssemblyNameReference name, ReaderParameters parameters) { if (string.Equals(name.Name, _self?.Name.Name, StringComparison.OrdinalIgnoreCase)) return _self; if (_assemblies.TryGetValue(name.Name, out var cached)) return cached; if (!_paths.TryGetValue(name.Name, out var path)) return null; parameters.AssemblyResolver = this; parameters.ReadingMode = ReadingMode.Immediate; var assembly = AssemblyDefinition.ReadAssembly(path, parameters); _assemblies[name.Name] = assembly; return assembly; } public void Dispose() { foreach (var assembly in _assemblies.Values) assembly.Dispose(); _assemblies.Clear(); } } }