Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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()));
        }