BlockExpression VisitBlock(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var variablesElement = element.Element(XNames.Elements.Variables);
            var variables        = VisitParameters(variablesElement);

            try
            {
                return(Expression.Block(
                           DataSerialization.GetType(element) ?? typeof(void),
                           variables,
                           VisitExpressions(element.Elements().Skip(variablesElement != null ? 1 : 0))));
            }
            finally
            {
                foreach (var v in variables)
                {
                    _references.Remove(v.Name);
                }
            }
        }
        LambdaExpression VisitLambda(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var parameters        = VisitParameters(element.Element(XNames.Elements.Parameters));
            var tailCallAttribute = element.Attribute(XNames.Attributes.TailCall);
            var delegateType      = DataSerialization.GetType(element.Attribute(XNames.Attributes.DelegateType));
            var name = GetName(element);

            return(delegateType != null
                ? Expression.Lambda(
                       delegateType,
                       Visit(element.Element(XNames.Elements.Body)
                             .Elements()
                             .First()),
                       name,
                       tailCallAttribute != null
                       ?XmlConvert.ToBoolean(tailCallAttribute.Value)
                       : false,
                       parameters)
                : Expression.Lambda(
                       Visit(element.Element(XNames.Elements.Body)
                             .Elements()
                             .First()),
                       name,
                       tailCallAttribute != null
                                        ? XmlConvert.ToBoolean(tailCallAttribute.Value)
                                        : false,
                       parameters));
        }
        ParameterExpression VisitParameter(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var name = GetName(element);
            var type = DataSerialization.GetType(element);

            if (type == null &&
                _references.TryGetValue(name, out var parameter))
            {
                return(parameter);
            }

            parameter = Expression.Parameter(type, name);


            if (_references.TryGetValue(name, out var reference) &&
                reference.CanReduce == parameter.CanReduce &&
                reference.IsByRef == parameter.IsByRef &&
                reference.NodeType == parameter.NodeType)
            {
                return(reference);
            }

            _references[name] = parameter;

            return(parameter);
        }
 ConditionalExpression VisitConditional(XElement element)
 => element != null
             ? Expression.Condition(
     Visit(element.Elements().ElementAt(0)),
     Visit(element.Elements().ElementAt(1)),
     Visit(element.Elements().ElementAt(2)),
     DataSerialization.GetType(element) ?? typeof(void))
             : throw new ArgumentNullException(nameof(element));
Пример #5
0
        internal static Type GetDataType(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var type = TypeNameResolver.GetType(element.Name.LocalName);

            if (type == null && element.Name == XNames.Elements.Anonymous)
            {
                type = DataSerialization.GetType(element);

                if (type == null)
                {
                    throw new SerializationException("Expected constant element's type.");
                }
            }

            if (type == typeof(Nullable <>))
            {
                Type valueType = GetType(element);

                if (valueType != null)
                {
                    return(typeof(Nullable <>).MakeGenericType(valueType));
                }

                var valueElement = element.Elements().FirstOrDefault();

                if (valueElement == null)
                {
                    return(null);
                }

                valueType = GetDataType(valueElement);

                if (valueType == null)
                {
                    return(null);
                }

                return(typeof(Nullable <>).MakeGenericType(valueType));
            }

            if (type == typeof(object))
            {
                return(GetCustomConstantType(element));
            }

            if (type == typeof(Enum))
            {
                return(GetEnumConstantType(element));
            }

            return(type);
        }
        static Type ConvertTo(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            return(DataSerialization.GetType(element.Attribute(XNames.Attributes.Type)));
        }
 Expression VisitTry(XElement e)
 => e != null
             ? Expression.MakeTry(
     DataSerialization.GetType(e),
     Visit(e.Elements().First()),
     Visit(e.Elements(XNames.Elements.Finally).FirstOrDefault()),
     Visit(e.Elements(XNames.Elements.Fault).FirstOrDefault()),
     e.Elements(XNames.Elements.Catch).Select(c => VisitCatchBlock(c)))
             : throw new ArgumentNullException(nameof(e));
Пример #8
0
        Expression VisitNewArrayBounds(XElement e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            return(Expression.NewArrayBounds(
                       DataSerialization.GetType(e),
                       VisitExpressions(e.Element(XNames.Elements.Bounds).Elements())));
        }
