Skip to content

Commit

Permalink
feat: support IList<T>, List<T> and IReadOnlyList<T> targets (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
latonz authored Jan 23, 2023
1 parent 0eccd4d commit fcaf5a5
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static class DictionaryMappingBuilder
if (valueMapping == null)
return null;

// target is of type IDictionary<,> or IReadOnlyDictionary<,>.
// target is of type IDictionary<,>, IReadOnlyDictionary<,> or Dictionary<,>.
// The constructed type should be Dictionary<,>
if (IsDictionaryType(ctx, ctx.Target))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,12 @@ private static (bool CanMapWithLinq, string? CollectMethod) ResolveCollectMethod
if (targetIsReadOnlyCollection && sourceCountIsKnown)
return (true, ToArrayMethodName);

// if target is a list, ICollection<T> or IReadOnlyCollection<T> collect with ToList()
// if target is a IReadOnlyCollection<T>, IList<T>, List<T> or ICollection<T> with ToList()
return targetIsReadOnlyCollection
|| SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IReadOnlyList)
|| SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IList)
|| SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.List)
|| SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ICollection)
|| targetIsReadOnlyCollection
? (true, ToListMethodName)
: (false, null);
}
Expand Down
6 changes: 6 additions & 0 deletions src/Riok.Mapperly/Descriptors/WellKnownTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public class WellKnownTypes
private INamedTypeSymbol? _enumerable;
private INamedTypeSymbol? _iCollection;
private INamedTypeSymbol? _iReadOnlyCollection;
private INamedTypeSymbol? _iList;
private INamedTypeSymbol? _list;
private INamedTypeSymbol? _iReadOnlyList;
private INamedTypeSymbol? _keyValuePair;
private INamedTypeSymbol? _dictionary;

Expand All @@ -44,6 +47,9 @@ internal WellKnownTypes(Compilation compilation)
public INamedTypeSymbol Enumerable => _enumerable ??= GetTypeSymbol(typeof(Enumerable));
public INamedTypeSymbol ICollection => _iCollection ??= GetTypeSymbol(typeof(ICollection<>));
public INamedTypeSymbol IReadOnlyCollection => _iReadOnlyCollection ??= GetTypeSymbol(typeof(IReadOnlyCollection<>));
public INamedTypeSymbol IList => _iList ??= GetTypeSymbol(typeof(IList<>));
public INamedTypeSymbol List => _list ??= GetTypeSymbol(typeof(List<>));
public INamedTypeSymbol IReadOnlyList => _iReadOnlyList ??= GetTypeSymbol(typeof(IReadOnlyList<>));
public INamedTypeSymbol KeyValuePair => _keyValuePair ??= GetTypeSymbol(typeof(KeyValuePair<,>));
public INamedTypeSymbol Dictionary => _dictionary ??= GetTypeSymbol(typeof(Dictionary<,>));

Expand Down
33 changes: 33 additions & 0 deletions test/Riok.Mapperly.Tests/Mapping/EnumerableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,39 @@ public void EnumerableToReadOnlyCollectionOfCastedTypes()
.HaveSingleMethodBody("return System.Linq.Enumerable.ToList(System.Linq.Enumerable.Select(source, x => (int)x));");
}

[Fact]
public void EnumerableToIListOfCastedTypes()
{
var source = TestSourceBuilder.Mapping(
"IEnumerable<long>",
"IList<int>");
TestHelper.GenerateMapper(source)
.Should()
.HaveSingleMethodBody("return System.Linq.Enumerable.ToList(System.Linq.Enumerable.Select(source, x => (int)x));");
}

[Fact]
public void EnumerableToListOfCastedTypes()
{
var source = TestSourceBuilder.Mapping(
"IEnumerable<long>",
"List<int>");
TestHelper.GenerateMapper(source)
.Should()
.HaveSingleMethodBody("return System.Linq.Enumerable.ToList(System.Linq.Enumerable.Select(source, x => (int)x));");
}

[Fact]
public void EnumerableToIReadOnlyListOfCastedTypes()
{
var source = TestSourceBuilder.Mapping(
"IEnumerable<long>",
"IReadOnlyList<int>");
TestHelper.GenerateMapper(source)
.Should()
.HaveSingleMethodBody("return System.Linq.Enumerable.ToList(System.Linq.Enumerable.Select(source, x => (int)x));");
}

[Fact]
public void EnumerableToCustomCollection()
{
Expand Down

0 comments on commit fcaf5a5

Please sign in to comment.