stuff
This commit is contained in:
parent
60ccbd53ca
commit
ffc3dc7729
|
@ -18,7 +18,7 @@ namespace MapTo
|
||||||
return typeSymbol
|
return typeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IFieldSymbol>()
|
.OfType<IFieldSymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapField(sourceTypeSymbol, sourceProperties, property))
|
.Select(property => MapField(sourceTypeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -31,7 +31,7 @@ namespace MapTo
|
||||||
return typeSymbol
|
return typeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IPropertySymbol>()
|
.OfType<IPropertySymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -44,7 +44,7 @@ namespace MapTo
|
||||||
return sourceTypeSymbol
|
return sourceTypeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IFieldSymbol>()
|
.OfType<IFieldSymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapFieldSimple(typeSymbol, property))
|
.Select(property => MapFieldSimple(typeSymbol, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -57,7 +57,7 @@ namespace MapTo
|
||||||
return sourceTypeSymbol
|
return sourceTypeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IPropertySymbol>()
|
.OfType<IPropertySymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapPropertySimple(typeSymbol, property))
|
.Select(property => MapPropertySimple(typeSymbol, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace MapTo
|
||||||
Create($"{ErrorId}030", location, $"No matching properties found between '{classType.ToDisplayString()}' and '{sourceType.ToDisplayString()}' types.");
|
Create($"{ErrorId}030", location, $"No matching properties found between '{classType.ToDisplayString()}' and '{sourceType.ToDisplayString()}' types.");
|
||||||
|
|
||||||
internal static Diagnostic NoMatchingPropertyTypeFoundError(ISymbol property) =>
|
internal static Diagnostic NoMatchingPropertyTypeFoundError(ISymbol property) =>
|
||||||
Create($"{ErrorId}031", property.Locations.FirstOrDefault(), $"Cannot create a map for '{property.ToDisplayString()}' property because source and destination types are not implicitly convertible. Consider using '{MapTypeConverterAttributeSource.FullyQualifiedName}' to provide a type converter or ignore the property using '{IgnorePropertyAttributeSource.FullyQualifiedName}'.");
|
Create($"{ErrorId}031", property.Locations.FirstOrDefault(), $"Cannot create a map for '{property.ToDisplayString()}' property because source and destination types are not implicitly convertible. Consider using '{MapTypeConverterAttributeSource.FullyQualifiedName}' to provide a type converter or ignore the property using '{IgnoreMemberAttributeSource.FullyQualifiedName}'.");
|
||||||
|
|
||||||
internal static Diagnostic InvalidTypeConverterGenericTypesError(ISymbol property, IPropertySymbol sourceProperty) =>
|
internal static Diagnostic InvalidTypeConverterGenericTypesError(ISymbol property, IPropertySymbol sourceProperty) =>
|
||||||
Create($"{ErrorId}032", property.Locations.FirstOrDefault(), $"Cannot map '{property.ToDisplayString()}' property because the annotated converter does not implement '{RootNamespace}.{ITypeConverterSource.InterfaceName}<{sourceProperty.Type.ToDisplayString()}, {property.GetTypeSymbol()?.ToDisplayString()}>'.");
|
Create($"{ErrorId}032", property.Locations.FirstOrDefault(), $"Cannot map '{property.ToDisplayString()}' property because the annotated converter does not implement '{RootNamespace}.{ITypeConverterSource.InterfaceName}<{sourceProperty.Type.ToDisplayString()}, {property.GetTypeSymbol()?.ToDisplayString()}>'.");
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MapTo.Sources;
|
using MapTo.Sources;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -12,6 +13,21 @@ namespace MapTo.Extensions
|
||||||
return builder.WriteLine($"// {comment}");
|
return builder.WriteLine($"// {comment}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static SourceBuilder WriteCommentArray(this SourceBuilder builder, IEnumerable<object> enumerable, string name = "")
|
||||||
|
{
|
||||||
|
builder.WriteComment($"Printing Array: {name}");
|
||||||
|
foreach (var o in enumerable)
|
||||||
|
{
|
||||||
|
if (o != null)
|
||||||
|
{
|
||||||
|
builder.WriteComment($" {o.ToString()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteComment($"End printing Array: {name}");
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
internal static SourceBuilder WriteModelInfo(this SourceBuilder builder, MappingModel model)
|
internal static SourceBuilder WriteModelInfo(this SourceBuilder builder, MappingModel model)
|
||||||
{
|
{
|
||||||
return builder
|
return builder
|
||||||
|
@ -32,6 +48,16 @@ namespace MapTo.Extensions
|
||||||
{
|
{
|
||||||
foreach (var item in mappedProperties)
|
foreach (var item in mappedProperties)
|
||||||
{
|
{
|
||||||
|
string str = "";
|
||||||
|
|
||||||
|
if (item.NamedTypeSymbol != null)
|
||||||
|
foreach (var named in item.NamedTypeSymbol?.TypeArguments)
|
||||||
|
{
|
||||||
|
str += $"typeToString: {named.ToString()} ";
|
||||||
|
bool? containedTypeIsJsonEXtension = named?.HasAttribute(MappingContext.JsonExtensionAttributeSymbol);
|
||||||
|
str += $"typeArgumentTypeIsJsonExtensioN: {containedTypeIsJsonEXtension.ToString()}";
|
||||||
|
}
|
||||||
|
|
||||||
builder .WriteComment($" Name {item.Name}")
|
builder .WriteComment($" Name {item.Name}")
|
||||||
.WriteComment($" Type {item.Type}")
|
.WriteComment($" Type {item.Type}")
|
||||||
.WriteComment($" MappedSourcePropertyTypeName {item.MappedSourcePropertyTypeName}")
|
.WriteComment($" MappedSourcePropertyTypeName {item.MappedSourcePropertyTypeName}")
|
||||||
|
@ -41,6 +67,10 @@ namespace MapTo.Extensions
|
||||||
.WriteComment($" SourcePropertyName {item.SourcePropertyName}")
|
.WriteComment($" SourcePropertyName {item.SourcePropertyName}")
|
||||||
.WriteComment($" TypeSymbol {item.FullyQualifiedType.ToString()}")
|
.WriteComment($" TypeSymbol {item.FullyQualifiedType.ToString()}")
|
||||||
.WriteComment($" isReadOnly {item.isReadOnly.ToString()}")
|
.WriteComment($" isReadOnly {item.isReadOnly.ToString()}")
|
||||||
|
.WriteComment($" isEnumerable {item.isEnumerable.ToString()}")
|
||||||
|
.WriteComment($" INamedTypeSymbol {item.NamedTypeSymbol?.ToString()}")
|
||||||
|
.WriteComment($" INamedTypeSymbolTypeArguments {str}")
|
||||||
|
|
||||||
.WriteLine();
|
.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace MapTo.Extensions
|
namespace MapTo.Extensions
|
||||||
{
|
{
|
||||||
|
@ -23,7 +25,7 @@ namespace MapTo.Extensions
|
||||||
.WriteLine($"namespace {model.Namespace}")
|
.WriteLine($"namespace {model.Namespace}")
|
||||||
.WriteOpeningBracket();
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
if(writeDebugInfo)
|
if (writeDebugInfo)
|
||||||
builder
|
builder
|
||||||
.WriteModelInfo(model)
|
.WriteModelInfo(model)
|
||||||
.WriteLine()
|
.WriteLine()
|
||||||
|
@ -49,7 +51,9 @@ namespace MapTo.Extensions
|
||||||
// Class body
|
// Class body
|
||||||
.GeneratePublicConstructor(model);
|
.GeneratePublicConstructor(model);
|
||||||
|
|
||||||
|
if (model.IsJsonExtension) builder.WriteToJsonMethod(model);
|
||||||
if (model.IsTypeUpdatable && model.TypeProperties.GetWritableMappedProperties().Length > 0) builder.GenerateUpdateMethod(model);
|
if (model.IsTypeUpdatable && model.TypeProperties.GetWritableMappedProperties().Length > 0) builder.GenerateUpdateMethod(model);
|
||||||
|
if (model.IsTypeUpdatable && model.TypeFields.GetWritableMappedProperties().Length > 0) builder.GenerateUpdateMethod(model);
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.WriteLine()
|
.WriteLine()
|
||||||
|
@ -105,9 +109,10 @@ namespace MapTo.Extensions
|
||||||
return builder.WriteClosingBracket();
|
return builder.WriteClosingBracket();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsMappedProperty(this System.Collections.Immutable.ImmutableArray<MappedMember> properties, MappedMember property) {
|
private static bool IsMappedProperty(this System.Collections.Immutable.ImmutableArray<MappedMember> properties, MappedMember property)
|
||||||
|
{
|
||||||
|
|
||||||
foreach(var prop in properties)
|
foreach (var prop in properties)
|
||||||
{
|
{
|
||||||
if (prop.Name == property.Name) return true;
|
if (prop.Name == property.Name) return true;
|
||||||
}
|
}
|
||||||
|
@ -115,6 +120,110 @@ namespace MapTo.Extensions
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SourceBuilder WriteToJsonMethod(this SourceBuilder builder, MappingModel model)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WriteLine($"public string ToJson()")
|
||||||
|
.WriteOpeningBracket()
|
||||||
|
.WriteLine("var stringBuilder = new System.Text.StringBuilder();")
|
||||||
|
.WriteLine(GetStringBuilderAppendNoInterpolation("{"));
|
||||||
|
|
||||||
|
foreach (var property in model.TypeProperties)
|
||||||
|
{
|
||||||
|
if (!property.isEnumerable)
|
||||||
|
HandlePropertyEnumerable(builder, property);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder = WriteJsonField(builder, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var property in model.TypeFields)
|
||||||
|
{
|
||||||
|
if (!property.isEnumerable)
|
||||||
|
HandleFieldEnumerable(builder, property);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.WriteLine(GetStringBuilderAppend($"\\\"{property.Name.ToCamelCase()}\\\" : [{GetJsonArrayValue(property, ref builder)}],"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteLine(GetStringBuilderAppendNoInterpolation("}"));
|
||||||
|
builder.WriteLine("return stringBuilder.ToString();");
|
||||||
|
builder.WriteClosingBracket();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SourceBuilder WriteJsonField(SourceBuilder builder, MappedMember property)
|
||||||
|
{
|
||||||
|
builder.WriteLine(
|
||||||
|
GetStringBuilderAppend(
|
||||||
|
$"\\\"{property.Name.ToCamelCase()}\\\" : [{GetJsonArrayValue(property, ref builder)}],"));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandleEnumerable(SourceBuilder builder, MappedMember property)
|
||||||
|
{
|
||||||
|
var symbol = property.ActualSymbol as IPropertySymbol;
|
||||||
|
builder.WriteCommentArray(symbol.Parameters, nameof(symbol.Parameters));
|
||||||
|
builder.WriteCommentArray(symbol.TypeCustomModifiers, nameof(symbol.TypeCustomModifiers));
|
||||||
|
|
||||||
|
builder.WriteComment($"Is enumerable {(property.ActualSymbol as IPropertySymbol).Parameters}");
|
||||||
|
builder.WriteLine(
|
||||||
|
GetStringBuilderAppend($"\\\"{property.Name.ToCamelCase()}\\\" : {GetJsonValue(property, builder)},"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void HandleFieldEnumerable(SourceBuilder builder, MappedMember property)
|
||||||
|
{
|
||||||
|
HandleEnumerable(builder, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandlePropertyEnumerable(SourceBuilder builder, MappedMember property)
|
||||||
|
{
|
||||||
|
HandleEnumerable(builder, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetJsonArrayValue(MappedMember member, ref SourceBuilder builder)
|
||||||
|
{
|
||||||
|
if (member.isEnumerable)
|
||||||
|
{
|
||||||
|
// get underlying type (check if is a json extension)
|
||||||
|
|
||||||
|
builder.WriteLine("var arrStrBuilder = new StringBuilder();");
|
||||||
|
|
||||||
|
foreach (var named in member.NamedTypeSymbol?.TypeArguments!)
|
||||||
|
{
|
||||||
|
bool? containedTypeIsJsonEXtension = named?.HasAttribute(MappingContext.JsonExtensionAttributeSymbol);
|
||||||
|
if (!containedTypeIsJsonEXtension.HasValue) continue;
|
||||||
|
builder.WriteLine($"foreach (var v in {member.SourcePropertyName.ToString()})");
|
||||||
|
builder.WriteOpeningBracket();
|
||||||
|
builder.WriteLine("arrStrBuilder.Append(v.ToJson());");
|
||||||
|
builder.WriteLine("arrStrBuilder.Append(\", \");");
|
||||||
|
builder.WriteClosingBracket();
|
||||||
|
}
|
||||||
|
builder.WriteLine("arrStrBuilder.Remove(arrStrBuilder.Length -1, 1);");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{arrStrBuilder.ToString()}";
|
||||||
|
}
|
||||||
|
private static string GetJsonValue(MappedMember member, SourceBuilder builder)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (member.FullyQualifiedType == "string") return $"\\\"{{{member.SourcePropertyName}}}\\\"";
|
||||||
|
if (member.FullyQualifiedType is "int" or "double" or "float" or "long") return $"{{{member.SourcePropertyName}}}";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetStringBuilderAppend(string stringToAppend)
|
||||||
|
{
|
||||||
|
return $"stringBuilder.Append($\"{stringToAppend}\");";
|
||||||
|
}
|
||||||
|
private static string GetStringBuilderAppendNoInterpolation(string stringToAppend)
|
||||||
|
{
|
||||||
|
return $"stringBuilder.Append(\"{stringToAppend}\");";
|
||||||
|
}
|
||||||
|
|
||||||
private static SourceBuilder WriteAssignmentMethod(this SourceBuilder builder, MappingModel model, System.Collections.Immutable.ImmutableArray<MappedMember>? otherProperties,
|
private static SourceBuilder WriteAssignmentMethod(this SourceBuilder builder, MappingModel model, System.Collections.Immutable.ImmutableArray<MappedMember>? otherProperties,
|
||||||
string? sourceClassParameterName, string mappingContextParameterName, bool fromUpdate)
|
string? sourceClassParameterName, string mappingContextParameterName, bool fromUpdate)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +232,7 @@ namespace MapTo.Extensions
|
||||||
{
|
{
|
||||||
if (property.isReadOnly && fromUpdate) continue;
|
if (property.isReadOnly && fromUpdate) continue;
|
||||||
|
|
||||||
builder.WriteLine( $"{property.Name} = {sourceClassParameterName}.{property.SourcePropertyName};");
|
builder.WriteLine($"{property.Name} = {sourceClassParameterName}.{property.SourcePropertyName};");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,5 +287,17 @@ namespace MapTo.Extensions
|
||||||
.WriteLine("/// </summary>")
|
.WriteLine("/// </summary>")
|
||||||
.WriteLine($"/// <param name=\"{sourceClassParameterName}\">The instance of <see cref=\"{model.SourceType}\"/> to use as source.</param>");
|
.WriteLine($"/// <param name=\"{sourceClassParameterName}\">The instance of <see cref=\"{model.SourceType}\"/> to use as source.</param>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SourceBuilder GenerateEnumerableJsonSourceTypeExtensionMethod(this SourceBuilder builder, MappingModel model)
|
||||||
|
{
|
||||||
|
var sourceClassParameterName = model.SourceTypeIdentifierName.ToCamelCase();
|
||||||
|
|
||||||
|
return builder
|
||||||
|
.WriteLineIf(model.Options.SupportNullableStaticAnalysis, $"[return: NotNullIfNotNull(\"{sourceClassParameterName}\")]")
|
||||||
|
.WriteLine($"{model.Options.GeneratedMethodsAccessModifier.ToLowercaseString()} static string ToJson(this IEnumerable<{model.SourceType}{model.Options.NullableReferenceSyntax}> {sourceClassParameterName}List)")
|
||||||
|
.WriteOpeningBracket()
|
||||||
|
.WriteLine($"return {sourceClassParameterName} == null ? null : new {model.TypeIdentifierName}({sourceClassParameterName});")
|
||||||
|
.WriteClosingBracket();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,9 @@ namespace MapTo
|
||||||
|
|
||||||
var compilation = context.Compilation
|
var compilation = context.Compilation
|
||||||
.AddSource(ref context, UseUpdateAttributeSource.Generate(options))
|
.AddSource(ref context, UseUpdateAttributeSource.Generate(options))
|
||||||
|
.AddSource(ref context, JsonExtensionAttributeSource.Generate(options))
|
||||||
.AddSource(ref context, MapFromAttributeSource.Generate(options))
|
.AddSource(ref context, MapFromAttributeSource.Generate(options))
|
||||||
.AddSource(ref context, IgnorePropertyAttributeSource.Generate(options))
|
.AddSource(ref context, IgnoreMemberAttributeSource.Generate(options))
|
||||||
.AddSource(ref context, ITypeConverterSource.Generate(options))
|
.AddSource(ref context, ITypeConverterSource.Generate(options))
|
||||||
.AddSource(ref context, MapTypeConverterAttributeSource.Generate(options))
|
.AddSource(ref context, MapTypeConverterAttributeSource.Generate(options))
|
||||||
.AddSource(ref context, MapPropertyAttributeSource.Generate(options))
|
.AddSource(ref context, MapPropertyAttributeSource.Generate(options))
|
||||||
|
|
|
@ -28,12 +28,13 @@ namespace MapTo
|
||||||
TypeSyntax = typeSyntax;
|
TypeSyntax = typeSyntax;
|
||||||
Compilation = compilation;
|
Compilation = compilation;
|
||||||
|
|
||||||
IgnorePropertyAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(IgnorePropertyAttributeSource.FullyQualifiedName);
|
IgnoreMemberAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(IgnoreMemberAttributeSource.FullyQualifiedName);
|
||||||
MapTypeConverterAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapTypeConverterAttributeSource.FullyQualifiedName);
|
MapTypeConverterAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapTypeConverterAttributeSource.FullyQualifiedName);
|
||||||
TypeConverterInterfaceTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(ITypeConverterSource.FullyQualifiedName);
|
TypeConverterInterfaceTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(ITypeConverterSource.FullyQualifiedName);
|
||||||
MapPropertyAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapPropertyAttributeSource.FullyQualifiedName);
|
MapPropertyAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapPropertyAttributeSource.FullyQualifiedName);
|
||||||
MapFromAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapFromAttributeSource.FullyQualifiedName);
|
MapFromAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MapFromAttributeSource.FullyQualifiedName);
|
||||||
UseUpdateAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(UseUpdateAttributeSource.FullyQualifiedName);
|
UseUpdateAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(UseUpdateAttributeSource.FullyQualifiedName);
|
||||||
|
JsonExtensionAttributeSymbol = compilation.GetTypeByMetadataNameOrThrow(JsonExtensionAttributeSource.FullyQualifiedName);
|
||||||
MappingContextTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MappingContextSource.FullyQualifiedName);
|
MappingContextTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MappingContextSource.FullyQualifiedName);
|
||||||
|
|
||||||
AddUsingIfRequired(sourceGenerationOptions.SupportNullableStaticAnalysis, "System.Diagnostics.CodeAnalysis");
|
AddUsingIfRequired(sourceGenerationOptions.SupportNullableStaticAnalysis, "System.Diagnostics.CodeAnalysis");
|
||||||
|
@ -45,12 +46,14 @@ namespace MapTo
|
||||||
|
|
||||||
protected Compilation Compilation { get; }
|
protected Compilation Compilation { get; }
|
||||||
|
|
||||||
protected INamedTypeSymbol IgnorePropertyAttributeTypeSymbol { get; }
|
protected INamedTypeSymbol IgnoreMemberAttributeTypeSymbol { get; }
|
||||||
|
|
||||||
protected INamedTypeSymbol MapFromAttributeTypeSymbol { get; }
|
protected INamedTypeSymbol MapFromAttributeTypeSymbol { get; }
|
||||||
|
|
||||||
protected INamedTypeSymbol UseUpdateAttributeTypeSymbol { get; }
|
protected INamedTypeSymbol UseUpdateAttributeTypeSymbol { get; }
|
||||||
|
|
||||||
|
public static INamedTypeSymbol JsonExtensionAttributeSymbol { get; set; }
|
||||||
|
|
||||||
protected INamedTypeSymbol MappingContextTypeSymbol { get; }
|
protected INamedTypeSymbol MappingContextTypeSymbol { get; }
|
||||||
|
|
||||||
protected INamedTypeSymbol MapPropertyAttributeTypeSymbol { get; }
|
protected INamedTypeSymbol MapPropertyAttributeTypeSymbol { get; }
|
||||||
|
@ -158,7 +161,10 @@ namespace MapTo
|
||||||
{
|
{
|
||||||
return TypeSyntax.GetAttribute("UseUpdate") != null;
|
return TypeSyntax.GetAttribute("UseUpdate") != null;
|
||||||
}
|
}
|
||||||
|
protected bool HasJsonExtension()
|
||||||
|
{
|
||||||
|
return TypeSyntax.GetAttribute("JsonExtension") != null;
|
||||||
|
}
|
||||||
protected virtual MappedMember? MapProperty(ISymbol sourceTypeSymbol, IReadOnlyCollection<IPropertySymbol> sourceProperties, ISymbol property)
|
protected virtual MappedMember? MapProperty(ISymbol sourceTypeSymbol, IReadOnlyCollection<IPropertySymbol> sourceProperties, ISymbol property)
|
||||||
{
|
{
|
||||||
var sourceProperty = FindSourceProperty(sourceProperties, property);
|
var sourceProperty = FindSourceProperty(sourceProperties, property);
|
||||||
|
@ -186,6 +192,9 @@ namespace MapTo
|
||||||
AddUsingIfRequired(enumerableTypeArgumentType);
|
AddUsingIfRequired(enumerableTypeArgumentType);
|
||||||
AddUsingIfRequired(mappedSourcePropertyType);
|
AddUsingIfRequired(mappedSourcePropertyType);
|
||||||
|
|
||||||
|
INamedTypeSymbol? namedType;
|
||||||
|
var isEnumerable = IsEnumerable(property, out namedType);
|
||||||
|
|
||||||
|
|
||||||
return new MappedMember(
|
return new MappedMember(
|
||||||
property.Name,
|
property.Name,
|
||||||
|
@ -196,6 +205,9 @@ namespace MapTo
|
||||||
sourceProperty.Name,
|
sourceProperty.Name,
|
||||||
ToQualifiedDisplayName(mappedSourcePropertyType),
|
ToQualifiedDisplayName(mappedSourcePropertyType),
|
||||||
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
||||||
|
property,
|
||||||
|
namedType,
|
||||||
|
isEnumerable,
|
||||||
(property as IPropertySymbol).IsReadOnly);
|
(property as IPropertySymbol).IsReadOnly);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -232,6 +244,9 @@ namespace MapTo
|
||||||
AddUsingIfRequired(mappedSourcePropertyType);
|
AddUsingIfRequired(mappedSourcePropertyType);
|
||||||
|
|
||||||
|
|
||||||
|
INamedTypeSymbol? namedType;
|
||||||
|
var isEnumerable = IsEnumerable(property, out namedType);
|
||||||
|
|
||||||
return new MappedMember(
|
return new MappedMember(
|
||||||
property.Name,
|
property.Name,
|
||||||
property.GetTypeSymbol().ToString(),
|
property.GetTypeSymbol().ToString(),
|
||||||
|
@ -241,6 +256,9 @@ namespace MapTo
|
||||||
sourceProperty.Name,
|
sourceProperty.Name,
|
||||||
ToQualifiedDisplayName(mappedSourcePropertyType),
|
ToQualifiedDisplayName(mappedSourcePropertyType),
|
||||||
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
||||||
|
property,
|
||||||
|
namedType,
|
||||||
|
isEnumerable,
|
||||||
(property as IFieldSymbol).IsReadOnly);
|
(property as IFieldSymbol).IsReadOnly);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -262,6 +280,8 @@ namespace MapTo
|
||||||
AddUsingIfRequired(enumerableTypeArgumentType);
|
AddUsingIfRequired(enumerableTypeArgumentType);
|
||||||
AddUsingIfRequired(mappedSourcePropertyType);
|
AddUsingIfRequired(mappedSourcePropertyType);
|
||||||
|
|
||||||
|
INamedTypeSymbol? namedType;
|
||||||
|
var isEnumerable = IsEnumerable(property, out namedType);
|
||||||
|
|
||||||
return new MappedMember(
|
return new MappedMember(
|
||||||
property.Name,
|
property.Name,
|
||||||
|
@ -272,6 +292,9 @@ namespace MapTo
|
||||||
property.Name,
|
property.Name,
|
||||||
ToQualifiedDisplayName(mappedSourcePropertyType),
|
ToQualifiedDisplayName(mappedSourcePropertyType),
|
||||||
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
||||||
|
property,
|
||||||
|
namedType,
|
||||||
|
isEnumerable,
|
||||||
(property as IPropertySymbol).IsReadOnly);
|
(property as IPropertySymbol).IsReadOnly);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -299,6 +322,9 @@ namespace MapTo
|
||||||
AddUsingIfRequired(enumerableTypeArgumentType);
|
AddUsingIfRequired(enumerableTypeArgumentType);
|
||||||
AddUsingIfRequired(mappedSourcePropertyType);
|
AddUsingIfRequired(mappedSourcePropertyType);
|
||||||
|
|
||||||
|
INamedTypeSymbol? namedType;
|
||||||
|
var isEnumerable = IsEnumerable(property, out namedType);
|
||||||
|
|
||||||
|
|
||||||
return new MappedMember(
|
return new MappedMember(
|
||||||
property.Name,
|
property.Name,
|
||||||
|
@ -309,6 +335,9 @@ namespace MapTo
|
||||||
property.Name,
|
property.Name,
|
||||||
ToQualifiedDisplayName(mappedSourcePropertyType),
|
ToQualifiedDisplayName(mappedSourcePropertyType),
|
||||||
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
ToQualifiedDisplayName(enumerableTypeArgumentType),
|
||||||
|
property,
|
||||||
|
namedType,
|
||||||
|
isEnumerable,
|
||||||
(property as IFieldSymbol).IsReadOnly);
|
(property as IFieldSymbol).IsReadOnly);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -403,7 +432,27 @@ namespace MapTo
|
||||||
|
|
||||||
return Diagnostics.IsEmpty();
|
return Diagnostics.IsEmpty();
|
||||||
}
|
}
|
||||||
|
protected bool IsEnumerable(ISymbol property, out INamedTypeSymbol? namedTypeSymbolResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!property.TryGetTypeSymbol(out var propertyType))
|
||||||
|
{
|
||||||
|
AddDiagnostic(DiagnosticsFactory.NoMatchingPropertyTypeFoundError(property));
|
||||||
|
namedTypeSymbolResult = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
propertyType is INamedTypeSymbol namedTypeSymbol &&
|
||||||
|
!propertyType.IsPrimitiveType() &&
|
||||||
|
(Compilation.IsGenericEnumerable(propertyType) || propertyType.AllInterfaces.Any(i => Compilation.IsGenericEnumerable(i))))
|
||||||
|
{
|
||||||
|
namedTypeSymbolResult = namedTypeSymbol;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
namedTypeSymbolResult = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
private static ImmutableArray<string> GetTypeConverterParameters(AttributeData typeConverterAttribute)
|
private static ImmutableArray<string> GetTypeConverterParameters(AttributeData typeConverterAttribute)
|
||||||
{
|
{
|
||||||
var converterParameter = typeConverterAttribute.ConstructorArguments.Skip(1).FirstOrDefault();
|
var converterParameter = typeConverterAttribute.ConstructorArguments.Skip(1).FirstOrDefault();
|
||||||
|
@ -434,6 +483,7 @@ namespace MapTo
|
||||||
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
||||||
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
|
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
|
||||||
var isTypeUpdatable = IsTypeUpdatable();
|
var isTypeUpdatable = IsTypeUpdatable();
|
||||||
|
var hasJsonExtension = HasJsonExtension();
|
||||||
var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol);
|
var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol);
|
||||||
|
|
||||||
var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass);
|
var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass);
|
||||||
|
@ -460,6 +510,7 @@ namespace MapTo
|
||||||
sourceTypeIdentifierName,
|
sourceTypeIdentifierName,
|
||||||
sourceTypeSymbol.ToDisplayString(),
|
sourceTypeSymbol.ToDisplayString(),
|
||||||
isTypeUpdatable,
|
isTypeUpdatable,
|
||||||
|
hasJsonExtension,
|
||||||
mappedProperties,
|
mappedProperties,
|
||||||
allProperties,
|
allProperties,
|
||||||
mappedFields,
|
mappedFields,
|
||||||
|
|
|
@ -31,6 +31,9 @@ namespace MapTo
|
||||||
string SourcePropertyName,
|
string SourcePropertyName,
|
||||||
string? MappedSourcePropertyTypeName,
|
string? MappedSourcePropertyTypeName,
|
||||||
string? EnumerableTypeArgument,
|
string? EnumerableTypeArgument,
|
||||||
|
ISymbol ActualSymbol,
|
||||||
|
INamedTypeSymbol? NamedTypeSymbol,
|
||||||
|
bool isEnumerable,
|
||||||
bool isReadOnly)
|
bool isReadOnly)
|
||||||
{
|
{
|
||||||
public bool IsEnumerable => EnumerableTypeArgument is not null;
|
public bool IsEnumerable => EnumerableTypeArgument is not null;
|
||||||
|
@ -46,6 +49,7 @@ namespace MapTo
|
||||||
string SourceTypeIdentifierName,
|
string SourceTypeIdentifierName,
|
||||||
string SourceTypeFullName,
|
string SourceTypeFullName,
|
||||||
bool IsTypeUpdatable,
|
bool IsTypeUpdatable,
|
||||||
|
bool IsJsonExtension,
|
||||||
ImmutableArray<MappedMember> SourceProperties,
|
ImmutableArray<MappedMember> SourceProperties,
|
||||||
ImmutableArray<MappedMember> TypeProperties,
|
ImmutableArray<MappedMember> TypeProperties,
|
||||||
ImmutableArray<MappedMember> SourceFields,
|
ImmutableArray<MappedMember> SourceFields,
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MapTo
|
||||||
.OrderByDescending(s => s.Parameters.Length)
|
.OrderByDescending(s => s.Parameters.Length)
|
||||||
.First(s => s.Name == ".ctor")
|
.First(s => s.Name == ".ctor")
|
||||||
.Parameters
|
.Parameters
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -43,7 +43,7 @@ namespace MapTo
|
||||||
.OrderByDescending(s => s.Parameters.Length)
|
.OrderByDescending(s => s.Parameters.Length)
|
||||||
.First(s => s.Name == ".ctor")
|
.First(s => s.Name == ".ctor")
|
||||||
.Parameters
|
.Parameters
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapProperty(typeSymbol, sourceProperties, property))
|
.Select(property => MapProperty(typeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
using static MapTo.Sources.Constants;
|
||||||
|
|
||||||
|
namespace MapTo.Sources
|
||||||
|
{
|
||||||
|
internal static class DictionaryToListAttributeSource
|
||||||
|
{
|
||||||
|
internal const string AttributeName = "DictionaryToList";
|
||||||
|
internal const string AttributeClassName = AttributeName + "Attribute";
|
||||||
|
internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
|
||||||
|
internal const string SourceMemberNameFieldOrPropertyName = "SourcePropertyName";
|
||||||
|
|
||||||
|
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||||
|
{
|
||||||
|
using var builder = new SourceBuilder()
|
||||||
|
.WriteLine(GeneratedFilesHeader)
|
||||||
|
.WriteNullableContextOptionIf(options.SupportNullableReferenceTypes)
|
||||||
|
.WriteLine()
|
||||||
|
.WriteLine("using System;")
|
||||||
|
.WriteLine()
|
||||||
|
.WriteLine($"namespace {RootNamespace}")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
if (options.GenerateXmlDocument)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WriteLine("/// <summary>")
|
||||||
|
.WriteLine("/// Specifies the mapping behavior of the annotated property.")
|
||||||
|
.WriteLine("/// </summary>")
|
||||||
|
.WriteLine("/// <remarks>")
|
||||||
|
.WriteLine($"/// {AttributeClassName} has a number of uses:")
|
||||||
|
.WriteLine("/// <list type=\"bullet\">")
|
||||||
|
.WriteLine("/// <item><description>By default properties with same name will get mapped. This attribute allows the names to be different.</description></item>")
|
||||||
|
.WriteLine("/// <item><description>Indicates that a property should be mapped when member serialization is set to opt-in.</description></item>")
|
||||||
|
.WriteLine("/// </list>")
|
||||||
|
.WriteLine("/// </remarks>");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]")
|
||||||
|
.WriteLine($"public sealed class {AttributeClassName} : Attribute")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
if (options.GenerateXmlDocument)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WriteLine("/// <summary>")
|
||||||
|
.WriteLine("/// Gets or sets the property name of the object to mapping from.")
|
||||||
|
.WriteLine("/// </summary>");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine($"public string{options.NullableReferenceSyntax} {SourceMemberNameFieldOrPropertyName} {{ get; set; }}")
|
||||||
|
.WriteClosingBracket() // class
|
||||||
|
.WriteClosingBracket(); // namespace
|
||||||
|
|
||||||
|
|
||||||
|
return new(builder.ToString(), $"{AttributeClassName}.g.cs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
namespace MapTo.Sources
|
namespace MapTo.Sources
|
||||||
{
|
{
|
||||||
internal static class IgnorePropertyAttributeSource
|
internal static class IgnoreMemberAttributeSource
|
||||||
{
|
{
|
||||||
internal const string AttributeName = "IgnoreProperty";
|
internal const string AttributeName = "IgnoreMemberMapTo";
|
||||||
internal const string AttributeClassName = AttributeName + "Attribute";
|
internal const string AttributeClassName = AttributeName + "Attribute";
|
||||||
internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
|
internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace MapTo.Sources
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.WriteLine("[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]")
|
.WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]")
|
||||||
.WriteLine($"public sealed class {AttributeClassName} : Attribute {{ }}")
|
.WriteLine($"public sealed class {AttributeClassName} : Attribute {{ }}")
|
||||||
.WriteClosingBracket();
|
.WriteClosingBracket();
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
using static MapTo.Sources.Constants;
|
||||||
|
|
||||||
|
namespace MapTo.Sources
|
||||||
|
{
|
||||||
|
internal static class JsonExtensionAttributeSource
|
||||||
|
{
|
||||||
|
internal const string AttributeName = "JsonExtension";
|
||||||
|
internal const string AttributeClassName = AttributeName + "Attribute";
|
||||||
|
internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
|
||||||
|
|
||||||
|
internal static SourceCode Generate(SourceGenerationOptions options)
|
||||||
|
{
|
||||||
|
using var builder = new SourceBuilder()
|
||||||
|
.WriteLine(GeneratedFilesHeader)
|
||||||
|
.WriteLine("using System;")
|
||||||
|
.WriteLine()
|
||||||
|
.WriteLine($"namespace {RootNamespace}")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
if (options.GenerateXmlDocument)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WriteLine("/// <summary>")
|
||||||
|
.WriteLine("/// Specifies that the annotated class has a json extension.")
|
||||||
|
.WriteLine("/// </summary>");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine("[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]")
|
||||||
|
.WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteClosingBracket() // class
|
||||||
|
.WriteClosingBracket(); // namespace
|
||||||
|
|
||||||
|
return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ namespace MapTo
|
||||||
return typeSymbol
|
return typeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IFieldSymbol>()
|
.OfType<IFieldSymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapField(sourceTypeSymbol, sourceProperties, property))
|
.Select(property => MapField(sourceTypeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -31,7 +31,7 @@ namespace MapTo
|
||||||
return typeSymbol
|
return typeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IPropertySymbol>()
|
.OfType<IPropertySymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
.Select(property => MapProperty(sourceTypeSymbol, sourceProperties, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -44,7 +44,7 @@ namespace MapTo
|
||||||
return sourceTypeSymbol
|
return sourceTypeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IFieldSymbol>()
|
.OfType<IFieldSymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapFieldSimple(typeSymbol, property))
|
.Select(property => MapFieldSimple(typeSymbol, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
@ -57,7 +57,7 @@ namespace MapTo
|
||||||
return sourceTypeSymbol
|
return sourceTypeSymbol
|
||||||
.GetAllMembers()
|
.GetAllMembers()
|
||||||
.OfType<IPropertySymbol>()
|
.OfType<IPropertySymbol>()
|
||||||
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
|
.Where(p => !p.HasAttribute(IgnoreMemberAttributeTypeSymbol))
|
||||||
.Select(property => MapPropertySimple(typeSymbol, property))
|
.Select(property => MapPropertySimple(typeSymbol, property))
|
||||||
.Where(mappedProperty => mappedProperty is not null)
|
.Where(mappedProperty => mappedProperty is not null)
|
||||||
.ToImmutableArray()!;
|
.ToImmutableArray()!;
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace BlueWest.Data
|
||||||
Sell
|
Sell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonExtension]
|
||||||
[MapFrom(typeof(FinanceTransactionInsertDto))]
|
[MapFrom(typeof(FinanceTransactionInsertDto))]
|
||||||
public partial struct FinanceTransaction
|
public partial struct FinanceTransaction
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,12 +5,12 @@ namespace BlueWest.Data
|
||||||
|
|
||||||
public partial struct FinanceTransactionInsertDto
|
public partial struct FinanceTransactionInsertDto
|
||||||
{
|
{
|
||||||
public int UserId { get; set; }
|
public readonly int UserId;
|
||||||
public FinanceTransactionType FinanceTransactionType { get; }
|
public readonly FinanceTransactionType FinanceTransactionType;
|
||||||
public FinanceSymbol FinanceSymbol { get; }
|
public readonly FinanceSymbol FinanceSymbol;
|
||||||
public double Amount { get; } // To Buy
|
public readonly double Amount; // To Buy
|
||||||
public double Quantity { get; } // Bought
|
public readonly double Quantity; // Bought
|
||||||
public double Fee { get; }
|
public readonly double Fee;
|
||||||
public DateTime DateTime { get; }
|
public readonly DateTime DateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,14 +9,14 @@ namespace BlueWest.Data
|
||||||
|
|
||||||
partial struct FinanceTransactionReadDto
|
partial struct FinanceTransactionReadDto
|
||||||
{
|
{
|
||||||
public int UserId { get; set; }
|
public readonly int UserId;
|
||||||
public FinanceTransactionType FinanceTransactionType { get; }
|
public readonly FinanceTransactionType FinanceTransactionType;
|
||||||
public FinanceSymbol FinanceSymbol { get; }
|
public readonly FinanceSymbol FinanceSymbol;
|
||||||
public double Amount { get; } // To Buy
|
public readonly double Amount; // To Buy
|
||||||
public double Quantity { get; } // Bought
|
public readonly double Quantity; // Bought
|
||||||
public double Fee { get; }
|
public readonly double Fee;
|
||||||
public DateTime DateTime { get; }
|
public readonly DateTime DateTime;
|
||||||
|
|
||||||
public string ReadData { get; }
|
public readonly string ReadData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using MapTo;
|
||||||
namespace BlueWest.Data
|
namespace BlueWest.Data
|
||||||
{
|
{
|
||||||
[MapFrom(typeof(UserUpdateDto))]
|
[MapFrom(typeof(UserUpdateDto))]
|
||||||
|
[JsonExtension]
|
||||||
public partial class User
|
public partial class User
|
||||||
{
|
{
|
||||||
public readonly int Id;
|
public readonly int Id;
|
||||||
|
|
Loading…
Reference in New Issue