Пример #9
0
        TypeBinaryExpression VisitTypeBinary(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            return(Expression.TypeIs(
                       Visit(element.Elements().First()),
                       DataSerialization.GetType(element)));
        }
 GotoExpression VisitGoto(XElement element)
 => element != null
             ? Expression.MakeGoto(
     (GotoExpressionKind)Enum.Parse(
         typeof(GotoExpressionKind),
         element.Attribute(XNames.Attributes.Kind).Value,
         true),
     VisitLabelTarget(element.Elements().ElementAt(0)),
     Visit(element.Elements().Skip(1).FirstOrDefault()),
     DataSerialization.GetType(element))
             : throw new ArgumentNullException(nameof(element));
        LabelTarget VisitLabelTarget(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var name = GetName(element);

            return(GetLabelTarget(
                       (element.Attribute(XNames.Attributes.Uid) ?? element.Attribute(XNames.Attributes.Uidref)).Value,
                       name,
                       DataSerialization.GetType(element) ?? typeof(void)));
        }
        static MemberInfo GetMemberInfo(XElement e)
        {
            if (e == null)
            {
                return(null);
            }

            var type = DataSerialization.GetType(e);

            if (!_memberInfoDeserializers.TryGetValue(e.Name, out var getMemberInfo))
            {
                throw new SerializationException("Expected a member info type of element.");
            }

            return(getMemberInfo(type, e));
        }
        static MethodInfo GetMethodInfo(Type type, XElement e)
        {
            if (e != null && type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            return(e == null
                        ? null
                        : type.GetMethod(
                       GetName(e),
                       e.Element(XNames.Elements.Parameters)
                       .Elements(XNames.Elements.Parameter)
                       .Select(p => DataSerialization.GetType(p))
                       .ToArray()));
        }
        static MethodInfo GetMethodInfo(XElement e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            var method = e.Elements(XNames.Elements.Method).FirstOrDefault();

            if (method == null)
            {
                return(null);
            }

            return(GetMethodInfo(
                       DataSerialization.GetType(method),
                       method));
        }
        static ConstructorInfo GetConstructorInfo(XElement e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            var constructor = e.Elements(XNames.Elements.Constructor).FirstOrDefault();

            if (constructor == null)
            {
                return(null);
            }

            return(GetConstructorInfo(
                       DataSerialization.GetType(constructor),
                       constructor));
        }
        static ConstructorInfo GetConstructorInfo(Type type, XElement e)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (e == null)
            {
                return(null);
            }

            return(type.GetConstructor(
                       e.Element(XNames.Elements.Parameters)
                       .Elements()
                       .Select(p => DataSerialization.GetType(p))
                       .ToArray()));
        }
        Expression VisitSwitch(XElement e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            var defaultElement = e.Elements(XNames.Elements.DefaultCase).FirstOrDefault();

            return(Expression.Switch(
                       DataSerialization.GetType(e),
                       Visit(e.Elements().FirstOrDefault()),
                       defaultElement != null
                                ? Visit(defaultElement.Elements().FirstOrDefault())
                                : null,
                       GetMethodInfo(e),
                       e.Elements(XNames.Elements.Case).Select(c => VisitSwitchCase(c))));
        }
        static ConstantExpression VisitConstant(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var constantElement = element.Elements().FirstOrDefault();

            if (constantElement == null)
            {
                throw new SerializationException("Expected constant element's contents.");
            }

            var type  = DataSerialization.GetDataType(constantElement);
            var value = DataSerialization.GetDeserializer(constantElement)(constantElement, type);

            return(Expression.Constant(value, type));
        }
        MemberExpression VisitMember(XElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            var memberElement = element.Element(XNames.Elements.Property);

            if (memberElement == null)
            {
                memberElement = element.Element(XNames.Elements.Field);
            }

            return(Expression.MakeMemberAccess(
                       Visit(element.Elements().First()),
                       GetMemberInfo(
                           DataSerialization.GetType(memberElement),
                           memberElement)));
        }
        CatchBlock VisitCatchBlock(XElement e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            var exceptionElement = e.Elements(XNames.Elements.Exception)
                                   .FirstOrDefault();
            var exception = exceptionElement != null
                                        ? Expression.Parameter(
                DataSerialization.GetType(exceptionElement),
                GetName(exceptionElement))
                                        : null;

            try
            {
                if (exception != null)
                {
                    _references[exception.Name] = exception;
                }

                var filter         = Visit(e.Elements(XNames.Elements.Filter).FirstOrDefault());
                var catchBodyIndex = (exceptionElement == null ? 0 : 1) + (filter == null ? 0 : 1);

                return(Expression.MakeCatchBlock(
                           DataSerialization.GetType(e),
                           exception,
                           Visit(e.Elements().ElementAt(catchBodyIndex)),
                           filter));
            }
            finally
            {
                if (exception != null)
                {
                    _references.Remove(exception.Name);
                }
            }
        }
 Expression VisitNewArrayBounds(XElement e)
 => e != null
             ? Expression.NewArrayBounds(
     DataSerialization.GetType(e),
     VisitExpressions(e.Element(XNames.Elements.Bounds).Elements()))
             : throw new ArgumentNullException(nameof(e));
 static Expression VisitDefault(XElement element)
 => Expression.Default(DataSerialization.GetType(element));
 static Type ConvertTo(XElement e)
 => e != null
             ? DataSerialization.GetType(e.Attribute(XNames.Attributes.Type))
             : throw new ArgumentNullException(nameof(e));
 TypeBinaryExpression VisitTypeBinary(XElement element)
 => element != null
             ? Expression.TypeIs(
     Visit(element.Elements().First()),
     DataSerialization.GetType(element))
             : throw new ArgumentNullException(nameof(element));