This commit is contained in:
Wvader 2021-12-11 21:06:58 +00:00
parent 768dbb4532
commit efdd3ada94
11 changed files with 152 additions and 52 deletions

View File

@ -11,26 +11,25 @@ namespace MapTo
internal ClassMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax) internal ClassMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
: base(compilation, sourceGenerationOptions, typeSyntax) { } : base(compilation, sourceGenerationOptions, typeSyntax) { }
protected override ImmutableArray<MappedProperty> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass) protected override ImmutableArray<MappedProperty> GetSourceMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().ToArray();
return typeSymbol return typeSymbol
.GetAllMembers(!isInheritFromMappedBaseClass) .GetAllMembers(!isInheritFromMappedBaseClass)
.OfType<IPropertySymbol>()
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol)) .Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
.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()!;
} }
protected override ImmutableArray<MappedProperty> GetTypeMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass) protected override ImmutableArray<MappedProperty> GetTypeMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().ToArray();
return typeSymbol return typeSymbol
.GetAllMembers() .GetAllMembers()
.OfType<IPropertySymbol>()
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol)) .Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
.Select(property => MapProperty(typeSymbol, sourceProperties, property)) .Select(property => MapProperty(typeSymbol, sourceProperties, property))
.Where(mappedProperty => mappedProperty is not null) .Where(mappedProperty => mappedProperty is not null)

View File

@ -27,8 +27,12 @@ namespace MapTo
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 '{IgnorePropertyAttributeSource.FullyQualifiedName}'.");
internal static Diagnostic InvalidTypeConverterGenericTypesError(ISymbol property, IPropertySymbol sourceProperty) => internal static Diagnostic InvalidTypeConverterGenericTypesError(ISymbol property, ISymbol memberSymbol)
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()}>'."); {
return Create($"{ErrorId}032", property.Locations.FirstOrDefault(), $"Cannot map '{property.ToDisplayString()}' property because the annotated converter does not implement '{RootNamespace}.{ITypeConverterSource.InterfaceName}<{memberSymbol.ToString()}, {property.GetTypeSymbol()?.ToDisplayString()}>'.");
}
internal static Diagnostic ConfigurationParseError(string error) => internal static Diagnostic ConfigurationParseError(string error) =>
Create($"{ErrorId}040", Location.None, error); Create($"{ErrorId}040", Location.None, error);

View File

