Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add fully qualified Names for method parameters, return types, new constructor call and generic types #318

Merged
merged 22 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7cb51b8
fix: closes #298
ismaeel-ch Apr 9, 2023
d0b9158
add fully qualified Names for method return types, new constructor ca…
ismaeel-ch Apr 11, 2023
10e7dc6
Merge branch 'main' into fix-colliding-namespaces
ismaeel-ch Apr 11, 2023
cc2a371
resolve integration test issue and change fully qualified name extens…
ismaeel-ch Apr 12, 2023
a25162e
Merge branch 'main' into fix-colliding-namespaces
ismaeel-ch Apr 12, 2023
8788150
Fix integration testing issue closes #298
ismaeel-ch Apr 12, 2023
9e996ec
Remove Null check #298
ismaeel-ch Apr 12, 2023
c7c030c
chnage FullyQualifiedNonNullableIdentifier(t) =>FullyQualifiedIdentif…
ismaeel-ch Apr 12, 2023
0c04028
Update other framework integration issue
ismaeel-ch Apr 12, 2023
94f4002
Fix spacing issue in snapshots
ismaeel-ch Apr 12, 2023
c166286
add remaing global alias in ProjectionMapper
ismaeel-ch Apr 12, 2023
b984e54
Fix spacing issue in StaticTestMapper
ismaeel-ch Apr 12, 2023
20d0be4
FIx spacing issue
ismaeel-ch Apr 12, 2023
4903029
fix global alias issue in ProjectionMapper
ismaeel-ch Apr 12, 2023
160eab0
Fix spacing issue in StaticTestMapper
ismaeel-ch Apr 13, 2023
b46ce8a
Fix spacing issue in MapperTest class
ismaeel-ch Apr 13, 2023
ea411a4
fix: spacing issue in MapperTest class
ismaeel-ch Apr 13, 2023
93ab2d7
Merge branch 'fix-colliding-namespaces' of https://github.com/chIsmae…
ismaeel-ch Apr 13, 2023
5c4d8d3
fix: format, lint issues and update integration test version
ismaeel-ch Apr 13, 2023
28a1198
Fix some spaces issues
ismaeel-ch Apr 13, 2023
da1e6e6
Fix lint issue in arrayclonemapping
ismaeel-ch Apr 13, 2023
4c3a9e4
fix lint issue in SyntaxFactoryHelper
ismaeel-ch Apr 13, 2023
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
3 changes: 2 additions & 1 deletion src/Riok.Mapperly/Descriptors/Mappings/ArrayCloneMapping.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 @@ -22,7 +23,7 @@ public ArrayCloneMapping(
public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
return CastExpression(
IdentifierName(TargetType.ToDisplayString()),
TargetType.GetFullyQualifiedTypeSyntax(),
InvocationExpression(MemberAccess(ctx.Source, CloneMethodName)));
}
}
3 changes: 2 additions & 1 deletion src/Riok.Mapperly/Descriptors/Mappings/ArrayForMapping.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 @@ -32,7 +33,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(IdentifierName(_targetArrayElementType.ToDisplayString()))
ArrayType(_targetArrayElementType.GetFullyQualifiedTypeSyntax())
.WithRankSpecifiers(SingletonList(sourceLengthArrayRank)));
yield return DeclareLocalVariable(targetVariableName, targetInitializationValue);

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

namespace Riok.Mapperly.Descriptors.Mappings;
Expand All @@ -22,6 +23,6 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
var objToCast = _delegateMapping != null
? _delegateMapping.Build(ctx)
: ctx.Source;
return CastExpression(IdentifierName(TargetType.ToDisplayString()), objToCast);
return CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), objToCast);
}
}
4 changes: 2 additions & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/CtorMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public CtorMapping(ITypeSymbol sourceType, ITypeSymbol targetType)

public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
{
var type = IdentifierName(TargetType.NonNullable().ToDisplayString());
return ObjectCreationExpression(type).WithArgumentList(ArgumentList(ctx.Source));
return ObjectCreationExpression(TargetType.GetFullyQualifiedTypeSyntax()).WithArgumentList(ArgumentList(ctx.Source));

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 @@ -38,15 +39,15 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx)
return GenericInvocation(
EnumClassName,
ParseMethodName,
new[] { IdentifierName(TargetType.ToDisplayString()) },
new[] { TargetType.GetFullyQualifiedTypeSyntax() },
ctx.Source,
BooleanLiteral(_ignoreCase));
}

