public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            var genMethodInfo        = typeof(Gen).GetMethod(nameof(Gen.Enum), BindingFlags.Public | BindingFlags.Static);
            var genericGenMethodInfo = genMethodInfo.MakeGenericMethod(type);

            return((IGen)genericGenMethodInfo.Invoke(null !, new object[] { }));
        }
Esempio n. 2
0
        public static IGen Build(
            Type type,
            IReadOnlyDictionary <Type, IGen> registeredGensByType,
            IReadOnlyList <ReflectedGenMemberOverride> memberOverrides,
            ErrorFactory errorFactory,
            ReflectedGenHandlerContext context)
        {
            ContextualErrorFactory contextualErrorFactory = (message, context) =>
            {
                var suffix = context.Members.Count() == 1 ? "" : $" at path '{context.MemberPath}'";
                return(errorFactory(message + suffix));
            };

            var genFactoriesByPriority = new List <IReflectedGenHandler>
            {
                new MemberOverrideReflectedGenHandler(memberOverrides),
                new RegistryReflectedGenHandler(registeredGensByType, contextualErrorFactory),
                new CollectionReflectedGenHandler(),
                new SetReflectedGenHandler(),
                new ArrayReflectedGenHandler(),
                new EnumReflectedGenHandler(),
                new DefaultConstructorReflectedGenHandler(contextualErrorFactory),
                new NonDefaultConstructorReflectedGenHandler(contextualErrorFactory),
            };

            var compositeReflectedGenFactory = new CompositeReflectedGenHandler(genFactoriesByPriority, contextualErrorFactory);

            return(compositeReflectedGenFactory.CreateGen(type, context));
        }
        public bool CanHandleGen(Type type, ReflectedGenHandlerContext context)
        {
            if (type.IsGenericType)
            {
                var genericTypeDefinition = type.GetGenericTypeDefinition();
                return(GenMethodByGenericTypeDefinition.ContainsKey(genericTypeDefinition));
            }

            return(false);
        }
Esempio n. 4
0
        public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            var methodInfo = typeof(DefaultConstructorReflectedGenHandler).GetMethod(
                nameof(CreateGenGeneric),
                BindingFlags.Static | BindingFlags.NonPublic) !;

            var genericMethodInfo = methodInfo.MakeGenericMethod(type);

            return((IGen)genericMethodInfo.Invoke(null !, new object[] { innerHandler, context, _errorFactory }));
        }
        public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            var elementType = type.GetElementType();
            var elementGen  = innerHandler.CreateGen(elementType, context);

            var methodInfo = typeof(ArrayReflectedGenHandler).GetMethod(
                nameof(CreateArrayGen),
                BindingFlags.Static | BindingFlags.NonPublic) !;

            var genericMethodInfo = methodInfo.MakeGenericMethod(elementType);

            return((IGen)genericMethodInfo.Invoke(null !, new object[] { elementGen }));
        }
        public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            var elementType = type.GetGenericArguments().Single();
            var elementGen  = innerHandler.CreateGen(elementType, context);

            var genericTypeDefinition = type.GetGenericTypeDefinition();
            var methodName            = GenMethodByGenericTypeDefinition[genericTypeDefinition];

            var methodInfo = typeof(CollectionReflectedGenHandler).GetMethod(
                methodName,
                BindingFlags.Static | BindingFlags.NonPublic) !;

            var genericMethodInfo = methodInfo.MakeGenericMethod(elementType);

            return((IGen)genericMethodInfo.Invoke(null !, new object[] { elementGen }));
        }
Esempio n. 7
0
        public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            foreach (var kvp in _registeredGensByType)
            {
                var registeredType  = kvp.Key;
                var genTypeArgument = kvp.Value.ReflectGenTypeArgument();

                if (registeredType.IsAssignableFrom(genTypeArgument) == false)
                {
                    return(_errorFactory(
                               $"type '{genTypeArgument}' was not assignable to the type it was registered to, '{registeredType}'",
                               context));
                }
            }

            return(_registeredGensByType[type]);
        }
Esempio n. 8
0
        private static IGen <T> BuildGen(
            IReadOnlyDictionary <Type, IGen> registeredGensByType,
            IReadOnlyList <ReflectedGenMemberOverride> memberOverrides,
            string?errorExpression)
        {
            if (errorExpression != null)
            {
                return(Error(
                           $"expression '{errorExpression}' was invalid, an overridding expression may only contain member access"));
            }

            var context = ReflectedGenHandlerContext.Create(typeof(T));

            return(ReflectedGenBuilder
                   .Build(typeof(T), registeredGensByType, memberOverrides, Error, context)
                   .Cast <T>());
        }