@ -88,7 +88,7 @@ namespace MapTo.Extensions
return builder.WriteClosingBracket(); return builder.WriteClosingBracket();
} }
private static bool IsMappedProperty(this System.Collections.Immutable.ImmutableArray<MappedProperty> properties, MappedProperty property) { private static bool IsMappedProperty(this ImmutableArray<MappedProperty> properties, MappedProperty property) {
foreach(var prop in properties) foreach(var prop in properties)
{ {
@ -98,7 +98,7 @@ namespace MapTo.Extensions
return false; return false;
} }
private static SourceBuilder TryWriteProperties(this SourceBuilder builder, System.Collections.Immutable.ImmutableArray<MappedProperty> properties, System.Collections.Immutable.ImmutableArray<MappedProperty>? otherProperties, private static SourceBuilder TryWriteProperties(this SourceBuilder builder, ImmutableArray<MappedProperty> properties, System.Collections.Immutable.ImmutableArray<MappedProperty>? otherProperties,
string? sourceClassParameterName, string mappingContextParameterName, bool fromUpdate) string? sourceClassParameterName, string mappingContextParameterName, bool fromUpdate)
{ {
if (fromUpdate) if (fromUpdate)

View File

@ -67,6 +67,9 @@ namespace MapTo.Extensions
case IPropertySymbol propertySymbol: case IPropertySymbol propertySymbol:
typeSymbol = propertySymbol.Type; typeSymbol = propertySymbol.Type;
return true; return true;
case IFieldSymbol fieldSymbol:
typeSymbol = fieldSymbol.Type;
return true;
case IParameterSymbol parameterSymbol: case IParameterSymbol parameterSymbol:
typeSymbol = parameterSymbol.Type; typeSymbol = parameterSymbol.Type;

View File

@ -34,6 +34,8 @@ namespace MapTo
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);
JsonExtensionAttributeTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(UseUpdateAttributeSource.FullyQualifiedName);
MappingContextTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MappingContextSource.FullyQualifiedName); MappingContextTypeSymbol = compilation.GetTypeByMetadataNameOrThrow(MappingContextSource.FullyQualifiedName);
AddUsingIfRequired(sourceGenerationOptions.SupportNullableStaticAnalysis, "System.Diagnostics.CodeAnalysis"); AddUsingIfRequired(sourceGenerationOptions.SupportNullableStaticAnalysis, "System.Diagnostics.CodeAnalysis");
@ -51,6 +53,8 @@ namespace MapTo
protected INamedTypeSymbol UseUpdateAttributeTypeSymbol { get; } protected INamedTypeSymbol UseUpdateAttributeTypeSymbol { get; }
protected INamedTypeSymbol JsonExtensionAttributeTypeSymbol { get; }
protected INamedTypeSymbol MappingContextTypeSymbol { get; } protected INamedTypeSymbol MappingContextTypeSymbol { get; }
protected INamedTypeSymbol MapPropertyAttributeTypeSymbol { get; } protected INamedTypeSymbol MapPropertyAttributeTypeSymbol { get; }
@ -99,19 +103,31 @@ namespace MapTo
} }
} }
protected IPropertySymbol? FindSourceProperty(IEnumerable<IPropertySymbol> sourceProperties, ISymbol property) protected ISymbol? FindSourceProperty(IEnumerable<ISymbol> sourceMembers, ISymbol member)
{ {
var propertyName = property var propertyName = member
.GetAttribute(MapPropertyAttributeTypeSymbol) .GetAttribute(MapPropertyAttributeTypeSymbol)
?.NamedArguments ?.NamedArguments
.SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName) .SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
.Value.Value as string ?? property.Name; .Value.Value as string ?? member.Name;
foreach(var sourceProperty in sourceMembers)
{
if(sourceProperty is IPropertySymbol propertySymbol)
{
if (propertySymbol.Name == propertyName) return sourceProperty;
}
if (sourceProperty is IFieldSymbol fieldSymbol)
{
if (fieldSymbol.Name == propertyName) return sourceProperty;
}
return sourceProperties.SingleOrDefault(p => p.Name == propertyName); }
return sourceMembers.SingleOrDefault(p => p.Name == propertyName);
} }
protected abstract ImmutableArray<MappedProperty> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass); protected abstract ImmutableArray<MappedProperty> GetSourceMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
protected abstract ImmutableArray<MappedProperty> GetTypeMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass); protected abstract ImmutableArray<MappedProperty> GetTypeMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
protected INamedTypeSymbol? GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null) => protected INamedTypeSymbol? GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null) =>
GetSourceTypeSymbol(typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName), semanticModel); GetSourceTypeSymbol(typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName), semanticModel);
@ -144,7 +160,12 @@ namespace MapTo
return TypeSyntax.GetAttribute("UseUpdate") != null; return TypeSyntax.GetAttribute("UseUpdate") != null;
} }
protected virtual MappedProperty? MapProperty(ISymbol sourceTypeSymbol, IReadOnlyCollection<IPropertySymbol> sourceProperties, ISymbol property) protected bool IsJsonExtension()
{
return TypeSyntax.GetAttribute("JsonExtension") != null;
}
protected virtual MappedProperty? MapProperty(ISymbol sourceTypeSymbol, IReadOnlyCollection<ISymbol> sourceProperties, ISymbol property)
{ {
var sourceProperty = FindSourceProperty(sourceProperties, property); var sourceProperty = FindSourceProperty(sourceProperties, property);
if (sourceProperty is null || !property.TryGetTypeSymbol(out var propertyType)) if (sourceProperty is null || !property.TryGetTypeSymbol(out var propertyType))
@ -171,6 +192,16 @@ namespace MapTo
AddUsingIfRequired(enumerableTypeArgumentType); AddUsingIfRequired(enumerableTypeArgumentType);
AddUsingIfRequired(mappedSourcePropertyType); AddUsingIfRequired(mappedSourcePropertyType);
bool isReadOnly = false;
if(property is IPropertySymbol pSymbol)
{
isReadOnly = pSymbol.IsReadOnly;
}
if (property is IFieldSymbol fSymbol)
{
isReadOnly = fSymbol.IsReadOnly;
}
return new MappedProperty( return new MappedProperty(
property.Name, property.Name,
@ -181,7 +212,7 @@ namespace MapTo
sourceProperty.Name, sourceProperty.Name,
ToQualifiedDisplayName(mappedSourcePropertyType), ToQualifiedDisplayName(mappedSourcePropertyType),
ToQualifiedDisplayName(enumerableTypeArgumentType), ToQualifiedDisplayName(enumerableTypeArgumentType),
(property as IPropertySymbol).IsReadOnly); isReadOnly);
; ;
} }
protected virtual MappedProperty? MapPropertySimple(ISymbol sourceTypeSymbol, ISymbol property) protected virtual MappedProperty? MapPropertySimple(ISymbol sourceTypeSymbol, ISymbol property)
@ -202,7 +233,16 @@ namespace MapTo
AddUsingIfRequired(enumerableTypeArgumentType); AddUsingIfRequired(enumerableTypeArgumentType);
AddUsingIfRequired(mappedSourcePropertyType); AddUsingIfRequired(mappedSourcePropertyType);
bool isReadOnly = false;
if (property is IPropertySymbol pSymbol)
{
isReadOnly = pSymbol.IsReadOnly;
}
if (property is IFieldSymbol fSymbol)
{
isReadOnly = fSymbol.IsReadOnly;
}
return new MappedProperty( return new MappedProperty(
property.Name, property.Name,
property.GetTypeSymbol().ToString(), property.GetTypeSymbol().ToString(),
@ -212,10 +252,10 @@ namespace MapTo
property.Name, property.Name,
ToQualifiedDisplayName(mappedSourcePropertyType), ToQualifiedDisplayName(mappedSourcePropertyType),
ToQualifiedDisplayName(enumerableTypeArgumentType), ToQualifiedDisplayName(enumerableTypeArgumentType),
(property as IPropertySymbol).IsReadOnly); isReadOnly);
; ;
} }
protected bool TryGetMapTypeConverter(ISymbol property, IPropertySymbol sourceProperty, out string? converterFullyQualifiedName, protected bool TryGetMapTypeConverter(ISymbol property, ISymbol sourceMember, out string? converterFullyQualifiedName,
out ImmutableArray<string> converterParameters) out ImmutableArray<string> converterParameters)
{ {
converterFullyQualifiedName = null; converterFullyQualifiedName = null;
@ -232,10 +272,10 @@ namespace MapTo
return false; return false;
} }
var baseInterface = GetTypeConverterBaseInterface(converterTypeSymbol, property, sourceProperty); var baseInterface = GetTypeConverterBaseInterface(converterTypeSymbol, property, sourceMember);
if (baseInterface is null) if (baseInterface is null)
{ {
AddDiagnostic(DiagnosticsFactory.InvalidTypeConverterGenericTypesError(property, sourceProperty)); AddDiagnostic(DiagnosticsFactory.InvalidTypeConverterGenericTypesError(property, sourceMember));
return false; return false;
} }
@ -310,18 +350,19 @@ 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 isJsonExtension = IsJsonExtension();
var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol); var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol);
var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass); var mappedProperties = GetSourceMappedMembers(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass);
if (!mappedProperties.Any()) /* if (!mappedProperties.Any())
{ {
AddDiagnostic(DiagnosticsFactory.NoMatchingPropertyFoundError(TypeSyntax.GetLocation(), typeSymbol, sourceTypeSymbol)); AddDiagnostic(DiagnosticsFactory.NoMatchingPropertyFoundError(TypeSyntax.GetLocation(), typeSymbol, sourceTypeSymbol));
return null; return null;
} }*/
AddUsingIfRequired(mappedProperties.Any(p => p.IsEnumerable), "System.Linq"); AddUsingIfRequired(mappedProperties.Any(p => p.IsEnumerable), "System.Linq");
var allProperties = GetTypeMappedProperties(sourceTypeSymbol, typeSymbol , isTypeInheritFromMappedBaseClass); var allProperties = GetTypeMappedMembers(sourceTypeSymbol, typeSymbol , isTypeInheritFromMappedBaseClass);
return new MappingModel( return new MappingModel(
SourceGenerationOptions, SourceGenerationOptions,
@ -333,6 +374,7 @@ namespace MapTo
sourceTypeIdentifierName, sourceTypeIdentifierName,
sourceTypeSymbol.ToDisplayString(), sourceTypeSymbol.ToDisplayString(),
isTypeUpdatable, isTypeUpdatable,
isJsonExtension,
mappedProperties, mappedProperties,
allProperties, allProperties,
isTypeInheritFromMappedBaseClass, isTypeInheritFromMappedBaseClass,
@ -342,18 +384,31 @@ namespace MapTo
private INamedTypeSymbol? GetTypeConverterBaseInterface(ITypeSymbol converterTypeSymbol, ISymbol property, IPropertySymbol sourceProperty) private INamedTypeSymbol? GetTypeConverterBaseInterface(ITypeSymbol converterTypeSymbol, ISymbol property, ISymbol sourceMember)
{ {
if (!property.TryGetTypeSymbol(out var propertyType)) if (!property.TryGetTypeSymbol(out var propertyType))
{ {
return null; return null;
} }
ISymbol? type = null;
if(sourceMember is IPropertySymbol propertySymbol)
{
type = propertySymbol.Type;
}
if (sourceMember is IFieldSymbol fieldSymbol)
{
type = fieldSymbol.Type;
}
if (type == null) return null;
return converterTypeSymbol.AllInterfaces return converterTypeSymbol.AllInterfaces
.SingleOrDefault(i => .SingleOrDefault(i =>
i.TypeArguments.Length == 2 && i.TypeArguments.Length == 2 &&
SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) && SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) &&
SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) && SymbolEqualityComparer.Default.Equals(type, i.TypeArguments[0]) &&
SymbolEqualityComparer.Default.Equals(propertyType, i.TypeArguments[1])); SymbolEqualityComparer.Default.Equals(propertyType, i.TypeArguments[1]));
} }

