Skip to content

Commit

Permalink
feat: refactor ITypeMapping
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyMakkison committed Aug 1, 2023
1 parent 1cff8e3 commit 911f838
Show file tree
Hide file tree
Showing 59 changed files with 224 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ conversionType is not MappingConversionType.EnumToString and not MappingConversi
/// </summary>
/// <param name="sourceType">The source type.</param>
/// <param name="targetType">The target type.</param>
/// <returns>The <see cref="ITypeMapping"/> if a mapping was found or <c>null</c> if none was found.</returns>
public override ITypeMapping? FindMapping(ITypeSymbol sourceType, ITypeSymbol targetType)
/// <returns>The <see cref="INewInstanceMapping"/> if a mapping was found or <c>null</c> if none was found.</returns>
public override INewInstanceMapping? FindMapping(ITypeSymbol sourceType, ITypeSymbol targetType)
{
if (_inlineExpressionMappings.Find(sourceType, targetType) is { } mapping)
return mapping;
Expand Down Expand Up @@ -92,7 +92,7 @@ conversionType is not MappingConversionType.EnumToString and not MappingConversi
/// <param name="targetType">The target type.</param>
/// <param name="options">The options, <see cref="MappingBuildingOptions.MarkAsReusable"/> is ignored.</param>
/// <returns></returns>
public override ITypeMapping? FindOrBuildMapping(
public override INewInstanceMapping? FindOrBuildMapping(
ITypeSymbol sourceType,
ITypeSymbol targetType,
MappingBuildingOptions options = MappingBuildingOptions.Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private static IEnumerable<ITypeMapping> GetUserMappingCandidates(MappingBuilder
foreach (var userMapping in ctx.UserMappings)
{
// exclude runtime target type and user implemented existing type mappings
if (userMapping is UserDefinedNewInstanceRuntimeTargetTypeMapping or UserImplementedExistingTargetMethodMapping)
if (userMapping is UserDefinedNewInstanceRuntimeTargetTypeMapping)
continue;

if (userMapping.CallableByOtherMappings)
Expand Down Expand Up @@ -76,6 +76,7 @@ IEnumerable<ITypeMapping> childMappings
// in the type switch
// to use the most specific mapping
var runtimeTargetTypeMappings = childMappings
.OfType<INewInstanceMapping>()
.OrderByDescending(x => x.SourceType.GetInheritanceLevel())
.ThenByDescending(x => x.TargetType.GetInheritanceLevel())
.ThenBy(x => x.TargetType.IsNullable())
Expand Down
8 changes: 4 additions & 4 deletions src/Riok.Mapperly/Descriptors/MappingBuilderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ bool clearDerivedTypes
/// <param name="sourceType">The source type.</param>
/// <param name="targetType">The target type.</param>
/// <returns>The found mapping, or <c>null</c> if none is found.</returns>
public virtual ITypeMapping? FindMapping(ITypeSymbol sourceType, ITypeSymbol targetType) =>
public virtual INewInstanceMapping? FindMapping(ITypeSymbol sourceType, ITypeSymbol targetType) =>
MappingBuilder.Find(sourceType.UpgradeNullable(), targetType.UpgradeNullable());

/// <summary>
Expand All @@ -90,7 +90,7 @@ bool clearDerivedTypes
/// <param name="targetType">The target type.</param>
/// <param name="options">The mapping building options.</param>
/// <returns>The found or created mapping, or <c>null</c> if no mapping could be created.</returns>
public virtual ITypeMapping? FindOrBuildMapping(
public virtual INewInstanceMapping? FindOrBuildMapping(
ITypeSymbol sourceType,
ITypeSymbol targetType,
MappingBuildingOptions options = MappingBuildingOptions.Default
Expand All @@ -108,7 +108,7 @@ bool clearDerivedTypes
/// <param name="target">The target type.</param>
/// <param name="options">The options.</param>
/// <returns>The created mapping, or <c>null</c> if no mapping could be created.</returns>
public ITypeMapping? BuildMapping(ITypeSymbol source, ITypeSymbol target, MappingBuildingOptions options)
public INewInstanceMapping? BuildMapping(ITypeSymbol source, ITypeSymbol target, MappingBuildingOptions options)
{
var userSymbol = options.HasFlag(MappingBuildingOptions.KeepUserSymbol) ? UserSymbol : null;
return BuildMapping(userSymbol, source, target, options);
Expand Down Expand Up @@ -193,7 +193,7 @@ MappingBuildingOptions options
return new(this, userSymbol, sourceType, targetType, options.HasFlag(MappingBuildingOptions.ClearDerivedTypes));
}

protected ITypeMapping? BuildMapping(
protected INewInstanceMapping? BuildMapping(
IMethodSymbol? userSymbol,
ITypeSymbol sourceType,
ITypeSymbol targetType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public static class DerivedTypeMappingBuilder
{
public static ITypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static INewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
var derivedTypeMappings = TryBuildContainedMappings(ctx);
if (derivedTypeMappings == null)
Expand All @@ -19,7 +19,7 @@ public static class DerivedTypeMappingBuilder
: new DerivedTypeSwitchMapping(ctx.Source, ctx.Target, derivedTypeMappings);
}

public static IReadOnlyCollection<ITypeMapping>? TryBuildContainedMappings(
public static IReadOnlyCollection<INewInstanceMapping>? TryBuildContainedMappings(
MappingBuilderContext ctx,
bool duplicatedSourceTypesAllowed = false
)
Expand All @@ -29,14 +29,14 @@ public static class DerivedTypeMappingBuilder
: BuildContainedMappings(ctx, ctx.Configuration.DerivedTypes, duplicatedSourceTypesAllowed);
}

private static IReadOnlyCollection<ITypeMapping> BuildContainedMappings(
private static IReadOnlyCollection<INewInstanceMapping> BuildContainedMappings(
MappingBuilderContext ctx,
IReadOnlyCollection<DerivedTypeMappingConfiguration> configs,
bool duplicatedSourceTypesAllowed
)
{
var derivedTypeMappingSourceTypes = new HashSet<ITypeSymbol>(SymbolEqualityComparer.Default);
var derivedTypeMappings = new List<ITypeMapping>(configs.Count);
var derivedTypeMappings = new List<INewInstanceMapping>(configs.Count);
Func<ITypeSymbol, bool> isAssignableToSource = ctx.Source is ITypeParameterSymbol sourceTypeParameter
? t => ctx.SymbolAccessor.DoesTypeSatisfyTypeParameterConstraints(sourceTypeParameter, t, ctx.Source.NullableAnnotation)
: t => ctx.SymbolAccessor.HasImplicitConversion(t, ctx.Source);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class DictionaryMappingBuilder
private const string ToImmutableSortedDictionaryMethodName =
"global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary";

public static ITypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static INewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
if (!ctx.IsConversionEnabled(MappingConversionType.Dictionary))
return null;
Expand Down Expand Up @@ -117,7 +117,7 @@ or CollectionType.IReadOnlyDictionary
);
}

private static (ITypeMapping, ITypeMapping)? BuildKeyValueMapping(MappingBuilderContext ctx)
private static (INewInstanceMapping, INewInstanceMapping)? BuildKeyValueMapping(MappingBuilderContext ctx)
{
if (ctx.CollectionInfos!.Target.GetDictionaryKeyValueTypes(ctx) is not var (targetKeyType, targetValueType))
return null;
Expand Down Expand Up @@ -153,8 +153,8 @@ out var isExplicit

private static LinqDictionaryMapping? ResolveImmutableCollectMethod(
MappingBuilderContext ctx,
ITypeMapping keyMapping,
ITypeMapping valueMapping
INewInstanceMapping keyMapping,
INewInstanceMapping valueMapping
)
{
return ctx.CollectionInfos!.Target.CollectionType switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public static class DirectAssignmentMappingBuilder
{
public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
return
SymbolEqualityComparer.IncludeNullability.Equals(ctx.Source, ctx.Target)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public static class EnumMappingBuilder
{
public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
var sourceIsEnum = ctx.Source.TryGetEnumUnderlyingType(out var sourceEnumType);
var targetIsEnum = ctx.Target.TryGetEnumUnderlyingType(out var targetEnumType);
Expand Down Expand Up @@ -44,7 +44,7 @@ public static class EnumMappingBuilder
};
}

private static TypeMapping BuildCastMappingAndDiagnostic(MappingBuilderContext ctx)
private static NewInstanceMapping BuildCastMappingAndDiagnostic(MappingBuilderContext ctx)
{
ctx.ReportDiagnostic(
DiagnosticDescriptors.EnumMappingNotSupportedInProjectionMappings,
Expand All @@ -54,7 +54,7 @@ private static TypeMapping BuildCastMappingAndDiagnostic(MappingBuilderContext c
return BuildEnumToEnumCastMapping(ctx, true);
}

private static TypeMapping BuildEnumToEnumCastMapping(
private static NewInstanceMapping BuildEnumToEnumCastMapping(
MappingBuilderContext ctx,
bool ignoreExplicitAndIgnoredMappings = false,
bool checkTargetDefined = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public static class EnumToStringMappingBuilder
{
public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
if (!ctx.IsConversionEnabled(MappingConversionType.EnumToString))
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static class EnumerableMappingBuilder
private const string CreateRangeStackMethodName = "global::System.Collections.Immutable.ImmutableStack.CreateRange";
private const string ToImmutableSortedSetMethodName = "global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet";

public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
if (!ctx.IsConversionEnabled(MappingConversionType.Enumerable))
return null;
Expand Down Expand Up @@ -127,7 +127,11 @@ ForEachAddEnumerableExistingTargetMapping CreateForEach(string methodName)
}
}

private static LinqEnumerableMapping BuildLinqMapping(MappingBuilderContext ctx, ITypeMapping elementMapping, string? collectMethod)
private static LinqEnumerableMapping BuildLinqMapping(
MappingBuilderContext ctx,
INewInstanceMapping elementMapping,
string? collectMethod
)
{
var selectMethod = elementMapping.IsSynthetic ? null : SelectMethodName;
return new LinqEnumerableMapping(ctx.Source, ctx.Target, elementMapping, selectMethod, collectMethod);
Expand All @@ -154,14 +158,14 @@ private static LinqEnumerableMapping BuildLinqMapping(MappingBuilderContext ctx,
private static LinqConstructorMapping BuildLinqConstructorMapping(
MappingBuilderContext ctx,
INamedTypeSymbol targetTypeToConstruct,
ITypeMapping elementMapping
INewInstanceMapping elementMapping
)
{
var selectMethod = elementMapping.IsSynthetic ? null : SelectMethodName;
return new LinqConstructorMapping(ctx.Source, ctx.Target, targetTypeToConstruct, elementMapping, selectMethod);
}

private static ExistingTargetMappingMethodWrapper? BuildCustomTypeMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static ExistingTargetMappingMethodWrapper? BuildCustomTypeMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (
!ctx.ObjectFactories.TryFindObjectFactory(ctx.Source, ctx.Target, out var objectFactory)
Expand Down Expand Up @@ -234,7 +238,7 @@ or CollectionType.ICollection
: (false, null);
}

private static LinqEnumerableMapping? TryBuildImmutableLinqMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static LinqEnumerableMapping? TryBuildImmutableLinqMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
var collectMethod = ResolveImmutableCollectMethod(ctx);
if (collectMethod is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public class MappingBuilder
{
private delegate ITypeMapping? BuildMapping(MappingBuilderContext context);
private delegate INewInstanceMapping? BuildMapping(MappingBuilderContext context);

private static readonly IReadOnlyCollection<BuildMapping> _builders = new BuildMapping[]
{
Expand Down Expand Up @@ -43,9 +43,9 @@ public MappingBuilder(MappingCollection mappings)
public IReadOnlyCollection<IUserMapping> UserMappings => _mappings.UserMappings;

/// <inheritdoc cref="MappingBuilderContext.FindMapping"/>
public ITypeMapping? Find(ITypeSymbol sourceType, ITypeSymbol targetType) => _mappings.Find(sourceType, targetType);
public INewInstanceMapping? Find(ITypeSymbol sourceType, ITypeSymbol targetType) => _mappings.Find(sourceType, targetType);

public ITypeMapping? Build(MappingBuilderContext ctx, bool resultIsReusable)
public INewInstanceMapping? Build(MappingBuilderContext ctx, bool resultIsReusable)
{
foreach (var mappingBuilder in _builders)
{
Expand All @@ -54,7 +54,7 @@ public MappingBuilder(MappingCollection mappings)

if (resultIsReusable)
{
_mappings.Add(mapping);
_mappings.AddNewInstanceMapping(mapping);
}

_mappings.EnqueueToBuildBody(mapping, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class MemoryMappingBuilder
private const string SpanMemberName = nameof(Memory<int>.Span);
private const string ToArrayMethodName = nameof(Enumerable.ToArray);

public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
if (!ctx.IsConversionEnabled(MappingConversionType.Memory))
return null;
Expand Down Expand Up @@ -104,7 +104,7 @@ public static class MemoryMappingBuilder
return new SourceObjectMemberDelegateExistingTargetMapping(ctx.Source, ctx.Target, SpanMemberName, enumerableMapping);
}

private static TypeMapping? BuildSpanToMemoryMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildSpanToMemoryMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (elementMapping.IsSynthetic && !ctx.MapperConfiguration.UseDeepCloning)
return new SourceObjectMethodMapping(ctx.Source, ctx.Target, ToArrayMethodName);
Expand All @@ -115,23 +115,23 @@ public static class MemoryMappingBuilder
: new CastMapping(ctx.Source, ctx.Target, arrayMapping);
}

private static TypeMapping? BuildMemoryToArrayMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildMemoryToArrayMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (!elementMapping.IsSynthetic || ctx.MapperConfiguration.UseDeepCloning)
return BuildSpanToArrayMethodMapping(ctx, elementMapping);

return new SourceObjectMethodMapping(ctx.Source, ctx.Target, ToArrayMethodName);
}

private static TypeMapping? BuildMemoryToSpanMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildMemoryToSpanMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (!elementMapping.IsSynthetic || ctx.MapperConfiguration.UseDeepCloning)
return BuildMemoryToSpanMethod(ctx, elementMapping);

return new SourceObjectMemberMapping(ctx.Source, ctx.Target, SpanMemberName);
}

private static TypeMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (!elementMapping.IsSynthetic || ctx.MapperConfiguration.UseDeepCloning)
return new ArrayForMapping(
Expand All @@ -144,7 +144,7 @@ private static TypeMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx,
return new CastMapping(ctx.Source, ctx.Target);
}

private static TypeMapping? BuildMemoryToSpanMethod(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildMemoryToSpanMethod(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
var sourceSpan = ctx.Types.Get(typeof(ReadOnlySpan<>)).Construct(elementMapping.SourceType);
if (ctx.FindOrBuildMapping(sourceSpan, ctx.Target) is not { } spanMapping)
Expand All @@ -153,15 +153,15 @@ private static TypeMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx,
return new SourceObjectMemberMapping(ctx.Source, ctx.Target, SpanMemberName, spanMapping);
}

private static TypeMapping? BuildMemoryToMemoryMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildMemoryToMemoryMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
if (!elementMapping.IsSynthetic || ctx.MapperConfiguration.UseDeepCloning)
return BuildSpanToArrayMethodMapping(ctx, elementMapping);

return new CastMapping(ctx.Source, ctx.Target);
}

private static TypeMapping? BuildMemoryToEnumerableMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildMemoryToEnumerableMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
var sourceSpan = ctx.Types.Get(typeof(ReadOnlySpan<>)).Construct(elementMapping.SourceType);
if (ctx.FindOrBuildMapping(sourceSpan, ctx.Target) is not { } enumerableMapping)
Expand All @@ -170,7 +170,7 @@ private static TypeMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx,
return new SourceObjectMemberMapping(ctx.Source, ctx.Target, SpanMemberName, enumerableMapping);
}

private static TypeMapping? BuildEnumerableToMemoryMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildEnumerableToMemoryMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
var targetArray = ctx.Types.GetArrayType(elementMapping.TargetType);
if (ctx.FindOrBuildMapping(ctx.Source, targetArray.NonNullable()) is not { } arrayMapping)
Expand All @@ -179,7 +179,7 @@ private static TypeMapping BuildArrayToMemoryMapping(MappingBuilderContext ctx,
return new DelegateMapping(ctx.Source, ctx.Target, arrayMapping);
}

private static TypeMapping? BuildSpanToArrayMethodMapping(MappingBuilderContext ctx, ITypeMapping elementMapping)
private static NewInstanceMapping? BuildSpanToArrayMethodMapping(MappingBuilderContext ctx, INewInstanceMapping elementMapping)
{
var sourceSpan = ctx.Types.Get(typeof(ReadOnlySpan<>)).Construct(elementMapping.SourceType);
var targetArray = ctx.Types.GetArrayType(elementMapping.TargetType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Riok.Mapperly.Descriptors.MappingBuilders;

public static class NewInstanceObjectPropertyMappingBuilder
{
public static TypeMapping? TryBuildMapping(MappingBuilderContext ctx)
public static NewInstanceMapping? TryBuildMapping(MappingBuilderContext ctx)
{
if (ctx.Target.SpecialType != SpecialType.None || ctx.Source.SpecialType != SpecialType.None)
return null;
Expand Down
Loading

0 comments on commit 911f838

Please sign in to comment.