public BoundExpressionCache(CachedDynamicExpression dynamicExpression)
        {
            Require.NotNull(dynamicExpression, "dynamicExpression");

            _dynamicExpression = dynamicExpression;
        }
Example #2
0
        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;
        }