diff --git a/Compentio.SourceMapper.Generator/AnalyzerReleases.Unshipped.md b/Compentio.SourceMapper.Generator/AnalyzerReleases.Unshipped.md
index e880452..26ab822 100644
--- a/Compentio.SourceMapper.Generator/AnalyzerReleases.Unshipped.md
+++ b/Compentio.SourceMapper.Generator/AnalyzerReleases.Unshipped.md
@@ -5,6 +5,7 @@
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
SMAP0004 | Design | Warning | SourceMapperDescriptors, [Documentation](https://github.com/alekshura/SourceMapper/wiki/Diagnostics##smap0004)
+SMAP0005 | Design | Warning | SourceMapperDescriptors, [Documentation](https://github.com/alekshura/SourceMapper/wiki/Diagnostics##smap0005)
### Changed Rules
Rule ID | New Category | New Severity | Old Category | Old Severity | Notes
diff --git a/Compentio.SourceMapper.Generator/Diagnostics/SourceMapperDescriptors.cs b/Compentio.SourceMapper.Generator/Diagnostics/SourceMapperDescriptors.cs
index e8528e0..9e9e66a 100644
--- a/Compentio.SourceMapper.Generator/Diagnostics/SourceMapperDescriptors.cs
+++ b/Compentio.SourceMapper.Generator/Diagnostics/SourceMapperDescriptors.cs
@@ -28,5 +28,9 @@ public static class SourceMapperDescriptors
public static readonly DiagnosticDescriptor DependencyInjectionNotUsed =
new("SMAP0004", "Dependency Injection not used", "No Dependency Injection mechanism used in project. '{0}'.", "Design", DiagnosticSeverity.Warning, true,
"SourceMapper based on Dependency Injection, but no used in project.", $"{DiagnosticsDescriptorsUri}#smap0004");
+
+ public static readonly DiagnosticDescriptor FieldIsNotMapped =
+ new("SMAP0005", "Field is not mapped", "The field '{0}' is not mapped", "Design", DiagnosticSeverity.Warning, true,
+ "Source field for defined target field not found, thus field does not mapped.", $"{DiagnosticsDescriptorsUri}#smap0005");
}
}
diff --git a/Compentio.SourceMapper.Generator/Matchers/AttributesMatchers.cs b/Compentio.SourceMapper.Generator/Matchers/AttributesMatchers.cs
index 8ddeb28..747f644 100644
--- a/Compentio.SourceMapper.Generator/Matchers/AttributesMatchers.cs
+++ b/Compentio.SourceMapper.Generator/Matchers/AttributesMatchers.cs
@@ -13,7 +13,7 @@ internal static class AttributesMatchers
/// Attributes collection
/// Target property to match
/// Matched attribute
- internal static MappingAttribute MatchTargetAttribute(this IEnumerable attributes, IPropertyMetadata targetProperty)
+ internal static MappingAttribute MatchTargetAttribute(this IEnumerable attributes, IMetadata targetProperty)
{
return attributes.FirstOrDefault(attribute => attribute?.Target == targetProperty?.Name);
}
@@ -26,7 +26,7 @@ internal static MappingAttribute MatchTargetAttribute(this IEnumerable
///
///
- internal static MappingAttribute MatchExpressionAttribute(this IEnumerable attributes, IPropertyMetadata targetProperty, IPropertyMetadata sourceProperty)
+ internal static MappingAttribute MatchExpressionAttribute(this IEnumerable attributes, IMetadata targetProperty, IMetadata sourceProperty)
{
var matchedExpressionAttribute = attributes.FirstOrDefault(attribute => attribute?.Target == targetProperty?.Name
&& attribute?.Source == sourceProperty?.Name
diff --git a/Compentio.SourceMapper.Generator/Matchers/MembersMatchers.cs b/Compentio.SourceMapper.Generator/Matchers/MembersMatchers.cs
index 76e7f9f..9da3c60 100644
--- a/Compentio.SourceMapper.Generator/Matchers/MembersMatchers.cs
+++ b/Compentio.SourceMapper.Generator/Matchers/MembersMatchers.cs
@@ -8,13 +8,13 @@ namespace Compentio.SourceMapper.Matchers
internal static class MembersMatchers
{
///
- /// Method searches for source member that matches value. This also should match the target property.
+ /// Method searches for source member that matches value. This also should match the target member.
///
- /// Collection of source properties
+ /// Collection of source members
/// Collection of all defined mapping attributes
/// Target member
/// Matched source member
- internal static IPropertyMetadata MatchSourceMember(this IEnumerable sourceMembers, IEnumerable mappingAttributes, IPropertyMetadata targetMember)
+ internal static IMemberMetadata MatchSourceMember(this IEnumerable sourceMembers, IEnumerable mappingAttributes, IMemberMetadata targetMember)
{
var matchedAttribute = mappingAttributes.MatchTargetAttribute(targetMember);
var matchedSourceMember = sourceMembers.FirstOrDefault(member => member?.Name == matchedAttribute?.Source);
@@ -27,21 +27,21 @@ internal static IPropertyMetadata MatchSourceMember(this IEnumerable
/// Method searches for source member that name matches target member.
///
- /// Collection of source properties
+ /// Collection of source members
/// Target member
/// Matched source member
- internal static IPropertyMetadata MatchSourceMember(this IEnumerable members, IPropertyMetadata targetMember)
+ internal static IMemberMetadata MatchSourceMember(this IEnumerable members, IMemberMetadata targetMember)
{
return members.FirstOrDefault(member => member?.Name == targetMember?.Name);
}
///
- /// Method searches for target member that matches value. This also should match the target property.
+ /// Method searches for target member that matches value. This also should match the target member.
///
- /// Collection of target properties
+ /// Collection of target members
/// Collection of all defined mapping attributes
/// Target member
/// Matched target member
- internal static IPropertyMetadata MatchTargetMember(this IEnumerable targetMembers, IEnumerable mappingAttributes, IPropertyMetadata targetMember)
+ internal static IMemberMetadata MatchTargetMember(this IEnumerable targetMembers, IEnumerable mappingAttributes, IMemberMetadata targetMember)
{
var matchedAttribute = mappingAttributes.MatchTargetAttribute(targetMember);
var matchedTargetMember = targetMembers.FirstOrDefault(member => member?.Name == matchedAttribute?.Target);
diff --git a/Compentio.SourceMapper.Generator/Matchers/MethodsMatchers.cs b/Compentio.SourceMapper.Generator/Matchers/MethodsMatchers.cs
index 0fcd198..e85aed4 100644
--- a/Compentio.SourceMapper.Generator/Matchers/MethodsMatchers.cs
+++ b/Compentio.SourceMapper.Generator/Matchers/MethodsMatchers.cs
@@ -12,10 +12,10 @@ internal static class MethodsMatchers
/// Returns method data that defined in mapping corresponds to source and target types.
/// This method can be used in mappings of nested types.
///
- /// Source property metadata
- /// Target property metadata
+ /// Source member metadata
+ /// Target member metadata
/// Matched method
- internal static IMethodMetadata MatchDefinedMethod(this IMapperMetadata mapperMetadata, IPropertyMetadata source, IPropertyMetadata target)
+ internal static IMethodMetadata MatchDefinedMethod(this IMapperMetadata mapperMetadata, IMemberMetadata source, IMemberMetadata target)
{
var method = mapperMetadata.MethodsMetadata.FirstOrDefault(m =>
m.ReturnType.FullName == target.FullName && m.Parameters.FirstOrDefault().FullName == source.FullName);
diff --git a/Compentio.SourceMapper.Generator/Metadata/MemberMetadata.cs b/Compentio.SourceMapper.Generator/Metadata/MemberMetadata.cs
new file mode 100644
index 0000000..528178d
--- /dev/null
+++ b/Compentio.SourceMapper.Generator/Metadata/MemberMetadata.cs
@@ -0,0 +1,120 @@
+using Compentio.SourceMapper.Attributes;
+using Microsoft.CodeAnalysis;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Compentio.SourceMapper.Metadata
+{
+ ///
+ /// Encapsulates a member that is mapped
+ ///
+ internal interface IMemberMetadata : IMetadata
+ {
+ ///
+ /// Indicate that member is field or property (or unknown)
+ /// Based od and
+ ///
+ MemberType MemberType { get; }
+
+ ///
+ /// Full name with namespace of the member
+ ///
+ string FullName { get; }
+
+ ///
+ /// Indicates whether the member is user defined class or no
+ ///
+ bool IsClass { get; }
+
+ ///
+ /// Indicates whether the member is static
+ ///
+ bool IsStatic { get; }
+
+ ///
+ /// Indicate that field should be ignored during mapping generating, due to
+ ///
+ bool IgnoreInMapping { get; }
+
+ ///
+ /// List of properties. It is empty in a case when the property is not user defined class: IsClass == false or is a field: IsField == true
+ ///
+ ///
+ ///
+ IEnumerable Properties { get; }
+ }
+
+ internal class MemberMetadata : IMemberMetadata
+ {
+ private readonly ISymbol _symbol;
+
+ internal MemberMetadata(ISymbol symbol)
+ {
+ _symbol = symbol;
+ }
+
+ public MemberType MemberType
+ {
+ get
+ {
+ if (_symbol is IFieldSymbol) return MemberType.Field;
+ if (_symbol is IPropertySymbol) return MemberType.Property;
+
+ return MemberType.Unknown;
+ }
+ }
+
+ public string FullName => TypeMetadata.FullName;
+
+ public bool IsClass => Type.SpecialType == SpecialType.None && Type.TypeKind == TypeKind.Class;
+
+ public bool IsStatic => _symbol.IsStatic;
+
+ public bool IgnoreInMapping
+ {
+ get
+ {
+ var attribute = _symbol.GetAttributes().FirstOrDefault(attribute => attribute is not null && attribute.AttributeClass?.Name == nameof(IgnoreMappingAttribute));
+ return attribute != null;
+ }
+ }
+
+ public IEnumerable Properties
+ {
+ get
+ {
+ if (!IsClass || MemberType != MemberType.Property)
+ return Enumerable.Empty();
+
+ return Type.GetMembers()
+ .Where(member => member.Kind == SymbolKind.Property && !member.IsStatic)
+ .Select(member => new MemberMetadata(member as IPropertySymbol));
+ }
+ }
+
+ public Location? Location => _symbol.Locations.FirstOrDefault();
+
+ public string Name => _symbol.Name;
+
+ private ITypeSymbol Type
+ {
+ get
+ {
+ if (MemberType == MemberType.Field) return ((IFieldSymbol)_symbol).Type;
+ else return ((IPropertySymbol)_symbol).Type;
+ }
+ }
+
+ private ITypeMetadata TypeMetadata => new TypeMetadata(Type);
+ }
+
+ ///
+ /// Types of member
+ ///
+ internal enum MemberType
+ {
+ Field,
+ Property,
+ Unknown
+ }
+}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Generator/Metadata/PropertyMetadata.cs b/Compentio.SourceMapper.Generator/Metadata/PropertyMetadata.cs
deleted file mode 100644
index bcd0f61..0000000
--- a/Compentio.SourceMapper.Generator/Metadata/PropertyMetadata.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using Compentio.SourceMapper.Attributes;
-using Microsoft.CodeAnalysis;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Compentio.SourceMapper.Metadata
-{
- ///
- /// Encapsulates a property that is mapped
- ///
- internal interface IPropertyMetadata : IMetadata
- {
- ///
- /// Full name with namespace of the property
- ///
- string FullName { get; }
-
- ///
- /// Indicates whether the property is user defined class or no
- ///
- ///
- bool IsClass { get; }
-
- ///
- /// Indicate that property should be ignored during mapping generating, due to
- ///
- bool IgnoreInMapping { get; }
-
- ///
- /// List of properties. It is empty in a case when the property is not user defined class: IsClass == false
- ///
- ///
- IEnumerable Properties { get; }
- }
-
- internal class PropertyMetadata : IPropertyMetadata
- {
- private readonly IPropertySymbol _propertySymbol;
-
- internal PropertyMetadata(IPropertySymbol propertySymbol)
- {
- _propertySymbol = propertySymbol;
- }
-
- public string Name => _propertySymbol.Name;
-
- public string FullName => Type.FullName;
-
- public bool IsClass => _propertySymbol.Type.SpecialType == SpecialType.None && _propertySymbol.Type.TypeKind == TypeKind.Class;
-
- private ITypeMetadata Type => new TypeMetadata(_propertySymbol.Type);
-
- public IEnumerable Properties
- {
- get
- {
- if (!IsClass)
- return Enumerable.Empty();
-
- return _propertySymbol.Type.GetMembers()
- .Where(member => member.Kind == SymbolKind.Property && !member.IsStatic)
- .Select(member => new PropertyMetadata(member as IPropertySymbol));
- }
- }
-
- public Location? Location => _propertySymbol.Locations.FirstOrDefault();
-
- ///
- /// Indicate that property should be ignored during mapping generating, due to
- ///
- public bool IgnoreInMapping
- {
- get
- {
- var attribute = _propertySymbol.GetAttributes().FirstOrDefault(attribute => attribute is not null && attribute.AttributeClass?.Name == nameof(IgnoreMappingAttribute));
- return attribute != null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Generator/Metadata/TypeMetadata.cs b/Compentio.SourceMapper.Generator/Metadata/TypeMetadata.cs
index 6a40b8c..d5d0a34 100644
--- a/Compentio.SourceMapper.Generator/Metadata/TypeMetadata.cs
+++ b/Compentio.SourceMapper.Generator/Metadata/TypeMetadata.cs
@@ -15,16 +15,21 @@ internal interface ITypeMetadata : IMetadata
string FullName { get; }
///
- /// Object lis of properties
+ /// Object list of properties
///
- IEnumerable Properties { get; }
+ IEnumerable Properties { get; }
+
+ ///
+ /// Object list of fields
+ ///
+ IEnumerable Fields { get; }
///
/// Recurrent method that return flatten list of properties tree for the object
///
/// List of properties
///
- IEnumerable FlattenProperties(IEnumerable propertyMetadata);
+ IEnumerable FlattenProperties(IEnumerable propertyMetadata);
}
internal class ParameterTypeMetadata : ITypeMetadata
@@ -39,13 +44,17 @@ internal ParameterTypeMetadata(IParameterSymbol parameterSymbol)
public string Name => _parameterSymbol.Name;
public string FullName => _parameterSymbol.ToDisplayString();
- public IEnumerable Properties => _parameterSymbol.Type.GetMembers()
+ public IEnumerable Properties => _parameterSymbol.Type.GetMembers()
.Where(member => member as IPropertySymbol is not null)
- .Select(member => new PropertyMetadata(member as IPropertySymbol));
+ .Select(member => new MemberMetadata(member as IPropertySymbol));
+
+ public IEnumerable Fields => _parameterSymbol.Type.GetMembers()
+ .Where(member => member is IFieldSymbol && member.CanBeReferencedByName && !((IFieldSymbol)member).IsConst)
+ .Select(member => new MemberMetadata(member as IFieldSymbol));
public Location? Location => _parameterSymbol.Locations.FirstOrDefault();
- public IEnumerable FlattenProperties(IEnumerable propertyMetadata) =>
+ public IEnumerable FlattenProperties(IEnumerable propertyMetadata) =>
propertyMetadata.SelectMany(c => FlattenProperties(c.Properties)).Concat(propertyMetadata);
}
@@ -63,13 +72,17 @@ internal TypeMetadata(ITypeSymbol typeSymbol)
public ITypeSymbol Type => _typeSymbol;
- public IEnumerable Properties => _typeSymbol.GetMembers()
+ public IEnumerable Properties => _typeSymbol.GetMembers()
.Where(member => member.Kind == SymbolKind.Property && !member.IsStatic)
- .Select(member => new PropertyMetadata(member as IPropertySymbol));
+ .Select(member => new MemberMetadata(member as IPropertySymbol));
+
+ public IEnumerable Fields => _typeSymbol.GetMembers()
+ .Where(member => member.Kind == SymbolKind.Field && member.CanBeReferencedByName && !((IFieldSymbol)member).IsConst)
+ .Select(member => new MemberMetadata(member as IFieldSymbol));
public Location? Location => _typeSymbol.Locations.FirstOrDefault();
- public IEnumerable FlattenProperties(IEnumerable propertyMetadata) =>
+ public IEnumerable FlattenProperties(IEnumerable propertyMetadata) =>
propertyMetadata.SelectMany(c => FlattenProperties(c.Properties)).Concat(propertyMetadata);
}
}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Generator/Processors/ClassProcessorStrategy.cs b/Compentio.SourceMapper.Generator/Processors/ClassProcessorStrategy.cs
index 2108f08..4091888 100644
--- a/Compentio.SourceMapper.Generator/Processors/ClassProcessorStrategy.cs
+++ b/Compentio.SourceMapper.Generator/Processors/ClassProcessorStrategy.cs
@@ -1,5 +1,4 @@
-using Compentio.SourceMapper.Attributes;
-using Compentio.SourceMapper.Matchers;
+using Compentio.SourceMapper.Matchers;
using Compentio.SourceMapper.Metadata;
using System.Linq;
using System.Text;
@@ -13,6 +12,8 @@ internal class ClassProcessorStrategy : AbstractProcessorStrategy
{
protected override string Modifier => "override";
+ protected override ProcessorType ProcessorType => ProcessorType.Class;
+
protected override string GenerateMapperCode(IMapperMetadata mapperMetadata)
{
var result = @$"//
@@ -66,54 +67,5 @@ private string GeneratePartialClassMethod(IMethodMetadata methodMetadata)
{
return $"public abstract {methodMetadata.InverseMethodFullName};";
}
-
- protected override string GenerateMappings(IMapperMetadata sourceMetadata, IMethodMetadata methodMetadata, bool inverseMapping = false)
- {
- var mappingsStringBuilder = new StringBuilder();
- var sourceMembers = methodMetadata.Parameters.First().Properties;
- var targetMemebers = methodMetadata.ReturnType.Properties;
-
- foreach (var targetMember in targetMemebers)
- {
- var matchedSourceMember = sourceMembers.MatchSourceMember(methodMetadata.MappingAttributes, targetMember);
- var matchedTargetMember = targetMemebers.MatchTargetMember(methodMetadata.MappingAttributes, targetMember);
-
- if (IgnorePropertyMapping(matchedSourceMember, matchedTargetMember)) continue;
-
- var expressionAttribute = methodMetadata.MappingAttributes.MatchExpressionAttribute(targetMember, matchedSourceMember);
- var expressionMapping = MapExpression(expressionAttribute, methodMetadata.Parameters.First(), matchedSourceMember, matchedTargetMember);
-
- if (!string.IsNullOrEmpty(expressionMapping))
- {
- if (inverseMapping) continue;
-
- mappingsStringBuilder.Append(expressionMapping);
- continue;
- }
-
- mappingsStringBuilder.Append(GenerateMapping(sourceMetadata, methodMetadata.Parameters.First(), matchedSourceMember, matchedTargetMember, inverseMapping));
- }
-
- return mappingsStringBuilder.ToString();
- }
-
- private string MapExpression(MappingAttribute expressionAttribute, ITypeMetadata parameter, IPropertyMetadata matchedSourceMember, IPropertyMetadata matchedTargetMember)
- {
- var mapping = new StringBuilder();
-
- if (expressionAttribute is not null && matchedSourceMember is not null)
- {
- mapping.AppendLine($"target.{expressionAttribute?.Target} = {expressionAttribute?.Expression}({parameter.Name}.{matchedSourceMember.Name});");
- return mapping.ToString();
- }
-
- if (expressionAttribute is not null && matchedTargetMember is not null && matchedSourceMember is null)
- {
- mapping.AppendLine($"target.{expressionAttribute?.Target} = {expressionAttribute?.Expression}({parameter.Name});");
- return mapping.ToString();
- }
-
- return mapping.ToString();
- }
}
}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Generator/Processors/IProcessorStrategy.cs b/Compentio.SourceMapper.Generator/Processors/IProcessorStrategy.cs
index e373b39..733592c 100644
--- a/Compentio.SourceMapper.Generator/Processors/IProcessorStrategy.cs
+++ b/Compentio.SourceMapper.Generator/Processors/IProcessorStrategy.cs
@@ -1,4 +1,5 @@
-using Compentio.SourceMapper.Diagnostics;
+using Compentio.SourceMapper.Attributes;
+using Compentio.SourceMapper.Diagnostics;
using Compentio.SourceMapper.Helpers;
using Compentio.SourceMapper.Matchers;
using Compentio.SourceMapper.Metadata;
@@ -55,9 +56,12 @@ public IResult GenerateCode(IMapperMetadata mapperMetadata)
///
protected abstract string Modifier { get; }
- protected abstract string GenerateMapperCode(IMapperMetadata mapperMetadata);
+ ///
+ /// Determine processor strategy type
+ ///
+ protected abstract ProcessorType ProcessorType { get; }
- protected abstract string GenerateMappings(IMapperMetadata sourceMetadata, IMethodMetadata methodMetadata, bool inverseMapping = false);
+ protected abstract string GenerateMapperCode(IMapperMetadata mapperMetadata);
protected string GenerateMethods(IMapperMetadata sourceMetadata)
{
@@ -85,7 +89,8 @@ protected string GenerateMethod(IMapperMetadata sourceMetadata, IMethodMetadata
var target = new {methodMetadata.ReturnType.FullName}();
- {GenerateMappings(sourceMetadata, methodMetadata)}
+ {GenerateMappings(sourceMetadata, methodMetadata, MemberType.Field)}
+ {GenerateMappings(sourceMetadata, methodMetadata, MemberType.Property)}
return target;
}}";
@@ -100,47 +105,88 @@ protected string GenerateInverseMethod(IMapperMetadata sourceMetadata, IMethodMe
var target = new {methodMetadata.Parameters.First().FullName}();
- {GenerateMappings(sourceMetadata, methodMetadata, true)}
+ {GenerateMappings(sourceMetadata, methodMetadata, MemberType.Field, true)}
+ {GenerateMappings(sourceMetadata, methodMetadata, MemberType.Property, true)}
return target;
}}";
}
- protected string GenerateMapping(IMapperMetadata sourceMetadata, ITypeMetadata parameter, IPropertyMetadata matchedSourceMember, IPropertyMetadata matchedTargetMember, bool inverseMapping = false)
+ protected string GenerateMappings(IMapperMetadata sourceMetadata, IMethodMetadata methodMetadata, MemberType memberType, bool inverseMapping = false)
+ {
+ var mappingsStringBuilder = new StringBuilder();
+ var sourceMembers = GetSourceMembers(methodMetadata, memberType);
+ var targetMemebers = GetTargetMembers(methodMetadata, memberType);
+
+ foreach (var targetMember in targetMemebers)
+ {
+ var matchedSourceMember = sourceMembers.MatchSourceMember(methodMetadata.MappingAttributes, targetMember);
+ var matchedTargetMember = targetMemebers.MatchTargetMember(methodMetadata.MappingAttributes, targetMember);
+
+ if (IgnoreMapping(matchedSourceMember, matchedTargetMember)) continue;
+
+ if (ProcessorType == ProcessorType.Class && memberType == MemberType.Property)
+ {
+ var expressionAttribute = methodMetadata.MappingAttributes.MatchExpressionAttribute(targetMember, matchedSourceMember);
+ var expressionMapping = MapExpression(expressionAttribute, methodMetadata.Parameters.First(), matchedSourceMember, matchedTargetMember);
+
+ if (!string.IsNullOrEmpty(expressionMapping))
+ {
+ if (inverseMapping) continue;
+
+ mappingsStringBuilder.Append(expressionMapping);
+ continue;
+ }
+ }
+
+ mappingsStringBuilder.Append(GenerateMapping(sourceMetadata, methodMetadata, matchedSourceMember, matchedTargetMember, memberType, inverseMapping));
+ }
+
+ return mappingsStringBuilder.ToString();
+ }
+
+ protected string GenerateMapping(IMapperMetadata sourceMetadata, IMethodMetadata methodMetadata, IMemberMetadata matchedSourceMember, IMemberMetadata matchedTargetMember, MemberType memberType, bool inverseMapping = false)
{
if (inverseMapping) ObjectHelper.Swap(ref matchedSourceMember, ref matchedTargetMember);
if (matchedTargetMember is null && matchedSourceMember is not null)
{
- PropertyMappingWarning(matchedSourceMember);
+ MemberMappingWarning(matchedSourceMember);
}
if (matchedSourceMember is null || matchedTargetMember is null)
{
- PropertyMappingWarning(matchedSourceMember ?? matchedTargetMember);
+ MemberMappingWarning(matchedSourceMember ?? matchedTargetMember);
return string.Empty;
}
var mapping = new StringBuilder();
+ if (matchedSourceMember.IsStatic && matchedTargetMember.IsStatic && memberType == MemberType.Field)
+ {
+ mapping.AppendLine(MapStaticProperty(matchedSourceMember, matchedTargetMember, methodMetadata, inverseMapping));
+ return mapping.ToString();
+ }
+
if (!matchedSourceMember.IsClass && !matchedTargetMember.IsClass)
{
- mapping.AppendLine(MapProperty(matchedSourceMember, matchedTargetMember, parameter));
+ mapping.AppendLine(MapProperty(matchedSourceMember, matchedTargetMember, methodMetadata.Parameters.First()));
}
if (matchedSourceMember.IsClass && matchedTargetMember.IsClass)
{
- mapping.AppendLine(MapClass(sourceMetadata, matchedSourceMember, matchedTargetMember, parameter, inverseMapping));
+ mapping.AppendLine(MapClass(sourceMetadata, matchedSourceMember, matchedTargetMember, methodMetadata.Parameters.First(), inverseMapping));
}
+
return mapping.ToString();
}
- protected string MapProperty(IPropertyMetadata matchedSourceMember, IPropertyMetadata matchedTargetMember, ITypeMetadata parameter)
+ protected string MapProperty(IMetadata matchedSourceMember, IMetadata matchedTargetMember, ITypeMetadata parameter)
{
return $"target.{matchedTargetMember?.Name} = {parameter.Name}.{matchedSourceMember?.Name};";
}
- protected string MapClass(IMapperMetadata sourceMetadata, IPropertyMetadata matchedSourceMember, IPropertyMetadata matchedTargetMember, ITypeMetadata parameter, bool inverseMapping)
+ protected string MapClass(IMapperMetadata sourceMetadata, IMemberMetadata matchedSourceMember, IMemberMetadata matchedTargetMember, ITypeMetadata parameter, bool inverseMapping)
{
var method = GetDefinedMethod(sourceMetadata, matchedSourceMember, matchedTargetMember, inverseMapping);
@@ -153,13 +199,40 @@ protected string MapClass(IMapperMetadata sourceMetadata, IPropertyMetadata matc
}
else
{
- PropertyMappingWarning(matchedTargetMember);
+ MemberMappingWarning(matchedTargetMember);
}
return string.Empty;
}
- protected IMethodMetadata? GetDefinedMethod(IMapperMetadata sourceMetadata, IPropertyMetadata matchedSourceMember, IPropertyMetadata matchedTargetMember, bool inverseMapping)
+ protected string MapStaticProperty(IMemberMetadata matchedSourceMember, IMemberMetadata matchedTargetMember, IMethodMetadata methodMetadata, bool inverseMapping)
+ {
+ if (inverseMapping)
+ return $"{methodMetadata.Parameters.First().FullName}.{matchedTargetMember?.Name} = {methodMetadata.ReturnType.FullName}.{matchedSourceMember?.Name};";
+ else
+ return $"{methodMetadata.ReturnType.FullName}.{matchedTargetMember?.Name} = {methodMetadata.Parameters.First().FullName}.{matchedSourceMember?.Name};";
+ }
+
+ protected string MapExpression(MappingAttribute expressionAttribute, ITypeMetadata parameter, IMemberMetadata matchedSourceMember, IMemberMetadata matchedTargetMember)
+ {
+ var mapping = new StringBuilder();
+
+ if (expressionAttribute is not null && matchedSourceMember is not null)
+ {
+ mapping.AppendLine($"target.{expressionAttribute?.Target} = {expressionAttribute?.Expression}({parameter.Name}.{matchedSourceMember.Name});");
+ return mapping.ToString();
+ }
+
+ if (expressionAttribute is not null && matchedTargetMember is not null && matchedSourceMember is null)
+ {
+ mapping.AppendLine($"target.{expressionAttribute?.Target} = {expressionAttribute?.Expression}({parameter.Name});");
+ return mapping.ToString();
+ }
+
+ return mapping.ToString();
+ }
+
+ protected IMethodMetadata? GetDefinedMethod(IMapperMetadata sourceMetadata, IMemberMetadata matchedSourceMember, IMemberMetadata matchedTargetMember, bool inverseMapping)
{
if (inverseMapping)
{
@@ -172,23 +245,66 @@ protected string MapClass(IMapperMetadata sourceMetadata, IPropertyMetadata matc
}
///
- /// Metchod checks that property metadata should be ignored during mapping due to
+ /// Metchod checks that member metadata should be ignored during mapping due to
///
- ///
- ///
+ ///
+ ///
///
- protected bool IgnorePropertyMapping(IPropertyMetadata? sourcePropertyMetadata, IPropertyMetadata? targetPropertyMetadata)
+ protected bool IgnoreMapping(IMemberMetadata? sourceFieldMetadata, IMemberMetadata? targetFieldMetadata)
{
- return (sourcePropertyMetadata?.IgnoreInMapping is true || targetPropertyMetadata?.IgnoreInMapping is true);
+ return (sourceFieldMetadata?.IgnoreInMapping is true || targetFieldMetadata?.IgnoreInMapping is true);
}
- protected void PropertyMappingWarning(IPropertyMetadata metadata)
+ protected void MemberMappingWarning(IMemberMetadata metadata)
{
_diagnostics.Add(new DiagnosticsInfo
{
- DiagnosticDescriptor = SourceMapperDescriptors.PropertyIsNotMapped,
+ DiagnosticDescriptor = metadata.MemberType == MemberType.Field ? SourceMapperDescriptors.FieldIsNotMapped : SourceMapperDescriptors.PropertyIsNotMapped,
Metadata = metadata
});
}
+
+ protected IEnumerable GetSourceMembers(IMethodMetadata methodMetadata, MemberType memberType)
+ {
+ var typeMetadata = methodMetadata.Parameters.First();
+
+ switch (memberType)
+ {
+ case MemberType.Field:
+ return typeMetadata.Fields;
+
+ case MemberType.Property:
+ return typeMetadata.Properties;
+
+ default:
+ return Enumerable.Empty();
+ }
+ }
+
+ protected IEnumerable GetTargetMembers(IMethodMetadata methodMetadata, MemberType memberType)
+ {
+ var typeMetadata = methodMetadata.ReturnType;
+
+ switch (memberType)
+ {
+ case MemberType.Field:
+ return typeMetadata.Fields;
+
+ case MemberType.Property:
+ return typeMetadata.Properties;
+
+ default:
+ return Enumerable.Empty();
+ }
+ }
+ }
+
+ ///
+ /// Encapsulate processor strategy types
+ ///
+ internal enum ProcessorType
+ {
+ Class,
+ Interface
}
}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Generator/Processors/InterfaceProcessorStrategy.cs b/Compentio.SourceMapper.Generator/Processors/InterfaceProcessorStrategy.cs
index 0d3487e..a17abf3 100644
--- a/Compentio.SourceMapper.Generator/Processors/InterfaceProcessorStrategy.cs
+++ b/Compentio.SourceMapper.Generator/Processors/InterfaceProcessorStrategy.cs
@@ -12,6 +12,8 @@ internal class InterfaceProcessorStrategy : AbstractProcessorStrategy
{
protected override string Modifier => "virtual";
+ protected override ProcessorType ProcessorType => ProcessorType.Interface;
+
protected override string GenerateMapperCode(IMapperMetadata mapperMetadata)
{
var result = @$"//
@@ -67,24 +69,5 @@ private string GenerateInterfaceMethod(IMethodMetadata methodMetadata)
{
return $"{methodMetadata.InverseMethodFullName};";
}
-
- protected override string GenerateMappings(IMapperMetadata sourceMetadata, IMethodMetadata methodMetadata, bool inverseMapping = false)
- {
- var mappingsStringBuilder = new StringBuilder();
- var sourceMembers = methodMetadata.Parameters.First().Properties;
- var targetMemebers = methodMetadata.ReturnType.Properties;
-
- foreach (var targetMember in targetMemebers)
- {
- var matchedSourceMember = sourceMembers.MatchSourceMember(methodMetadata.MappingAttributes, targetMember);
- var matchedTargetMember = targetMemebers.MatchTargetMember(methodMetadata.MappingAttributes, targetMember);
-
- if (IgnorePropertyMapping(matchedSourceMember, matchedTargetMember)) continue;
-
- mappingsStringBuilder.Append(GenerateMapping(sourceMetadata, methodMetadata.Parameters.First(), matchedSourceMember, matchedTargetMember, inverseMapping));
- }
-
- return mappingsStringBuilder.ToString();
- }
}
}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Tests/Entities/UserDao.cs b/Compentio.SourceMapper.Tests/Entities/UserDao.cs
index fd98776..31f639b 100644
--- a/Compentio.SourceMapper.Tests/Entities/UserDao.cs
+++ b/Compentio.SourceMapper.Tests/Entities/UserDao.cs
@@ -6,6 +6,11 @@ namespace Compentio.SourceMapper.Tests.Entities
{
public class UserDao
{
+ public static string UserCodeStatic = "UserCodeStaticDao";
+ public string UserCode = "UserCodeDao";
+ [IgnoreMapping]
+ public int IgnoredField;
+
public long UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
@@ -20,6 +25,8 @@ public class UserDao
public class UserDataDao
{
+ public AddressDao AddressField;
+
public long UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
diff --git a/Compentio.SourceMapper.Tests/Entities/UserInfo.cs b/Compentio.SourceMapper.Tests/Entities/UserInfo.cs
index 33988b0..40b6455 100644
--- a/Compentio.SourceMapper.Tests/Entities/UserInfo.cs
+++ b/Compentio.SourceMapper.Tests/Entities/UserInfo.cs
@@ -6,6 +6,9 @@ namespace Compentio.SourceMapper.Tests.Entities
{
public class UserInfo
{
+ public static string UserCodeStatic = "UserCodeStaticInfo";
+ public string UserCode = "UserCodeInfo";
+ public Address AddressField;
public int Id { get; set; }
public string Name { get; set; }
public Sex Sex { get; set; }
diff --git a/Compentio.SourceMapper.Tests/Matchers/AttributesMatchersTests.cs b/Compentio.SourceMapper.Tests/Matchers/AttributesMatchersTests.cs
index 8ebc159..2a9936c 100644
--- a/Compentio.SourceMapper.Tests/Matchers/AttributesMatchersTests.cs
+++ b/Compentio.SourceMapper.Tests/Matchers/AttributesMatchersTests.cs
@@ -15,8 +15,8 @@ public class AttributesMatchersTests
private readonly IFixture _fixture;
private readonly Mock _mockMethodMetadata;
private readonly Mock _mockMappingAttribute;
- private readonly Mock _mockTargetPropertyMetadata;
- private readonly Mock _mockSourcePropertyMetadata;
+ private readonly Mock _mockTargetMemberMetadata;
+ private readonly Mock _mockSourceMemberMetadata;
public AttributesMatchersTests()
{
@@ -25,8 +25,8 @@ public AttributesMatchersTests()
.Customize(new SupportMutableValueTypesCustomization());
_mockMethodMetadata = _fixture.Create>();
_mockMappingAttribute = _fixture.Create>();
- _mockTargetPropertyMetadata = _fixture.Create>();
- _mockSourcePropertyMetadata = _fixture.Create>();
+ _mockTargetMemberMetadata = _fixture.Create>();
+ _mockSourceMemberMetadata = _fixture.Create>();
}
[Fact]
@@ -67,10 +67,10 @@ public void MatchTargetAttribute_Match()
{
// Arrange
IEnumerable mappingAttributes = new List { _mockMappingAttribute.Object };
- _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetPropertyMetadata.Object.Name);
+ _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetMemberMetadata.Object.Name);
// Act
- var result = mappingAttributes.MatchTargetAttribute(_mockTargetPropertyMetadata.Object);
+ var result = mappingAttributes.MatchTargetAttribute(_mockTargetMemberMetadata.Object);
// Assert
result.Should().NotBeNull();
@@ -84,7 +84,7 @@ public void MatchTargetAttribute_NotMatch()
_mockMappingAttribute.Setup(m => m.Target).Returns(string.Empty);
// Act
- var result = mappingAttributes.MatchTargetAttribute(_mockTargetPropertyMetadata.Object);
+ var result = mappingAttributes.MatchTargetAttribute(_mockTargetMemberMetadata.Object);
// Assert
result.Should().BeNull();
@@ -95,11 +95,11 @@ public void MatchExpressionAttribute_MatchSourceAndTarget()
{
// Arrange
IEnumerable mappingAttributes = new List { _mockMappingAttribute.Object };
- _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetPropertyMetadata.Object.Name);
- _mockMappingAttribute.Setup(m => m.Source).Returns(_mockSourcePropertyMetadata.Object.Name);
+ _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetMemberMetadata.Object.Name);
+ _mockMappingAttribute.Setup(m => m.Source).Returns(_mockSourceMemberMetadata.Object.Name);
// Act
- var result = mappingAttributes.MatchExpressionAttribute(_mockTargetPropertyMetadata.Object, _mockSourcePropertyMetadata.Object);
+ var result = mappingAttributes.MatchExpressionAttribute(_mockTargetMemberMetadata.Object, _mockSourceMemberMetadata.Object);
// Assert
result.Should().NotBeNull();
@@ -110,10 +110,10 @@ public void MatchExpressionAttribute_MatchTarget()
{
// Arrange
IEnumerable mappingAttributes = new List { _mockMappingAttribute.Object };
- _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetPropertyMetadata.Object.Name);
+ _mockMappingAttribute.Setup(m => m.Target).Returns(_mockTargetMemberMetadata.Object.Name);
// Act
- var result = mappingAttributes.MatchExpressionAttribute(_mockTargetPropertyMetadata.Object, _mockSourcePropertyMetadata.Object);
+ var result = mappingAttributes.MatchExpressionAttribute(_mockTargetMemberMetadata.Object, _mockSourceMemberMetadata.Object);
// Assert
result.Should().NotBeNull();
@@ -128,7 +128,7 @@ public void MatchExpressionAttribute_NotMatchSourceAndTarget()
_mockMappingAttribute.Setup(m => m.Source).Returns(string.Empty);
// Act
- var result = mappingAttributes.MatchExpressionAttribute(_mockTargetPropertyMetadata.Object, _mockSourcePropertyMetadata.Object);
+ var result = mappingAttributes.MatchExpressionAttribute(_mockTargetMemberMetadata.Object, _mockSourceMemberMetadata.Object);
// Assert
result.Should().BeNull();
@@ -140,10 +140,10 @@ public void MatchExpressionAttribute_NotMatchTarget()
// Arrange
IEnumerable mappingAttributes = new List { _mockMappingAttribute.Object };
_mockMappingAttribute.Setup(m => m.Target).Returns(string.Empty);
- _mockMappingAttribute.Setup(m => m.Source).Returns(_mockSourcePropertyMetadata.Object.Name);
+ _mockMappingAttribute.Setup(m => m.Source).Returns(_mockSourceMemberMetadata.Object.Name);
// Act
- var result = mappingAttributes.MatchExpressionAttribute(_mockTargetPropertyMetadata.Object, _mockSourcePropertyMetadata.Object);
+ var result = mappingAttributes.MatchExpressionAttribute(_mockTargetMemberMetadata.Object, _mockSourceMemberMetadata.Object);
// Assert
result.Should().BeNull();
diff --git a/Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTestBase.cs b/Compentio.SourceMapper.Tests/Metadata/MemberMetadataTestBase.cs
similarity index 90%
rename from Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTestBase.cs
rename to Compentio.SourceMapper.Tests/Metadata/MemberMetadataTestBase.cs
index 3c2581f..01daf7d 100644
--- a/Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTestBase.cs
+++ b/Compentio.SourceMapper.Tests/Metadata/MemberMetadataTestBase.cs
@@ -6,7 +6,7 @@
namespace Compentio.SourceMapper.Tests.Metadata
{
- public abstract class PropertyMetadataTestBase
+ public abstract class MemberMetadataTestBase
{
protected abstract string MockNamespace { get; }
protected abstract string MockClassName { get; }
@@ -27,7 +27,7 @@ protected ImmutableArray GetAttributeDataMock(string sourceCode,
protected Compilation GetCompilationMock(string sourceCode)
{
- return CSharpCompilation.Create("PropertyMetadataTestBase",
+ return CSharpCompilation.Create("MemberMetadataTestBase",
new[] { CSharpSyntaxTree.ParseText(sourceCode) },
new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
@@ -41,13 +41,15 @@ namespace {MockNamespace}
public abstract class {MockClassName}
{{
- public abstract MockTypeDto {MockMethodName}(MockTypeDao fake);
+ public abstract MockTypeDto {MockMethodName}(MockTypeDao mock);
}}
public class MockTypeDao
{{
[IgnoreMapping]
public virtual string PropertyToIgnore {{ get; set; }}
+ public static string StaticFieldProperty;
+ public string FieldProperty;
}}
{IgnoreMappingAttributeSourceCode}
diff --git a/Compentio.SourceMapper.Tests/Metadata/MemberMetadataTests.cs b/Compentio.SourceMapper.Tests/Metadata/MemberMetadataTests.cs
new file mode 100644
index 0000000..1b15ea8
--- /dev/null
+++ b/Compentio.SourceMapper.Tests/Metadata/MemberMetadataTests.cs
@@ -0,0 +1,255 @@
+using AutoFixture;
+using AutoFixture.AutoMoq;
+using Compentio.SourceMapper.Metadata;
+using FluentAssertions;
+using Microsoft.CodeAnalysis;
+using Moq;
+using System.Collections.Immutable;
+using Xunit;
+
+namespace Compentio.SourceMapper.Tests.Metadata
+{
+ public class MemberMetadataTests : MemberMetadataTestBase
+ {
+ private readonly IFixture _fixture;
+ private readonly Mock _mockPropertySymbol;
+ private readonly Mock _mockFieldSymbol;
+ private readonly Mock _mockLocation;
+ private readonly Mock _mockSymbol;
+
+ private const string MockName = "MockName";
+ private const string MockFullName = "MockFullName";
+
+ protected override string MockNamespace => "MockNamespace";
+
+ protected override string MockClassName => "MockClassName";
+
+ protected override string MockMethodName => "MockMethodName";
+
+ public MemberMetadataTests()
+ {
+ _fixture = new Fixture()
+ .Customize(new AutoMoqCustomization { ConfigureMembers = true })
+ .Customize(new SupportMutableValueTypesCustomization());
+ _mockPropertySymbol = _fixture.Create>();
+ _mockFieldSymbol = _fixture.Create>();
+ _mockLocation = _fixture.Create>();
+ _mockSymbol = _fixture.Create>();
+ }
+
+ [Fact]
+ public void InstanceForProperty_ValidNameField()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Name).Returns(MockName);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.Name.Should().Be(MockName);
+ }
+
+ [Fact]
+ public void InstanceForField_ValidNameField()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.Name).Returns(MockName);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.Name.Should().Be(MockName);
+ }
+
+ [Fact]
+ public void InstanceForProperty_ValidFullNameField()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Type.ToDisplayString(It.IsAny())).Returns(MockFullName);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.FullName.Should().Be(MockFullName);
+ }
+
+ [Fact]
+ public void InstanceForField_ValidFullNameField()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.Type.ToDisplayString(It.IsAny())).Returns(MockFullName);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.FullName.Should().Be(MockFullName);
+ }
+
+ [Fact]
+ public void InstanceForProperty_ValidIsClassField()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Class);
+ _mockPropertySymbol.Setup(p => p.Type.SpecialType).Returns(SpecialType.None);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.IsClass.Should().BeTrue();
+ }
+
+ [Fact]
+ public void InstanceForField_ValidIsClassField()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Class);
+ _mockFieldSymbol.Setup(p => p.Type.SpecialType).Returns(SpecialType.None);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.IsClass.Should().BeTrue();
+ }
+
+ [Fact]
+ public void InstanceForProperty_ValidLocationField()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Locations).Returns(ImmutableArray.Create(_mockLocation.Object));
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.Location.Should().NotBeNull();
+ }
+
+ [Fact]
+ public void InstanceForField_ValidLocationField()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.Locations).Returns(ImmutableArray.Create(_mockLocation.Object));
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.Location.Should().NotBeNull();
+ }
+
+ [Fact]
+ public void InstanceForProperty_NotEmptyProperties()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Class);
+ _mockPropertySymbol.Setup(p => p.Type.SpecialType).Returns(SpecialType.None);
+ _mockPropertySymbol.Setup(p => p.Type.GetMembers()).Returns(ImmutableArray.Create(_mockSymbol.Object));
+ _mockSymbol.Setup(s => s.Kind).Returns(SymbolKind.Property);
+ _mockSymbol.Setup(s => s.IsStatic).Returns(false);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.Properties.Should().NotBeEmpty();
+ }
+
+ [Fact]
+ public void InstanceForProperty_EmptyProperties()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Interface);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.Properties.Should().BeEmpty();
+ }
+
+ [Fact]
+ public void InstanceForField_EmptyProperties()
+ {
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.Properties.Should().BeEmpty();
+ }
+
+ [Fact]
+ public void InstanceForProperty_ValidIgnoreInMapping()
+ {
+ // Arrange
+ _mockPropertySymbol.Setup(p => p.GetAttributes()).Returns(GetAttributeDataMock(MockSourceCode, MockMethodName));
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.IgnoreInMapping.Should().BeTrue();
+ }
+
+ [Fact]
+ public void InstanceForField_ValidIgnoreInMapping()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.GetAttributes()).Returns(GetAttributeDataMock(MockSourceCode, MockMethodName));
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.IgnoreInMapping.Should().BeTrue();
+ }
+
+ [Fact]
+ public void InstanceForField_ValidIsStatic()
+ {
+ // Arrange
+ _mockFieldSymbol.Setup(p => p.IsStatic).Returns(true);
+
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.IsStatic.Should().BeTrue();
+ }
+
+ [Fact]
+ public void InstanceForProperty_IsPropertyMember()
+ {
+ // Act
+ var memberMetadata = new MemberMetadata(_mockPropertySymbol.Object);
+
+ // Assert
+ memberMetadata.MemberType.Should().Be(MemberType.Property);
+ }
+
+ [Fact]
+ public void InstanceForField_IsFieldMember()
+ {
+ // Act
+ var memberMetadata = new MemberMetadata(_mockFieldSymbol.Object);
+
+ // Assert
+ memberMetadata.MemberType.Should().Be(MemberType.Field);
+ }
+
+ [Fact]
+ public void Instance_MemberUnknown()
+ {
+ // Act
+ var memberMetadata = new MemberMetadata(_mockSymbol.Object);
+
+ // Assert
+ memberMetadata.MemberType.Should().Be(MemberType.Unknown);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Tests/Metadata/ParameterTypeMetadataTests.cs b/Compentio.SourceMapper.Tests/Metadata/ParameterTypeMetadataTests.cs
index be908c8..ae3e203 100644
--- a/Compentio.SourceMapper.Tests/Metadata/ParameterTypeMetadataTests.cs
+++ b/Compentio.SourceMapper.Tests/Metadata/ParameterTypeMetadataTests.cs
@@ -16,7 +16,7 @@ public class ParameterTypeMetadataTests
private readonly Mock _mockParameterSymbol;
private readonly Mock _mockLocation;
private readonly Mock _mockSymbol;
- private readonly Mock _mockPropertyMetadata;
+ private readonly Mock _mockMemberMetadata;
public ParameterTypeMetadataTests()
{
@@ -26,7 +26,7 @@ public ParameterTypeMetadataTests()
_mockParameterSymbol = _fixture.Create>();
_mockLocation = _fixture.Create>();
_mockSymbol = _fixture.Create>();
- _mockPropertyMetadata = _fixture.Create>();
+ _mockMemberMetadata = _fixture.Create>();
}
[Fact]
@@ -84,15 +84,29 @@ public void Instance_EmptyProperties()
parameterTypeMetadata.Properties.Should().BeEmpty();
}
+ [Fact]
+ public void Instance_EmptyFields()
+ {
+ // Arrange
+ _mockSymbol.Setup(s => s.CanBeReferencedByName).Returns(false);
+ _mockParameterSymbol.Setup(t => t.Type.GetMembers()).Returns(ImmutableArray.Create(_mockSymbol.Object));
+
+ // Act
+ var parameterTypeMetadata = new ParameterTypeMetadata(_mockParameterSymbol.Object);
+
+ // Assert
+ parameterTypeMetadata.Fields.Should().BeEmpty();
+ }
+
[Fact]
public void FlattenProperties_ValidFlatten()
{
// Arrange
- var limitedPropertyMetadata = _fixture.Create>();
- limitedPropertyMetadata.Setup(l => l.Properties).Returns(new List());
+ var limitedPropertyMetadata = _fixture.Create>();
+ limitedPropertyMetadata.Setup(l => l.Properties).Returns(new List());
- _mockPropertyMetadata.Setup(p => p.Properties).Returns(
- new List
+ _mockMemberMetadata.Setup(p => p.Properties).Returns(
+ new List
{
limitedPropertyMetadata.Object,
limitedPropertyMetadata.Object,
@@ -103,7 +117,7 @@ public void FlattenProperties_ValidFlatten()
// Act
var parameterTypeMetadata = new ParameterTypeMetadata(_mockParameterSymbol.Object);
- var result = parameterTypeMetadata.FlattenProperties(new List { _mockPropertyMetadata.Object });
+ var result = parameterTypeMetadata.FlattenProperties(new List { _mockMemberMetadata.Object });
// Assert
result.Should().NotBeEmpty();
diff --git a/Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTests.cs b/Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTests.cs
deleted file mode 100644
index acb3098..0000000
--- a/Compentio.SourceMapper.Tests/Metadata/PropertyMetadataTests.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-using AutoFixture;
-using AutoFixture.AutoMoq;
-using Compentio.SourceMapper.Metadata;
-using FluentAssertions;
-using Microsoft.CodeAnalysis;
-using Moq;
-using System.Collections.Immutable;
-using Xunit;
-
-namespace Compentio.SourceMapper.Tests.Metadata
-{
- public class PropertyMetadataTests : PropertyMetadataTestBase
- {
- private readonly IFixture _fixture;
- private readonly Mock _mockPropertySymbol;
- private readonly Mock _mockLocation;
- private readonly Mock _mockSymbol;
-
- protected override string MockNamespace => "MockNamespace";
-
- protected override string MockClassName => "MockClassName";
-
- protected override string MockMethodName => "MockMethodName";
-
- public PropertyMetadataTests()
- {
- _fixture = new Fixture()
- .Customize(new AutoMoqCustomization { ConfigureMembers = true })
- .Customize(new SupportMutableValueTypesCustomization());
- _mockPropertySymbol = _fixture.Create>();
- _mockLocation = _fixture.Create>();
- _mockSymbol = _fixture.Create>();
- }
-
- [Fact]
- public void InstanceForClass_ValidNameField()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Name).Returns("Name");
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.Name.Should().Be("Name");
- }
-
- [Fact]
- public void InstanceForClass_ValidFullNameField()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Type.ToDisplayString(It.IsAny())).Returns("FullName");
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.FullName.Should().Be("FullName");
- }
-
- [Fact]
- public void InstanceForClass_ValidIsClassField()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Class);
- _mockPropertySymbol.Setup(p => p.Type.SpecialType).Returns(SpecialType.None);
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.IsClass.Should().BeTrue();
- }
-
- [Fact]
- public void InstanceForClass_ValidLocationField()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Locations).Returns(ImmutableArray.Create(_mockLocation.Object));
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.Location.Should().NotBeNull();
- }
-
- [Fact]
- public void InstanceForClass_NotEmptyProperties()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Class);
- _mockPropertySymbol.Setup(p => p.Type.SpecialType).Returns(SpecialType.None);
- _mockPropertySymbol.Setup(p => p.Type.GetMembers()).Returns(ImmutableArray.Create(_mockSymbol.Object));
- _mockSymbol.Setup(s => s.Kind).Returns(SymbolKind.Property);
- _mockSymbol.Setup(s => s.IsStatic).Returns(false);
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.Properties.Should().NotBeEmpty();
- }
-
- [Fact]
- public void InstanceForInterface_EmptyProperties()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.Type.TypeKind).Returns(TypeKind.Interface);
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.Properties.Should().BeEmpty();
- }
-
- [Fact]
- public void InstanceForClass_ValidIgnoreInMapping()
- {
- // Arrange
- _mockPropertySymbol.Setup(p => p.GetAttributes()).Returns(GetAttributeDataMock(MockSourceCode, MockMethodName));
-
- // Act
- var propertyMetadata = new PropertyMetadata(_mockPropertySymbol.Object);
-
- // Assert
- propertyMetadata.IgnoreInMapping.Should().BeTrue();
- }
- }
-}
\ No newline at end of file
diff --git a/Compentio.SourceMapper.Tests/Metadata/TypeMetadataTests.cs b/Compentio.SourceMapper.Tests/Metadata/TypeMetadataTests.cs
index 056e7e0..dc2e0a5 100644
--- a/Compentio.SourceMapper.Tests/Metadata/TypeMetadataTests.cs
+++ b/Compentio.SourceMapper.Tests/Metadata/TypeMetadataTests.cs
@@ -16,7 +16,7 @@ public class TypeMetadataTests
private readonly Mock _mockTypeSymbol;
private readonly Mock _mockLocation;
private readonly Mock _mockSymbol;
- private readonly Mock _mockPropertyMetadata;
+ private readonly Mock _mockMemberMetadata;
public TypeMetadataTests()
{
@@ -26,7 +26,7 @@ public TypeMetadataTests()
_mockTypeSymbol = _fixture.Create>();
_mockLocation = _fixture.Create>();
_mockSymbol = _fixture.Create>();
- _mockPropertyMetadata = _fixture.Create>();
+ _mockMemberMetadata = _fixture.Create>();
}
[Fact]
@@ -95,6 +95,23 @@ public void Instanc_NotEmptyProperties()
typeMetadata.Properties.Should().NotBeEmpty();
}
+ [Fact]
+ public void Instanc_NotEmptyFields()
+ {
+ // Arrange
+ var mockFieldSymbol = _fixture.Create>();
+ mockFieldSymbol.Setup(s => s.Kind).Returns(SymbolKind.Field);
+ mockFieldSymbol.Setup(s => s.CanBeReferencedByName).Returns(true);
+ mockFieldSymbol.Setup(s => s.IsConst).Returns(false);
+ _mockTypeSymbol.Setup(t => t.GetMembers()).Returns(ImmutableArray.Create(mockFieldSymbol.Object as ISymbol));
+
+ // Act
+ var typeMetadata = new TypeMetadata(_mockTypeSymbol.Object);
+
+ // Assert
+ typeMetadata.Fields.Should().NotBeEmpty();
+ }
+
[Fact]
public void Instanc_EmptyProperties()
{
@@ -110,15 +127,29 @@ public void Instanc_EmptyProperties()
typeMetadata.Properties.Should().BeEmpty();
}
+ [Fact]
+ public void Instanc_EmptyFields()
+ {
+ // Arrange
+ _mockTypeSymbol.Setup(t => t.GetMembers()).Returns(ImmutableArray.Create(_mockSymbol.Object));
+ _mockSymbol.Setup(s => s.Kind).Returns(SymbolKind.ErrorType);
+
+ // Act
+ var typeMetadata = new TypeMetadata(_mockTypeSymbol.Object);
+
+ // Assert
+ typeMetadata.Fields.Should().BeEmpty();
+ }
+
[Fact]
public void FlattenProperties_ValidFlatten()
{
// Arrange
- var limitedPropertyMetadata = _fixture.Create>();
- limitedPropertyMetadata.Setup(l => l.Properties).Returns(new List());
+ var limitedPropertyMetadata = _fixture.Create>();
+ limitedPropertyMetadata.Setup(l => l.Properties).Returns(new List());
- _mockPropertyMetadata.Setup(p => p.Properties).Returns(
- new List
+ _mockMemberMetadata.Setup(p => p.Properties).Returns(
+ new List
{
limitedPropertyMetadata.Object,
limitedPropertyMetadata.Object,
@@ -129,7 +160,7 @@ public void FlattenProperties_ValidFlatten()
// Act
var typeMetadata = new TypeMetadata(_mockTypeSymbol.Object);
- var result = typeMetadata.FlattenProperties(new List { _mockPropertyMetadata.Object });
+ var result = typeMetadata.FlattenProperties(new List { _mockMemberMetadata.Object });
// Assert
result.Should().NotBeEmpty();
diff --git a/Compentio.SourceMapper.Tests/Processors/ClassProcessorStrategyTests.cs b/Compentio.SourceMapper.Tests/Processors/ClassProcessorStrategyTests.cs
index e5c116d..0c4d203 100644
--- a/Compentio.SourceMapper.Tests/Processors/ClassProcessorStrategyTests.cs
+++ b/Compentio.SourceMapper.Tests/Processors/ClassProcessorStrategyTests.cs
@@ -93,7 +93,7 @@ public void GenerateCode_UnmatchedData_ReportNotMapped()
// Arrange
var methodMetadata = GetValidMethodWithAttributes(_mockMappingAttribute);
// Create unmatched mock source and target metadata
- methodMetadata.Setup(m => m.ReturnType.Properties).Returns(_fixture.Create>());
+ methodMetadata.Setup(m => m.ReturnType.Properties).Returns(_fixture.Create>());
methodMetadata.Setup(m => m.Parameters).Returns(_fixture.Create>());
_sourceMetadataMock.Setup(sourceMetadata => sourceMetadata.MethodsMetadata).Returns(new List { methodMetadata.Object });
@@ -101,7 +101,8 @@ public void GenerateCode_UnmatchedData_ReportNotMapped()
var result = _processorStrategy.GenerateCode(_sourceMetadataMock.Object);
// Assert
- result.Diagnostics.Should().Contain(d => d.DiagnosticDescriptor == SourceMapperDescriptors.PropertyIsNotMapped);
+ result.Diagnostics.Should().Contain(d => d.DiagnosticDescriptor == SourceMapperDescriptors.PropertyIsNotMapped ||
+ d.DiagnosticDescriptor == SourceMapperDescriptors.FieldIsNotMapped);
}
[Fact]
@@ -138,13 +139,13 @@ private Mock GetValidMethodWithAttributes(Mock>();
// Create new method property
- var mockProperty = _fixture.Create>();
+ var mockProperty = _fixture.Create>();
mockProperty.Setup(p => p.IsClass).Returns(false);
mockProperty.Setup(p => p.IgnoreInMapping).Returns(ignoreInMapping);
// Inject property
var mockTypeMetadata = _fixture.Create>();
- mockTypeMetadata.Setup(t => t.Properties).Returns(new List { mockProperty.Object });
+ mockTypeMetadata.Setup(t => t.Properties).Returns(new List { mockProperty.Object });
var sourceParameters = mockTypeMetadata.Object;
var mockParameters = GetValidMethodParameters(sourceParameters);
@@ -164,7 +165,7 @@ private Mock GetValidMethodParameters(ITypeMetadata sourceTypeMet
mockParameters.Setup(p => p.Name).Returns(sourceTypeMetadata.Name);
mockParameters.Setup(p => p.FullName).Returns(sourceTypeMetadata.FullName);
mockParameters.Setup(p => p.Location).Returns(sourceTypeMetadata.Location);
- mockParameters.Setup(p => p.Properties).Returns(new List { sourceTypeMetadata.Properties.First() });
+ mockParameters.Setup(p => p.Properties).Returns(new List { sourceTypeMetadata.Properties.First() });
return mockParameters;
}
diff --git a/Compentio.SourceMapper.Tests/Processors/ClassUserMapperTests.cs b/Compentio.SourceMapper.Tests/Processors/ClassUserMapperTests.cs
index 5bc8448..a71e0a9 100644
--- a/Compentio.SourceMapper.Tests/Processors/ClassUserMapperTests.cs
+++ b/Compentio.SourceMapper.Tests/Processors/ClassUserMapperTests.cs
@@ -36,7 +36,9 @@ public void Mapper_User_Dao_Match_Converters()
mappingResult.Name.Should().Be($"{userDao.FirstName} {userDao.LastName}");
mappingResult.BirthDate.Should().Be(userDao.BirthDate);
mappingResult.Id.Should().Be((int)userDao.UserId);
- mappingResult.Sex.Should().Be(Sex.W);
+ mappingResult.Sex.Should().Be(Sex.W);
+ mappingResult.UserCode.Should().Be(userDao.UserCode);
+ UserInfo.UserCodeStatic.Should().Be(UserDao.UserCodeStatic);
}
[Fact]
@@ -54,6 +56,8 @@ public void Mapper_User_Info_Match_Converters()
// Assert
mappingResult.BirthDate.Should().Be(userInfo.BirthDate);
mappingResult.UserGender.Should().Be(UserGender.Female);
+ mappingResult.UserCode.Should().Be(userInfo.UserCode);
+ UserDao.UserCodeStatic.Should().Be(UserInfo.UserCodeStatic);
// Not mapped
mappingResult.UserId.Should().NotBe(userInfo.Id);
diff --git a/Compentio.SourceMapper.Tests/Processors/InterfaceProcessorStrategyTests.cs b/Compentio.SourceMapper.Tests/Processors/InterfaceProcessorStrategyTests.cs
index c7750a4..a18a37f 100644
--- a/Compentio.SourceMapper.Tests/Processors/InterfaceProcessorStrategyTests.cs
+++ b/Compentio.SourceMapper.Tests/Processors/InterfaceProcessorStrategyTests.cs
@@ -90,7 +90,7 @@ public void GenerateCode_UnmatchedData_ReportNotMapped()
{
// Arrange
var methodMetadata = GetValidMethodWithAttributes(_mockMappingAttribute);
- methodMetadata.Setup(m => m.ReturnType.Properties).Returns(_fixture.Create>());
+ methodMetadata.Setup(m => m.ReturnType.Properties).Returns(_fixture.Create>());
methodMetadata.Setup(m => m.Parameters).Returns(_fixture.Create>());
_sourceMetadataMock.Setup(sourceMetadata => sourceMetadata.MethodsMetadata).Returns(new List { methodMetadata.Object });
@@ -98,7 +98,8 @@ public void GenerateCode_UnmatchedData_ReportNotMapped()
var result = _processorStrategy.GenerateCode(_sourceMetadataMock.Object);
// Assert
- result.Diagnostics.Should().Contain(d => d.DiagnosticDescriptor == SourceMapperDescriptors.PropertyIsNotMapped);
+ result.Diagnostics.Should().Contain(d => d.DiagnosticDescriptor == SourceMapperDescriptors.PropertyIsNotMapped ||
+ d.DiagnosticDescriptor == SourceMapperDescriptors.FieldIsNotMapped);
}
[Fact]
@@ -135,13 +136,13 @@ private Mock GetValidMethodWithAttributes(Mock>();
// Create new method property
- var mockProperty = _fixture.Create>();
+ var mockProperty = _fixture.Create>();
mockProperty.Setup(p => p.IsClass).Returns(false);
mockProperty.Setup(p => p.IgnoreInMapping).Returns(ignoreInMapping);
// Inject property
var mockTypeMetadata = _fixture.Create>();
- mockTypeMetadata.Setup(t => t.Properties).Returns(new List { mockProperty.Object });
+ mockTypeMetadata.Setup(t => t.Properties).Returns(new List { mockProperty.Object });
var sourceParameters = mockTypeMetadata.Object;
var mockParameters = GetValidMethodParameters(sourceParameters);
@@ -161,7 +162,7 @@ private Mock GetValidMethodParameters(ITypeMetadata sourceTypeMet
mockParameters.Setup(p => p.Name).Returns(sourceTypeMetadata.Name);
mockParameters.Setup(p => p.FullName).Returns(sourceTypeMetadata.FullName);
mockParameters.Setup(p => p.Location).Returns(sourceTypeMetadata.Location);
- mockParameters.Setup(p => p.Properties).Returns(new List { sourceTypeMetadata.Properties.First() });
+ mockParameters.Setup(p => p.Properties).Returns(new List { sourceTypeMetadata.Properties.First() });
return mockParameters;
}
diff --git a/Compentio.SourceMapper.Tests/Processors/InterfaceUserMapperTests.cs b/Compentio.SourceMapper.Tests/Processors/InterfaceUserMapperTests.cs
index 6db63e8..d0d523e 100644
--- a/Compentio.SourceMapper.Tests/Processors/InterfaceUserMapperTests.cs
+++ b/Compentio.SourceMapper.Tests/Processors/InterfaceUserMapperTests.cs
@@ -31,6 +31,8 @@ public void Mapper_User_Dao_Match_Properties_And_Attributes()
// Assert
mappingResult.Name.Should().Be(userDao.FirstName);
mappingResult.BirthDate.Should().Be(userDao.BirthDate);
+ mappingResult.UserCode.Should().Be(userDao.UserCode);
+ UserInfo.UserCodeStatic.Should().Be(UserDao.UserCodeStatic);
// Not mapped
mappingResult.Id.Should().NotBe((int)userDao.UserId);
mappingResult.Address.Should().BeNull();
@@ -49,6 +51,8 @@ public void Mapper_User_Info_Match_Properties_And_Attributes()
// Assert
mappingResult.FirstName.Should().Be(userInfo.Name);
mappingResult.BirthDate.Should().Be(userInfo.BirthDate);
+ mappingResult.UserCode.Should().Be(userInfo.UserCode);
+ UserDao.UserCodeStatic.Should().Be(UserInfo.UserCodeStatic);
//// Not mapped
mappingResult.UserId.Should().NotBe(userInfo.Id);
mappingResult.City.Should().BeNull();
@@ -87,7 +91,7 @@ public void Mapper_User_Data_Dao_Match_Properties_And_Attributes()
mappingResult.Name.Should().Be(userDataDao.FirstName);
mappingResult.BirthDate.Should().Be(userDataDao.BirthDate);
-
+ // Property
mappingResult.Address.Should().NotBeNull();
mappingResult.Address.City.Should().Be(userDataDao.UserAddress.City);
mappingResult.Address.House.Should().Be(userDataDao.UserAddress.House);
@@ -96,6 +100,15 @@ public void Mapper_User_Data_Dao_Match_Properties_And_Attributes()
mappingResult.Address.Region.Should().NotBeNull();
mappingResult.Address.Region.State.Should().Be(userDataDao.UserAddress.Region.State);
mappingResult.Address.Region.District.Should().Be(userDataDao.UserAddress.Region.District);
+ // Field
+ mappingResult.AddressField.Should().NotBeNull();
+ mappingResult.AddressField.City.Should().Be(userDataDao.AddressField.City);
+ mappingResult.AddressField.House.Should().Be(userDataDao.AddressField.House);
+ mappingResult.AddressField.Street.Should().Be(userDataDao.AddressField.Street);
+
+ mappingResult.AddressField.Region.Should().NotBeNull();
+ mappingResult.AddressField.Region.State.Should().Be(userDataDao.AddressField.Region.State);
+ mappingResult.AddressField.Region.District.Should().Be(userDataDao.AddressField.Region.District);
}
[Fact]
@@ -113,7 +126,7 @@ public void Mapper_User_Data_Info_Match_Properties_And_Attributes()
mappingResult.FirstName.Should().Be(userInfo.Name);
mappingResult.BirthDate.Should().Be(userInfo.BirthDate);
-
+ // Property
mappingResult.UserAddress.Should().NotBeNull();
mappingResult.UserAddress.City.Should().Be(userInfo.Address.City);
mappingResult.UserAddress.House.Should().Be(userInfo.Address.House);
@@ -122,6 +135,15 @@ public void Mapper_User_Data_Info_Match_Properties_And_Attributes()
mappingResult.UserAddress.Region.Should().NotBeNull();
mappingResult.UserAddress.Region.State.Should().Be(userInfo.Address.Region.State);
mappingResult.UserAddress.Region.District.Should().Be(userInfo.Address.Region.District);
+ // Field
+ mappingResult.AddressField.Should().NotBeNull();
+ mappingResult.AddressField.City.Should().Be(userInfo.AddressField.City);
+ mappingResult.AddressField.House.Should().Be(userInfo.AddressField.House);
+ mappingResult.AddressField.Street.Should().Be(userInfo.AddressField.Street);
+
+ mappingResult.AddressField.Region.Should().NotBeNull();
+ mappingResult.AddressField.Region.State.Should().Be(userInfo.AddressField.Region.State);
+ mappingResult.AddressField.Region.District.Should().Be(userInfo.AddressField.Region.District);
}
[Fact]
diff --git a/README.md b/README.md
index be02bd0..471aecd 100644
--- a/README.md
+++ b/README.md
@@ -42,11 +42,11 @@ public interface INotesMapper
NoteDto MapToDto(NoteDao source);
}
```
-This will generate mapping class with default class name `NotesMapper` for properties that names are the same for `NoteDto` and `NoteDao` classes.
+This will generate mapping class with default class name `NotesMapper` for properties and fields that names are the same for `NoteDto` and `NoteDao` classes.
The generated class is in the same namespace as its base abstract class of interface. It can be found in project in Visual Studio:
> Dependencies -> Analyzers -> Compentio.SourceMapper.Generators.MainSourceGenerator.
-When the names are different than we can use `Source` and `Target` names of the properties:
+When the names are different than we can use `Source` and `Target` names of the properties or fields:
```csharp
[Mapper(ClassName = "InterfaceUserMapper")]
@@ -149,13 +149,13 @@ public abstract class NotesClassMapper
```
-`Expression` - it is a name of mapping function, that can be used for additional properties mapping.
+`Expression` - it is a name of mapping function, that can be used for additional properties/fields mapping.
> It must be `public` or `protected`, since it is used in generated mapper class that implements abstract mapping class.
## Ignore mapping
-If for any reason part of the class/interface properties should not be mapped, `IgnoreMapping` attribute should be used for that.
-Added `IgnoreMapping` causes that both source and target property during mapping generation will be omitted, not generating any linked map and not reporting any warning in diagnostics.
+If for any reason part of the class/interface properties or fields should not be mapped, `IgnoreMapping` attribute should be used for that.
+Added `IgnoreMapping` causes that both source and target property/field during mapping generation will be omitted, not generating any linked map and not reporting any warning in diagnostics.
If we have two classes `NoteDao` and `NoteDto`
```csharp