示例#1
0
        Expression FieldValue(IParser parser, Expression var, Expression valueType, Type schemaType, bool initialize)
        {
            Expression body;

            if (schemaType.IsBondStruct() && var.Type.IsValueType())
            {
                // Special handling for properties of struct types: we deserialize into
                // a temp variable and then assign the value to the property.
                var temp = Expression.Variable(var.Type, $"{var.Type.Name}_temp");
                body = Expression.Block(
                    new[] { temp },
                    Value(parser, temp, valueType, schemaType, true),
                    Expression.Assign(var, temp));
            }
            else
            {
                body = Value(parser, var, valueType, schemaType, initialize);
            }

            if (schemaType.IsBondContainer() || schemaType.IsBondStruct() || schemaType.IsBondNullable())
            {
                var expectedType = Expression.Constant(schemaType.GetBondDataType());
                return(PrunedExpression.IfThenElse(
                           Expression.Equal(valueType, expectedType),
                           body,
                           ThrowExpression.InvalidTypeException(expectedType, valueType)));
            }

            return(body);
        }
示例#2
0
        Expression Value(IParser parser, Expression valueType)
        {
            if (parser.IsBonded)
            {
                return(parser.Bonded(value =>
                                     writer.WriteBonded(PrunedExpression.Convert(value, typeof(IBonded)))));
            }

            var switchCases = new List <DeferredSwitchCase>
            {
                PrunedExpression.SwitchCase(
                    () => GenerateSerialize(Container, parser),
                    BondDataType.BT_LIST,
                    BondDataType.BT_SET),
                PrunedExpression.SwitchCase(
                    () => GenerateSerialize(Map, parser),
                    BondDataType.BT_MAP),
                PrunedExpression.SwitchCase(
                    () => GenerateSerialize(Struct, parser),
                    BondDataType.BT_STRUCT)
            };

            switchCases.AddRange(
                from type in new[]
            {
                BondDataType.BT_BOOL,
                BondDataType.BT_UINT8,
                BondDataType.BT_UINT16,
                BondDataType.BT_UINT32,
                BondDataType.BT_UINT64,
                BondDataType.BT_FLOAT,
                BondDataType.BT_DOUBLE,
                BondDataType.BT_STRING,
                BondDataType.BT_INT8,
                BondDataType.BT_INT16,
                BondDataType.BT_INT32,
                BondDataType.BT_INT64,
                BondDataType.BT_WSTRING
            }
                select
                PrunedExpression.SwitchCase(
                    () => parser.Scalar(Expression.Constant(type), type,
                                        value => writer.Write(value, type)),
                    type));

            return(PrunedExpression.Switch(
                       valueType,
                       ThrowExpression.InvalidTypeException(valueType),
                       switchCases));
        }
示例#3
0
        Expression Struct(IParser parser, Expression var, Type schemaType, bool initialize)
        {
            var body = new List <Expression>();

            if (initialize)
            {
                body.Add(Expression.Assign(var, newObject(var.Type, schemaType)));
            }

            ITransform transform;

            if (parser.HierarchyDepth > schemaType.GetHierarchyDepth())
            {
                // Parser inheritance hierarchy is deeper than the type we are deserializing.
                // Recurse until hierarchies align.
                transform = new Transform(
                    Base: baseParser => Struct(baseParser, var, schemaType, initialize: false));
            }
            else
            {
                var baseType = schemaType.GetBaseSchemaType();

                transform = new Transform(
                    Fields:
                    from field in schemaType.GetSchemaFields()
                    select new Field(
                        Id: field.Id,
                        Value: (fieldParser, fieldType) => FieldValue(
                            fieldParser,
                            DataExpression.PropertyOrField(var, field.Name),
                            fieldType,
                            field.GetSchemaType(),
                            field.GetDefaultValue() == null),
                        Omitted: () => field.GetModifier() == Modifier.Required ?
                        ThrowExpression.RequiredFieldMissingException(
                            field.DeclaringType.Name, Expression.Constant(field.Name)) :
                        Expression.Empty()),
                    Base: baseParser => baseType != null
                        ? Struct(baseParser, Expression.Convert(var, baseType.GetObjectType()), baseType, initialize: false)
                        : Expression.Empty());
            }

            body.Add(parser.Apply(transform));
            return(Expression.Block(body));
        }