/// <summary>
        /// Deserialize an <see cref="Expression"/>.
        /// </summary>
        /// <param name="json">The fragment to deserialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The deserialized <see cref="Expression"/>.</returns>
        public Expression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            if (json.ValueKind == JsonValueKind.Null)
            {
                return(null);
            }

            if (!json.TryGetProperty(nameof(Type), out JsonElement typeElem))
            {
                return(null);
            }

            if (typeElem.ValueKind == JsonValueKind.Null)
            {
                return(null);
            }

            var type = (ExpressionType)typeElem.GetInt32();

            if (serializers.ContainsKey(type))
            {
                return(serializers[type].Deserialize(json, state));
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Deserialize the list of <see cref="MemberBinding"/>.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The list of member bindings.</returns>
        private IEnumerable <MemberBinding> DeserializeBindings(
            IEnumerable <JsonElement> list, SerializationState state)
        {
            var result = new List <MemberBinding>();

            foreach (var element in list)
            {
                var type = (MemberBindingType)element
                           .GetProperty(nameof(MemberBinding.BindingType))
                           .GetInt32();

                switch (type)
                {
                case MemberBindingType.Assignment:
                    result.Add(DeserializeAssignment(element, state));
                    break;

                case MemberBindingType.MemberBinding:
                    result.Add(DeserializeMember(element, state));
                    break;

                case MemberBindingType.ListBinding:
                    result.Add(DeserializeList(element, state));
                    break;
                }
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Deserializes a list.
        /// </summary>
        /// <param name="element">The <see cref="JsonElement"/> to parse.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The <see cref="MemberListBinding"/>.</returns>
        private MemberBinding DeserializeList(
            JsonElement element,
            SerializationState state)
        {
            var member = GetMemberFromKey(
                element.GetProperty(nameof(MemberBindingList.MemberKey))
                .GetString());
            var auth = new List <MemberInfo>
            {
                member,
            };
            var initializers = new List <ElementInit>();

            foreach (var init in
                     element.GetProperty(
                         nameof(MemberBindingList.Initializers))
                     .EnumerateArray())
            {
                var addMethod = GetMemberFromKey <MethodInfo>(
                    init.GetProperty(nameof(MemberBindingInitializer.AddMethodKey))
                    .GetString());
                auth.Add(addMethod);
                initializers.Add(Expression.ElementInit(
                                     addMethod,
                                     init.GetProperty(nameof(MemberBindingInitializer.Arguments))
                                     .EnumerateArray().Select(json => Serializer.Deserialize(json, state))
                                     .ToArray()));
            }

            AuthorizeMembers(auth.ToArray());

            return(Expression.ListBind(member, initializers));
        }
예제 #4
0
        /// <summary>
        /// Deserialize a <see cref="MethodExpr"/> to a <see cref="MethodCallExpression"/>.
        /// </summary>
        /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="MethodCallExpression"/>.</returns>
        public override MethodCallExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            Expression obj = null;

            if (json.TryGetProperty(
                    nameof(MethodExpr.MethodObject),
                    out JsonElement jsonObj))
            {
                obj = Serializer.Deserialize(jsonObj, state);
            }

            var key = json.GetProperty(nameof(MethodExpr.MethodInfoKey))
                      .GetString();

            var methodInfo = GetMemberFromKey <MethodInfo>(key);

            AuthorizeMembers(methodInfo);

            var list         = json.GetProperty(nameof(MethodExpr.Arguments));
            var argumentList = list.EnumerateArray().Select(element =>
                                                            Serializer.Deserialize(element, state)).ToList();

            if (obj != null)
            {
                return(Expression.Call(obj, methodInfo, argumentList));
            }

            return(Expression.Call(methodInfo, argumentList));
        }
예제 #5
0
        /// <summary>
        /// Creates a template of the serializable type with keys decompressed.
        /// </summary>
        /// <param name="expression">The <see cref="SerializableExpression"/>.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The <see cref="SerializableExpression"/> instance.</returns>
        protected TSerializable DecompressTypes(
            TSerializable expression,
            SerializationState state)
        {
            // single props
            var parameters = KeyCache
                             .Where(entry => !entry.IsCollection)
                             .Select(
                cache =>
                (cache.GetKeys(expression)[0],
                 (Action <string>)(
                     s => cache.SetKeys(expression, new[] { s }))))
                             .ToArray();

            state.DecompressTypesForKeys(parameters);

            // lists
            foreach (var parameter in KeyCache.Where(entry => entry.IsCollection))
            {
                var keys = parameter.GetKeys(expression).Select(
                    k => state.DecompressTypesForKey(k)).ToArray();
                parameter.SetKeys(expression, keys);
            }

            return(expression);
        }
예제 #6
0
        /// <summary>
        /// Deserializes a <see cref="UnaryExpression"/>.
        /// </summary>
        /// <param name="unary">The serialized fragment.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The <see cref="UnaryExpression"/>.</returns>
        public override UnaryExpression Deserialize(
            Unary unary,
            SerializationState state)
        {
            MethodInfo methodInfo = null;

            if (!string.IsNullOrWhiteSpace(unary.UnaryMethodKey))
            {
                methodInfo = GetMemberFromKey <MethodInfo>(unary.UnaryMethodKey);
            }

            var operand   = unary.Operand == null ? null : Serializer.Deserialize(unary.Operand, state);
            var unaryType = GetMemberFromKey <Type>(unary.UnaryTypeKey);

            if (methodInfo != null)
            {
                return(Expression.MakeUnary(
                           (ExpressionType)unary.Type,
                           operand,
                           unaryType,
                           methodInfo));
            }

            return(Expression.MakeUnary((ExpressionType)unary.Type, operand, unaryType));
        }
예제 #7
0
        /// <summary>
        /// Deserialize the list of <see cref="MemberBinding"/>.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The list of member bindings.</returns>
        private IEnumerable <MemberBinding> DeserializeBindings(
            IEnumerable <MemberBindingExpr> list, SerializationState state)
        {
            var result = new List <MemberBinding>();

            foreach (var element in list)
            {
                var type = (MemberBindingType)element.BindingType;
                switch (type)
                {
                case MemberBindingType.Assignment:
                    result.Add(DeserializeAssignment((MemberBindingAssignment)element, state));
                    break;

                case MemberBindingType.MemberBinding:
                    result.Add(DeserializeMember((MemberBindingMember)element, state));
                    break;

                case MemberBindingType.ListBinding:
                    result.Add(DeserializeList((MemberBindingList)element, state));
                    break;
                }
            }

            return(result);
        }
예제 #8
0
        /// <summary>
        /// Deserializes a list.
        /// </summary>
        /// <param name="element">The <see cref="MemberBindingList"/> to parse.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The <see cref="MemberListBinding"/>.</returns>
        private MemberBinding DeserializeList(
            MemberBindingList element,
            SerializationState state)
        {
            var member = GetMemberFromKey(element.MemberKey);
            var auth   = new List <MemberInfo>
            {
                member,
            };
            var initializers = new List <ElementInit>();

            foreach (var init in element.Initializers)
            {
                var addMethodKey = init.AddMethodKey;
                typesCompressor.Value.DecompressTypes(
                    state.TypeIndex,
                    (addMethodKey, newKey => addMethodKey = newKey));
                var addMethod = GetMemberFromKey <MethodInfo>(addMethodKey);
                auth.Add(addMethod);
                initializers.Add(Expression.ElementInit(
                                     addMethod,
                                     init.Arguments.Select(arg => Serializer.Deserialize(arg, state))
                                     .ToArray()));
            }

            AuthorizeMembers(auth.ToArray());

            return(Expression.ListBind(member, initializers));
        }
예제 #9
0
        /// <summary>
        /// Compress the types on the serializable class.
        /// </summary>
        /// <param name="serializable">The serializable entity.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        public void CompressTypes(
            SerializableExpression serializable,
            SerializationState state)
        {
            if (KeyCache.Count < 1)
            {
                return;
            }

            var expression = (TSerializable)serializable;

            // single props
            var parameters = KeyCache
                             .Where(entry => !entry.IsCollection)
                             .Select(
                cache =>
                (cache.GetKeys(expression)[0],
                 (Action <string>)(
                     s => cache.SetKeys(expression, new[] { s }))))
                             .ToArray();

            state.CompressTypesForKeys(parameters);

            // lists
            foreach (var parameter in KeyCache.Where(entry => entry.IsCollection))
            {
                var keys = parameter.GetKeys(expression).Select(
                    k => state.CompressTypesforKey(k)).ToArray();
                parameter.SetKeys(expression, keys);
            }
        }
        /// <summary>
        /// Serializes the expression.
        /// </summary>
        /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param>
        /// <returns>The serializable <see cref="Constant"/>.</returns>
        public override Constant Serialize(ConstantExpression expression, SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            if (expression.Type.IsAnonymousType())
            {
                expression = Expression.Constant(
                    ConvertAnonymousTypeToAnonType(expression.Value),
                    typeof(AnonType));
            }

            var result = new Constant(expression);

            if (expression.Value is Expression expr)
            {
                result.Value        = Serializer.Serialize(expr, state);
                result.ValueTypeKey = GetKeyForMember(result.Value.GetType());
            }

            if (result.ValueTypeKey == result.ConstantTypeKey)
            {
                result.ValueTypeKey = null;
            }

            return(result);
        }
예제 #11
0
        /// <summary>
        /// Deserialize a <see cref="MemberExpr"/> to a <see cref="MemberExpression"/>.
        /// </summary>
        /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="MemberExpression"/>.</returns>
        public override MemberExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            Expression expr = null;

            if (json.TryGetProperty(
                    nameof(MemberExpr.Expression),
                    out JsonElement jsonObj))
            {
                expr = Serializer.Deserialize(jsonObj, state);
            }

            var memberInfo = GetMemberFromKey(json
                                              .GetProperty(nameof(MemberExpr.MemberTypeKey)).GetString());

            if (json.TryGetProperty(nameof(MemberExpr.Indexer), out JsonElement indexer))
            {
                if (!string.IsNullOrWhiteSpace(indexer.GetString()))
                {
                    return(null);
                }
            }

            AuthorizeMembers(new[] { memberInfo });

            return(Expression.MakeMemberAccess(expr, memberInfo));
        }
