public BoundExpressionCache(CachedDynamicExpression dynamicExpression) { Require.NotNull(dynamicExpression, "dynamicExpression"); _dynamicExpression = dynamicExpression; }
public static bool IsValidUnaryArgument(Type type) { Require.NotNull(type, "type"); return(ImplicitCastingTable.ContainsKey(type)); }
private Type ResolveExpressionCommonType(Type left, Type right, bool allowStringConcat, bool allowBothImplicit, bool allowObjectCoercion) { Require.NotNull(left, "left"); Require.NotNull(right, "right"); // No casting required. if (left == right) return left; if (allowObjectCoercion) { if (left == typeof(object)) return right; if (right == typeof(object)) return left; } // Special cast for adding strings. if (allowStringConcat && (left == typeof(string) || right == typeof(string))) return typeof(string); // Can we cast implicitly? var leftTable = TypeUtil.GetImplicitCastingTable(left); var rightTable = TypeUtil.GetImplicitCastingTable(right); if (leftTable != null && rightTable != null) { // See whether one of the types appears in the other. foreach (var leftType in leftTable) { if (leftType == right) return leftType; } foreach (var rightType in rightTable) { if (rightType == left) return rightType; } // Otherwise, find the first common type. int lowest = int.MaxValue; for (int i = 0; i < leftTable.Count; i++) { for (int j = 0; j < rightTable.Count; j++) { if (leftTable[i] == rightTable[j]) lowest = Math.Min(lowest, j); } } if (lowest != int.MaxValue) { if ( allowBothImplicit || (IsAllowableImplicit(left, rightTable[lowest]) && IsAllowableImplicit(right, rightTable[lowest])) ) return rightTable[lowest]; } } // We can't cast implicitly. throw new ExpressionsException("Cannot resolve expression type", ExpressionsExceptionType.TypeMismatch); }
private Type ResolveExpressionType(Type left, Type right, Type commonType, ExpressionType type) { Require.NotNull(left, "left"); Require.NotNull(right, "right"); // TODO: Implicit/explicit operators and operators for the expression type. // Boolean operators. switch (type) { case ExpressionType.And: case ExpressionType.Or: case ExpressionType.Xor: case ExpressionType.AndBoth: case ExpressionType.OrBoth: if (TypeUtil.IsInteger(commonType)) return commonType; else if (left != typeof(bool) || right != typeof(bool)) throw new ExpressionsException("Invalid operand for expression type", ExpressionsExceptionType.TypeMismatch); return typeof(bool); case ExpressionType.Greater: case ExpressionType.GreaterOrEquals: case ExpressionType.Less: case ExpressionType.LessOrEquals: if ( !(left.IsEnum || TypeUtil.IsNumeric(left)) || !(right.IsEnum || TypeUtil.IsNumeric(right)) ) throw new ExpressionsException("Invalid operand for expression type", ExpressionsExceptionType.TypeMismatch); return typeof(bool); case ExpressionType.Equals: case ExpressionType.NotEquals: case ExpressionType.In: case ExpressionType.LogicalAnd: case ExpressionType.LogicalOr: case ExpressionType.Compares: case ExpressionType.NotCompares: return typeof(bool); case ExpressionType.Add: if ( !(left == typeof(string) || right == typeof(string)) && !(TypeUtil.IsNumeric(left) && TypeUtil.IsNumeric(right)) ) throw new ExpressionsException("Invalid operand for expression type", ExpressionsExceptionType.TypeMismatch); return commonType; case ExpressionType.Subtract: case ExpressionType.Multiply: case ExpressionType.Divide: case ExpressionType.Power: if (!TypeUtil.IsNumeric(left) || !TypeUtil.IsNumeric(right)) throw new ExpressionsException("Invalid operand for expression type", ExpressionsExceptionType.TypeMismatch); return commonType; default: return commonType; } }
public BindingVisitor(Resolver resolver) { Require.NotNull(resolver, "resolver"); _resolver = resolver; }