示例#1
0
 public Address Clone(IDictionary<Address, Address> map)
 {
     if (map.ContainsKey(this))
         return map[this];
     var result = new Address() { Expression = this.Expression };
     map[this] = result;
     return result;
 }
示例#2
0
 public static Address Merge(Expression test, Address address1, Address address2,
     IDictionary<Tuple<Address, Address>, Address> map)
 {
     var addresses = Tuple.Create(address1, address2);
     if (map.ContainsKey(addresses))
         return map[addresses];
     Address result;
     if (address1.Expression == address2.Expression)
     {
         result = address1;
     }
     else
     {
         var left = address1.Expression ?? Expression.Default(address2.Type);
         var right = address2.Expression ?? Expression.Default(address1.Type);
         left = Processor.AdjustType(left, right.Type);
         right = Processor.AdjustType(right, left.Type);
         result = Expression.Condition(test, left, right);
     }
     map[addresses] = result;
     return result;
 }
示例#3
0
        static Expression BuildMethodCallExpression(MethodInfo m, Address instance, Expression[] arguments)
        {
            if (m.Name == "Add" && instance.Expression != null && typeof(IEnumerable).IsAssignableFrom(instance.Type))
            {
                var newExpression = instance.Expression as NewExpression;
                if (newExpression != null)
                {
                    var init = Expression.ListInit(newExpression, Expression.ElementInit(m, arguments));
                    instance.Expression = init;
                    return instance;
                }
                var initExpression = instance.Expression as ListInitExpression;
                if (initExpression != null)
                {
                    var initializers = initExpression.Initializers.ToList();
                    initializers.Add(Expression.ElementInit(m, arguments));
                    var init = Expression.ListInit(initExpression.NewExpression, initializers);
                    instance.Expression = init;
                    return instance;
                }
            }
            if (m.IsSpecialName && m.IsHideBySig)
            {
                if (m.Name.StartsWith("get_"))
                {
                    return Expression.Property(instance, m);
                }
                if (m.Name.StartsWith("op_"))
                {
                    ExpressionType type;
                    if (TryParseOperator(m, out type))
                    {
                        switch (arguments.Length)
                        {
                            case 1:
                                return Expression.MakeUnary(type, arguments[0], arguments[0].Type);
                            case 2:
                                return Expression.MakeBinary(type, arguments[0], arguments[1]);
                        }
                    }
                    else
                    {
                        switch (m.Name)
                        {
                            case "op_Increment":
                                return Expression.Add(arguments[0], Expression.Constant(Convert.ChangeType(1, arguments[0].Type)));
                            case "op_Decrement":
                                return Expression.Subtract(arguments[0], Expression.Constant(Convert.ChangeType(1, arguments[0].Type)));
                            case "op_Implicit":
                                return Expression.Convert(arguments[0], m.ReturnType, m);
                        }
                    }
                }
            }
            if (m.Name == "Concat" && m.DeclaringType == typeof (string))
            {
                var expressions = GetExpressionsForStringConcat(arguments);
                if (expressions.Count > 1)
                {
                    var expression = expressions[0];
                    for (var i = 1; i < expressions.Count; i++)
                    {
                        expression = Expression.Add(expression, expressions[i], StringConcat);
                    }
                    return expression;
                }
            }

            if (m.Name == "InitializeArray" && m.DeclaringType == typeof (RuntimeHelpers))
            {
                var arrayGetter = (Func<Array>) Expression.Lambda(arguments[0]).Compile();
                var fieldGetter = (Func<RuntimeFieldHandle>) Expression.Lambda(arguments[1]).Compile();
                var array = arrayGetter();
                RuntimeHelpers.InitializeArray(array, fieldGetter());

                IEnumerable<Expression> initializers = array.Cast<object>().Select(Expression.Constant);

                return Expression.NewArrayInit(arguments[0].Type.GetElementType(), initializers);
            }

            var parameters = m.GetParameters();
            for (int i = 0; i < parameters.Length; i++)
            {
                var parameter = parameters[i];
                var argument = arguments[i];
                var parameterType = parameter.ParameterType;
                arguments[i] = AdjustType(argument, parameterType);
            }

            if (instance.Expression != null)
                return Expression.Call(instance, m, arguments);

            return Expression.Call(null, m, arguments);
        }
示例#4
0
 public VariableInfo(Type type)
 {
     Type = type;
     Address = new Address();
 }