예제 #12
0
        /// <summary>
        /// Deserializes a <see cref="UnaryExpression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="UnaryExpression"/>.</returns>
        public override UnaryExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var        methodKey  = json.GetNullableProperty(nameof(Unary.UnaryMethodKey));
            MethodInfo methodInfo = null;

            if (methodKey.ValueKind != JsonValueKind.Null)
            {
                var key = methodKey.GetString();
                if (!string.IsNullOrWhiteSpace(key))
                {
                    methodInfo = GetMemberFromKey <MethodInfo>(key);
                }
            }

            var expressionType = (ExpressionType)json.GetProperty(nameof(SerializableExpression.Type)).GetInt32();
            var operandElement = json.GetNullableProperty(nameof(UnaryExpression.Operand));
            var operand        = Serializer.Deserialize(operandElement, state);
            var unaryType      = GetMemberFromKey <Type>(json.GetProperty(nameof(Unary.UnaryTypeKey)).GetString());

            if (methodInfo != null)
            {
                return(Expression.MakeUnary(
                           expressionType,
                           operand,
                           unaryType,
                           methodInfo));
            }

            return(Expression.MakeUnary(expressionType, operand, unaryType));
        }
        /// <summary>
        /// Deserializes a <see cref="LambdaExpression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="LambdaExpression"/>.</returns>
        public override LambdaExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var materializedType = GetMemberFromKey <Type>(
                json.GetProperty(nameof(Lambda.LambdaTypeKey))
                .GetString());

            var materializedReturnType = GetMemberFromKey <Type>(json.GetProperty(nameof(Lambda.ReturnTypeKey))
                                                                 .GetString());

            var name = json.GetNullableProperty(nameof(Lambda.Name)).GetString();

            var list = json.GetNullableProperty(nameof(Lambda.Parameters));

            var parameterList = list.ValueKind == JsonValueKind.Array ?
                                list.EnumerateArray().Select(element =>
                                                             Serializer.Deserialize(element, state) as ParameterExpression).ToList() :
                                new List <ParameterExpression>();

            var jsonBody = json.GetProperty(nameof(Lambda.Body));

            Expression body = Serializer.Deserialize(jsonBody, state);

            return(Expression.Lambda(
                       materializedType,
                       body,
                       name,
                       parameterList));
        }