Esempio n. 9
0
        public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
        {
            if (context.TypeHistory.Skip(1).Any(t => t == type))
            {
                return(_errorFactory($"detected circular reference on type '{type}'", context));
            }

            var gen = _genHandlersByPriority
                      .Where(genFactory => genFactory.CanHandleGen(type, context))
                      .Select(genFactory => genFactory.CreateGen(innerHandler, type, context))
                      .FirstOrDefault();

            if (gen == null)
            {
                return(_errorFactory($"could not resolve type '{type}'", context));
            }

            return(gen);
        }
Esempio n. 10
0
 private static IEnumerable <IGen <Action <object> > > CreateSetPropertyActionGens(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
 {
     return(type
            .GetProperties()
            .Where(property => property.CanWrite)
            .Select(property => innerHandler
                    .CreateGen(property.PropertyType, context.Next(property.Name, property.PropertyType))
                    .Cast <object>()
                    .Select <object, Action <object> >(value => obj => property.SetValue(obj, value))));
 }
Esempio n. 11
0
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) =>
 TryFindConstructor(type) != null;
Esempio n. 12
0
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) =>
 _genHandlersByPriority.Any(genFactory => genFactory.CanHandleGen(type, context));
 public IGen CreateGen(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context) =>
 _memberOverrides
 .Where(mo => mo.Path == context.MemberPath)
 .Select(mo => mo.Gen)
 .Last();         // Last registered override wins
Esempio n. 14
0
        private static IGen <T> CreateGenGeneric <T>(IReflectedGenHandler innerHandler, ReflectedGenHandlerContext context, ContextualErrorFactory errorFactory)
        {
            var constructor = TryFindConstructor(typeof(T)) !;

            var parameterGens = constructor
                                .GetParameters()
                                .Select(parameter => innerHandler
                                        .CreateGen(parameter.ParameterType, context.Next(parameter.Name, parameter.ParameterType)) // TODO: Indicate it's a ctor param in the path
                                        .Cast <object>());

            return(Gen
                   .Zip(parameterGens)
                   .SelectMany(parameters =>
            {
                try
                {
                    return Gen.Constant((T)constructor.Invoke(parameters.ToArray()));
                }
                catch (TargetInvocationException ex)
                {
                    var innerEx = ex.InnerException;
                    var message = $"'{innerEx.GetType()}' was thrown while calling constructor with message '{innerEx.Message}'";
                    return errorFactory(message, context).Cast <T>();
                }
            }));
        }
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) =>
 _memberPathOverrides.Contains(context.MemberPath);
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) => type.IsEnum;
Esempio n. 17
0
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) =>
 _registeredGensByType.ContainsKey(type);
Esempio n. 18
0
        private static IGen <T> CreateGenGeneric <T>(IReflectedGenHandler innerHandler, ReflectedGenHandlerContext context, ContextualErrorFactory errorFactory)
        {
            return(Gen
                   .Zip(
                       Gen.Zip(CreateSetPropertyActionGens(innerHandler, typeof(T), context)),
                       Gen.Zip(CreateSetFieldActionGens(innerHandler, typeof(T), context)))
                   .SelectMany((x) =>
            {
                T instance;
                try
                {
                    instance = (T)Activator.CreateInstance(typeof(T));
                }
                catch (TargetInvocationException ex)
                {
                    var innerEx = ex.InnerException;
                    var message = $"'{innerEx.GetType()}' was thrown while calling constructor with message '{innerEx.Message}'";
                    return errorFactory(message, context).Cast <T>();
                }

                foreach (var setPropertyAction in x.Item1)
                {
                    try
                    {
                        setPropertyAction(instance);
                    }
                    catch (TargetInvocationException ex)
                    {
                        var innerEx = ex.InnerException;
                        var message = $"'{innerEx.GetType()}' was thrown while setting property with message '{innerEx.Message}'";
                        return errorFactory(message, context).Cast <T>();
                    }
                }

                foreach (var setFieldAction in x.Item2)
                {
                    setFieldAction(instance);
                }

                return Gen.Constant(instance);
            }));
        }
Esempio n. 19
0
 public bool CanHandleGen(Type type, ReflectedGenHandlerContext context) =>
 type.GetConstructors().Any(constructor => constructor.GetParameters().Any() == false);
Esempio n. 20
0
 private static IEnumerable <IGen <Action <object> > > CreateSetFieldActionGens(IReflectedGenHandler innerHandler, Type type, ReflectedGenHandlerContext context)
 {
     return(type
            .GetFields()
            .Where(field => field.IsPublic)
            .Select(field => innerHandler
                    .CreateGen(field.FieldType, context.Next(field.Name, field.FieldType))
                    .Cast <object>()
                    .Select <object, Action <object> >(value => obj => field.SetValue(obj, value))));
 }
 public static IGen CreateGen(
     this IReflectedGenHandler innerHandler,
     Type type,
     ReflectedGenHandlerContext context) =>
 innerHandler.CreateGen(innerHandler, type, context);