Expression VisitElseIf(ElseIfExpression node) { var changed = false; var ifs = new List <ConditionalExpression>(); Expression newElse = null; for (var i = 0; i < node.If.Length; i++) { if (i == 0) { Write("if"); } else { Write("else if"); } WriteSpace(); Write("("); var test = Expression.Block(VisitWithDebug(node.If[i].Test, 0)); Write(")"); WriteLine(); var ifTrue = VisitAsBlock(node.If[i].IfTrue); if (node.If[i].Test != test || node.If[i].IfTrue != ifTrue) { changed = true; ifs.Add(Expression.IfThenElse(test, ifTrue, node.If[i].IfFalse)); } else { ifs.Add(node.If[i]); } } if (node.Else != null) { if (node.If.Length > 0) { Write("else"); WriteLine(); newElse = VisitAsBlock(node.Else); } else { newElse = MaybeVisitAsBlock(node.Else, false); } } if (changed) { return(new ElseIfExpression(ifs.ToArray(), newElse)); } return(node); }
public Expression GetLadder() { var castReaderName = Expression.Convert(XmlExpressionConstants.XmlReader_Name, typeof(object)); var assignReaderName = Expression.Assign(XmlExpressionConstants.Serializer_Name(attributeType), castReaderName); var conditions = generator.ForEachMappingValue <ConditionalExpression>(BuildConditions); var elseIf = new ElseIfExpression(conditions.ToArray(), XmlExpressionConstants.Serializer_SkipUnknownNode); if (Mappings.Where(m => m.AttributeType == attributeType).Count() > 0) { return(Expression.Block( assignReaderName, elseIf )); } else { return(elseIf); } }
private Expression ProcessElement() { var nodeType = XmlExpressionConstants.XmlReader_NodeType; var element = Expression.Constant(XmlNodeType.Element); var endElement = Expression.Constant(XmlNodeType.EndElement); var none = Expression.Constant(XmlNodeType.None); var loopCondition = Expression.AndAlso( nodeType.NotEqual(endElement), //reader.NodeType != XmlNodeType.EndElement nodeType.NotEqual(none) //reader.NodeType != XmlNodeType.none ); var builder = new LadderBuilder(this, XmlAttributeType.Element); var isElement = nodeType.Equal(element); var elementLadder = builder.GetLadder(); var skipUnknown = XmlExpressionConstants.Serializer_SkipUnknownNode; Expression loopBody; var textMappings = Mappings.Where(m => m.AttributeType == XmlAttributeType.Text).ToList(); if (textMappings.Count > 0) { if (textMappings.Count > 1) { var str = string.Join(", ", textMappings.Select(m => m.PropertyCache.Property.Name)); throw new InvalidOperationException($"Canot deserialize type {trueType.Name} as multiple properties contain a {nameof(XmlTextAttribute)} ({str})."); //todo: complain about the name of this type and the properties that have the two xmltextattributes } var isText = nodeType.Equal(Expression.Constant(XmlNodeType.Text)); var textBlock = GetTextBlock(textMappings.Single()); loopBody = new ElseIfExpression( new[] { Expression.IfThen(isElement, elementLadder), //if (reader.NodeType == XmlNodeType.Element) [Ladder] Expression.IfThen(isText, textBlock) //else if (reader.NodeType == XmlNodeType.Text) [TextBlock] }, skipUnknown //else SkipUnknownNode() ); } else { loopBody = Expression.IfThenElse( //if (reader.NodeType == XmlNodeType.Element) isElement, // [Ladder] elementLadder, //else skipUnknown // SkipUnknownNode() ); } var @break = Expression.Label("break"); var loop = Expression.Loop( Expression.IfThenElse(loopCondition, loopBody, Expression.Break(@break)), @break ); var body = new List <Expression>(); body.Add(XmlExpressionConstants.XmlReader_ReadStartElement); body.Add(XmlExpressionConstants.XmlReader_MoveToContent); body.Add(loop); body.Add(XmlExpressionConstants.XmlReader_ReadEndElement); var validator = MakeValidateValueTypes(); if (validator != null) { body.Add(validator); } if (!update) { body.Add(Target); } return(Expression.Block(body.ToArray())); }