예제 #14
0
        /// <summary>
        /// Deserializes a <see cref="NewArrayExpression"/>.
        /// </summary>
        /// <param name="newArray">The serialized fragment.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The <see cref="NewArrayExpression"/>.</returns>
        public override NewArrayExpression Deserialize(
            NewArray newArray,
            SerializationState state)
        {
            var materializedType = GetMemberFromKey <Type>(newArray.ArrayTypeKey);
            var expressionList   = newArray.Expressions.Select(element => Serializer.Deserialize(
                                                                   element, state)).ToList();

            return(Expression.NewArrayInit(materializedType, expressionList));
        }
        /// <summary>
        /// Deserialize a serializable class to an actionable <see cref="Expression"/>.
        /// </summary>
        /// <param name="param">The serialized fragment.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The deserialized <see cref="Expression"/>.</returns>
        public override ParameterExpression Deserialize(
            Parameter param,
            SerializationState state)
        {
            Type type      = GetMemberFromKey <Type>(param.ParameterTypeKey);
            var  parameter = string.IsNullOrWhiteSpace(param.Name) ? Expression.Parameter(type) :
                             Expression.Parameter(type, param.Name);

            return(state.GetOrCacheParameter(parameter));
        }
        /// <summary>
        /// Deserializes a <see cref="InvocationExpression"/>.
        /// </summary>
        /// <param name="expr">The serialized fragment.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The <see cref="InvocationExpression"/>.</returns>
        public override InvocationExpression Deserialize(
            Invocation expr,
            SerializationState state)
        {
            var expression   = Serializer.Deserialize(expr.Expression, state);
            var argumentList = expr.Arguments.Select(element =>
                                                     Serializer.Deserialize(element, state)).ToList();

            return(Expression.Invoke(expression, argumentList));
        }
        /// <summary>
        /// Deserialize a serializable class to an actionable <see cref="Expression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The deserialized <see cref="Expression"/>.</returns>
        public override ParameterExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var type      = GetMemberFromKey <Type>(json.GetProperty(nameof(Parameter.ParameterTypeKey)).GetString());
            var name      = json.GetNullableProperty(nameof(Parameter.Name)).GetString();
            var parameter = string.IsNullOrWhiteSpace(name) ? Expression.Parameter(type) :
                            Expression.Parameter(type, name);

            return(state.GetOrCacheParameter(parameter));
        }
        /// <summary>
        /// Deserializes a <see cref="NewArrayExpression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="NewArrayExpression"/>.</returns>
        public override NewArrayExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var materializedType = GetMemberFromKey <Type>(json.GetProperty(nameof(NewArray.ArrayTypeKey)).GetString());
            var list             = json.GetProperty(nameof(NewArray.Expressions));
            var expressionList   = list.EnumerateArray().Select(element => Serializer.Deserialize(
                                                                    element, state)).ToList();

            return(Expression.NewArrayInit(materializedType, expressionList));
        }