// (TargetType)System.Enum.Parse(typeof(TargetType), source, ignoreCase)
var enumParseInvocation = Invocation(
MemberAccess(EnumClassName, ParseMethodName),
TypeOfExpression(IdentifierName(TargetType.ToDisplayString())), ctx.Source, BooleanLiteral(_ignoreCase));
return CastExpression(IdentifierName(TargetType.ToDisplayString()), enumParseInvocation);
TypeOfExpression(TargetType.GetFullyQualifiedTypeSyntax()), ctx.Source, BooleanLiteral(_ignoreCase));
return CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), enumParseInvocation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private SwitchExpressionArmSyntax BuildArmIgnoreCase(string ignoreCaseSwitchDesi

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

// when s.Equals(nameof(source.Value1), StringComparison.OrdinalIgnoreCase)
Expand All @@ -87,7 +87,7 @@ private SwitchExpressionArmSyntax BuildArm(IFieldSymbol field)
{
// nameof(source.Value1) => source.Value1;
var typeMemberAccess = MemberAccess(
IdentifierName(field.ContainingType.NonNullable().ToDisplayString()),
IdentifierName(field.ContainingType.NonNullable().GetFullyQualifiedIdentifierName()),
field.Name);
var pattern = ConstantPattern(NameOf(typeMemberAccess));
return SwitchExpressionArm(pattern, typeMemberAccess);
Expand Down
5 changes: 3 additions & 2 deletions src/Riok.Mapperly/Descriptors/Mappings/EnumNameMapping.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 @@ -44,8 +45,8 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c

private SwitchExpressionArmSyntax BuildArm(KeyValuePair<string, string> sourceTargetField)
{
var sourceMember = MemberAccess(SourceType.ToDisplayString(), sourceTargetField.Key);
var targetMember = MemberAccess(TargetType.ToDisplayString(), sourceTargetField.Value);
var sourceMember = MemberAccess(SourceType.GetFullyQualifiedIdentifierName(), sourceTargetField.Key);
var targetMember = MemberAccess(TargetType.GetFullyQualifiedIdentifierName(), sourceTargetField.Value);
var pattern = ConstantPattern(sourceMember);
return SwitchExpressionArm(pattern, targetMember);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public override IEnumerable<StatementSyntax> BuildBody(TypeMappingBuildContext c
private SwitchExpressionArmSyntax BuildArm(IFieldSymbol field)
{
var typeMemberAccess = MemberAccess(
IdentifierName(field.ContainingType.NonNullable().ToDisplayString()),
IdentifierName(field.ContainingType.NonNullable().GetFullyQualifiedIdentifierName()),
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))
: IdentifierName(TargetType.ToDisplayString());
: TargetType.GetFullyQualifiedTypeSyntax();

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(IdentifierName(TargetType.ToDisplayString()), _delegateMapping.Build(ctx))
? CastExpression(TargetType.GetFullyQualifiedTypeSyntax(), _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(IdentifierName(Method.ReceiverType!.ToDisplayString()), ThisExpression());
var castedThis = CastExpression(Method.ReceiverType!.GetFullyQualifiedTypeSyntax(), 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,6 +2,7 @@
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 @@ -18,7 +19,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(IdentifierName(mapping.SourceType.ToDisplayString()), IdentifierName(mapping.TargetType.ToDisplayString())));
.WithTypeArgumentList(TypeArgumentList(mapping.SourceType.GetFullyQualifiedTypeSyntax(), mapping.TargetType.GetFullyQualifiedTypeSyntax()));
var method = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, refHandler, methodName);

// out var target
Expand Down Expand Up @@ -46,7 +47,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(IdentifierName(mapping.SourceType.ToDisplayString()), IdentifierName(mapping.TargetType.ToDisplayString())));
.WithTypeArgumentList(TypeArgumentList(mapping.SourceType.GetFullyQualifiedTypeSyntax(), (mapping.TargetType.GetFullyQualifiedTypeSyntax())));
var method = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, refHandler, methodName);

return Invocation(method, ctx.Source, target);
Expand Down
8 changes: 5 additions & 3 deletions src/Riok.Mapperly/Emit/SyntaxFactoryHelper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

using Riok.Mapperly.Descriptors.Mappings;
using Riok.Mapperly.Helpers;
using Riok.Mapperly.Symbols;

using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace Riok.Mapperly.Emit;
Expand Down Expand Up @@ -215,7 +217,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(IdentifierName(parameter.Type.ToDisplayString()));
.WithType(parameter.Type.GetFullyQualifiedTypeSyntax());

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

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

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

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

private static IEnumerable<SyntaxNodeOrToken> JoinByComma(IEnumerable<SyntaxNode> nodes, bool insertTrailingComma = false)
=> Join(Token(SyntaxKind.CommaToken), insertTrailingComma, nodes);
Expand Down
60 changes: 60 additions & 0 deletions src/Riok.Mapperly/Helpers/SymbolExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Diagnostics.CodeAnalysis;

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

namespace Riok.Mapperly.Helpers;

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

return true;
}

internal static TypeSyntax GetFullyQualifiedTypeSyntax(this ITypeSymbol typeSymbol)
ismaeel-ch marked this conversation as resolved.
Show resolved Hide resolved
ismaeel-ch marked this conversation as resolved.
Show resolved Hide resolved
{
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;
}
}
Loading