Exemplo n.º 1
0
        public static Func <StringBuilder, IEnumerable <T>, bool> ComposeEnumerableSerializer <T>(
            ChainNode root
            , Func <ChainNode, SerializerOptions> getSerializerOptions
            , Func <ChainNode, InternalNodeOptions> getInternalNodeOptions
            , bool rootHandleNull
            , bool rootHandleEmptyLiteral
            , Func <LambdaExpression, Delegate> compile
            , bool doCompileInnerLambdas = true)
        {
            Func <StringBuilder, IEnumerable <T>, bool> @value = null;
            var enumerableType = typeof(IEnumerable <T>);

            var expressions = JsonChainTools.CreateSerializsPair(root, /* node.Type,*/ getSerializerOptions, getInternalNodeOptions, compile, doCompileInnerLambdas);

            ConstantExpression nullSerializerExpression = null;

            if (JsonChainTools.IsNullable(root.Type))
            {
                if (expressions.NullSerializer == null)
                {
                    throw new NotSupportedException($"Null serializer is not setuped for root node");
                }
                nullSerializerExpression = JsonChainTools.CreateSerializeNullConstant(expressions.NullSerializer);
            }

            var sbExpression     = Expression.Parameter(typeof(StringBuilder), "sb");
            var tExpression      = Expression.Parameter(enumerableType, "t");
            var isNullableStruct = JsonChainTools.IsNullableStruct(root.Type);

            var serializationType = Nullable.GetUnderlyingType(root.Type) ?? root.Type;

            var methodCallExpression = JsonChainTools.CreateSerializeArrayMethodCall(
                serializationType,
                isNullableStruct,
                expressions.SerializerExpression,
                nullSerializerExpression,
                sbExpression,
                tExpression,
                rootHandleEmptyLiteral);

            Expression serializeConditionalExpression;

            if (rootHandleNull)
            {
                var serializers        = getInternalNodeOptions(root);
                var rootNullMethodInfo = serializers.NullSerializer.GetMethodInfo();
                MethodCallExpression nullCallExpression = Expression.Call(rootNullMethodInfo, new Expression[] { sbExpression });
                serializeConditionalExpression = Expression.Condition(
                    Expression.Equal(tExpression, Expression.Constant(null)),
                    nullCallExpression,
                    methodCallExpression
                    );
            }
            else
            {
                serializeConditionalExpression = Expression.Condition(
                    Expression.Equal(tExpression, Expression.Constant(null)),
                    Expression.Constant(false),
                    methodCallExpression
                    );
            }

            var serializeArrayLambda = Expression.Lambda(serializeConditionalExpression, new[] { sbExpression, tExpression });

            @value = (Func <StringBuilder, IEnumerable <T>, bool>)compile(serializeArrayLambda);
            return(@value);
        }
Exemplo n.º 2
0
        public static Func <StringBuilder, T, bool> ComposeSerializer <T>(
            ChainNode root
            , Func <ChainNode, SerializerOptions> getSerializerOptions
            , Func <ChainNode, InternalNodeOptions> getInternalNodeOptions
            , bool rootHandleNull
            , bool rootHandleEmptyLiteral
            , Func <LambdaExpression, Delegate> compile
            , bool doCompileInnerLambdas
            )
        {
            Func <StringBuilder, T, bool> @value = null;
            Expression serializeExpression;

            var objectType            = typeof(T);
            var sbParameterExpression = Expression.Parameter(typeof(StringBuilder), "sb");
            var tParameterExpression  = Expression.Parameter(objectType, "t");

            if (root.Children.Count == 0) // leaf
            {
                var serializerSet    = getSerializerOptions(root);
                var isNullableStruct = JsonChainTools.IsNullableStruct(root.Type);
                if (isNullableStruct != null && isNullableStruct.Value == false)
                {
                    var delegateMethodInfo = serializerSet.Serializer.GetMethodInfo();
                    var target             = serializerSet.Serializer.Target;
                    serializeExpression = Expression.Call(target != null ? Expression.Constant(target) : null, delegateMethodInfo, new Expression[] { sbParameterExpression, tParameterExpression });
                }
                else
                {
                    Expression nullCallExpression;
                    if (rootHandleNull)
                    {
                        if (serializerSet.NullSerializer == null)
                        {
                            throw new NotSupportedException($"Null serializer is not setuped for root node");
                        }
                        var rootNullSerializeMethodInfo = serializerSet.NullSerializer.GetMethodInfo();
                        nullCallExpression = Expression.Call(rootNullSerializeMethodInfo, new Expression[] { sbParameterExpression });
                    }
                    else
                    {
                        nullCallExpression = Expression.Constant(false);
                    }

                    if (isNullableStruct == null) // class
                    {
                        var @delegate            = serializerSet.Serializer.GetMethodInfo();
                        var methodCallExpression = Expression.Call(@delegate, new Expression[] { sbParameterExpression, tParameterExpression });
                        serializeExpression = Expression.Condition(
                            Expression.Equal(tParameterExpression, Expression.Constant(null)),
                            nullCallExpression,
                            methodCallExpression
                            );
                    }
                    else if (isNullableStruct.Value)
                    {
                        var @delegate            = serializerSet.Serializer.GetMethodInfo();
                        var hasValueExpression   = Expression.Property(tParameterExpression, "HasValue");
                        var valueExpression      = Expression.Property(tParameterExpression, "Value");
                        var methodCallExpression = Expression.Call(@delegate, new Expression[] { sbParameterExpression, valueExpression });
                        serializeExpression = Expression.Condition(
                            hasValueExpression,
                            methodCallExpression,
                            nullCallExpression
                            );
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            else // internal (note: currently can't be nullable struct)
            {
                var serializerSet       = getInternalNodeOptions(root);
                var parentObjectAsArray = serializerSet.ObjectAsArray;
                var properies           = new List <Expression>();
                foreach (var c in root.Children)
                {
                    var n = c.Value;
                    JsonChainTools.ConfigureSerializeProperty(n, root.Type,
                                                              parentObjectAsArray,
                                                              properies, getSerializerOptions, getInternalNodeOptions,
                                                              compile, doCompileInnerLambdas);
                }
                var methodCallExpression = JsonChainTools.CreateSerializeMethodCallExpression(sbParameterExpression, tParameterExpression, objectType, parentObjectAsArray, rootHandleEmptyLiteral, properies.ToArray());

                if (JsonChainTools.IsNullable(root.Type))
                {
                    if (rootHandleNull)
                    {
                        if (serializerSet.NullSerializer == null)
                        {
                            throw new NotSupportedException($"Null serializer is not setuped for internal node '{root.FindLinkedRootXPath()}' ");
                        }
                        var rootNullSerializeMethodInfo         = serializerSet.NullSerializer.GetMethodInfo();
                        MethodCallExpression nullCallExpression = Expression.Call(rootNullSerializeMethodInfo, new Expression[] { sbParameterExpression });

                        serializeExpression = Expression.Condition(
                            Expression.Equal(tParameterExpression, Expression.Constant(null)),
                            nullCallExpression,
                            methodCallExpression
                            );
                    }
                    else
                    {
                        serializeExpression = Expression.Condition(
                            Expression.Equal(tParameterExpression, Expression.Constant(null)),
                            Expression.Constant(false),
                            methodCallExpression
                            );
                    }
                }
                else // struct
                {
                    serializeExpression = methodCallExpression;
                }
            }
            var serializeLambda = Expression.Lambda(serializeExpression, new[] { sbParameterExpression, tParameterExpression });

            @value = (Func <StringBuilder, T, bool>)compile(serializeLambda);
            return(@value);
        }