Skip to content

Commit

Permalink
collection expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
lbargaoanu committed May 15, 2024
1 parent 6bb05d5 commit c0349ec
Show file tree
Hide file tree
Showing 21 changed files with 114 additions and 130 deletions.
8 changes: 4 additions & 4 deletions src/AutoMapper/Configuration/INamingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface INamingConvention
public sealed class ExactMatchNamingConvention : INamingConvention
{
public static readonly ExactMatchNamingConvention Instance = new();
public string[] Split(string _) => Array.Empty<string>();
public string[] Split(string _) => [];
public string SeparatorCharacter => null;
}
public sealed class PascalCaseNamingConvention : INamingConvention
Expand All @@ -26,17 +26,17 @@ public string[] Split(string input)
{
if (char.IsUpper(input[index]))
{
result ??= new();
result ??= [];
result.Add(input[lower..index]);
lower = index;
}
}
if (result == null)
{
return Array.Empty<string>();
return [];
}
result.Add(input[lower..]);
return result.ToArray();
return [..result];
}
}
public sealed class LowerUnderscoreNamingConvention : INamingConvention
Expand Down
24 changes: 12 additions & 12 deletions src/AutoMapper/Configuration/MapperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,24 @@ public sealed class MapperConfiguration : IGlobalConfiguration
private readonly ConfigurationValidator _validator;
private readonly Features<IRuntimeFeature> _features = new();
private readonly bool _hasOpenMaps;
private readonly HashSet<TypeMap> _typeMapsPath = new();
private readonly List<MemberInfo> _sourceMembers = new();
private readonly List<ParameterExpression> _variables = new();
private readonly ParameterExpression[] _parameters = new[] { null, null, ContextParameter };
private readonly CatchBlock[] _catches = new CatchBlock[1];
private readonly List<Expression> _expressions = new();
private readonly HashSet<TypeMap> _typeMapsPath = [];
private readonly List<MemberInfo> _sourceMembers = [];
private readonly List<ParameterExpression> _variables = [];
private readonly ParameterExpression[] _parameters = [null, null, ContextParameter];
private readonly CatchBlock[] _catches = [null];
private readonly List<Expression> _expressions = [];
private readonly Dictionary<Type, DefaultExpression> _defaults;
private readonly ParameterReplaceVisitor _parameterReplaceVisitor = new();
private readonly ConvertParameterReplaceVisitor _convertParameterReplaceVisitor = new();
private readonly List<Type> _typesInheritance = new();
private readonly List<Type> _typesInheritance = [];
public MapperConfiguration(MapperConfigurationExpression configurationExpression)
{
var configuration = (IGlobalConfigurationExpression)configurationExpression;
if (configuration.MethodMappingEnabled != false)
{
configuration.IncludeSourceExtensionMethods(typeof(Enumerable));
}
_mappers = configuration.Mappers.ToArray();
_mappers = [..configuration.Mappers];
_executionPlans = new(CompileExecutionPlan);
_validator = new(configuration);
_projectionBuilder = new(CreateProjectionBuilder);
Expand Down Expand Up @@ -224,7 +224,7 @@ LambdaExpression GenerateObjectMapperExpression(in MapRequest mapRequest, IObjec
}
}
IGlobalConfigurationExpression ConfigurationExpression => _validator.Expression;
ProjectionBuilder CreateProjectionBuilder() => new(this, ConfigurationExpression.ProjectionMappers.ToArray());
ProjectionBuilder CreateProjectionBuilder() => new(this, [..ConfigurationExpression.ProjectionMappers]);
IProjectionBuilder IGlobalConfiguration.ProjectionBuilder => _projectionBuilder.Value;
Func<Type, object> IGlobalConfiguration.ServiceCtor => ConfigurationExpression.ServiceCtor;
bool IGlobalConfiguration.EnableNullPropagationForQueryMapping => ConfigurationExpression.EnableNullPropagationForQueryMapping.GetValueOrDefault();
Expand Down Expand Up @@ -320,7 +320,7 @@ private TypeMap GetTypeMap(TypePair initialTypes)
List<Type> typesInheritance;
if (_typesInheritance == null)
{
typesInheritance = new();
typesInheritance = [];
}
else
{
Expand Down Expand Up @@ -432,7 +432,7 @@ TypeMap[] IGlobalConfiguration.GetIncludedTypeMaps(IReadOnlyCollection<TypePair>
{
if (includedTypes.Count == 0)
{
return Array.Empty<TypeMap>();
return [];
}
var typeMaps = new TypeMap[includedTypes.Count];
int index = 0;
Expand Down Expand Up @@ -476,7 +476,7 @@ IObjectMapper FindMapper(TypePair types)
return null;
}
void IGlobalConfiguration.RegisterTypeMap(TypeMap typeMap) => _configuredMaps[typeMap.Types] = typeMap;
void IGlobalConfiguration.AssertConfigurationIsValid(TypeMap typeMap) => _validator.AssertConfigurationIsValid(this, new[] { typeMap });
void IGlobalConfiguration.AssertConfigurationIsValid(TypeMap typeMap) => _validator.AssertConfigurationIsValid(this, [typeMap]);
void IGlobalConfiguration.AssertConfigurationIsValid(string profileName)
{
if (Array.TrueForAll(Profiles, x => x.Name != profileName))
Expand Down
2 changes: 1 addition & 1 deletion src/AutoMapper/Configuration/MappingExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public sealed class MappingExpression : MappingExpressionBase<object, object, IM
{
public MappingExpression(TypePair types, MemberList memberList) : base(memberList, types){}
public MappingExpression(TypeMap typeMap) : this(typeMap.Types, typeMap.ConfiguredMemberList) => Projection = typeMap.Projection;
public string[] IncludedMembersNames { get; internal set; } = Array.Empty<string>();
public string[] IncludedMembersNames { get; internal set; } = [];
public IMappingExpression ReverseMap()
{
var reversedTypes = new TypePair(DestinationType, SourceType);
Expand Down
18 changes: 9 additions & 9 deletions src/AutoMapper/Configuration/Profile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public interface IProfileConfiguration
/// </summary>
public class Profile : IProfileExpressionInternal, IProfileConfiguration
{
private readonly List<string> _prefixes = new() { "Get" };
private readonly List<string> _postfixes = new();
private readonly List<TypeMapConfiguration> _typeMapConfigs = new();
private readonly List<string> _prefixes = ["Get"];
private readonly List<string> _postfixes = [];
private readonly List<TypeMapConfiguration> _typeMapConfigs = [];
private readonly PrePostfixName _prePostfixName = new();
private ReplaceName _replaceName;
private readonly MemberConfiguration _memberConfiguration;
Expand Down Expand Up @@ -108,20 +108,20 @@ public INamingConvention DestinationMemberNamingConvention
get => _memberConfiguration.DestinationNamingConvention;
set => _memberConfiguration.DestinationNamingConvention = value;
}
public List<ValueTransformerConfiguration> ValueTransformers => _valueTransformerConfigs ??= new();
public List<ValueTransformerConfiguration> ValueTransformers => _valueTransformerConfigs ??= [];
List<string> IProfileExpressionInternal.Prefixes => _prefixes;
List<string> IProfileExpressionInternal.Postfixes => _postfixes;
public void DisableConstructorMapping() => _constructorMappingEnabled = false;

void IProfileExpressionInternal.ForAllMaps(Action<TypeMap, IMappingExpression> configuration)
{
_allTypeMapActions ??= new();
_allTypeMapActions ??= [];
_allTypeMapActions.Add(configuration);
}

void IProfileExpressionInternal.ForAllPropertyMaps(Func<PropertyMap, bool> condition, Action<PropertyMap, IMemberConfigurationExpression> configuration)
{
_allPropertyMapActions ??= new();
_allPropertyMapActions ??= [];
_allPropertyMapActions.Add(new(condition, configuration));
}
public IProjectionExpression<TSource, TDestination> CreateProjection<TSource, TDestination>() =>
Expand Down Expand Up @@ -149,7 +149,7 @@ public IMappingExpression CreateMap(Type sourceType, Type destinationType, Membe
_typeMapConfigs.Add(map);
if (types.ContainsGenericParameters)
{
_openTypeMapConfigs ??= new();
_openTypeMapConfigs ??= [];
_openTypeMapConfigs.Add(map);
}
return map;
Expand All @@ -170,12 +170,12 @@ public void ReplaceMemberName(string original, string newValue)
public void RecognizeDestinationPostfixes(params string[] postfixes) => _prePostfixName.DestinationPostfixes.TryAdd(postfixes);
public void AddGlobalIgnore(string propertyNameStartingWith)
{
_globalIgnores ??= new();
_globalIgnores ??= [];
_globalIgnores.Add(propertyNameStartingWith);
}
public void IncludeSourceExtensionMethods(Type type)
{
_sourceExtensionMethods ??= new();
_sourceExtensionMethods ??= [];
_sourceExtensionMethods.AddRange(
type.GetMethods(Internal.TypeExtensions.StaticFlags).Where(m => m.Has<ExtensionAttribute>() && m.GetParameters().Length == 1));
}
Expand Down
2 changes: 1 addition & 1 deletion src/AutoMapper/Configuration/TypeMapConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ private void MapDestinationCtorToSource(TypeMap typeMap, List<MemberInfo> source
bool IsConfigured(ParameterInfo parameter) => _ctorParamConfigurations?.Any(c => c.CtorParamName == parameter.Name) is true;
}
protected IEnumerable<IPropertyMapConfiguration> MapToSourceMembers() =>
_memberConfigurations?.Where(m => m.SourceExpression != null && m.SourceExpression.Body == m.SourceExpression.Parameters[0]) ?? Array.Empty<IPropertyMapConfiguration>();
_memberConfigurations?.Where(m => m.SourceExpression != null && m.SourceExpression.Body == m.SourceExpression.Parameters[0]) ?? [];
private void ReverseIncludedMembers(TypeMap typeMap)
{
Stack<Member> chain = null;
Expand Down
4 changes: 2 additions & 2 deletions src/AutoMapper/ConstructorMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public sealed class ConstructorMap
{
private bool? _canResolve;
private readonly List<ConstructorParameterMap> _ctorParams = new();
private readonly List<ConstructorParameterMap> _ctorParams = [];
public ConstructorInfo Ctor { get; private set; }
public IReadOnlyCollection<ConstructorParameterMap> CtorParams => _ctorParams;
public void Reset(ConstructorInfo ctor)
Expand Down Expand Up @@ -76,7 +76,7 @@ public ConstructorParameterMap(TypeMap typeMap, ParameterInfo parameter, MemberI
}
else
{
SourceMembers = Array.Empty<MemberInfo>();
SourceMembers = [];
}
}
public ParameterInfo Parameter { get; }
Expand Down
8 changes: 4 additions & 4 deletions src/AutoMapper/Execution/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static (List<ParameterExpression> Variables, List<Expression> Expressions
var variables = configuration?.Variables;
if (variables == null)
{
variables = new();
variables = [];
}
else
{
Expand All @@ -51,7 +51,7 @@ public static (List<ParameterExpression> Variables, List<Expression> Expressions
var expressions = configuration?.Expressions;
if (expressions == null)
{
expressions = new();
expressions = [];
}
else
{
Expand Down Expand Up @@ -234,7 +234,7 @@ public static MemberInfo[] ToMemberInfos(this Stack<Member> chain)
}
public static Stack<Member> GetChain(this Expression expression)
{
var stack = new Stack<Member>();
Stack<Member> stack = [];
while (expression != null)
{
var member = expression switch
Expand All @@ -260,7 +260,7 @@ public static IEnumerable<MemberExpression> GetMemberExpressions(this Expression
{
if (expression is not MemberExpression memberExpression)
{
return Array.Empty<MemberExpression>();
return [];
}
return expression.GetChain().Select(m => m.Expression as MemberExpression).TakeWhile(m => m != null);
}
Expand Down
4 changes: 2 additions & 2 deletions src/AutoMapper/Execution/ObjectFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class ObjectFactory
};
private static Expression CallConstructor(Type type, IGlobalConfiguration configuration)
{
var defaultCtor = type.GetConstructor(Internal.TypeExtensions.InstanceFlags, null, Type.EmptyTypes, null);
var defaultCtor = type.GetConstructor(Internal.TypeExtensions.InstanceFlags, []);
if (defaultCtor != null)
{
return New(defaultCtor);
Expand All @@ -39,7 +39,7 @@ private static Expression CallConstructor(Type type, IGlobalConfiguration config
type.IsGenericType(typeof(ISet<>)) ? CreateCollection(type, typeof(HashSet<>)) :
type.IsCollection() ? CreateCollection(type, typeof(List<>), GetIEnumerableArguments(type)) :
InvalidType(type, $"Cannot create an instance of interface type {type}.");
private static Type[] GetIEnumerableArguments(Type type) => type.GetIEnumerableType()?.GenericTypeArguments ?? new[] { typeof(object) };
private static Type[] GetIEnumerableArguments(Type type) => type.GetIEnumerableType()?.GenericTypeArguments ?? [typeof(object)];
private static Expression CreateCollection(Type type, Type collectionType, Type[] genericArguments = null) =>
ToType(New(collectionType.MakeGenericType(genericArguments ?? type.GenericTypeArguments)), type);
private static Expression CreateReadOnlyDictionary(Type[] typeArguments)
Expand Down
25 changes: 12 additions & 13 deletions src/AutoMapper/Execution/ProxyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ namespace AutoMapper.Execution;

public static class ProxyGenerator
{
private static readonly MethodInfo DelegateCombine = typeof(Delegate).GetMethod(nameof(Delegate.Combine), new[] { typeof(Delegate), typeof(Delegate) });
private static readonly MethodInfo DelegateCombine = typeof(Delegate).GetMethod(nameof(Delegate.Combine), [typeof(Delegate), typeof(Delegate)]);
private static readonly MethodInfo DelegateRemove = typeof(Delegate).GetMethod(nameof(Delegate.Remove));
private static readonly EventInfo PropertyChanged = typeof(INotifyPropertyChanged).GetEvent(nameof(INotifyPropertyChanged.PropertyChanged));
private static readonly ConstructorInfo ProxyBaseCtor = typeof(ProxyBase).GetConstructor(Type.EmptyTypes);
private static readonly ConstructorInfo ProxyBaseCtor = typeof(ProxyBase).GetConstructor([]);
private static readonly ModuleBuilder ProxyModule = CreateProxyModule();
private static readonly LockingConcurrentDictionary<TypeDescription, Type> ProxyTypes = new(EmitProxy);
private static ModuleBuilder CreateProxyModule()
Expand All @@ -34,11 +34,11 @@ TypeBuilder GenerateType()
var propertyNames = string.Join("_", typeDescription.AdditionalProperties.Select(p => p.Name));
var typeName = $"Proxy_{interfaceType.FullName}_{typeDescription.GetHashCode()}_{propertyNames}";
const int MaxTypeNameLength = 1023;
typeName = typeName.Substring(0, Math.Min(MaxTypeNameLength, typeName.Length));
typeName = typeName[..Math.Min(MaxTypeNameLength, typeName.Length)];
Debug.WriteLine(typeName, "Emitting proxy type");
return ProxyModule.DefineType(typeName,
TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, typeof(ProxyBase),
interfaceType.IsInterface ? new[] { interfaceType } : Type.EmptyTypes);
interfaceType.IsInterface ? [interfaceType] : []);
}
void GeneratePropertyChanged()
{
Expand All @@ -65,7 +65,7 @@ void EventAccessor(MethodInfo method, MethodInfo delegateMethod)
}
void GenerateFields()
{
var fieldBuilders = new Dictionary<string, PropertyEmitter>();
Dictionary<string, PropertyEmitter> fieldBuilders = [];
foreach (var property in PropertiesToImplement())
{
if (fieldBuilders.TryGetValue(property.Name, out var propertyEmitter))
Expand All @@ -83,8 +83,8 @@ void GenerateFields()
}
List<PropertyDescription> PropertiesToImplement()
{
var propertiesToImplement = new List<PropertyDescription>();
var allInterfaces = new List<Type>(interfaceType.GetInterfaces()) { interfaceType };
List<PropertyDescription> propertiesToImplement = [];
List<Type> allInterfaces = [..interfaceType.GetInterfaces(), interfaceType];
// first we collect all properties, those with setters before getters in order to enable less specific redundant getters
foreach (var property in
allInterfaces.Where(intf => intf != typeof(INotifyPropertyChanged))
Expand All @@ -105,16 +105,16 @@ List<PropertyDescription> PropertiesToImplement()
}
void GenerateConstructor()
{
var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, []);
var ctorIl = constructorBuilder.GetILGenerator();
ctorIl.Emit(OpCodes.Ldarg_0);
ctorIl.Emit(OpCodes.Call, ProxyBaseCtor);
ctorIl.Emit(OpCodes.Ret);
}
}
public static Type GetProxyType(Type interfaceType) => ProxyTypes.GetOrAdd(new(interfaceType, Array.Empty<PropertyDescription>()));
public static Type GetProxyType(Type interfaceType) => ProxyTypes.GetOrAdd(new(interfaceType, []));
public static Type GetSimilarType(Type sourceType, IEnumerable<PropertyDescription> additionalProperties) =>
ProxyTypes.GetOrAdd(new(sourceType, additionalProperties.OrderBy(p=>p.Name).ToArray()));
ProxyTypes.GetOrAdd(new(sourceType, [..additionalProperties.OrderBy(p => p.Name)]));
class PropertyEmitter
{
private static readonly MethodInfo ProxyBaseNotifyPropertyChanged = typeof(ProxyBase).GetInstanceMethod("NotifyPropertyChanged");
Expand Down Expand Up @@ -142,7 +142,7 @@ public PropertyEmitter(TypeBuilder owner, PropertyDescription property, FieldBui
}
_setterBuilder = owner.DefineMethod($"set_{name}",
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig |
MethodAttributes.SpecialName, typeof(void), new[] { propertyType });
MethodAttributes.SpecialName, typeof(void), [propertyType]);
ILGenerator setterIl = _setterBuilder.GetILGenerator();
setterIl.Emit(OpCodes.Ldarg_0);
setterIl.Emit(OpCodes.Ldarg_1);
Expand All @@ -164,8 +164,7 @@ public PropertyEmitter(TypeBuilder owner, PropertyDescription property, FieldBui
public abstract class ProxyBase
{
public ProxyBase() { }
protected void NotifyPropertyChanged(PropertyChangedEventHandler handler, string method) =>
handler?.Invoke(this, new PropertyChangedEventArgs(method));
protected void NotifyPropertyChanged(PropertyChangedEventHandler handler, string method) => handler?.Invoke(this, new(method));
}
public readonly record struct TypeDescription(Type Type, PropertyDescription[] AdditionalProperties)
{
Expand Down

0 comments on commit c0349ec

Please sign in to comment.