Skip to content

Commit

Permalink
fix: Generator.Equals can't handle IEnumerable<T> when it should (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegofrata authored Jan 23, 2024
1 parent a7fa97d commit a63fe59
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
13 changes: 13 additions & 0 deletions Generator.Equals.Tests/Classes/EnumerableEquality.Sample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace Generator.Equals.Tests.Classes
{
public partial class EnumerableEquality
{
[Equatable]
public partial class Sample
{
[UnorderedEquality] public IEnumerable<int>? Properties { get; set; }
}
}
}
47 changes: 47 additions & 0 deletions Generator.Equals.Tests/Classes/EnumerableEquality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Linq;

namespace Generator.Equals.Tests.Classes
{
public partial class EnumerableEquality
{
public class EqualsTests : EqualityTestCase
{
public override object Factory1()
{
var randomSort = new Random();

// This should generate objects with the same contents, but different orders, thus proving
// that dictionary equality is being used instead of the normal sequence equality.
return new Sample
{
Properties = Enumerable
.Range(1, 1000)
.OrderBy(_ => randomSort.NextDouble())
.ToList()
};
}

public override bool EqualsOperator(object value1, object value2) => (Sample) value1 == (Sample) value2;
public override bool NotEqualsOperator(object value1, object value2) => (Sample) value1 != (Sample) value2;
}

public class NotEqualsTest : EqualityTestCase
{
public override bool Expected => false;

public override object Factory1() => new Sample
{
Properties = Enumerable.Range(1, 1000).ToList()
};

public override object Factory2() => new Sample
{
Properties = Enumerable.Range(1, 1001).ToList()
};

public override bool EqualsOperator(object value1, object value2) => (Sample) value1 == (Sample) value2;
public override bool NotEqualsOperator(object value1, object value2) => (Sample) value1 != (Sample) value2;
}
}
}
14 changes: 10 additions & 4 deletions Generator.Equals/SymbolHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;

Expand All @@ -21,11 +22,11 @@ public static IEnumerable<ISymbol> GetPropertiesAndFields(this ITypeSymbol symbo
_ => false
};
});

foreach (var member in members)
yield return member;
}

// ReSharper disable once InconsistentNaming
public static string ToNullableFQF(this ISymbol symbol) =>
symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions(
Expand All @@ -49,15 +50,20 @@ public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attribute)

public static INamedTypeSymbol? GetInterface(this ITypeSymbol symbol, string interfaceFqn)
{
return symbol.AllInterfaces
var result = symbol.AllInterfaces
.FirstOrDefault(x => x.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == interfaceFqn);

if (result == null && symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == interfaceFqn)
result = (INamedTypeSymbol)symbol;

return result;
}

public static ImmutableArray<ITypeSymbol>? GetIEnumerableTypeArguments(this ITypeSymbol symbol)
{
return symbol.GetInterface("global::System.Collections.Generic.IEnumerable<T>")?.TypeArguments;
}

public static ImmutableArray<ITypeSymbol>? GetIDictionaryTypeArguments(this ITypeSymbol symbol)
{
return symbol.GetInterface("global::System.Collections.Generic.IDictionary<TKey, TValue>")?.TypeArguments;
Expand Down

0 comments on commit a63fe59

Please sign in to comment.