This commit is contained in:
parent
768dbb4532
commit
efdd3ada94
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue