private static Expression CreateObject(Type type, ParameterExpression factParameter, ParameterExpression emitterParameter) { var constructorInfos = type.GetConstructors(); if (constructorInfos.Length != 1) { throw new NotImplementedException($"More than one constructor for {type.Name}"); } var constructor = constructorInfos.Single(); var parameters = constructor.GetParameters(); var parameterExpressions = parameters .Select(parameter => Interrogate.IsField(parameter.ParameterType) ? GetFieldValue(parameter.Name, parameter.ParameterType, factParameter) : Interrogate.IsFactType(parameter.ParameterType) ? GetPredecessor(parameter.Name, parameter.ParameterType, factParameter, emitterParameter) : Interrogate.IsArrayOfFactType(parameter.ParameterType) ? GetPredecessorArray(parameter.Name, parameter.ParameterType.GetElementType(), factParameter, emitterParameter) : throw new NotImplementedException() ) .ToArray(); return(Expression.New( constructor, parameterExpressions )); }
private static Expression FieldList(Type type, ParameterExpression instanceParameter) { var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); Expression emptyList = Expression.Field( null, typeof(ImmutableList <Field>), nameof(ImmutableList <Field> .Empty) ); var addMethod = typeof(ImmutableList <Field>).GetMethod(nameof(ImmutableList <Field> .Add)); var fieldList = properties .Where(property => Interrogate.IsField(property.PropertyType)) .Select(property => FieldGetter(property, instanceParameter)) .Aggregate(emptyList, (list, field) => Expression.Call(list, addMethod, field)); return(fieldList); }
private static Expression PredecessorList(Type type, ParameterExpression instanceParameter, ParameterExpression collectorParameter) { var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); Expression emptyList = Expression.Field( null, typeof(ImmutableList <Predecessor>), nameof(ImmutableList <Predecessor> .Empty) ); var addMethod = typeof(ImmutableList <Predecessor>).GetMethod(nameof(ImmutableList <Predecessor> .Add)); var predecessorList = properties .Where(property => Interrogate.IsPredecessor(property.PropertyType)) .Select(property => Interrogate.IsFactType(property.PropertyType) ? PredecessorSingleGetter(property, instanceParameter, collectorParameter) : PredecessorMultipleGetter(property, instanceParameter, collectorParameter)) .Aggregate(emptyList, (list, predecessor) => Expression.Call(list, addMethod, predecessor)); return(predecessorList); }