View File

@ -46,6 +46,7 @@ namespace MapTo
string SourceTypeIdentifierName, string SourceTypeIdentifierName,
string SourceTypeFullName, string SourceTypeFullName,
bool IsTypeUpdatable, bool IsTypeUpdatable,
bool IsJsonExtension,
ImmutableArray<MappedProperty> SourceProperties, ImmutableArray<MappedProperty> SourceProperties,
ImmutableArray<MappedProperty> TypeProperties, ImmutableArray<MappedProperty> TypeProperties,
bool HasMappedBaseClass, bool HasMappedBaseClass,

View File

@ -11,7 +11,7 @@ namespace MapTo
internal RecordMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax) internal RecordMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
: base(compilation, sourceGenerationOptions, typeSyntax) { } : base(compilation, sourceGenerationOptions, typeSyntax) { }
protected override ImmutableArray<MappedProperty> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass) protected override ImmutableArray<MappedProperty> GetSourceMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
return typeSymbol.GetMembers() return typeSymbol.GetMembers()
@ -25,7 +25,7 @@ namespace MapTo
.ToImmutableArray()!; .ToImmutableArray()!;
} }
protected override ImmutableArray<MappedProperty> GetTypeMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass) protected override ImmutableArray<MappedProperty> GetTypeMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
return typeSymbol.GetMembers() return typeSymbol.GetMembers()

