예제 #1
0
        /// <summary>
        /// Attempts to coerce the operand types on a binary operation for some special type and value cases as treated by JsonValue:
        /// "true" and "false" can be converted to boolean.
        /// Guid, DateTime and other types can be converted to string.
        /// </summary>
        /// <param name="thisOperand">The first operand.</param>
        /// <param name="otherOperand">The second operand</param>
        /// <param name="coercedType">On success, this parameter contains the coerced type.</param>
        /// <returns>true if the coercion is performed, false otherwise.</returns>
        private static bool TryCoerceSpecialTypes(DynamicMetaObject thisOperand, DynamicMetaObject otherOperand, out Type coercedType)
        {
            JsonValue thisValue  = thisOperand.Value as JsonValue;
            JsonValue otherValue = otherOperand.Value as JsonValue;

            if (thisValue is JsonPrimitive)
            {
                Type thisType = thisValue.Read().GetType();

                if (thisType != otherOperand.LimitType)
                {
                    if (otherOperand.LimitType == typeof(string) || (thisType == typeof(string) && otherValue == null))
                    {
                        object value;
                        if (thisValue.TryReadAs(otherOperand.LimitType, out value))
                        {
                            coercedType = otherOperand.LimitType;
                            return(true);
                        }
                    }
                }
            }

            coercedType = default(Type);
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Gets the operation support value for the specified operation on the specified operand.
        /// </summary>
        /// <param name="operation">The operation type.</param>
        /// <param name="thisValue">The JsonValue instance to check operation for.</param>
        /// <returns>An <see cref="OperationSupport"/> value.</returns>
        private static OperationSupport GetUnaryOperationSupport(ExpressionType operation, JsonValue thisValue)
        {
            //// Unary operators: +, -, !, ~, false (&&), true (||)
            //// unsupported: ++, --

            switch (operation)
            {
            case ExpressionType.UnaryPlus:
            case ExpressionType.Negate:
            case ExpressionType.OnesComplement:
            case ExpressionType.IsFalse:
            case ExpressionType.IsTrue:
                break;

            case ExpressionType.Not:
                ////  The DLR converts the 'Not' operation into a 'OnesComplement' operation for integer numbers, need to block that scenario.
                bool boolVal;
                if (!thisValue.TryReadAs <bool>(out boolVal))
                {
                    return(OperationSupport.NotSupportedOnOperand);
                }

                break;

            default:
                return(OperationSupport.NotSupported);
            }

            return(OperationSupport.Supported);
        }
예제 #3
0
        /// <summary>
        /// Gets the return type for unary operations.
        /// </summary>
        /// <param name="binder">The unary operation binder.</param>
        /// <returns>The type representing the operation return type.</returns>
        private Type GetUnaryOperationReturnType(UnaryOperationBinder binder)
        {
            JsonValue thisValue = this.Value as JsonValue;

            Type returnType = binder.ReturnType == typeof(object) ? thisValue.Read().GetType() : binder.ReturnType;

            //// The DLR sets the binder.ReturnType for the unary 'Not' operation as 'object' as opposed to 'bool',
            //// we need to detect this case and fix up the type to enable boolean conversions from strings.

            if (returnType == typeof(string) && binder.Operation == ExpressionType.Not)
            {
                bool boolVal;
                if (thisValue.TryReadAs <bool>(out boolVal))
                {
                    returnType = typeof(bool);
                }
            }

            return(returnType);
        }
예제 #4
0
        public void ReadAsTests()
        {
            JsonValue target   = AnyInstance.DefaultJsonValue;
            string    typeName = target.GetType().FullName;

            string errorMsgFormat = "Cannot read '{0}' as '{1}' type.";

            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs(typeof(bool)); }, String.Format(errorMsgFormat, typeName, typeof(bool)));
            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs(typeof(string)); }, String.Format(errorMsgFormat, typeName, typeof(string)));
            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs(typeof(JsonObject)); }, String.Format(errorMsgFormat, typeName, typeof(JsonObject)));

            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs <bool>(); }, String.Format(errorMsgFormat, typeName, typeof(bool)));
            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs <string>(); }, String.Format(errorMsgFormat, typeName, typeof(string)));
            ExceptionHelper.Throws <NotSupportedException>(delegate { target.ReadAs <JsonObject>(); }, String.Format(errorMsgFormat, typeName, typeof(JsonObject)));

            bool       boolValue;
            string     stringValue;
            JsonObject objValue;

            object value;

            Assert.False(target.TryReadAs(typeof(bool), out value), "TryReadAs expected to return false");
            Assert.Null(value);

            Assert.False(target.TryReadAs(typeof(string), out value), "TryReadAs expected to return false");
            Assert.Null(value);

            Assert.False(target.TryReadAs(typeof(JsonObject), out value), "TryReadAs expected to return false");
            Assert.Null(value);

            Assert.False(target.TryReadAs <bool>(out boolValue), "TryReadAs expected to return false");
            Assert.False(boolValue);

            Assert.False(target.TryReadAs <string>(out stringValue), "TryReadAs expected to return false");
            Assert.Null(stringValue);

            Assert.False(target.TryReadAs <JsonObject>(out objValue), "TryReadAs expected to return false");
            Assert.Null(objValue);
        }