Exemplo n.º 1
0
        private static Expression Prepare(ArgMap map, ExpressionBlockBuilder block, ParameterExpression p)
        {
            if (!map.Method.IsOut && !map.Method.IsByRef)
            {
                // normal parameter
                return(map.Method.Type == map.Delegate.Type ? (Expression)p : Expression.Convert(p, map.Method.Type));
            }
            // out or ref
            var mt = map.Method.Type.RemoveByRef();
            var dt = map.Delegate.Type.RemoveByRef();

            if (mt == dt)
            {
                return(p);
            }

            var localVariable = Expression.Variable(mt);

            block.AddVariable(localVariable);
            if (map.Method.IsOut)
            {
                return(localVariable);
            }

            // ref
            var value = map.Delegate.IsOut
                ? (Expression)Expression.Default(mt)
                : Expression.Convert(p, mt);
            var assign = Expression.Assign(localVariable, value);

            block.Add(assign);

            return(localVariable);
        }
Exemplo n.º 2
0
        private static void ConvertReturn(RetValMap retValMap, ExpressionBlockBuilder block, Expression invoke, ParameterExpression retVal)
        {
            if (retValMap.Method == typeof(void))
            {
                if (retValMap.Delegate != typeof(void))
                {
                    // add default(_delegateReturn)
                    block.Add(Expression.Default(retValMap.Delegate));
                }
                else if (block.Last != invoke)
                {
                    // should we return void?
                    block.Add(_void);
                }
                return;
            }
            if (retValMap.Delegate == typeof(void))
            {
                block.Add(_void);
                return;
            }

            // try optimize local variable
            Expression result;

            if (block.Last is BinaryExpression binary && binary.NodeType == ExpressionType.Assign && binary.Left == retVal)
            {
                result = binary.Right;
                block.RemoveVariable(retVal);
                block.RemoveLast();
            }
Exemplo n.º 3
0
        private BlockExpression BuildExpressionBlock(Type targetType, ParameterExpression targetInstanceParameter,
                                                     ParameterExpression dataReaderParameter, PropertyInfo indexerProperty)
        {
            var expressionBlockBuilder = new ExpressionBlockBuilder(targetInstanceParameter.Type, new[] { targetInstanceParameter });

            return(expressionBlockBuilder
                   .Add(Expression.Assign(targetInstanceParameter, Expression.New(targetType)))
                   .AddRange(BuildPrimitivePropertyExpressions(targetType, targetInstanceParameter, dataReaderParameter,
                                                               indexerProperty))
                   .AddRange(BuildComplexPropertyExpressions(targetType, targetInstanceParameter, dataReaderParameter,
                                                             indexerProperty))
                   .Add(targetInstanceParameter)
                   .Build());
        }
Exemplo n.º 4
0
        private static ParameterExpression PrepareInvoke(RetValMap retValMap, ExpressionBlockBuilder block, Expression invoke)
        {
            if (retValMap.Method == typeof(void) || retValMap.Delegate == typeof(void))
            {
                // no local variables for void
                block.Add(invoke);
                return(null);
            }
            var variable = Expression.Variable(retValMap.Method);
            var assign   = Expression.Assign(variable, invoke);

            block.AddVariable(variable);
            block.Add(assign);
            return(variable);
        }
Exemplo n.º 5
0
        private static Delegate BuildDelegate(DelegateMap map, Func <Expression[], Expression> buildInvoke)
        {
            var pm               = map.ParametersMap;
            var parameters       = pm.ConvertAll(p => Expression.Parameter(p.Delegate.Type));
            var block            = new ExpressionBlockBuilder();
            var invokeParameters = parameters.ConvertAll((p, i) => Prepare(pm[i], block, p));
            var invoke           = buildInvoke(invokeParameters);
            var retVal           = PrepareInvoke(map.RetValMap, block, invoke);

            for (var i = 0; i < parameters.Length; i++)
            {
                Finish(pm[i], block, invokeParameters[i], parameters[i]);
            }
            ConvertReturn(map.RetValMap, block, invoke, retVal);

            var body   = block.CreateExpression();
            var lambda = Expression.Lambda(map.DelegateType, body, parameters);

            return(lambda.Compile());
        }
Exemplo n.º 6
0
        private static void Finish(ArgMap map, ExpressionBlockBuilder block, Expression prepare, ParameterExpression p)
        {
            // Not out and (Not By Ref or ([byRef] and not (delegate ref or delegate out)
            if (!map.Method.IsOut && (!map.Method.IsByRef || !(map.Delegate.IsByRef || map.Delegate.IsOut)))
            {
                return;
            }
            // out/ref and typeSame - do nothing
            var mt = map.Method.Type.RemoveByRef();
            var dt = map.Delegate.Type.RemoveByRef();

            if (mt == dt)
            {
                return;
            }

            // convert and assign back
            var convertResult = Expression.Convert(prepare, dt);
            var assign        = Expression.Assign(p, convertResult);

            block.Add(assign);
        }