Skip to content

Commit

Permalink
Generalize interface impl traversal. Simplify implementation of IsDir…
Browse files Browse the repository at this point in the history
…ectlyCompatibleWith.
  • Loading branch information
Washi1337 committed Mar 18, 2023
1 parent 078a81d commit bf84256
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,10 @@ public override IEnumerable<TypeSignature> GetDirectlyImplementedInterfaces()
/// <inheritdoc />
protected override bool IsDirectlyCompatibleWith(TypeSignature other, SignatureComparer comparer)
{
return base.IsDirectlyCompatibleWith(other, comparer)
|| IsDirectlyClassCompatibleWith(other, comparer)
|| IsDirectlyInterfaceCompatibleWith(other, comparer);
}
if (base.IsDirectlyCompatibleWith(other, comparer))
return true;

private bool IsDirectlyClassCompatibleWith(TypeSignature other, SignatureComparer comparer)
{
// Other type must be a generic instance with the same generic base type and type argument count.
if (other is not GenericInstanceTypeSignature otherGenericInstance
|| otherGenericInstance.TypeArguments.Count != TypeArguments.Count
|| !comparer.Equals(GenericType, otherGenericInstance.GenericType))
Expand Down Expand Up @@ -201,18 +198,8 @@ private bool IsDirectlyClassCompatibleWith(TypeSignature other, SignatureCompare
if (!argumentIsCompatible)
return false;
}
return true;
}

private bool IsDirectlyInterfaceCompatibleWith(TypeSignature other, SignatureComparer comparer)
{
foreach (var @interface in GetDirectlyImplementedInterfaces())
{
if (@interface.IsCompatibleWith(other, comparer))
return true;
}

return false;
return true;
}

/// <inheritdoc />
Expand Down
12 changes: 0 additions & 12 deletions src/AsmResolver.DotNet/Signatures/Types/TypeDefOrRefSignature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,6 @@ public override IEnumerable<TypeSignature> GetDirectlyImplementedInterfaces()
return type.Interfaces.Select(i => i.Interface!.ToTypeSignature(false));
}

/// <inheritdoc />
protected override bool IsDirectlyCompatibleWith(TypeSignature other, SignatureComparer comparer)
{
if (base.IsDirectlyCompatibleWith(other, comparer))
return true;
if (IsValueType)
return false;

return comparer.Equals(GetDirectBaseClass(), other)
|| GetDirectlyImplementedInterfaces().Contains(other, comparer);
}

/// <inheritdoc />
public override TResult AcceptVisitor<TResult>(ITypeSignatureVisitor<TResult> visitor) =>
visitor.VisitTypeDefOrRef(this);
Expand Down
9 changes: 9 additions & 0 deletions src/AsmResolver.DotNet/Signatures/Types/TypeSignature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,18 @@ public bool IsCompatibleWith(TypeSignature other, SignatureComparer comparer)
// Achieve the transitivity rule by moving up the type hierarchy iteratively.
while (current is not null)
{
// Is the current type compatible?
if (current.IsDirectlyCompatibleWith(other, comparer))
return true;

// Are any of the interfaces compatible instead?
foreach (var @interface in current.GetDirectlyImplementedInterfaces())
{
if (@interface.IsCompatibleWith(other, comparer))
return true;
}

// If neither, move up type hierarchy.
current = current.GetDirectBaseClass()?.StripModifiers();
}

Expand Down

0 comments on commit bf84256

Please sign in to comment.