예제 #1
0
        public Expression BuildExpression(ExpressionBuilderArgs args)
        {
            var members         = GetMembers();
            var resultObjectVar = args.InstanceVar;
            var innerArgs       = args.Clone();

            if (_endianness.HasValue)
            {
                innerArgs.Endianness = Expression.Constant(_endianness.Value, typeof(Endianness));
            }
            var instanceVar = Expression.Parameter(typeof(T), "result");
            var expressions = new List <Expression>();

            expressions.Add(Expression.Call(typeof(Debug), "Indent", null));
            expressions.Add(Expression.Assign(instanceVar, Expression.Convert(resultObjectVar, typeof(T))));
            if (typeof(T).IsClass())
            {
                expressions.Add(Expression.IfThen(Expression.Equal(instanceVar, Expression.Constant(null)),
                                                  Expression.Throw(Expression.New(typeof(ArgumentNullException).GetConstructor(new[] { typeof(String) }),
                                                                                  Expression.Constant(instanceVar.Name, typeof(String))))));
            }
            innerArgs.InstanceVar = instanceVar;
            expressions.AddRange(members
                                 // filter ignored members
                                 .Where(pair => pair.Value != null)
                                 .Select(pair =>
            {
                var expression = pair.Value.BuildExpression(innerArgs);
                return((Expression)Expression.Assign(
                           Expression.PropertyOrField(instanceVar, pair.Value.MemberName),
                           expression));
            }));
            expressions.Add(Expression.Call(typeof(Debug), "Unindent", null));
            return(Expression.Block(new[] { instanceVar }, expressions));
        }
        protected override Expression BuildBodyExpression(ExpressionBuilderArgs args, ParameterExpression innerResultVar, ParameterExpression typeVar)
        {
            var elementType = typeof(TElement);
            //IExpressionBuilder typeBuilder = FileFormatBuilder.Types[elementType];
            var iVar           = Expression.Variable(typeof(int), "i");
            var elementVar     = Expression.Variable(elementType, "iterator");
            var loopEndLabel   = Expression.Label();
            var elementBuilder = MemberBuilder <TMember, TElement> .Create("[i]");

            if (_elementBuilderConfiguration != null)
            {
                _elementBuilderConfiguration(elementBuilder);
            }
            var innerArgs = args.Clone();

            innerArgs.InstanceVar = innerResultVar;
            return(Expression.Block(
                       new[] { iVar, elementVar },
                       Expression.Assign(iVar, Expression.Constant(0)),
                       AdvancedExpression.Debug("Reading collection {0}...", Expression.Constant(MemberName)),
                       Expression.Loop(
                           Expression.IfThenElse(
                               GetLoopCondition(args, innerResultVar, iVar, elementVar),
                               Expression.Block(
                                   AdvancedExpression.Debug("Reading {0}[{1}]...", Expression.Constant(MemberName), iVar),
                                   Expression.Assign(elementVar, elementBuilder.BuildExpression(innerArgs)),

/*
 *                          Expression.Assign(elementVar, elementCtor),
 *                          typeBuilder.BuildExpression(brParameter, elementVar, typeReaders),
 */
                                   InsertElement(args, innerResultVar, iVar, elementVar),
                                   Expression.PostIncrementAssign(iVar)),
                               Expression.Break(loopEndLabel)),
                           loopEndLabel)));
        }