Skip to content

Commit

Permalink
feat: improve constructor mapping readability
Browse files Browse the repository at this point in the history
Co-Authored-By: latonz <[email protected]>
  • Loading branch information
aradalvand and latonz committed Aug 3, 2024
1 parent 34e08bc commit 6de94d9
Show file tree
Hide file tree
Showing 108 changed files with 1,079 additions and 497 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Descriptors.Mappings;
using Riok.Mapperly.Emit.Syntax;

namespace Riok.Mapperly.Descriptors.Constructors;

Expand All @@ -13,5 +12,5 @@ public ExpressionSyntax CreateInstance(
TypeMappingBuildContext ctx,
IEnumerable<ArgumentSyntax> args,
InitializerExpressionSyntax? initializer = null
) => SyntaxFactoryHelper.CreateInstance(type, args).WithInitializer(initializer);
) => ctx.SyntaxFactory.CreateInstance(type, args).WithInitializer(initializer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ protected static ExpressionStatementSyntax EnsureCapacityStatement(
sum = Add(sourceCount, targetCount);
}

return syntaxFactory.ExpressionStatement(Invocation(MemberAccess(target, EnsureCapacityName), sum));
return syntaxFactory.ExpressionStatement(syntaxFactory.Invocation(MemberAccess(target, EnsureCapacityName), sum));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override StatementSyntax Build(TypeMappingBuildContext ctx, ExpressionSyn
var enumerableArgument = Argument(ctx.Source);
var outVarArgument = OutVarArgument(sourceCountName);

var getNonEnumeratedInvocation = StaticInvocation(getNonEnumeratedMethod, enumerableArgument, outVarArgument);
var getNonEnumeratedInvocation = ctx.SyntaxFactory.StaticInvocation(getNonEnumeratedMethod, enumerableArgument, outVarArgument);
var ensureCapacity = EnsureCapacityStatement(
ctx.SyntaxFactory.AddIndentation(),
target,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ private SwitchSectionSyntax BuildDefaultSwitchSection(TypeMappingBuildContext ct
var defaultCaseLabel = DefaultSwitchLabel().AddLeadingLineFeed(sectionCtx.Indentation);

// throw new ArgumentException(msg, nameof(ctx.Source)),
var sourceTypeExpr = Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var targetTypeExpr = Invocation(MemberAccess(target, GetTypeMethodName));
var sourceTypeExpr = ctx.SyntaxFactory.Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var targetTypeExpr = ctx.SyntaxFactory.Invocation(MemberAccess(target, GetTypeMethodName));
var statementContext = sectionCtx.AddIndentation();
var throwExpression = ThrowArgumentExpression(
InterpolatedString($"Cannot map {sourceTypeExpr} to {targetTypeExpr} as there is no known derived type mapping"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class DerivedTypeSwitchMapping(ITypeSymbol sourceType, ITypeSymbol target
public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
// _ => throw new ArgumentException(msg, nameof(ctx.Source)),
var sourceTypeExpr = Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var sourceTypeExpr = ctx.SyntaxFactory.Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var fallbackArm = SwitchArm(
DiscardPattern(),
ThrowArgumentExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
// System.Enum.Parse<TargetType>(source, ignoreCase)
if (genericParseMethodSupported)
{
return GenericInvocation(
return ctx.SyntaxFactory.GenericInvocation(
EnumClassName,
ParseMethodName,
new[] { FullyQualifiedIdentifier(TargetType) },
Expand All @@ -32,7 +32,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
}

// (TargetType)System.Enum.Parse(typeof(TargetType), source, ignoreCase)
var enumParseInvocation = Invocation(
var enumParseInvocation = ctx.SyntaxFactory.Invocation(
MemberAccess(EnumClassName, ParseMethodName),
TypeOfExpression(FullyQualifiedIdentifier(TargetType)),
ctx.Source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private SwitchExpressionArmSyntax BuildArmIgnoreCase(string ignoreCaseSwitchDesi

// when s.Equals(nameof(source.Value1), StringComparison.OrdinalIgnoreCase)
var whenClause = SwitchWhen(
Invocation(
InvocationWithoutIndention(
MemberAccess(ignoreCaseSwitchDesignatedVariableName, StringEqualsMethodName),
NameOf(typeMemberAccess),
IdentifierName(StringComparisonFullName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class EnumToStringMapping(ITypeSymbol sourceType, ITypeSymbol targetType,
public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext ctx)
{
// fallback switch arm: _ => source.ToString()
var fallbackArm = SwitchArm(DiscardPattern(), Invocation(MemberAccess(ctx.Source, ToStringMethodName)));
var fallbackArm = SwitchArm(DiscardPattern(), ctx.SyntaxFactory.Invocation(MemberAccess(ctx.Source, ToStringMethodName)));

// switch for each name to the enum value
// eg: Enum1.Value1 => "Value1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override IEnumerable<StatementSyntax> Build(TypeMappingBuildContext ctx,
var (loopItemCtx, loopItemVariableName) = ctx.WithNewSource(LoopItemVariableName);
var convertedSourceItemExpression = elementMapping.Build(loopItemCtx);
var addMethod = MemberAccess(target, insertMethodName);
var body = Invocation(addMethod, convertedSourceItemExpression);
var body = ctx.SyntaxFactory.Invocation(addMethod, convertedSourceItemExpression);
yield return ctx.SyntaxFactory.ForEach(loopItemVariableName, ctx.Source, body);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
var (lambdaCtx, lambdaSourceName) = ctx.WithNewScopedSource();
var sourceMapExpression = elementMapping.Build(lambdaCtx);
var convertLambda = Lambda(lambdaSourceName, sourceMapExpression);
mappedSource = Invocation(selectMethod, ctx.Source, convertLambda);
mappedSource = ctx.SyntaxFactory.Invocation(selectMethod, ctx.Source, convertLambda);
}
else
{
mappedSource = elementMapping.Build(ctx);
}

return CreateInstance(TargetType, mappedSource);
return ctx.SyntaxFactory.CreateInstance(TargetType, mappedSource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
// if key and value types do not change then use a simple call
// ie: source.ToImmutableDictionary();
if (keyMapping.IsSynthetic && valueMapping.IsSynthetic)
return Invocation(collectMethod, ctx.Source);
return ctx.SyntaxFactory.Invocation(collectMethod, ctx.Source);

// create expressions mapping the key and value and then create the final expression
// ie: source.ToImmutableDictionary(x => x.Key, x => (int)x.Value);
Expand All @@ -35,6 +35,6 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
var valueMapExpression = valueMapping.Build(valueLambdaCtx);
var valueExpression = Lambda(valueLambdaParamName, valueMapExpression);

return Invocation(collectMethod, ctx.Source, keyExpression, valueExpression);
return ctx.SyntaxFactory.Invocation(collectMethod, ctx.Source, keyExpression, valueExpression);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
var (lambdaCtx, lambdaSourceName) = ctx.WithNewScopedSource();
var sourceMapExpression = elementMapping.Build(lambdaCtx);
var convertLambda = Lambda(lambdaSourceName, sourceMapExpression);
mappedSource = Invocation(selectMethod, ctx.Source, convertLambda);
mappedSource = ctx.SyntaxFactory.Invocation(selectMethod, ctx.Source, convertLambda);
}
else
{
mappedSource = elementMapping.Build(ctx);
}

return collectMethod == null ? mappedSource : Invocation(collectMethod, mappedSource);
return collectMethod == null ? mappedSource : ctx.SyntaxFactory.Invocation(collectMethod, mappedSource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public override bool Equals(object? obj)
nullConditional: false,
skipTrailingNonNullable: true
);
return new[] { ctx.SyntaxFactory.ExpressionStatement(ThrowArgumentNullException(nameofSourceAccess)) };
return [ctx.SyntaxFactory.ExpressionStatement(ThrowArgumentNullException(nameofSourceAccess))];
}

// target.A = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ namespace Riok.Mapperly.Descriptors.Mappings.MemberMappings.SourceValue;
/// </summary>
public class MethodProvidedSourceValue(string methodName) : ISourceValue
{
public ExpressionSyntax Build(TypeMappingBuildContext ctx) => Invocation(methodName);
public ExpressionSyntax Build(TypeMappingBuildContext ctx) => ctx.SyntaxFactory.Invocation(methodName);
}
6 changes: 5 additions & 1 deletion src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ ITypeSymbol targetType
public bool IsSynthetic => false;

public virtual ExpressionSyntax Build(TypeMappingBuildContext ctx) =>
Invocation(MethodName, SourceParameter.WithArgument(ctx.Source), ReferenceHandlerParameter?.WithArgument(ctx.ReferenceHandler));
ctx.SyntaxFactory.Invocation(
MethodName,
SourceParameter.WithArgument(ctx.Source),
ReferenceHandlerParameter?.WithArgument(ctx.ReferenceHandler)
);

public virtual MethodDeclarationSyntax BuildMethod(SourceEmitterContext ctx)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
// new ValueTuple<T..>(ctorArgs)
var ctorArgs = _constructorPropertyMappings.Select(x => x.BuildArgument(ctx, emitFieldName: false));
var typeArguments = TypeArgumentList(((INamedTypeSymbol)TargetType).TypeArguments.Select(NonNullableIdentifier));
return CreateGenericInstance(ValueTupleName, typeArguments, ctorArgs);
return ctx.SyntaxFactory.CreateGenericInstance(ValueTupleName, typeArguments, ctorArgs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c

var delegateMappingSyntax = delegateMapping.Build(lambdaCtx);
var projectionLambda = Lambda(lambdaSourceName, delegateMappingSyntax);
var select = StaticInvocation(QueryableReceiverName, SelectMethodName, ctx.Source, projectionLambda);
var select = ctx.SyntaxFactory.StaticInvocation(QueryableReceiverName, SelectMethodName, ctx.Source, projectionLambda);
var returnStatement = ctx.SyntaxFactory.Return(select);
return new[]
{
returnStatement
.WithLeadingTrivia(returnStatement.GetLeadingTrivia().Insert(0, ElasticCarriageReturnLineFeed).Insert(1, Nullable(false)))
.WithTrailingTrivia(returnStatement.GetTrailingTrivia().Insert(0, ElasticCarriageReturnLineFeed).Insert(1, Nullable(true)))
};
var leadingTrivia = returnStatement.GetLeadingTrivia().Insert(0, ElasticCarriageReturnLineFeed).Insert(1, Nullable(false));
var trailingTrivia = returnStatement.GetTrailingTrivia().Insert(0, ElasticCarriageReturnLineFeed).Insert(1, Nullable(true));
returnStatement = returnStatement.WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia);
return [returnStatement];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public class SourceObjectMethodMapping(
{
public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
var sourceExpression = Invocation(MemberAccess(ctx.Source, methodName), BuildArguments(ctx).WhereNotNull().ToArray());
var sourceExpression = ctx.SyntaxFactory.Invocation(
MemberAccess(ctx.Source, methodName),
BuildArguments(ctx).WhereNotNull().ToArray()
);
return delegateMapping == null ? sourceExpression : delegateMapping.Build(ctx.WithSource(sourceExpression));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ namespace Riok.Mapperly.Descriptors.Mappings;
/// </summary>
public class StaticMethodMapping(IMethodSymbol method) : NewInstanceMapping(method.Parameters.Single().Type, method.ReturnType)
{
public override ExpressionSyntax Build(TypeMappingBuildContext ctx) => StaticInvocation(method, ctx.Source);
public override ExpressionSyntax Build(TypeMappingBuildContext ctx) => ctx.SyntaxFactory.StaticInvocation(method, ctx.Source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx) =>
public IEnumerable<StatementSyntax> Build(TypeMappingBuildContext ctx, ExpressionSyntax target)
{
return ctx.SyntaxFactory.SingleStatement(
Invocation(
ctx.SyntaxFactory.Invocation(
MethodName,
SourceParameter.WithArgument(ctx.Source),
TargetParameter.WithArgument(target),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c
var targetTypeExpr = BuildTargetType();

// _ => throw new ArgumentException(msg, nameof(ctx.Source)),
var sourceType = Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var sourceType = ctx.SyntaxFactory.Invocation(MemberAccess(ctx.Source, GetTypeMethodName));
var fallbackArm = SwitchArm(
DiscardPattern(),
ThrowArgumentExpression(
Expand Down Expand Up @@ -92,7 +92,7 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c
protected virtual ExpressionSyntax? BuildSwitchArmWhenClause(ExpressionSyntax runtimeTargetType, RuntimeTargetTypeMapping mapping)
{
// targetType.IsAssignableFrom(typeof(ADto))
return Invocation(
return InvocationWithoutIndention(
MemberAccess(runtimeTargetType, IsAssignableFromMethodName),
TypeOfExpression(FullyQualifiedIdentifier(mapping.Mapping.TargetType.NonNullable()))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override IEnumerable<StatementSyntax> Build(TypeMappingBuildContext ctx,
if (Method.ReceiverType?.TypeKind != TypeKind.Interface)
{
yield return ctx.SyntaxFactory.ExpressionStatement(
Invocation(
ctx.SyntaxFactory.Invocation(
receiver == null ? IdentifierName(Method.Name) : MemberAccess(receiver, Method.Name),
sourceParameter.WithArgument(ctx.Source),
targetParameter.WithArgument(target),
Expand All @@ -49,7 +49,7 @@ public override IEnumerable<StatementSyntax> Build(TypeMappingBuildContext ctx,
);
var methodExpr = MemberAccess(ParenthesizedExpression(castedThis), Method.Name);
yield return ctx.SyntaxFactory.ExpressionStatement(
Invocation(
ctx.SyntaxFactory.Invocation(
methodExpr,
sourceParameter.WithArgument(ctx.Source),
targetParameter.WithArgument(target),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
// if the user implemented method is on an interface,
// we explicitly cast to be able to use the default interface implementation or explicit implementations
if (Method.ReceiverType?.TypeKind != TypeKind.Interface)
return Invocation(
return ctx.SyntaxFactory.Invocation(
receiver == null ? IdentifierName(Method.Name) : MemberAccess(receiver, Method.Name),
sourceParameter.WithArgument(ctx.Source),
referenceHandlerParameter?.WithArgument(ctx.ReferenceHandler)
Expand All @@ -40,7 +40,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
receiver == null ? ThisExpression() : IdentifierName(receiver)
);
var methodExpr = MemberAccess(ParenthesizedExpression(castedReceiver), Method.Name);
return Invocation(
return ctx.SyntaxFactory.Invocation(
methodExpr,
sourceParameter.WithArgument(ctx.Source),
referenceHandlerParameter?.WithArgument(ctx.ReferenceHandler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ public override bool CanCreateInstanceOfType(ITypeSymbol sourceType, ITypeSymbol
&& typeChecker.CheckTypes((Method.TypeParameters[0], sourceType));

protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITypeSymbol targetTypeToCreate, ExpressionSyntax source) =>
GenericInvocation(Method.Name, [NonNullableIdentifier(sourceType)], source);
GenericInvocationWithoutIndention(Method.Name, [NonNullableIdentifier(sourceType)], source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITyp
var typeParams = new TypeSyntax[2];
typeParams[sourceTypeParameterIndex] = NonNullableIdentifier(sourceType);
typeParams[_targetTypeParameterIndex] = NonNullableIdentifier(targetTypeToCreate);
return GenericInvocation(Method.Name, typeParams, source);
return GenericInvocationWithoutIndention(Method.Name, typeParams, source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public override bool CanCreateInstanceOfType(ITypeSymbol sourceType, ITypeSymbol
typeChecker.CheckTypes((Method.TypeParameters[0], targetTypeToCreate));

protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITypeSymbol targetTypeToCreate, ExpressionSyntax source) =>
GenericInvocation(Method.Name, new[] { NonNullableIdentifier(targetTypeToCreate) });
GenericInvocationWithoutIndention(Method.Name, [NonNullableIdentifier(targetTypeToCreate)]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ public override bool CanCreateInstanceOfType(ITypeSymbol sourceType, ITypeSymbol
&& SymbolEqualityComparer.Default.Equals(Method.Parameters[0].Type, sourceType);

protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITypeSymbol targetTypeToCreate, ExpressionSyntax source) =>
GenericInvocation(Method.Name, new[] { NonNullableIdentifier(targetTypeToCreate) }, source);
GenericInvocationWithoutIndention(Method.Name, [NonNullableIdentifier(targetTypeToCreate)], source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public override bool CanCreateInstanceOfType(ITypeSymbol sourceType, ITypeSymbol
SymbolEqualityComparer.Default.Equals(Method.ReturnType, targetTypeToCreate);

protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITypeSymbol targetTypeToCreate, ExpressionSyntax source) =>
Invocation(Method.Name, Array.Empty<ExpressionSyntax>());
InvocationWithoutIndention(Method.Name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public override bool CanCreateInstanceOfType(ITypeSymbol sourceType, ITypeSymbol
&& SymbolEqualityComparer.Default.Equals(sourceType, Method.Parameters[0].Type);

protected override ExpressionSyntax BuildCreateType(ITypeSymbol sourceType, ITypeSymbol targetTypeToCreate, ExpressionSyntax source) =>
Invocation(Method.Name, source);
InvocationWithoutIndention(Method.Name, source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public ExpressionSyntax CreateInstance(
InitializerExpressionSyntax? initializer = null
)
{
return StaticInvocation(className, methodName, args);
return ctx.SyntaxFactory.StaticInvocation(className, methodName, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ExpressionSyntax BuildAccess(ExpressionSyntax? baseAccess, bool nullCondi
throw new ArgumentNullException(nameof(baseAccess));

ExpressionSyntax method = nullConditional ? ConditionalAccess(baseAccess, methodName) : MemberAccess(baseAccess, methodName);
return Invocation(method);
return InvocationWithoutIndention(method);
}

public ExpressionSyntax BuildAssignment(ExpressionSyntax? baseAccess, ExpressionSyntax valueToAssign, bool coalesceAssignment = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ public ExpressionSyntax BuildAccess(ExpressionSyntax? baseAccess, bool nullCondi
throw new ArgumentNullException(nameof(baseAccess));

ExpressionSyntax method = nullConditional ? ConditionalAccess(baseAccess, methodName) : MemberAccess(baseAccess, methodName);
return Invocation(method);
return InvocationWithoutIndention(method);
}
}
Loading

0 comments on commit 6de94d9

Please sign in to comment.