Пример #1
0
        /// <summary>
        /// Validates that the expected primitive type matches the actual primitive type.
        /// </summary>
        /// <param name="expectedTypeReference">The expected type.</param>
        /// <param name="typeReferenceFromValue">The actual type.</param>
        internal static void ValidateMetadataPrimitiveType(IEdmTypeReference expectedTypeReference, IEdmTypeReference typeReferenceFromValue)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(expectedTypeReference != null && expectedTypeReference.IsODataPrimitiveTypeKind(), "expectedTypeReference must be a primitive type.");
            Debug.Assert(typeReferenceFromValue != null && typeReferenceFromValue.IsODataPrimitiveTypeKind(), "typeReferenceFromValue must be a primitive type.");

            IEdmPrimitiveType expectedType  = (IEdmPrimitiveType)expectedTypeReference.Definition;
            IEdmPrimitiveType typeFromValue = (IEdmPrimitiveType)typeReferenceFromValue.Definition;

            // The two primitive types match if they have the same definition and either both or only the
            // expected type is nullable
            // NOTE: for strings and binary values we must not check nullability here because the type reference
            //       from the value is always nullable since C# has no way to express non-nullable strings.
            //       However, this codepath is only hit if the value is not 'null' so we can assign a non-null
            //       value to both nullable and non-nullable string/binary types.
            bool nullableCompatible = expectedTypeReference.IsNullable == typeReferenceFromValue.IsNullable ||
                                      expectedTypeReference.IsNullable && !typeReferenceFromValue.IsNullable ||
                                      !MetadataUtilsCommon.IsODataValueType(typeReferenceFromValue);

            bool typeCompatible = expectedType.IsAssignableFrom(typeFromValue);

            if (!nullableCompatible || !typeCompatible)
            {
                // incompatible type name for value!
                throw new ODataException(Strings.ValidationUtils_IncompatiblePrimitiveItemType(
                                             typeReferenceFromValue.ODataFullName(),
                                             typeReferenceFromValue.IsNullable,
                                             expectedTypeReference.ODataFullName(),
                                             expectedTypeReference.IsNullable));
            }
        }
Пример #2
0
        internal static void ValidateMetadataPrimitiveType(IEdmTypeReference expectedTypeReference, IEdmTypeReference typeReferenceFromValue)
        {
            IEdmPrimitiveType definition = (IEdmPrimitiveType)expectedTypeReference.Definition;
            IEdmPrimitiveType subtype    = (IEdmPrimitiveType)typeReferenceFromValue.Definition;
            bool flag  = ((expectedTypeReference.IsNullable == typeReferenceFromValue.IsNullable) || (expectedTypeReference.IsNullable && !typeReferenceFromValue.IsNullable)) || !typeReferenceFromValue.IsODataValueType();
            bool flag2 = definition.IsAssignableFrom(subtype);

            if (!flag || !flag2)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_IncompatiblePrimitiveItemType(typeReferenceFromValue.ODataFullName(), typeReferenceFromValue.IsNullable, expectedTypeReference.ODataFullName(), expectedTypeReference.IsNullable));
            }
        }
Пример #3
0
        internal static IEdmPrimitiveType GetCommonBaseType(this IEdmPrimitiveType firstType, IEdmPrimitiveType secondType)
        {
            IEdmPrimitiveType type;

            if (((IEdmType)firstType).IsEquivalentTo((IEdmType)secondType))
            {
                return(firstType);
            }
            for (type = firstType; type != null; type = type.BaseType())
            {
                if (type.IsAssignableFrom(secondType))
                {
                    return(type);
                }
            }
            for (type = secondType; type != null; type = type.BaseType())
            {
                if (type.IsAssignableFrom(firstType))
                {
                    return(type);
                }
            }
            return(null);
        }
Пример #4
0
        /// <summary>
        /// Checks if the <paramref name="firstType"/> primitive type and the <paramref name="secondType"/> primitive type
        /// have a common base type.
        /// In other words, if <paramref name="secondType"/> is a subtype of <paramref name="firstType"/> or not.
        /// </summary>
        /// <param name="firstType">Type of the base type.</param>
        /// <param name="secondType">Type of the sub type.</param>
        /// <returns>The common base type or null if no common base type exists.</returns>
        internal static IEdmPrimitiveType GetCommonBaseType(this IEdmPrimitiveType firstType, IEdmPrimitiveType secondType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(firstType != null, "firstType != null");
            Debug.Assert(secondType != null, "secondType != null");

            if (firstType.IsEquivalentTo(secondType))
            {
                return firstType;
            }

            IEdmPrimitiveType commonBaseType = firstType;
            while (commonBaseType != null)
            {
                if (commonBaseType.IsAssignableFrom(secondType))
                {
                    return commonBaseType;
                }

                commonBaseType = commonBaseType.BaseType();
            }

            commonBaseType = secondType;
            while (commonBaseType != null)
            {
                if (commonBaseType.IsAssignableFrom(firstType))
                {
                    return commonBaseType;
                }

                commonBaseType = commonBaseType.BaseType();
            }

            return null;
        }
