Skip to content

Commit

Permalink
fix: do not resolve existing one sideded loose nullable property mapp…
Browse files Browse the repository at this point in the history
…ings (#1090)
  • Loading branch information
latonz authored Feb 5, 2024
1 parent 682c26f commit 7998720
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
9 changes: 2 additions & 7 deletions src/Riok.Mapperly/Descriptors/MappingBuilderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ bool clearDerivedTypes
/// Finds or builds a mapping (<seealso cref="FindOrBuildMapping(Riok.Mapperly.Descriptors.TypeMappingKey,Riok.Mapperly.Descriptors.MappingBuildingOptions,Location)"/>).
/// Before a new mapping is built existing mappings are tried to be found by the following priorities:
/// 1. exact match
/// 2. ignoring the nullability of the source (needs to be handled by the caller of this method)
/// 3. ignoring the nullability of the target (needs to be handled by the caller of this method)
/// 4. ignoring the nullability of the source and the target (needs to be handled by the caller of this method)
/// 2. ignoring the nullability of the source and the target (needs to be handled by the caller of this method)
/// If no mapping can be found a new mapping is built with the source and the target as non-nullables.
/// </summary>
/// <param name="key">The mapping key.</param>
Expand All @@ -154,10 +152,7 @@ bool clearDerivedTypes
Location? diagnosticLocation = null
)
{
return FindMapping(key)
?? FindMapping(key.NonNullableSource())
?? FindMapping(key.NonNullableTarget())
?? FindOrBuildMapping(key.NonNullable(), options, diagnosticLocation);
return FindMapping(key) ?? FindOrBuildMapping(key.NonNullable(), options, diagnosticLocation);
}

/// <summary>
Expand Down
4 changes: 0 additions & 4 deletions src/Riok.Mapperly/Descriptors/TypeMappingKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ public TypeMappingKey(ITypeMapping mapping, TypeMappingConfiguration? config = n

public TypeMappingConfiguration Configuration { get; } = config ?? TypeMappingConfiguration.Default;

public TypeMappingKey NonNullableSource() => new(Source.NonNullable(), Target, Configuration);

public TypeMappingKey NonNullableTarget() => new(Source, Target.NonNullable(), Configuration);

public TypeMappingKey NonNullable() => new(Source.NonNullable(), Target.NonNullable(), Configuration);

private bool Equals(TypeMappingKey other) =>
Expand Down
18 changes: 18 additions & 0 deletions test/Riok.Mapperly.Tests/Mapping/ObjectPropertyNullableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -730,4 +730,22 @@ public void NullableDirectiveEnabledTargetWithSameNullableRefTypeAsPropertyAndIn
"""
);
}

[Fact]
public Task NullableToNullablePropertyWithAnotherNullableToNonNullableMappingShouldDirectAssign()
{
// see https://github.com/riok/mapperly/issues/1089
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
public static partial ADest? Map(A? source);
public static partial BDest MapToDestinationB(B source);
""",
"public record A(int? Prop);",
"public record B(List<int?> Prop);",
"public record ADest(int? Prop);",
"public record BDest(List<int> Prop);"
);

return TestHelper.VerifyGenerator(source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//HintName: Mapper.g.cs
// <auto-generated />
#nullable enable
public partial class Mapper
{
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::ADest? Map(global::A? source)
{
if (source == null)
return default;
var target = new global::ADest(source.Prop);
return target;
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::BDest MapToDestinationB(global::B source)
{
var target = new global::BDest(MapToList(source.Prop));
return target;
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private static global::System.Collections.Generic.List<int> MapToList(global::System.Collections.Generic.IReadOnlyCollection<int?> source)
{
var target = new global::System.Collections.Generic.List<int>(source.Count);
foreach (var item in source)
{
target.Add(item == null ? throw new System.ArgumentNullException(nameof(item)) : item.Value);
}
return target;
}
}

0 comments on commit 7998720

Please sign in to comment.