Skip to content

Commit

Permalink
improve reference assembly resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
saucecontrol committed Aug 7, 2020
1 parent bfce475 commit 49a82fa
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
36 changes: 32 additions & 4 deletions src/InheritDoc/CecilExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,46 @@ private static string encodeTypeName(TypeReference tr)
return typeName + suffix;
}

internal class RefAssemblyResolver : DefaultAssemblyResolver
internal sealed class RefAssemblyResolver : IAssemblyResolver
{
public static RefAssemblyResolver Create(string[] refAssemblies)
private readonly Dictionary<string, AssemblyDefinition> cache = new Dictionary<string, AssemblyDefinition>(StringComparer.Ordinal);

public static RefAssemblyResolver Create(string mainAssembly, string[] refAssemblies)
{
var resolver = new RefAssemblyResolver();
var rparams = new ReaderParameters { AssemblyResolver = resolver };

foreach (var assemblyFile in refAssemblies)
resolver.RegisterAssembly(AssemblyDefinition.ReadAssembly(assemblyFile, new ReaderParameters { AssemblyResolver = resolver }));
foreach (var assemblyFile in refAssemblies.Concat(new[] { mainAssembly }))
{
var assembly = AssemblyDefinition.ReadAssembly(assemblyFile, rparams);
resolver.cache[assembly.FullName] = assembly;
}

return resolver;
}

private RefAssemblyResolver() { }

private bool isCompatibleName(AssemblyNameReference name, AssemblyNameReference cname) =>
cname.Name == name.Name && cname.PublicKeyToken.SequenceEqual(name.PublicKeyToken) && cname.Version.Major == name.Version.Major && cname.Version.Minor >= name.Version.Minor;

public AssemblyDefinition Resolve(AssemblyNameReference name)
{
if (cache.TryGetValue(name.FullName, out var match))
return match;

match = cache[name.FullName] = cache.Values.FirstOrDefault(c => isCompatibleName(name, c.Name));
return match ?? throw new AssemblyResolutionException(name);
}

public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) => Resolve(name);

public void Dispose()
{
foreach (var asm in cache.Values)
asm.Dispose();

cache.Clear();
}
}
}
2 changes: 1 addition & 1 deletion src/InheritDoc/InheritDocProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static XDocument loadDoc(string path)
if (beforeCount == 0 && trimLevel == ApiLevel.None)
return Tuple.Create(0, 0, 0);

using var resolver = CecilExtensions.RefAssemblyResolver.Create(refPaths);
using var resolver = CecilExtensions.RefAssemblyResolver.Create(asmPath, refPaths);
using var asm = AssemblyDefinition.ReadAssembly(asmPath, new ReaderParameters { AssemblyResolver = resolver });

var types =
Expand Down

0 comments on commit 49a82fa

Please sign in to comment.