Пример #5
0
        /// <summary>
        /// Determines if a <paramref name="sourcePrimitiveType"/> is convertibale according to OData rules to the
        /// <paramref name="targetPrimitiveType"/>.
        /// </summary>
        /// <param name="sourceNodeOrNull">The node which is to be converted.</param>
        /// <param name="sourcePrimitiveType">The type which is to be converted.</param>
        /// <param name="targetPrimitiveType">The type to which we want to convert.</param>
        /// <returns>true if the source type is convertible to the target type; otherwise false.</returns>
        internal static bool CanConvertPrimitiveTypeTo(
            SingleValueNode sourceNodeOrNull,
            IEdmPrimitiveType sourcePrimitiveType,
            IEdmPrimitiveType targetPrimitiveType)
        {
            Debug.Assert(sourcePrimitiveType != null, "sourcePrimitiveType != null");
            Debug.Assert(targetPrimitiveType != null, "targetPrimitiveType != null");

            EdmPrimitiveTypeKind sourcePrimitiveKind = sourcePrimitiveType.PrimitiveKind;
            EdmPrimitiveTypeKind targetPrimitiveKind = targetPrimitiveType.PrimitiveKind;

            switch (sourcePrimitiveKind)
            {
            case EdmPrimitiveTypeKind.SByte:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.SByte:
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Byte:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Byte:
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int16:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int32:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int64:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Single:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                    return(true);

                // allow single constant->decimal in order to made L,M,D,F optional
                case EdmPrimitiveTypeKind.Decimal:
                    object tmp;
                    return(TryGetConstantNodePrimitiveLDMF(sourceNodeOrNull, out tmp));
                }

                break;

            case EdmPrimitiveTypeKind.Double:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Double:
                    return(true);

                // allow double constant->decimal in order to made L,M,D,F optional
                // (if the double value actually has overflowed decimal.MaxValue, exception will occur later. more details in ExpressionLexer.cs)
                case EdmPrimitiveTypeKind.Decimal:
                    object tmp;
                    return(TryGetConstantNodePrimitiveLDMF(sourceNodeOrNull, out tmp));
                }

                break;

            default:
                return(sourcePrimitiveKind == targetPrimitiveKind || targetPrimitiveType.IsAssignableFrom(sourcePrimitiveType));
            }

            return(false);
        }
Пример #6
0
        /// <summary>
        /// Determines if a <paramref name="sourcePrimitiveType"/> is convertibale according to OData rules to the
        /// <paramref name="targetPrimitiveType"/>.
        /// </summary>
        /// <param name="sourcePrimitiveType">The type which is to be converted.</param>
        /// <param name="targetPrimitiveType">The type to which we want to convert.</param>
        /// <returns>true if the source type is convertible to the target type; otherwise false.</returns>
        internal static bool CanConvertPrimitiveTypeTo(
            IEdmPrimitiveType sourcePrimitiveType,
            IEdmPrimitiveType targetPrimitiveType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(sourcePrimitiveType != null, "sourcePrimitiveType != null");
            Debug.Assert(targetPrimitiveType != null, "targetPrimitiveType != null");

            EdmPrimitiveTypeKind sourcePrimitiveKind = sourcePrimitiveType.PrimitiveKind;
            EdmPrimitiveTypeKind targetPrimitiveKind = targetPrimitiveType.PrimitiveKind;

            switch (sourcePrimitiveKind)
            {
            case EdmPrimitiveTypeKind.SByte:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.SByte:
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Byte:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Byte:
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int16:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int16:
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int32:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int32:
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Int64:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Int64:
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                case EdmPrimitiveTypeKind.Decimal:
                    return(true);
                }

                break;

            case EdmPrimitiveTypeKind.Single:
                switch (targetPrimitiveKind)
                {
                case EdmPrimitiveTypeKind.Single:
                case EdmPrimitiveTypeKind.Double:
                    return(true);
                }

                break;

            default:
                return(sourcePrimitiveKind == targetPrimitiveKind || targetPrimitiveType.IsAssignableFrom(sourcePrimitiveType));
            }

            return(false);
        }