예제 #19
0
        /// <summary>
        /// Deserializes a <see cref="InvocationExpression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="InvocationExpression"/>.</returns>
        public override InvocationExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var expr         = json.GetProperty(nameof(Invocation.Expression));
            var expression   = Serializer.Deserialize(expr, state);
            var list         = json.GetNullableProperty(nameof(Invocation.Arguments));
            var argumentList = list.EnumerateArray().Select(element =>
                                                            Serializer.Deserialize(element, state)).ToList();

            return(Expression.Invoke(expression, argumentList));
        }
        /// <summary>
        /// Deserialize a serializable class to an actionable <see cref="Expression"/>.
        /// </summary>
        /// <param name="json">The serialized fragment.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The deserialized <see cref="Expression"/>.</returns>
        public override ConstantExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var value     = json.GetNullableProperty(nameof(Constant.Value)).GetRawText();
            var type      = GetMemberFromKey <Type>(json.GetProperty(nameof(Constant.ConstantTypeKey)).GetString());
            var valueNode = json.GetNullableProperty(nameof(Constant.ValueTypeKey));
            var valueType = valueNode.ValueKind != JsonValueKind.Null ?
                            GetMemberFromKey <Type>(valueNode.GetString()) : type;

            if (typeof(SerializableExpression).IsAssignableFrom(valueType))
            {
                var innerValue = Serializer.Deserialize(
                    json.GetProperty(nameof(Constant.Value)),
                    state);
                return(Expression.Constant(innerValue, innerValue.GetType()));
            }

            if (valueType.IsGenericType &&
                valueType.GetGenericTypeDefinition()
                == typeof(EnumerableQuery <>))
            {
                if (state.QueryRoot is ConstantExpression ce)
                {
                    return(ce);
                }

                return(state.QueryRoot != null?
                       Expression.Constant(state.QueryRoot) : Expression.Constant(null, valueType));
            }

            if (typeof(MemberInfo).IsAssignableFrom(valueType))
            {
                var memberKey = JsonSerializer.Deserialize <string>(value, state.Options);
                return(Expression.Constant(GetMemberFromKey(memberKey)));
            }

            var constantVal = JsonSerializer.Deserialize(
                value,
                valueType,
                state.Options);

            if (constantVal is AnonType anonType)
            {
                constantVal = ConvertAnonTypeToAnonymousType(
                    anonType,
                    state.Options);
            }

            return(type == valueType && constantVal != null?Expression.Constant(constantVal) :
                       Expression.Constant(constantVal, type));
        }
        /// <summary>
        /// Serializes the expression.
        /// </summary>
        /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param>
        /// <returns>The serializable <see cref="Constant"/>.</returns>
        public override Parameter Serialize(
            ParameterExpression expression,
            SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            var result = new Parameter(expression);

            return(result);
        }
