Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ conversionType is not MappingConversionType.EnumToString and not MappingConversi

public INewInstanceMapping? FindNewInstanceMapping(IMethodSymbol method)
{
INewInstanceMapping? mapping = InlinedMappings.FindNewInstanceUserMapping(method, out var isInlined);
var mapping = InlinedMappings.FindNewInstanceMapping(method, out var isInlined);
if (mapping == null)
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class InlinedExpressionMappingCollection
return _delegate.FindNewInstanceMapping(mappingKey);
}

public INewInstanceUserMapping? FindNewInstanceUserMapping(IMethodSymbol method, out bool isInlined)
public INewInstanceMapping? FindNewInstanceMapping(IMethodSymbol method, out bool isInlined)
{
var mapping = _delegate.FindNewInstanceUserMapping(method);
if (mapping == null)
Expand All @@ -56,7 +56,7 @@ public class InlinedExpressionMappingCollection
if (_inlinedMappings.TryGetValue(new TypeMappingKey(mapping), out var inlinedMapping))
{
isInlined = true;
return inlinedMapping as INewInstanceUserMapping;
return inlinedMapping;
}

isInlined = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,109 @@ public Task UserImplementedAttributedNullableValueTypeToNullableMemberTypeMismat

return TestHelper.VerifyGenerator(source);
}

[Fact]
public Task UserImplementedTwoNestedProjectionsShouldReuseInlinedMapping()
{
// https://github.com/riok/mapperly/issues/1965
var source = TestSourceBuilder.CSharp(
"""
using System;
using System.Collections.Generic;
using Riok.Mapperly.Abstractions;
using System.Linq;

[Mapper]
public static partial class Mapper
{
public static partial IQueryable<VendorResponse> ProjectToDto(this IQueryable<Vendor> query);
public static partial IQueryable<ScopeResponse> ProjectToDto(this IQueryable<Scope> q);

[MapPropertyFromSource(nameof(CountryListResponse.Name), Use = nameof(GetCountryLocalizedName))]
public static partial CountryListResponse ToCountryListDto(this Country q);

private static IReadOnlyCollection<CountryListResponse> MapScopeCountries(ICollection<ScopeCountry> countries)
{
return countries.Select(c => ToCountryListDto(c.Country)).ToList();
}

private static IReadOnlyCollection<CountryListResponse> MapVendorCountries(ICollection<VendorCountry> models)
{
return models.Select(x => ToCountryListDto(x.Country)).ToList();
}

private static string GetCountryLocalizedName(Country x)
{
return x.LocalizedNames.FirstOrDefault()!.Name ?? x.Name;
}
}

public class Vendor
{
public string VendorName { get; set; } = null!;
public ICollection<VendorCountry> Countries { get; set; } = [];
}

public class VendorCountry
{
public Guid VendorId { get; set; }
public Vendor Vendor { get; set; } = null!;
public Guid CountryId { get; set; }
public Country Country { get; set; } = null!;
}

public class Scope
{
public Guid Id { get; set; }
public ICollection<ScopeCountry> Countries { get; set; } = [];
}

public class ScopeCountry
{
public Guid ScopeId { get; set; }
public Scope Scope { get; set; } = null!;
public Guid CountryId { get; set; }
public Country Country { get; set; } = null!;
}

public class Country
{
public string Code { get; set; } = null!;
public string Name { get; set; } = null!;
public ICollection<LocalizedName> LocalizedNames { get; set; } = [];
}

public class LocalizedName
{
public string LanguageCode { get; set; } = null!;
public string Name { get; set; } = null!;
}

public class CountryListResponse
{
public required string Code { get; set; }
public required string Name { get; set; }
}

public class CountryListResponse2
{
public required string Code { get; set; }
public required string Name { get; set; }
}

public class VendorResponse
{
public required string VendorName { get; set; }
public IReadOnlyCollection<CountryListResponse> Countries { get; set; } = [];
}

public class ScopeResponse
{
public required Guid Id { get; set; }
public IReadOnlyCollection<CountryListResponse> Countries { get; set; } = [];
}
"""
);
return TestHelper.VerifyGenerator(source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//HintName: Mapper.g.cs
// <auto-generated />
#nullable enable
public static partial class Mapper
{
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::System.Linq.IQueryable<global::VendorResponse> ProjectToDto(this global::System.Linq.IQueryable<global::Vendor> query)
{
#nullable disable
return global::System.Linq.Queryable.Select(
query,
x => new global::VendorResponse()
{
VendorName = x.VendorName,
Countries = global::System.Linq.Enumerable.ToList(global::System.Linq.Enumerable.Select(x.Countries, x => new global::CountryListResponse()
{
Code = x.Country.Code,
Name = global::System.Linq.Enumerable.FirstOrDefault(x.Country.LocalizedNames)!.Name ?? x.Country.Name,
})),
}
);
#nullable enable
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::System.Linq.IQueryable<global::ScopeResponse> ProjectToDto(this global::System.Linq.IQueryable<global::Scope> q)
{
#nullable disable
return global::System.Linq.Queryable.Select(
q,
x => new global::ScopeResponse()
{
Id = x.Id,
Countries = global::System.Linq.Enumerable.ToList(global::System.Linq.Enumerable.Select(x.Countries, c => new global::CountryListResponse()
{
Code = c.Country.Code,
Name = global::System.Linq.Enumerable.FirstOrDefault(c.Country.LocalizedNames)!.Name ?? c.Country.Name,
})),
}
);
#nullable enable
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::CountryListResponse ToCountryListDto(this global::Country q)
{
var target = new global::CountryListResponse()
{
Code = q.Code,
Name = GetCountryLocalizedName(q),
};
return target;
}
}
Empty file.
Loading