Skip to content

Commit

Permalink
resolve integration test issue and change fully qualified name extens…
Browse files Browse the repository at this point in the history
…ion method to static closes riok#298
  • Loading branch information
ismaeel-ch committed Apr 12, 2023
1 parent 10e7dc6 commit cc2a371
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 250 deletions.
3 changes: 1 addition & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/ArrayCloneMapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand All @@ -23,7 +22,7 @@ public ArrayCloneMapping(
public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
return CastExpression(
TargetType.GetFullyQualifiedTypeSyntax(),
FullyQualifiedIdentifier(TargetType),
InvocationExpression(MemberAccess(ctx.Source, CloneMethodName)));
}
}
3 changes: 1 addition & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/ArrayForMapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand Down Expand Up @@ -33,7 +32,7 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c
// var target = new T[source.Length];
var sourceLengthArrayRank = ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>(MemberAccess(ctx.Source, ArrayLengthProperty)));
var targetInitializationValue = ArrayCreationExpression(
ArrayType(_targetArrayElementType.GetFullyQualifiedTypeSyntax())
ArrayType(FullyQualifiedIdentifier(_targetArrayElementType))
.WithRankSpecifiers(SingletonList(sourceLengthArrayRank)));
yield return DeclareLocalVariable(targetVariableName, targetInitializationValue);

Expand Down
5 changes: 3 additions & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/CastMapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;

using Riok.Mapperly.Emit;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace Riok.Mapperly.Descriptors.Mappings;
Expand All @@ -23,6 +24,6 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
var objToCast = _delegateMapping != null
? _delegateMapping.Build(ctx)
: ctx.Source;
return CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), objToCast);
return CastExpression(SyntaxFactoryHelper.FullyQualifiedIdentifier(TargetType), objToCast);
}
}
3 changes: 1 addition & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/CtorMapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand All @@ -18,7 +17,7 @@ public CtorMapping(ITypeSymbol sourceType, ITypeSymbol targetType)

public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
return ObjectCreationExpression(TargetType.GetFullyQualifiedTypeSyntax()).WithArgumentList(ArgumentList(ctx.Source));
return ObjectCreationExpression(FullyQualifiedIdentifier(TargetType)).WithArgumentList(ArgumentList(ctx.Source));

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand Down Expand Up @@ -39,15 +38,15 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
return GenericInvocation(
EnumClassName,
ParseMethodName,
new[] { TargetType.GetFullyQualifiedTypeSyntax() },
new[] { FullyQualifiedIdentifier(TargetType) },
ctx.Source,
BooleanLiteral(_ignoreCase));
}

