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));
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));
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()))); }
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));