예제 #22
0
        /// <summary>
        /// Deserializes an assignment.
        /// </summary>
        /// <param name="element">The <see cref="JsonElement"/> to parse.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The <see cref="MemberAssignment"/>.</returns>
        private MemberBinding DeserializeAssignment(JsonElement element, SerializationState state)
        {
            var member = GetMemberFromKey(
                element.GetProperty(nameof(MemberBindingAssignment.MemberInfoKey))
                .GetString());

            AuthorizeMembers(member);

            var expression = Serializer.Deserialize(
                element.GetProperty(nameof(MemberBindingAssignment.Expression)),
                state);

            return(Expression.Bind(member, expression));
        }
예제 #23
0
        /// <summary>
        /// Deserialize a <see cref="MemberInit"/> to a <see cref="MemberInitExpression"/>.
        /// </summary>
        /// <param name="memberInit">The <see cref="MemberInit"/> to deserialize.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The <see cref="MemberInitExpression"/>.</returns>
        public override MemberInitExpression Deserialize(
            MemberInit memberInit,
            SerializationState state)
        {
            NewExpression expr = null;

            if (memberInit.NewExpression != null)
            {
                expr = Serializer.Deserialize(memberInit.NewExpression, state) as NewExpression;
            }

            var memberBindings = DeserializeBindings(memberInit.Bindings, state);

            return(Expression.MemberInit(expr, memberBindings.ToArray()));
        }
예제 #24
0
        /// <summary>
        /// Serialize a <see cref="UnaryExpression"/> to a <see cref="Unary"/>.
        /// </summary>
        /// <param name="expression">The <see cref="UnaryExpression"/>.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The <see cref="Unary"/>.</returns>
        public override Unary Serialize(
            UnaryExpression expression,
            SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            var unary = new Unary(expression)
            {
                Operand = Serializer.Serialize(expression.Operand, state),
            };

            return(unary);
        }
예제 #25
0
        /// <summary>
        /// Deserializes a member binding.
        /// </summary>
        /// <param name="element">The <see cref="JsonElement"/> to parse.</param>
        /// <param name="state">The <seealso cref="SerializationState"/>.</param>
        /// <returns>The <see cref="MemberMemberBinding"/>.</returns>
        private MemberBinding DeserializeMember(
            JsonElement element,
            SerializationState state)
        {
            var member = GetMemberFromKey(
                element.GetProperty(nameof(MemberBindingMember.MemberKey))
                .GetString());

            AuthorizeMembers(member);

            var bindings = DeserializeBindings(
                element.GetProperty(nameof(MemberBindingMember.Bindings))
                .EnumerateArray(), state).ToArray();

            return(Expression.MemberBind(member, bindings));
        }