// (TargetType)System.Enum.Parse(typeof(TargetType), source, ignoreCase)
var enumParseInvocation = Invocation(
MemberAccess(EnumClassName, ParseMethodName),
TypeOfExpression(TargetType.GetFullyQualifiedTypeSyntax()), ctx.Source, BooleanLiteral(_ignoreCase));
return CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), enumParseInvocation);
TypeOfExpression(FullyQualifiedIdentifier(TargetType)), ctx.Source, BooleanLiteral(_ignoreCase));
return CastExpression(FullyQualifiedIdentifier(TargetType), enumParseInvocation);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand Down Expand Up @@ -68,7 +67,7 @@ private SwitchExpressionArmSyntax BuildArmIgnoreCase(string ignoreCaseSwitchDesi

// source.Value1
var typeMemberAccess = MemberAccess(
IdentifierName(field.ContainingType.WithNullableAnnotation(NullableAnnotation.None).GetFullyQualifiedIdentifierName()),
FullyQualifiedNonNullableIdentifier(field.ContainingType),
field.Name);

// when s.Equals(nameof(source.Value1), StringComparison.OrdinalIgnoreCase)
Expand All @@ -87,7 +86,7 @@ private SwitchExpressionArmSyntax BuildArm(IFieldSymbol field)
{
// nameof(source.Value1) => source.Value1;
var typeMemberAccess = MemberAccess(
IdentifierName(field.ContainingType.NonNullable().GetFullyQualifiedIdentifierName()),
FullyQualifiedIdentifier(field.ContainingType),
field.Name);
var pattern = ConstantPattern(NameOf(typeMemberAccess));
return SwitchExpressionArm(pattern, typeMemberAccess);
Expand Down
5 changes: 2 additions & 3 deletions src/Riok.Mapperly/Descriptors/Mappings/EnumNameMapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand Down Expand Up @@ -45,8 +44,8 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c

private SwitchExpressionArmSyntax BuildArm(KeyValuePair<string, string> sourceTargetField)
{
var sourceMember = MemberAccess(SourceType.GetFullyQualifiedIdentifierName(), sourceTargetField.Key);
var targetMember = MemberAccess(TargetType.GetFullyQualifiedIdentifierName(), sourceTargetField.Value);
var sourceMember = MemberAccess(FullyQualifiedIdentifier(SourceType), sourceTargetField.Key);
var targetMember = MemberAccess(FullyQualifiedIdentifier(TargetType), sourceTargetField.Value);
var pattern = ConstantPattern(sourceMember);
return SwitchExpressionArm(pattern, targetMember);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand Down Expand Up @@ -48,7 +47,7 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c
private SwitchExpressionArmSyntax BuildArm(IFieldSymbol field)
{
var typeMemberAccess = MemberAccess(
IdentifierName(field.ContainingType.NonNullable().GetFullyQualifiedIdentifierName()),
FullyQualifiedNonNullableIdentifier(field.ContainingType),
field.Name);
var pattern = ConstantPattern(typeMemberAccess);
var nameOf = NameOf(typeMemberAccess);
Expand Down
2 changes: 1 addition & 1 deletion src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public MethodDeclarationSyntax BuildMethod(SourceEmitterContext ctx)
{
TypeSyntax returnType = ReturnType == null
? PredefinedType(Token(SyntaxKind.VoidKeyword))
: TargetType.GetFullyQualifiedTypeSyntax();
: FullyQualifiedIdentifier(TargetType);

var typeMappingBuildContext = new TypeMappingBuildContext(
SourceParameter.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
// if the target type is a nullable value type, there needs to be an additional cast in some cases
// (eg. in a linq expression, int => int?)
return TargetType.IsNullableValueType()
? CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), _delegateMapping.Build(ctx))
? CastExpression(FullyQualifiedIdentifier(TargetType), _delegateMapping.Build(ctx))
: _delegateMapping.Build(ctx);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
if (Method.ReceiverType?.TypeKind != TypeKind.Interface)
return Invocation(Method.Name, _sourceParameter.WithArgument(ctx.Source), _referenceHandlerParameter?.WithArgument(ctx.ReferenceHandler));

var castedThis = CastExpression(Method.ReceiverType!.GetFullyQualifiedTypeSyntax(), ThisExpression());
var castedThis = CastExpression(FullyQualifiedIdentifier(Method.ReceiverType!), ThisExpression());
var method = MemberAccess(ParenthesizedExpression(castedThis), Method.Name);
return Invocation(method, _sourceParameter.WithArgument(ctx.Source), _referenceHandlerParameter?.WithArgument(ctx.ReferenceHandler));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Riok.Mapperly.Abstractions.ReferenceHandling;
using Riok.Mapperly.Descriptors.Mappings;
using Riok.Mapperly.Helpers;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Riok.Mapperly.Emit.SyntaxFactoryHelper;

Expand All @@ -19,7 +18,7 @@ public static IfStatementSyntax TryGetReference(
// GetReference<TSource, TTarget>
var refHandler = ctx.ReferenceHandler ?? throw new ArgumentNullException(nameof(ctx.ReferenceHandler));
var methodName = GenericName(Identifier(nameof(IReferenceHandler.TryGetReference)))
.WithTypeArgumentList(TypeArgumentList(mapping.SourceType.GetFullyQualifiedTypeSyntax(), mapping.TargetType.GetFullyQualifiedTypeSyntax()));
.WithTypeArgumentList(TypeArgumentList(FullyQualifiedIdentifier(mapping.SourceType), FullyQualifiedIdentifier(mapping.TargetType)));
var method = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, refHandler, methodName);

// out var target
Expand Down Expand Up @@ -47,7 +46,7 @@ public static ExpressionSyntax SetReference(
// SetReference<TSource, TTarget>
var refHandler = ctx.ReferenceHandler ?? throw new ArgumentNullException(nameof(ctx.ReferenceHandler));
var methodName = GenericName(Identifier(nameof(IReferenceHandler.SetReference)))
.WithTypeArgumentList(TypeArgumentList(mapping.SourceType.GetFullyQualifiedTypeSyntax(), (mapping.TargetType.GetFullyQualifiedTypeSyntax())));
.WithTypeArgumentList(TypeArgumentList(FullyQualifiedIdentifier(mapping.SourceType), (FullyQualifiedIdentifier(mapping.TargetType))));
var method = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, refHandler, methodName);

return Invocation(method, ctx.Source, target);
Expand Down
37 changes: 33 additions & 4 deletions src/Riok.Mapperly/Emit/SyntaxFactoryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public static class SyntaxFactoryHelper
private const string NullReferenceExceptionClassName = "System.NullReferenceException";

public static readonly IdentifierNameSyntax VarIdentifier = IdentifierName("var");

private static readonly SymbolDisplayFormat _fullyQualifiedNullableFormat = SymbolDisplayFormat.FullyQualifiedFormat.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
private static readonly SymbolDisplayFormat _fullyQualifiedNonNullableFormat = SymbolDisplayFormat.FullyQualifiedFormat.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
private static readonly IdentifierNameSyntax _nameofIdentifier = IdentifierName("nameof");

public static SyntaxToken Accessibility(Accessibility accessibility)
Expand Down Expand Up @@ -217,7 +218,7 @@ public static ParameterListSyntax ParameterList(bool extensionMethod, params Met
public static ParameterSyntax Parameter(bool addThisKeyword, MethodParameter parameter)
{
var param = SyntaxFactory.Parameter(Identifier(parameter.Name))
.WithType(parameter.Type.GetFullyQualifiedTypeSyntax());
.WithType(FullyQualifiedIdentifier(parameter.Type));

if (addThisKeyword && parameter.Ordinal == 0)
{
Expand All @@ -236,7 +237,7 @@ public static InvocationExpressionSyntax StaticInvocation(string receiverType, s

public static InvocationExpressionSyntax StaticInvocation(IMethodSymbol method, params ExpressionSyntax[] arguments)
=> StaticInvocation(
method.ReceiverType?.NonNullable().GetFullyQualifiedIdentifierName() ?? throw new ArgumentNullException(nameof(method.ReceiverType)),
FullyQualifiedIdentifierName(method.ReceiverType?.NonNullable()!) ?? throw new ArgumentNullException(nameof(method.ReceiverType)),
method.Name,
arguments);

Expand Down Expand Up @@ -325,7 +326,7 @@ public static SeparatedSyntaxList<T> CommaSeparatedList<T>(IEnumerable<T> nodes,
=> SeparatedList<T>(JoinByComma(nodes, insertTrailingComma));

public static IdentifierNameSyntax NonNullableIdentifier(ITypeSymbol t)
=> IdentifierName(t.NonNullable().GetFullyQualifiedIdentifierName());
=> FullyQualifiedNonNullableIdentifier(t);

private static IEnumerable<SyntaxNodeOrToken> JoinByComma(IEnumerable<SyntaxNode> nodes, bool insertTrailingComma = false)
=> Join(Token(SyntaxKind.CommaToken), insertTrailingComma, nodes);
Expand All @@ -352,4 +353,32 @@ private static IEnumerable<SyntaxNodeOrToken> Join(SyntaxToken sep, bool insertT
yield return sep;
}
}

public static IdentifierNameSyntax FullyQualifiedIdentifier(ITypeSymbol typeSymbol)
{
if (typeSymbol is null)
throw new ArgumentNullException(nameof(typeSymbol));
return IdentifierName(FullyQualifiedIdentifierName(typeSymbol));
}

public static string FullyQualifiedIdentifierName(ITypeSymbol typeSymbol)
{
if (typeSymbol is null)
throw new ArgumentNullException(nameof(typeSymbol));
return typeSymbol.ToDisplayString(_fullyQualifiedNullableFormat);
}

public static IdentifierNameSyntax FullyQualifiedNonNullableIdentifier(ITypeSymbol typeSymbol)
{
if (typeSymbol is null)
throw new ArgumentNullException(nameof(typeSymbol));
return IdentifierName(FullyQualifiedNonNullableIdentifierName(typeSymbol));
}

public static string FullyQualifiedNonNullableIdentifierName(ITypeSymbol typeSymbol)
{
if (typeSymbol is null)
throw new ArgumentNullException(nameof(typeSymbol));
return typeSymbol.ToDisplayString(_fullyQualifiedNonNullableFormat);
}
}
59 changes: 0 additions & 59 deletions src/Riok.Mapperly/Helpers/SymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Riok.Mapperly.Helpers;

Expand Down Expand Up @@ -102,62 +101,4 @@ internal static bool CanConsumeType(this ITypeParameterSymbol typeParameter, Com

return true;
}

internal static TypeSyntax GetFullyQualifiedTypeSyntax(this ITypeSymbol typeSymbol)
{
if (typeSymbol is IArrayTypeSymbol arrayTypeSymbol)
{
var arrayFullName = arrayTypeSymbol.ToDisplayString();

string arrayQualifiedName = default!;
var rr = arrayTypeSymbol.ElementType.ToString();
if (IsPrimitiveType(arrayTypeSymbol.ElementType))
arrayQualifiedName = arrayFullName;
else
arrayQualifiedName = $"global::{arrayFullName}";
var identifierSyntax = SyntaxFactory.IdentifierName(arrayQualifiedName);
return arrayTypeSymbol.NullableAnnotation == NullableAnnotation.Annotated ?
SyntaxFactory.NullableType(identifierSyntax) :
identifierSyntax;
}
var returnTypeIdentifierSyntax = SyntaxFactory.IdentifierName(typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
var isNullableType = typeSymbol.NullableAnnotation == NullableAnnotation.Annotated;
if (isNullableType)
{
if (typeSymbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.ToDisplayString() == "System.Nullable<T>")
{
return returnTypeIdentifierSyntax;
}
else
return SyntaxFactory.NullableType(returnTypeIdentifierSyntax);
}
return returnTypeIdentifierSyntax;
}

internal static string GetFullyQualifiedIdentifierName(this ITypeSymbol typeSymbol)
{
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

}

// Method to check if a type is a primitive type
private static bool IsPrimitiveType(ITypeSymbol typeSymbol)
{
return typeSymbol.SpecialType is
SpecialType.System_Char
or SpecialType.System_SByte
or SpecialType.System_Single
or SpecialType.System_String
or SpecialType.System_Boolean
or SpecialType.System_UInt16
or SpecialType.System_UInt32
or SpecialType.System_UInt64
or SpecialType.System_UInt32
or SpecialType.System_UIntPtr
or SpecialType.System_Int32
or SpecialType.System_Int64
or SpecialType.System_IntPtr
or SpecialType.System_Decimal
or SpecialType.System_Double;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ namespace Riok.Mapperly.IntegrationTests.Mapper
{
public static partial class CircularReferenceMapper
{
public static partial Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto ToDto(Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject obj)
public static partial global::Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto ToDto(global::Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject obj)
{
return MapToCircularReferenceDto(obj, new Riok.Mapperly.Abstractions.ReferenceHandling.Internal.PreserveReferenceHandler());
return MapToCircularReferenceDto(obj, new global::Riok.Mapperly.Abstractions.ReferenceHandling.Internal.PreserveReferenceHandler());
}

private static Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto MapToCircularReferenceDto(Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject source, Riok.Mapperly.Abstractions.ReferenceHandling.IReferenceHandler refHandler)
private static global::Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto MapToCircularReferenceDto(global::Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject source, global::Riok.Mapperly.Abstractions.ReferenceHandling.IReferenceHandler refHandler)
{
if (refHandler.TryGetReference<Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject, Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto>(source, out var existingTargetReference))
if (refHandler.TryGetReference<global::Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject, global::Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto>(source, out var existingTargetReference))
return existingTargetReference;
var target = new Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto();
refHandler.SetReference<Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject, Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto>(source, target);
var target = new global::Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto();
refHandler.SetReference<global::Riok.Mapperly.IntegrationTests.Models.CircularReferenceObject, global::Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto>(source, target);
if (source.Parent != null)
{
target.Parent = MapToCircularReferenceDto(source.Parent, refHandler);
Expand All @@ -23,4 +23,4 @@ private static Riok.Mapperly.IntegrationTests.Dto.CircularReferenceDto MapToCirc
return target;
}
}
}
}
Loading

0 comments on commit cc2a371

Please sign in to comment.