View File

@ -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 needs ToJson method")
.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");
}
}
}

View File

@ -11,25 +11,23 @@ namespace MapTo
internal StructMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax) internal StructMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
: base(compilation, sourceGenerationOptions, typeSyntax) { } : base(compilation, sourceGenerationOptions, typeSyntax) { }
protected override ImmutableArray<MappedProperty> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool hasInheritedClass) protected override ImmutableArray<MappedProperty> GetSourceMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool hasInheritedClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
return typeSymbol return typeSymbol
.GetAllMembers() .GetAllMembers()
.OfType<IPropertySymbol>()
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol)) .Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
.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()!;
} }
protected override ImmutableArray<MappedProperty> GetTypeMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool hasInheritedClass) protected override ImmutableArray<MappedProperty> GetTypeMappedMembers(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool hasInheritedClass)
{ {
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray(); var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
return sourceTypeSymbol return sourceTypeSymbol
.GetAllMembers() .GetAllMembers()
.OfType<IPropertySymbol>()
.Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol)) .Where(p => !p.HasAttribute(IgnorePropertyAttributeTypeSymbol))
.Select(property => MapPropertySimple(typeSymbol, property)) .Select(property => MapPropertySimple(typeSymbol, property))
.Where(mappedProperty => mappedProperty is not null) .Where(mappedProperty => mappedProperty is not null)

View File

@ -8,17 +8,17 @@ namespace BlueWest.Data
[MapFrom(typeof(UserUpdateDto))] [MapFrom(typeof(UserUpdateDto))]
public partial class User public partial class User
{ {
public int Id { get; } public readonly int Id;
public string Name { get; set; } public string Name;
public string Address { get; set; } public string Address;
public string BTCAddress { get; set; } public string BTCAddress;
public string LTCAddress { get; set; } public string LTCAddress;
public double BTCAmount { get; set; } public double BTCAmount;
public double LTCAmount { get; set; } public double LTCAmount;
public List<FinanceTransaction> FinanceTransactions { get; } public List<FinanceTransaction> FinanceTransactions;
public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, List<FinanceTransaction> financeTransactions) public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, List<FinanceTransaction> financeTransactions)
{ {

View File

@ -4,16 +4,16 @@ namespace BlueWest.Data
{ {
[MapFrom(typeof(User))] [MapFrom(typeof(User))]
public partial struct UserUpdateDto public partial class UserUpdateDto
{ {
public string Name { get; set; } public string Name;
public string Address { get; set; } public string Address;
public string BTCAddress { get; set; } public string BTCAddress;
public string LTCAddress { get; set; } public string LTCAddress;
public double BTCAmount { get; set; } public double BTCAmount;
public double LTCAmount { get; set; } public double LTCAmount;
} }
} }