Пример #7
0
 internal static IEdmPrimitiveType GetCommonBaseType(this IEdmPrimitiveType firstType, IEdmPrimitiveType secondType)
 {
     IEdmPrimitiveType type;
     if (((IEdmType) firstType).IsEquivalentTo((IEdmType) secondType))
     {
         return firstType;
     }
     for (type = firstType; type != null; type = type.BaseType())
     {
         if (type.IsAssignableFrom(secondType))
         {
             return type;
         }
     }
     for (type = secondType; type != null; type = type.BaseType())
     {
         if (type.IsAssignableFrom(firstType))
         {
             return type;
         }
     }
     return null;
 }
Пример #8
0
        /// <summary>
        /// Determines if a <paramref name="sourcePrimitiveType"/> is convertibale according to OData rules to the
        /// <paramref name="targetPrimitiveType"/>.
        /// </summary>
        /// <param name="sourceNodeOrNull">The node which is to be converted.</param>
        /// <param name="sourcePrimitiveType">The type which is to be converted.</param>
        /// <param name="targetPrimitiveType">The type to which we want to convert.</param>
        /// <returns>true if the source type is convertible to the target type; otherwise false.</returns>
        internal static bool CanConvertPrimitiveTypeTo(
            SingleValueNode sourceNodeOrNull,
            IEdmPrimitiveType sourcePrimitiveType,
            IEdmPrimitiveType targetPrimitiveType)
        {
            Debug.Assert(sourcePrimitiveType != null, "sourcePrimitiveType != null");
            Debug.Assert(targetPrimitiveType != null, "targetPrimitiveType != null");

            EdmPrimitiveTypeKind sourcePrimitiveKind = sourcePrimitiveType.PrimitiveKind;
            EdmPrimitiveTypeKind targetPrimitiveKind = targetPrimitiveType.PrimitiveKind;
            switch (sourcePrimitiveKind)
            {
                case EdmPrimitiveTypeKind.SByte:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.SByte:
                        case EdmPrimitiveTypeKind.Int16:
                        case EdmPrimitiveTypeKind.Int32:
                        case EdmPrimitiveTypeKind.Int64:
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                        case EdmPrimitiveTypeKind.Decimal:
                            return true;
                    }

                    break;
                case EdmPrimitiveTypeKind.Byte:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Byte:
                        case EdmPrimitiveTypeKind.Int16:
                        case EdmPrimitiveTypeKind.Int32:
                        case EdmPrimitiveTypeKind.Int64:
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                        case EdmPrimitiveTypeKind.Decimal:
                            return true;
                    }

                    break;
                case EdmPrimitiveTypeKind.Int16:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Int16:
                        case EdmPrimitiveTypeKind.Int32:
                        case EdmPrimitiveTypeKind.Int64:
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                        case EdmPrimitiveTypeKind.Decimal:
                            return true;
                    }

                    break;
                case EdmPrimitiveTypeKind.Int32:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Int32:
                        case EdmPrimitiveTypeKind.Int64:
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                        case EdmPrimitiveTypeKind.Decimal:
                            return true;
                    }

                    break;
                case EdmPrimitiveTypeKind.Int64:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Int64:
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                        case EdmPrimitiveTypeKind.Decimal:
                            return true;
                    }

                    break;
                case EdmPrimitiveTypeKind.Single:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Single:
                        case EdmPrimitiveTypeKind.Double:
                            return true;

                        // allow single constant->decimal in order to made L,M,D,F optional
                        case EdmPrimitiveTypeKind.Decimal:
                            object tmp;
                            return TryGetConstantNodePrimitiveLDMF(sourceNodeOrNull, out tmp);
                    }

                    break;
                case EdmPrimitiveTypeKind.Double:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.Double:
                            return true;

                        // allow double constant->decimal in order to made L,M,D,F optional
                        // (if the double value actually has overflowed decimal.MaxValue, exception will occur later. more details in ExpressionLexer.cs)
                        case EdmPrimitiveTypeKind.Decimal:
                            object tmp;
                            return TryGetConstantNodePrimitiveLDMF(sourceNodeOrNull, out tmp);
                    }

                    break;
                case EdmPrimitiveTypeKind.DateTimeOffset:
                    switch (targetPrimitiveKind)
                    {
                        case EdmPrimitiveTypeKind.DateTimeOffset:
                            return true;
                        case EdmPrimitiveTypeKind.Date:
                            object tmp;
                            return TryGetConstantNodePrimitiveDate(sourceNodeOrNull, out tmp);
                    }

                    break;

                default:
                    return sourcePrimitiveKind == targetPrimitiveKind || targetPrimitiveType.IsAssignableFrom(sourcePrimitiveType);
            }

            return false;
        }