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; }
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; }
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); }
public VariableInfo(Type type) { Type = type; Address = new Address(); }