예제 #26
0
        /// <summary>
        /// Serialize a <see cref="MemberExpression"/>.
        /// </summary>
        /// <param name="expression">The <see cref="MemberExpression"/> to serialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param>
        /// <returns>The serializable <see cref="MemberExpr"/>.</returns>
        public override MemberExpr Serialize(
            MemberExpression expression,
            SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            var member = new MemberExpr(expression)
            {
                Expression = Serializer.Serialize(expression.Expression, state),
            };

            return(member);
        }
예제 #27
0
        /// <summary>
        /// Deserialize a <see cref="CtorExpr"/> to a <see cref="NewExpression"/>.
        /// </summary>
        /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param>
        /// <returns>The <see cref="NewExpression"/>.</returns>
        public override NewExpression Deserialize(
            JsonElement json,
            SerializationState state)
        {
            var ctorDescriptor = json.GetProperty(nameof(CtorExpr.CtorInfo)).GetString();

            var ctor = GetMemberFromKey <ConstructorInfo>(ctorDescriptor);

            var members = new List <MemberInfo>();

            if (json.TryGetProperty(
                    nameof(CtorExpr.MemberKeys),
                    out JsonElement memberList))
            {
                members = memberList.EnumerateArray()
                          .Select(memberJson => memberJson.GetString())
                          .Select(memberKey => GetMemberFromKey(memberKey))
                          .ToList();
            }

            var args = new List <Expression>();

            if (json.TryGetProperty(
                    nameof(CtorExpr.Arguments),
                    out JsonElement arguments))
            {
                foreach (var argElem in arguments.EnumerateArray())
                {
                    var arg = Serializer.Deserialize(argElem, state);
                    args.Add(arg);
                }
            }

            AuthorizeMembers(ctor);

            if (args.Count == 0)
            {
                return(Expression.New(ctor));
            }

            if (members.Count == 0)
            {
                return(Expression.New(ctor, args));
            }

            return(Expression.New(ctor, args, members));
        }
        /// <summary>
        /// Serializes the expression.
        /// </summary>
        /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param>
        /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param>
        /// <returns>The serializable <see cref="Constant"/>.</returns>
        public override Constant Serialize(ConstantExpression expression, SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            var result = new Constant(expression);

            if (expression.Value is Expression expr)
            {
                result.Value        = Serializer.Serialize(expr, state);
                result.ValueTypeKey = GetKeyForMember(result.Value.GetType());
            }

            return(result);
        }
예제 #29
0
        /// <summary>
        /// Deserializes an assignment.
        /// </summary>
        /// <param name="element">The <see cref="MemberBindingAssignment"/> to parse.</param>
        /// <param name="state">The <see cref="SerializationState"/>.</param>
        /// <returns>The <see cref="MemberAssignment"/>.</returns>
        private MemberBinding DeserializeAssignment(MemberBindingAssignment element, SerializationState state)
        {
            var key = element.MemberInfoKey;

            typesCompressor.Value.DecompressTypes(
                state.TypeIndex,
                (key, newKey => key = newKey));
            var member = GetMemberFromKey(key);

            AuthorizeMembers(member);

            var expression = Serializer.Deserialize(
                element.Expression,
                state);

            return(Expression.Bind(member, expression));
        }
예제 #30
0
        /// <summary>
        /// Serialize a <see cref="MemberInitExpression"/>.
        /// </summary>
        /// <param name="expression">The <see cref="MemberInitExpression"/> to serialize.</param>
        /// <param name="state">State for the serialization or deserialization.</param>
        /// <returns>The serializable <see cref="MemberInit"/>.</returns>
        public override MemberInit Serialize(
            MemberInitExpression expression,
            SerializationState state)
        {
            if (expression == null)
            {
                return(null);
            }

            var memberInit = new MemberInit(expression)
            {
                NewExpression = (CtorExpr)Serializer.Serialize(expression.NewExpression, state),
            };

            memberInit.Bindings.AddRange(SerializeBindings(expression.Bindings, state));
            return(memberInit);
        }