Skip to content

Commit

Permalink
Merge pull request #366 from ds5678/shared-signature-comparer
Browse files Browse the repository at this point in the history
SignatureComparer Improvements
  • Loading branch information
Washi1337 committed Oct 16, 2022
2 parents 4d1f816 + 8cf0f4f commit e9d9e5d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 33 deletions.
5 changes: 1 addition & 4 deletions src/AsmResolver.DotNet/AssemblyResolverBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ namespace AsmResolver.DotNet
public abstract class AssemblyResolverBase : IAssemblyResolver
{
private static readonly string[] BinaryFileExtensions = {".dll", ".exe"};
private static readonly SignatureComparer Comparer = new()
{
AcceptNewerAssemblyVersionNumbers = true
};
private static readonly SignatureComparer Comparer = new(SignatureComparisonFlags.AcceptNewerVersions);

private readonly Dictionary<AssemblyDescriptor, AssemblyDefinition> _cache = new(new SignatureComparer());

Expand Down
5 changes: 1 addition & 4 deletions src/AsmResolver.DotNet/DefaultMetadataResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ namespace AsmResolver.DotNet
public class DefaultMetadataResolver : IMetadataResolver
{
private readonly ConcurrentDictionary<ITypeDescriptor, TypeDefinition> _typeCache;
private readonly SignatureComparer _comparer = new()
{
IgnoreAssemblyVersionNumbers = true
};
private readonly SignatureComparer _comparer = new(SignatureComparisonFlags.VersionAgnostic);

/// <summary>
/// Creates a new metadata resolver.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,28 @@ public partial class SignatureComparer :
IEqualityComparer<IResolutionScope>,
IEqualityComparer<AssemblyDescriptor>
{
/// <summary>
/// Gets or sets a value indicating whether version numbers should be excluded in the comparison of two
/// assembly descriptors.
/// </summary>
public bool IgnoreAssemblyVersionNumbers
private bool IgnoreAssemblyVersionNumbers
{
get;
set;
get
{
return (Flags & SignatureComparisonFlags.VersionAgnostic) == SignatureComparisonFlags.VersionAgnostic;
}
}

/// <summary>
/// Gets or sets a value indicating whether the containing assembly of the second member to compare is
/// allowed to be a newer version than the containing assembly of the first member.
/// </summary>
/// <remarks>
/// <para>
/// If this property is set to <c>true</c>, then any member reference that is contained in a certain
/// assembly (e.g. with version 1.0.0.0), will be considered equal to a member reference with the
/// same name or signature contained in an assembly with a newer version (e.g. 1.1.0.0). When this
/// property is set to <c>false</c>, the exact version number must match instead.
/// </para>
/// <para>
/// This property is ignored if <see cref="IgnoreAssemblyVersionNumbers"/> is <c>true</c>.
/// </para>
/// </remarks>
public bool AcceptNewerAssemblyVersionNumbers
private bool AcceptNewerAssemblyVersionNumbers
{
get;
set;
get
{
return (Flags & SignatureComparisonFlags.AcceptNewerVersions) == SignatureComparisonFlags.AcceptNewerVersions;
}
}

private bool AcceptOlderAssemblyVersionNumbers
{
get
{
return (Flags & SignatureComparisonFlags.AcceptOlderVersions) == SignatureComparisonFlags.AcceptOlderVersions;
}
}

/// <inheritdoc />
Expand Down Expand Up @@ -80,6 +73,8 @@ public bool Equals(AssemblyDescriptor? x, AssemblyDescriptor? y)
versionMatch = true;
else if (AcceptNewerAssemblyVersionNumbers)
versionMatch = x.Version <= y.Version;
else if (AcceptOlderAssemblyVersionNumbers)
versionMatch = x.Version >= y.Version;
else
versionMatch = x.Version == y.Version;

Expand Down
29 changes: 29 additions & 0 deletions src/AsmResolver.DotNet/Signatures/SignatureComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,35 @@ public partial class SignatureComparer :
IEqualityComparer<byte[]>
{
private const int ElementTypeOffset = 24;
private const SignatureComparisonFlags DefaultFlags = SignatureComparisonFlags.ExactVersion;

/// <summary>
/// An immutable default instance of <see cref="SignatureComparer"/>.
/// </summary>
public static SignatureComparer Default { get; } = new();

/// <summary>
/// Flags for controlling comparison behavior.
/// </summary>
public SignatureComparisonFlags Flags { get; }

/// <summary>
/// The default <see cref="SignatureComparer"/> constructor.
/// </summary>
public SignatureComparer()
{
Flags = DefaultFlags;
}

/// <summary>
/// A <see cref="SignatureComparer"/> constructor with a parameter for specifying the <see cref="Flags"/>
/// used in comparisons.
/// </summary>
/// <param name="flags">The <see cref="Flags"/> used in comparisons.</param>
public SignatureComparer(SignatureComparisonFlags flags)
{
Flags = flags;
}

/// <inheritdoc />
public bool Equals(byte[]? x, byte[]? y) => ByteArrayEqualityComparer.Instance.Equals(x, y);
Expand Down
44 changes: 44 additions & 0 deletions src/AsmResolver.DotNet/Signatures/SignatureComparisonFlags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;

namespace AsmResolver.DotNet.Signatures
{
/// <summary>
/// Flags for controlling the behavior of <see cref="SignatureComparer"/>.
/// </summary>
[Flags]
public enum SignatureComparisonFlags
{
/// <summary>
/// When neither <see cref="AcceptOlderVersions"/> nor <see cref="AcceptNewerVersions"/> are specified,
/// the exact version number must match in the comparison of two assembly descriptors.
/// </summary>
ExactVersion = 0,
/// <summary>
/// If this flag is used, the containing assembly of the second member to compare is
/// allowed to be an older version than the containing assembly of the first member.
/// </summary>
/// <remarks>
/// If this flag is used, then any member reference that is contained in a certain
/// assembly (e.g. with version 1.1.0.0), will be considered equal to a member reference with the
/// same name or signature contained in an assembly with a older version (e.g. 1.0.0.0).
/// Otherwise, they will be treated as inequal.
/// </remarks>
AcceptOlderVersions = 1,
/// <summary>
/// If this flag is used, the containing assembly of the second member to compare is
/// allowed to be a newer version than the containing assembly of the first member.
/// </summary>
/// <remarks>
/// If this flag is used, then any member reference that is contained in a certain
/// assembly (e.g. with version 1.0.0.0), will be considered equal to a member reference with the
/// same name or signature contained in an assembly with a newer version (e.g. 1.1.0.0).
/// Otherwise, they will be treated as inequal.
/// </remarks>
AcceptNewerVersions = 2,
/// <summary>
/// If this flag is used, version numbers will be excluded in the comparison of two
/// assembly descriptors.
/// </summary>
VersionAgnostic = AcceptOlderVersions | AcceptNewerVersions,
}
}

0 comments on commit e9d9e5d

Please sign in to comment.