private static Expression CoalesceInternal(CodeBlock currentBlock, Expression left, Expression right, MethodInfo isTrue, bool isReverse) { Contract.RequiresNotNull(currentBlock, "currentBlock"); Contract.RequiresNotNull(left, "left"); Contract.RequiresNotNull(right, "right"); // A bit too strict, but on a safe side. Contract.Requires(left.Type == right.Type, "Expression types must match"); Variable tmp = currentBlock.CreateTemporaryVariable(SymbolTable.StringToId("tmp_left"), left.Type); Expression condition; if (isTrue != null) { Contract.Requires(isTrue.ReturnType == typeof(bool), "isTrue", "Predicate must return bool."); ParameterInfo[] parameters = isTrue.GetParameters(); Contract.Requires(parameters.Length == 1, "isTrue", "Predicate must take one parameter."); Contract.Requires(isTrue.IsStatic && isTrue.IsPublic, "isTrue", "Predicate must be public and static."); Type pt = parameters[0].ParameterType; Contract.Requires(TypeUtils.CanAssign(pt, left.Type), "left", "Incorrect left expression type"); condition = Call(isTrue, Assign(tmp, left)); } else { Contract.Requires(TypeUtils.CanCompareToNull(left.Type), "left", "Incorrect left expression type"); condition = Equal(Assign(tmp, left), Null(left.Type)); } Expression t, f; if (isReverse) { t = Read(tmp); f = right; } else { t = right; f = Read(tmp); } return(Condition(condition, t, f)); }
private static Expression CoalesceInternal(Expression left, Expression right, MethodInfo isTrue, bool isReverse, out ParameterExpression temp) { ContractUtils.RequiresNotNull(left, "left"); ContractUtils.RequiresNotNull(right, "right"); // A bit too strict, but on a safe side. ContractUtils.Requires(left.Type == right.Type, "Expression types must match"); temp = Expression.Variable(left.Type, "tmp_left"); Expression condition; if (isTrue != null) { ContractUtils.Requires(isTrue.ReturnType == typeof(bool), "isTrue", "Predicate must return bool."); ParameterInfo[] parameters = isTrue.GetParameters(); ContractUtils.Requires(parameters.Length == 1, "isTrue", "Predicate must take one parameter."); ContractUtils.Requires(isTrue.IsStatic && isTrue.IsPublic, "isTrue", "Predicate must be public and static."); Type pt = parameters[0].ParameterType; ContractUtils.Requires(TypeUtils.CanAssign(pt, left.Type), "left", "Incorrect left expression type"); condition = Expression.Call(isTrue, Expression.Assign(temp, left)); } else { ContractUtils.Requires(TypeUtils.CanCompareToNull(left.Type), "left", "Incorrect left expression type"); condition = Expression.Equal(Expression.Assign(temp, left), AstUtils.Constant(null, left.Type)); } Expression t, f; if (isReverse) { t = temp; f = right; } else { t = right; f = temp; } return(Expression.Condition(condition, t, f)); }